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

Maggiore dettagli più sotto.
Abbiamo avuto docker v.17.05, docker-compose v.1.21, Ubuntu Server 18 e una configurazione pulita di Let’sEncrypt. Non è necessario montare in produzione su Docker, ma una volta iniziato a costruire con Docker, è difficile fermarsi.
Quindi all'inizio presenterò le impostazioni standard che avevamo nella fase di sviluppo, ossia 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 / {
# 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;
}
Dopo di che, dobbiamo implementare SSL. A dire il vero, ho studiato la zona com per circa due ore. Tutti i suggerimenti là sono interessanti. Ma in questa fase del progetto, a noi (l'azienda) serviva qualcosa di veloce e affidabile da integrare. SSL Let’s Encrypt a nginx al contenitore e non di più.
Prima di tutto, 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 {тотКлючКоторыйВамВыдалCertBot}
E premiamo invio.
Dopo di ciò, certbot controllerà la presenza di questi record nel DNS e creerà i certificati per te.
se hai aggiunto il certificato, ma certbot non l'ha trovato — prova a riavviare il comando dopo 5-10 minuti.
Ecco, siamo orgogliosi di avere un certificato Let’sEncrypt della durata di 90 giorni, ma ora dobbiamo integrarlo in Docker.
Per fare questo, è sufficiente nel docker-compose.yml, nella sezione nginx — collegare 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 — ci rechiamo nella directory con Docker-compose, scriviamo docker-compose up -d. E verifichiamo il funzionamento di SSL. Dovrebbe andare tutto bene.
La cosa principale da ricordare è che il certificato Let’sEncrypt viene rilasciato per 90 giorni e sarà necessario rinnovarlo tramite il comando sudo certbot renew, e poi riavviare il progetto con il comando docker-compose restart
In alternativa, puoi aggiungere questa sequenza a crontab.
A mio parere, questo è il modo più semplice per collegare SSL a una web-app Docker.
P.S. Ti prego di tenere presente che tutti gli script presentati nel testo non sono definitivi, attualmente il progetto è in fase di sviluppo profondo, quindi ti chiedo di non criticare le configurazioni: saranno modificate molte volte.
Fonte: habr.com
