In questo articolo voglio condividere con voi un modo per creare un certificato SSL per la vostra web application in esecuzione su Docker, poiché non ho trovato soluzioni simili nella parte di internet in lingua russa.

Ulteriori dettagli sotto.
Avevamo docker v.17.05, docker-compose v.1.21, Ubuntu Server 18 e un flusso di Let’sEncrypt puro. Non è che sia assolutamente necessario implementare la produzione su Docker. Ma una volta che inizi a costruire Docker, diventa difficile fermarsi.
Quindi, per iniziare, ecco le impostazioni standard che avevamo nella fase di sviluppo, cioè senza la porta 443 e SSL in generale:
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.ru stomup.ru;
root \/var\/www\/StomUp\/public;
client_max_body_size 5M;
location \/ {
# prova a servire il file direttamente, ripiega su 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;
}
Successivamente, dobbiamo implementare SSL. A dire il vero, ho studiato la zona com per circa due ore. Tutte le opzioni offerte lì sono interessanti. Ma nella fase attuale del progetto, a noi (il business) era necessario integrare rapidamente e in modo affidabile SSL Let’sEncrypt al nginx al contenitore e nient'altro.
In primo luogo, abbiamo installato sul server certbot
sudo apt-get install certbot
Successivamente, abbiamo generato certificati wildcard per il nostro di dominio
sudo certbot certonly -d stomup.ru -d *.stomup.ru --manual --preferred-challenges dns
dopo aver eseguito certbot ci fornirà 2 record TXT che devono essere specificati nelle impostazioni DNS.
_acme-challenge.stomup.ru TXT {quellaChiaveCheTiHaFornitoCertBot}
E premiamo invio.
Dopo di ciò, certbot verificherà la presenza di questi record nel DNS e creerà i certificati per voi.
se hai aggiunto il certificato, ma certbot non è stato trovato — prova a rieseguire il comando tra 5-10 minuti..
Eccoci quindi orgogliosi possessori di un certificato Let’sEncrypt valido per 90 giorni, ma ora dobbiamo integrarlo in Docker.
Per farlo, in modo banale, nel docker-compose.yml, nella sezione nginx, collegate le directory.
Esempio di docker-compose.yml con SSL
version: '2'
services:
php:
build: .\/php-fpm
volumes:
- .\/StomUp:\var\/www\/StomUp
- \/etc\/letsencrypt\/live\/stomup.ru\/:\/etc\/letsencrypt\/live\/stomup.ru\/
- .\/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"
Collegato? Super — continuiamo:
Ora dobbiamo modificare la configurazione nginx per lavorare con 443 la porta e SSL in generale:
Esempio di configurazione main.conf con 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;
}
}
In effetti, dopo queste operazioni, andiamo nella directory di Docker-compose, scriviamo docker-compose up -d e verifichiamo il funzionamento dell'SSL. Tutto dovrebbe funzionare.
Ricordate che il certificato Let’sEncrypt viene emesso per 90 giorni e sarà necessario rinnovarlo con il comando sudo certbot renew, e poi riavviare il progetto con il comando docker-compose restart
Come opzione, aggiungere questa sequenza in crontab.
A mio parere, questo è il modo più semplice per collegare SSL a un'app web Docker.
P.S. Si prega di notare che tutti gli script presentati nel testo non sono definitivi, attualmente il progetto è in fase di sviluppo profondo, quindi vi chiedo di non criticare le configurazioni: saranno modificate molte altre volte.
Fonte: habr.com
