În acest articol vreau să împărtășesc cu voi o metodă de creare a unui certificat SSL pentru aplicația voastră web care funcționează pe Docker, deoarece nu am găsit o soluție similară în spațiul de limbă rusă.

Mai multe detalii mai jos.
Am avut docker v.17.05, docker-compose v.1.21, Ubuntu Server 18 și o dozare de Let’sEncrypt. Nu este neapărat necesar să desfășori un mediu de producție pe Docker, dar odată ce ai început să construiești cu Docker, devine greu să te oprești.
Așadar, pentru început, voi prezenta setările standard — pe care le-am avut în etapa de dezvoltare, adică fără portul 443 și SSL în general:
docker-compose.yml
version: '2'
services:
php:
build: .\/php-fpm
volumes:
- .\/StomUp:\/var\/www\/StomUp
- .\/php-fpm\/php.ini:\/usr\/local\/etc\/php\/php.ini
depends_on:
- mysql
container_name: "StomPHP"
web:
image: nginx:latest
ports:
- "80:80"
- "443:443"
volumes:
- .\/StomUp:\/var\/www\/StomUp
- .\/nginx\/main.conf:\/etc\/nginx\/conf.d\/default.conf
depends_on:
- php
mysql:
image: mysql:5.7
command: mysqld --sql_mode=""
environment:
MYSQL_ROOT_PASSWORD: xxx
ports:
- "3333:3306"
nginx\/main.conf
server {
listen 80;
server_name *.stomup.ro stomup.ro;
root \/var\/www\/StomUp\/public;
client_max_body_size 5M;
location \/ {
# încearcă să servească fișierul direct, revine la index.php
try_files $uri \/index.php$is_args$args;
}
location ~ ^\/index.php(\/|$) {
#fastcgi_pass unix:\/var\/run\/php7.2-fpm.sock;
fastcgi_pass php:9000;
fastcgi_split_path_info ^(.+.php)(\/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
internal;
}
location ~ .php$ {
return 404;
}
error_log \/var\/log\/nginx\/project_error.log;
access_log \/var\/log\/nginx\/project_access.log;
}
Apoi, trebuie să implementăm SSL. Sincer, am studiat zona com timp de aproximativ 2 ore. Toate opțiunile propuse acolo sunt interesante. Dar în etapa curentă a proiectului, aveam nevoie (afacerea) să adăugăm rapid și fiabil SSL Let’sEncrypt la nginx containerului și nu mai mult.
În primul rând, am instalat pe server certbot
sudo apt-get install certbot
Apoi, am generat certificate wildcard pentru domeniu
sudo certbot certonly -d stomup.ro -d *.stomup.ro --manual --preferred-challenges dns
după execuția certbot ne va oferi 2 înregistrări TXT pe care trebuie să le specificăm în setările DNS.
_acme-challenge.stomup.ro TXT {cheiaPeCareTiADatCertBot}
Și apăsăm enter.
După aceea, certbot va verifica existența acestor înregistrări în DNS și va crea certificatele pentru voi.
dacă ați adăugat certificatul, dar certbot nu l-a găsit — încercați să repetați comanda după 5-10 minute..
Iată-ne, mândri posesori ai certificatului Let’sEncrypt pentru 90 de zile, dar acum trebuie să-l integrăm în Docker.
Pentru aceasta, în mod banal, în docker-compose.yml, în secțiunea nginx — vom lega directoarele.
Exemplu de docker-compose.yml cu SSL
version: '2'
services:
php:
build: .\/php-fpm
volumes:
- .\/StomUp:\/var\/www\/StomUp
- \/etc\/letsencrypt\/live\/stomup.ro\/:\/etc\/letsencrypt\/live\/stomup.ro\/
- .\/php-fpm\/php.ini:\/usr\/local\/etc\/php\/php.ini
depends_on:
- mysql
container_name: "StomPHP"
web:
image: nginx:latest
ports:
- "80:80"
- "443:443"
volumes:
- .\/StomUp:\/var\/www\/StomUp
- \/etc\/letsencrypt\/:\/etc\/letsencrypt\/
- .\/nginx\/main.conf:\/etc\/nginx\/conf.d\/default.conf
depends_on:
- php
mysql:
image: mysql:5.7
command: mysqld --sql_mode=""
environment:
MYSQL_ROOT_PASSWORD: xxx
ports:
- "3333:3306"
Am legat? Superb — continuăm:
Acum trebuie să modificăm configurația nginx pentru a lucra cu 443 portul și SSL în general:
Exemplu de configurație main.conf cu SSL
#
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name *.stomup.ru stomup.ru;
set $base /var/www/StomUp;
root $base/public;
# SSL
ssl_certificate /etc/letsencrypt/live/stomup.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/stomup.ru/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/stomup.ru/chain.pem;
client_max_body_size 5M;
location / {
# try to serve file directly, fallback to index.php
try_files $uri /index.php$is_args$args;
}
location ~ ^/index.php(/|$) {
#fastcgi_pass unix:/var/run/php7.2-fpm.sock;
fastcgi_pass php:9000;
fastcgi_split_path_info ^(.+.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
internal;
}
location ~ .php$ {
return 404;
}
error_log /var/log/nginx/project_error.log;
access_log /var/log/nginx/project_access.log;
}
# HTTP redirect
server {
listen 80;
listen [::]:80;
server_name *.stomup.ru stomup.ru;
location / {
return 301 https://stomup.ru$request_uri;
}
}
Așadar, după aceste manevre — mergem în directorul cu Docker-compose, scriem docker-compose up -d. Și verificăm funcționarea SSL-ului. Ar trebui să pornească totul.
Cel mai important, nu uitați că certificatul Let’sEnctypt este emis pentru 90 de zile și va trebui să-l actualizați folosind comanda sudo certbot renew, iar apoi să reporniți proiectul cu comanda docker-compose restart
Ca alternativă — adăugați această secvență în crontab.
Din punctul meu de vedere, acesta este cel mai simplu mod de a conecta SSL la o aplicație web Docker.
P.S. Vă rog să țineți cont că toate scripturile prezentate în text — nu sunt finale, proiectul se află în stadiul de dezvoltare avansată, așa că vă rog să nu criticați configurațiile — acestea vor suferi multe modificări.
Sursa: habr.com
