Lokalne zDOCKERyzowane środowisko developerskie
Dzisiaj na sysops'owo - przedstawię jak w prosty sposób stworzyć w swojej lokalnej sieci środowisko developerskie na kilka / kilkanaście projektów - w dodatku łatwe i elastyczne do rozbudowy.
Wykorzystamy do tego oczywiście tytułowego Docker'a oraz świetnie się nada ku temu także malinka (Raspberry Pi). Szybki koncepcyjny diagram:
Sama konfiguracja dockera nie będzie wielki problemem - jedynie główny server (service) Nginx'a należy odpowiednio podejść - wykorzystałem do tego reverse proxy oraz upstream.
Przykładowy docker-compose - wyposażony w Nginx'a (z certbotem do generowania certyfikatów SSL), baze danych (MariaDB), Redis'aa, Rabbit'a:
version: "3"
services:
webserver:
image: nginx:latest
container_name: nginx
hostname: nginx
restart: unless-stopped
volumes:
- ./etc/nginx/conf:/etc/nginx/conf.d
- ./etc/nginx/www/nginx-default:/var/www/nginx-default
- ./etc/certbot/conf:/etc/letsencrypt
- ./etc/certbot/www:/var/www/certbot
ports:
- "80:80"
- "443:443"
networks:
- kosmcode
certbot:
image: certbot/certbot:latest
container_name: certbot
hostname: certbot
volumes:
- ./etc/certbot/conf/:/etc/letsencrypt
- ./etc/certbot/www/:/var/www/certbot
networks:
- kosmcode
mariadb:
image: mariadb:latest
container_name: mariadb
hostname: mariadb
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: "${MARIADB_ROOT_PASSWORD}"
volumes:
- mariadbData:/data/mysql/data
- ./data/db_backup:/db_backup
- ./etc/mariadb:/etc/mysql/conf.d
ports:
- "${MARIADB_PORT}:3306"
networks:
- kosmcode
redis:
image: redis:6.2-alpine
restart: unless-stopped
container_name: redis
hostname: redis
ports:
- '${REDIS_PORT}:6379'
volumes:
- ./data/redis:/data
networks:
- kosmcode
rabbitmq:
image: rabbitmq:management
container_name: rabbitmq
restart: unless-stopped
hostname: rabbitmq
environment:
RABBITMQ_DEFAULT_USER: "${RABBITMQ_USER}"
RABBITMQ_DEFAULT_PASS: "${RABBITMQ_PASSWORD}"
ports:
- "${RABBITMQ_PORT}:5672"
- "${RABBITMQ_ADMIN_PORT}:15672"
networks:
- kosmcode
networks:
kosmcode:
name: kosmcode-network
volumes:
mariadbData:
driver: local
driver_opts:
type: none
o: bind
device: ./data/mariadb
Przykładowy .env
MARIADB_PORT=3306
MARIADB_ROOT_PASSWORD=""
REDIS_PASSWORD=""
REDIS_PORT=6379
RABBITMQ_PORT=5672
RABBITMQ_ADMIN_PORT=15672
RABBITMQ_USER="guest"
RABBITMQ_PASSWORD="guest"
Istotnym jest, aby wszystkie servicy były w jednym dockerowym networku - także osobnych aplikacji. Co do tego docker-compose nie ma wielkiej filozofii - w katalogu /etc
przechowywane są różne dane serviców i tak:
/etc/certbot
- wygenerowane klucze certyfikatów SSL/etc/mariadb/my.cnf
- plik konfiguracyjny dla bazy danych/etc/nginx/conf/
- katalog przechowujący konfiguracje naszych stron (aplikacji)
Przykładowy plik konfiguracyjny dla nginx
wygląda następująco:
upstream smartpassword {
server {{ip_or_host_app_in_network}}:{{app_port}};
}
server {
listen 80;
listen [::]:80;
server_name {{site_domain}};
server_tokens off;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://smart-password.net$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name {{site_domain}};
ssl_certificate /etc/letsencrypt/live/{{site_domain}}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{site_domain}}/privkey.pem;
location / {
proxy_pass http://smartpassword;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
Oczywiście to najprostsza konfiguracja - wedle potrzeb można (a nawet trzeba) modyfikować - cache, kompresje, dodatkowe header'y które mają być przekazywane itd. Natomiast co do:
{{ip_or_host_app_in_network}}
- w upstream należy podać ip lub host naszej aplikacji, do której proxy ma być czynione. Może to być aplikacja oparta na osobnym service nginx, self-hostowana, sail dockera, octane, caddy czy django / flask python'owski np. ;) Czego akurat potrzebujemy, co obsługuje protokół HTTP/S tak naprawdę.{{app_port}}
- port naszej aplikacji, który jest wystawiony na zewnątrz.{{site_domain}}
- nazwę naszego service'u / domenę. Może to być lokalny adres servera w sieci lub jego subdomena, a także zwykła domena (jeżeli zdecydujemy się udostępniać / hostować zasoby poza naszą sieć lokalną).
Przyznam się, że sam hostuje kilka swoich mniejszych projektów na zewnątrz z sieci lokalnej - za server'ek służy mi właśnie Raspberry Pi 4B i byłem bardzo miło zaskoczony, jak dobrze znosi trudy dokeryzacji różnych usług / service'ów. Baa pozostawiając nawet jeszcze duże zasoby do działania - oczywiście nie są to sklepy produkcyjne, portale w dużym ruchem itp. aplikacje (to raczej by było szaleństwo). Ale mniejsze stronki dają jak najbardziej radę ;).
No to jak już mamy wszystko przygotowane - to wystarczy jedynie zbudować obraz, zrobić up -d
- wygenerować certyfikaty jeżeli potrzebujemy, zrestartować i powinno działać.
U mnie działa
- jak to się nawykło mawiać a naszej branży ;)