W poprzednim poście opisałem jak korzystać z technologii kontenerowej jaką jest Docker. Czas na kontynuację historii.
Go Git Service, w skrócie gogs, to mała i przejrzysta platforma do hostowania repozytoriów kodu. Ma UI bardzo zbliżony do GitHuba i posiada wszystkie niezbędne funkcje, takie jak Issues, PR, Wiki, Commit history, Source preview etc. Poniżej oficjalne screeny.
Serwer
Postanowiłem postawić maszynę wirtualną na Azurze i w końcu poradzić sobie z maszynami nowego typu (ARM). Po niemałej ilości bojów z zasadami Network Securtity Group udało mi się otworzyć porty 80 i 443 do maszyny. Wybrałem maszynę z Debianem 8 (Jessie).
Jedyne co pozostało to zainstalować Docker.
Kontenery
Gogs ma swój oficjalny obraz gogs/gogs. Dodatkowo potrzebna jest baza danych np. MySQL - mysql. Aby móc wysyłać maile potrzeba serwera SMTP np. namshi/smtp. Do tego użyłem jeszcze NGINX, ale o tym za chwilę.
Baza danych
Najpierw będziemy chcieli zainstalować MySQL. Ze strony obrazu dowiadujemy się, że należy ustawić flagę -e MYSQL_ROOT_PASSWORD=***
, gdzie w miejsce gwiazdek wpiszemy hasło dla roota. Żeby nie tracić danych po zatrzymaniu kontenera, będziemy chcieli podpiąć wolumen do /var/lib/mysql
. Do tego będziemy chcieli udostępnić port 3306 aby móc odwoływać się do bazy danych z zewnątrz kontenera.
Uruchomimy ją poleceniem
docker run -d --restart=always --name mysql -e MYSQL_ROOT_PASSWORD=*** -p 3306:3306 -v ~/mysql-data/:/var/lib/mysql mysql
Dodatkowo ustawiona została flaga --restart=always
, która ma na celu restart w przypadku błędów i automatyczne uruchomienie kontenera po restarcie systemu.
Musimy jeszcze utworzyć nową bazę danych o nazwie gogs
, więc logujemy się do konsoli mysql
i wpisujemy
CREATE DATABASE gogs COLLATE utf8_general_ci;
Aby zalogować się musimy najpierw sprawdzić IP tego kontenera przez
docker inspect mysql | grep IPAddress
SMTP
Tutaj jest jeszcze prościej, wystarczy udostępnić port 25.
docker run -d --restart=always --name mail -p 25:25 namshi/smtp
Gogs
Teraz czas na główny kontener. Po pierwsze chcemy połączyć go z poprzednimi dwoma, aby mógł się z nimi komunikować. Po drugie chcemy utworzyć wolumen na dane z folderu /data
.
docker run -d --restart=always --name gogs --link mail:mail --link mysql:mysql -v ~/gogs-data/:/data gogs/gogs
Gdyby nie to, że postanowiłem opakować gogs w proxy HTTP, to dodalibyśmy tu jeszcze -p 80:3000
, aby uzyskać publiczny dostęp do witryny.
Podczas konfiguracji odwołujemy się do bazy danych przez nazwę kontenera mysql
, tak samo z mail
.
HTTPS
Ponieważ połączenie powinno być szyfrowane postanowiłem się pomęczyć i zrobić porządne połączenie. Gogs ma wbudowane wsparcie dla HTTPS, natomiast wiele osób robiło lokalne proxy HTTP i szyfrowanie po stronie Apache’a lub NGINXa, więc i ja postanowiłem tak zrobić. Jedyne co musiałem zmienić w konfiguracji gogs, to ustawić https://
w ROOT_URL
Kontener NGINX
Kontener NGINX potrzebuje połączenie z kontenerem gogs, pliku konfiguracyjnego, certyfikatów SSL i upublicznienia portów 80 i 443.
docker run -d --restart=always --name nginx --link gogs:gogs -p 443:443 -p 80:80 -v ~/nginx/nginx.conf:/etc/nginx/nginx.conf:ro -v /etc/letsencrypt/live/myurl/:/etc/myssl/ nginx
Certyfikat SSL
HTTPS wymaga posiadania certyfikatu SSL podpisanego przez CA (Certification Authority). Normalnie jest to płatne i trochę skomplikowane, ale nie dawno Let’s Encrypt udostępnił narzędzie do darmowego generowania certyfikatów.
Po odrobinie problemów udało mi się uzyskać działający certyfikat, który podpiąłem do kontenera nginx i dodałem wpis do pliku konfiguracyjnego.
Plik konfiguracyjny
http {
server {
listen 80;
return 301 https://$http_host$request_uri;
server_name myurl;
}
server {
listen 443;
server_name myurl;
ssl on;
ssl_certificate /etc/myssl/cert.pem;
ssl_certificate_key /etc/myssl/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://gogs:3000/;
}
}
}
Ustawiłem automatyczne przekierowanie z HTTP → HTTPS, SSL i proxy do kontenera gogs.
Czy działa?
Tak działa :) Utworzyłem nowe konto, testowe repozytorium i sprawdziłem czy Git sobie radzi z klonowaniem i pushowaniem.
Jestem bardzo zadowolony z wyniku.