En este artículo quiero compartir con ustedes un método para crear un certificado SSL para su aplicación web que funciona en Docker, ya que no encontré una solución similar en la parte de habla rusa de Internet.

Más detalles debajo.
Teníamos Docker v.17.05, docker-compose v.1.21, Ubuntu Server 18 y una pizca de Let’sEncrypt puro. No es que sea necesario desplegar producción en Docker. Pero una vez que comienzas a construir en Docker, se vuelve difícil detenerse.
Así que para empezar, proporcionaré las configuraciones estándar que teníamos en la etapa de dev, es decir, sin el puerto 443 y SSL en 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.ru stomup.ru;
root \/var\/www\/StomUp\/public;
client_max_body_size 5M;
location \/ {
# intentar servir el archivo directamente, volver a 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;
}
A continuación, necesitamos implementar SSL. Para ser honesto, estudié la zona com durante aproximadamente 2 horas. Todas las opciones propuestas allí son interesantes. Pero en esta etapa del proyecto, necesitábamos (el negocio) integrar rápida y confiablemente SSL Let’sEncrypt a nginx al contenedor y no más.
Primero instalamos en el servidor certbot
sudo apt-get install certbot
Después generamos certificados wildcard para nuestro dominio
sudo certbot certonly -d stomup.ru -d *.stomup.ru --manual --preferred-challenges dns
después de ejecutar certbot, se nos proporcionarán 2 registros TXT que deben ser indicados en la configuración de DNS.
_acme-challenge.stomup.ru TXT {laClaveQueTeDioCertBot}
Y presionamos enter.
Después de esto, certbot verificará la existencia de esos registros en DNS y creará los certificados para usted.
si has añadido el certificado, pero certbot no lo encontró, intenta reiniciar el comando en 5-10 minutos..
Ahora somos orgullosos propietarios de un certificado Let’sEncrypt por 90 días, pero ahora necesitamos integrarlo en Docker.
Para ello, simplemente en el docker-compose.yml, en la sección de nginx, vinculamos los directorios.
Ejemplo de 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"
¿Vinculamos? Genial, continuamos:
Ahora necesitamos modificar la configuración nginx para trabajar con 443 el puerto y SSL en general:
Ejemplo de la configuración 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;
}
}
Después de estas maniobras, vamos al directorio con Docker-compose, escribimos docker-compose up -d. Y verificamos la operatividad de SSL. Todo debería funcionar.
No olviden que el certificado Let’sEncrypt se emite por 90 días y necesitarán renovarlo con el comando sudo certbot renew, y luego reiniciar el proyecto con el comando docker-compose restart
Como alternativa, agregar esta secuencia en crontab.
En mi opinión, esta es la forma más sencilla de conectar SSL a una aplicación web en Docker.
P.D. Tengan en cuenta que todos los scripts presentados en el texto no son definitivos, actualmente el proyecto se encuentra en una fase de desarrollo profundo, por lo que les pido que no critiquen las configuraciones, ya que cambiarán muchas veces.
Fuente: habr.com
