Neste artigo, quero compartilhar com vocês um método para criar um certificado SSL para sua aplicação web rodando no Docker, porque... Não encontrei essa solução na parte da Internet em língua russa.
Mais detalhes abaixo do corte.
Tínhamos docker v.17.05, docker-compose v.1.21, Ubuntu Server 18 e meio litro de Let'sEncrypt puro. Não é necessário implantar a produção no Docker. Mas depois que você começa a construir o Docker, fica difícil parar.
Então, para começar, darei as configurações padrão - que tínhamos no estágio de desenvolvimento, ou seja, sem porta 443 e SSL em geral:
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;
}
Em seguida, precisamos implementar SSL. Para ser sincero, passei cerca de 2 horas estudando a zona de comunicação. Todas as opções oferecidas são interessantes. Mas no estágio atual do projeto, nós (a empresa) precisávamos parafusar de forma rápida e confiável SSL Let'sEnctypt к nginx recipiente e nada mais.
Primeiro de tudo, instalamos no servidor certbot
sudo apt-get install certbot
A seguir, geramos certificados curinga para nosso domínio
sudo certbot certonly -d stomup.ru -d *.stomup.ru --manual --preferred-challenges dns
após a execução, o certbot nos fornecerá 2 registros TXT que precisam ser especificados nas configurações de DNS.
_acme-challenge.stomup.ru TXT {тотКлючКоторыйВамВыдалCertBot}
E pressione Enter.
Depois disso, o certbot verificará a presença desses registros no DNS e criará certificados para você.
se você adicionou um certificado, mas certbot não encontrei - tente reiniciar o comando após 5 a 10 minutos.
Bem, aqui somos os orgulhosos proprietários de um certificado Let'sEncrypt por 90 dias, mas agora precisamos carregá-lo no Docker.
Para fazer isso, da forma mais trivial, em docker-compose.yml, na seção nginx, vinculamos os diretórios.
Exemplo docker-compose.yml com 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"
Vinculado? Ótimo - vamos continuar:
Agora precisamos mudar a configuração nginx trabalhar com 443 porto e SSL geralmente:
Exemplo de configuração main.conf com 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;
}
}
Na verdade, após essas manipulações, vamos para o diretório com Docker-compose, escrevemos docker-compose up -d. E verificamos a funcionalidade do SSL. Tudo deveria decolar.
O principal é não esquecer que o certificado Let'sEnctypt é emitido por 90 dias e você precisará renová-lo através do comando sudo certbot renew
e reinicie o projeto com o comando docker-compose restart
Outra opção é adicionar esta sequência ao crontab.
Na minha opinião, esta é a maneira mais fácil de conectar SSL ao aplicativo Web Docker.
PS Por favor, leve em consideração que todos os scripts apresentados no texto não são finais, o projeto está agora em fase profunda de Dev, então gostaria de pedir que não critiquem as configurações - elas serão modificadas várias vezes.
Fonte: habr.com