Post

Construindo um Blog com Jekyll e CI/CD - Parte 3: Proxy Reverso com Nginx e Certbot

Construindo um Blog com Jekyll e CI/CD - Parte 3: Proxy Reverso com Nginx e Certbot

Configurando o Proxy Reverso com Nginx para Ambos os Ambientes

Nesta terceira e última parte do nosso tutorial, vamos abordar um componente crucial para a segurança, escalabilidade e organização do seu blog Jekyll: o proxy reverso Nginx. Um proxy reverso atua como um intermediário entre os clientes (navegadores dos usuários) e o seu servidor de aplicação (o contêiner Docker do seu blog). Ele é fundamental para gerenciar o tráfego, lidar com certificados SSL (HTTPS) e rotear requisições para os ambientes de homologação e produção de forma transparente.

Utilizaremos o Nginx em conjunto com o Certbot, ambos rodando em contêineres Docker, para automatizar a obtenção e renovação de certificados SSL gratuitos do Let's Encrypt. Isso garantirá que seu blog seja acessível via HTTPS, protegendo a comunicação entre seus usuários e o servidor.

Estrutura de Diretórios para o Proxy

Para manter a organização e facilitar o gerenciamento dos arquivos de configuração do Nginx e do Certbot, criaremos uma estrutura de diretórios específica na sua VPS. Estes diretórios serão mapeados como volumes para os contêineres Docker, garantindo a persistência dos dados e configurações.

1
sudo mkdir -p /opt/stacks/proxy/nginx/templates /opt/stacks/proxy/nginx/conf.d /opt/stacks/proxy/certbot/conf /opt/stacks/proxy/certbot/www

Explicação dos diretórios:

  • /opt/stacks/proxy: O diretório raiz para todos os arquivos relacionados ao seu stack de proxy.
  • /opt/stacks/proxy/nginx/templates: Conterá os templates de configuração do Nginx. Usaremos envsubst para preencher variáveis de ambiente nesses templates antes de gerar a configuração final.
  • /opt/stacks/proxy/nginx/conf.d: Onde o Nginx carregará suas configurações finais. O template será processado e o arquivo de configuração resultante será colocado aqui.
  • /opt/stacks/proxy/certbot/conf: Armazenará os certificados SSL emitidos pelo Let's Encrypt. Este diretório é mapeado para /etc/letsencrypt dentro do contêiner Certbot.
  • /opt/stacks/proxy/certbot/www: Será usado pelo Certbot para o desafio webroot, onde ele coloca arquivos temporários para verificar a propriedade do domínio durante a emissão/renovação de certificados.

Configurando o Proxy Reverso com Docker Compose

Vamos definir os serviços do Nginx e Certbot usando um arquivo docker-compose.yml. O Docker Compose nos permite definir e executar aplicações multi-contêiner de forma declarativa.

Nota: você também pode usar o Traefik como alternativa ao Nginx+Certbot

Crie o arquivo /opt/stacks/proxy/docker-compose.yml com o seguinte conteúdo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# /opt/stacks/proxy/docker-compose.yml
# Este arquivo define os serviços para o proxy reverso Nginx e o Certbot,
# permitindo a automação da obtenção e renovação de certificados SSL.

services:
  nginx:
    image: nginx:1-alpine
    container_name: proxy_nginx # Nome do contêiner Nginx para fácil referência
    restart: unless-stopped # Garante que o contêiner reinicie automaticamente
    ports:
      # Expõe as portas 80 (HTTP) e 443 (HTTPS) no host, para tráfego IPv4 e IPv6
      - "80:80"
      - "443:443"
    volumes:
      # Monta o diretório de templates do Nginx (somente leitura)
      - ./nginx/templates:/etc/nginx/templates:ro
      # Monta o diretório onde a configuração final do Nginx será gerada
      - ./nginx/conf.d:/etc/nginx/conf.d
      # Monta os certificados Let\'s Encrypt (somente leitura) para o Nginx
      - certbot_conf:/etc/letsencrypt:ro
      # Monta o volume para os desafios do Certbot (escrita)
      - certbot_www:/var/www/certbot
      # Monta o arquivo DH params (Diffie-Hellman) para segurança SSL aprimorada
      # Este arquivo deve ser gerado previamente: openssl dhparam -out /opt/stacks/proxy/nginx/templates/dhparam.pem 2048
      - ./nginx/templates/dhparam.pem:/etc/nginx/templates/dhparam.pem:ro
    environment:
      # Variáveis de ambiente que serão usadas pelo `envsubst` no template Nginx
      - PRIMARY_DOMAIN=${PRIMARY_DOMAIN}
      - TZ=${TZ}
    networks:
      proxy-net: # Conecta o Nginx à rede Docker personalizada \'proxy-net\'
        ipv4_address: 192.168.8.200 # Atribui um IP fixo IPv4 ao Nginx nesta rede
        ipv6_address: fd00:0:0:8::200 # Atribui um IP fixo IPv6 ao Nginx nesta rede
    # Comando de inicialização do Nginx:
    # 1. Processa o template Nginx (`nginx.template`) substituindo variáveis de ambiente
    # 2. Salva a configuração resultante em `default.conf`
    # 3. Inicia o Nginx em modo `daemon off;` para que ele rode em primeiro plano no contêiner
    command: /bin/sh -c "envsubst \'\\$$PRIMARY_DOMAIN\' < /etc/nginx/templates/nginx.template > /etc/nginx/conf.d/default.conf && nginx -g \'daemon off;\'"

  certbot:
    image: certbot/certbot:latest
    container_name: proxy_certbot # Nome do contêiner Certbot
    restart: unless-stopped # Garante que o contêiner reinicie automaticamente
    depends_on:
      - nginx  # Garante que o Nginx esteja rodando antes do Certbot tentar obter certificados
    volumes:
      # Monta os volumes para persistir as configurações e certificados do Certbot
      - certbot_conf:/etc/letsencrypt
      - certbot_www:/var/www/certbot
    networks:
      - proxy-net # Conecta o Certbot à mesma rede \'proxy-net\' para comunicação interna
    # Entrypoint para renovação automática:
    # O Certbot tentará renovar os certificados a cada 12 horas.
    # OBS: Descomente esta linha APÓS a primeira obtenção bem-sucedida dos certificados.
    # entrypoint: "/bin/sh -c \'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;\'

volumes:
  certbot_conf:
    driver: local # Define um volume Docker gerenciado para os certificados
  certbot_www:
    driver: local # Define um volume Docker gerenciado para os desafios webroot

networks:
  proxy-net:
    external: true # Indica que a rede \'proxy-net\' já existe e foi criada manualmente

Explicação Detalhada do docker-compose.yml:

  • services: Define os contêineres que compõem sua aplicação.
    • nginx: O serviço do proxy reverso.
      • image: nginx:1-alpine: Usa a imagem oficial do Nginx, versão alpine para ser leve.
      • ports: Mapeia as portas 80 e 443 do host para as portas correspondentes no contêiner, tornando o Nginx acessível externamente.
      • volumes: Mapeia diretórios do host para dentro do contêiner para persistência de dados e configurações. Note o uso de volumes nomeados (certbot_conf, certbot_www) para os dados do Certbot, que são gerenciados pelo Docker.
      • environment: Passa variáveis de ambiente para o contêiner Nginx, que serão usadas no template de configuração.
      • networks: Conecta o contêiner Nginx à rede proxy-net que criamos na Parte 2. Os ipv4_address e ipv6_address fixos são importantes para que outros contêineres (como o blog Jekyll) possam se referir ao Nginx por um IP estável, e para que o Nginx possa ser configurado para rotear o tráfego de forma previsível.
      • command: Este comando é executado na inicialização do contêiner Nginx. Ele usa envsubst para preencher o template nginx.template com as variáveis de ambiente e gera o arquivo de configuração final default.conf. Em seguida, inicia o Nginx.
    • certbot: O serviço para obtenção e renovação de certificados SSL.
      • image: certbot/certbot:latest: Usa a imagem oficial do Certbot.
      • depends_on: - nginx: Garante que o Nginx esteja em execução antes que o Certbot tente se comunicar com ele para o desafio webroot.
      • volumes: Mapeia os mesmos volumes nomeados que o Nginx para que ambos possam acessar os certificados e os arquivos de desafio.
      • entrypoint: O comando que o Certbot executa. A linha comentada é para a renovação automática, que deve ser ativada após a primeira obtenção manual dos certificados.
  • volumes: Define os volumes nomeados que serão usados pelos serviços. O driver: local indica que o Docker gerenciará esses volumes no sistema de arquivos local.
  • networks: Define as redes que os serviços usarão. external: true é crucial aqui, pois indica que a rede proxy-net já foi criada manualmente (na Parte 2) e o Docker Compose não deve tentar criá-la novamente.

Arquivo de Variáveis de Ambiente (.env)

Crie o arquivo /opt/stacks/proxy/.env para armazenar variáveis de ambiente que serão usadas pelo Docker Compose. Isso mantém informações sensíveis ou específicas do ambiente fora do docker-compose.yml.

# /opt/stacks/proxy/.env
# Variáveis de Ambiente para o Stack do Proxy

# Email para renovação e notificações do Let\'s Encrypt
CERTBOT_EMAIL=seu.email@example.com # SUBSTITUA PELO SEU E-MAIL REAL

# Domínios (separados por vírgula para o comando Certbot inicial)
# Inclua todos os subdomínios que você usará (ex: seu-dominio.com, www.seu-dominio.com, homolog.seu-dominio.com)
DOMAIN_NAMES=seu-dominio.com,www.seu-dominio.com,homolog.seu-dominio.com # SUBSTITUA PELOS SEUS DOMÍNIOS

# Domínio principal (usado no nome do certificado e template Nginx)
# Escolha um como o domínio principal para o certificado SSL
PRIMARY_DOMAIN=seu-dominio.com # SUBSTITUA PELO SEU DOMÍNIO PRINCIPAL

# Fuso Horário (Ex: America/Sao_Paulo)
TZ=America/Sao_Paulo

Importante: Substitua os valores de CERTBOT_EMAIL, DOMAIN_NAMES e PRIMARY_DOMAIN pelos seus dados reais.

Configuração Mínima do Nginx para Obtenção de Certificados

Antes de obter os certificados SSL, o Nginx precisa de uma configuração mínima para responder aos desafios do Certbot. Crie o arquivo /opt/stacks/proxy/nginx/templates/nginx.template com o seguinte conteúdo. Esta configuração redireciona todo o tráfego HTTP para HTTPS, exceto para o caminho de desafio do Certbot.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# /opt/stacks/proxy/nginx/templates/nginx.template (Versão MÍNIMA para Certbot)
# Este template é usado inicialmente para permitir que o Certbot valide seus domínios
# através do desafio HTTP-01 antes de configurar o proxy completo.

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    # O server_name _; aceita qualquer nome de host para o desafio ACME
    server_name _;

    # Configuração para o desafio Let\'s Encrypt (ACME-challenge)
    location /.well-known/acme-challenge/ {
        root /var/www/certbot; # O Certbot colocará os arquivos de validação aqui
    }

    # Bloqueia outras requisições HTTP para evitar acesso não seguro antes do HTTPS
    location / {
        return 404; # Retorna 404 para qualquer outra requisição na porta 80
    }
}

Iniciando o Proxy (Primeira Vez):

Navegue até o diretório do seu stack de proxy e inicie os contêineres. Neste momento, o Nginx estará rodando com a configuração mínima, pronto para o Certbot.

1
2
cd /opt/stacks/proxy
docker compose up -d

Gerando os Certificados SSL com Certbot

Com o Nginx rodando e a configuração mínima no lugar, podemos agora usar o Certbot para obter os certificados SSL para seus domínios. Faremos isso em duas etapas: primeiro um teste e depois a emissão real.

  1. Testando a Criação do Certificado (Staging): É altamente recomendável testar o processo de emissão de certificados usando o ambiente de staging do Let's Encrypt. Isso evita que você atinja os limites de taxa de emissão de certificados reais em caso de erros.
    1
    2
    3
    4
    5
    6
    7
    8
    
    cd /opt/stacks/proxy
    docker compose --env-file .env run --rm \
        certbot certonly --webroot --webroot-path /var/www/certbot/ \
        --email "${CERTBOT_EMAIL}" --agree-tos --no-eff-email \
        --staging \
        -d ${PRIMARY_DOMAIN} \
        -d www.${PRIMARY_DOMAIN} \
        -d homolog.${PRIMARY_DOMAIN} # Adicione todos os seus domínios aqui
    
    • --env-file .env: Carrega as variáveis do arquivo .env.
    • --rm: Remove o contêiner Certbot após a execução.
    • certonly: Apenas obtém o certificado, não o instala no Nginx (faremos isso manualmente no template).
    • --webroot --webroot-path /var/www/certbot/: Usa o método de desafio webroot, onde o Certbot coloca arquivos em um diretório específico (/var/www/certbot/) que o Nginx serve.
    • --email "${CERTBOT_EMAIL}": Seu e-mail para notificações do Let's Encrypt.
    • --agree-tos: Aceita os termos de serviço do Let's Encrypt.
    • --no-eff-email: Opta por não compartilhar seu e-mail com a EFF (Electronic Frontier Foundation).
    • --staging: Usa o ambiente de staging para testes.
    • -d: Especifica os domínios para os quais você deseja obter certificados. Certifique-se de listar todos os domínios e subdomínios que você usará (produção e homologação).

    Se o teste for bem-sucedido, você verá uma mensagem indicando que o certificado de staging foi obtido com sucesso.

  2. Criando os Certificados Reais (Produção): Após o teste bem-sucedido, execute o mesmo comando, mas remova a flag --staging para obter os certificados reais.
    1
    2
    3
    4
    5
    6
    7
    
    cd /opt/stacks/proxy
    docker compose --env-file .env run --rm \
        certbot certonly --webroot --webroot-path /var/www/certbot \
        --email "${CERTBOT_EMAIL}" --agree-tos --no-eff-email \
        -d ${PRIMARY_DOMAIN} \
        -d www.${PRIMARY_DOMAIN} \
        -d homolog.${PRIMARY_DOMAIN} # Mantenha todos os seus domínios aqui
    

    Se tudo ocorrer bem, você verá uma mensagem de sucesso e seus certificados estarão armazenados em /opt/stacks/proxy/certbot/conf/live/${PRIMARY_DOMAIN}/.

Configuração Completa do Nginx para Proxy Reverso

Agora que temos os certificados, vamos atualizar o template do Nginx para incluir a configuração completa do proxy reverso, roteando o tráfego para os contêineres do blog Jekyll de produção e homologação.

Primeiro, gere o arquivo dhparam.pem para segurança SSL aprimorada. Este arquivo deve ser gerado apenas uma vez:

1
openssl dhparam -out /opt/stacks/proxy/nginx/templates/dhparam.pem 2048

Crie o arquivo /opt/stacks/proxy/nginx/templates/proxy_params.conf para definir parâmetros comuns de proxy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# /opt/stacks/proxy/nginx/templates/proxy_params.conf
# Este arquivo contém parâmetros comuns para todas as configurações de proxy.

# Aumenta os buffers de hash para cabeçalhos de proxy, útil para cabeçalhos grandes
proxy_headers_hash_bucket_size 128;
proxy_headers_hash_max_size 1024;

# Parâmetros comuns a todos os proxys para repassar informações do cliente original
proxy_set_header Host $host; # Repassa o cabeçalho Host original
proxy_set_header X-Real-IP $remote_addr; # Repassa o IP real do cliente
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Adiciona o IP do cliente à lista X-Forwarded-For
proxy_set_header X-Forwarded-Proto $scheme; # Repassa o protocolo original (HTTP/HTTPS)
proxy_set_header X-Forwarded-Host $host; # Repassa o host original
proxy_set_header X-Forwarded-Port $server_port; # Repassa a porta original

Crie o arquivo /opt/stacks/proxy/nginx/templates/ssl_params.conf para definir parâmetros de segurança SSL:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# /opt/stacks/proxy/nginx/templates/ssl_params.conf
# Este arquivo define configurações de segurança SSL/TLS para o Nginx.

# Arquivo DH Params gerado manualmente para Perfect Forward Secrecy
ssl_dhparam /etc/nginx/templates/dhparam.pem;

# Protocolos SSL/TLS permitidos (priorize versões mais seguras)
ssl_protocols TLSv1.2 TLSv1.3;

# Cifras (prioridade para TLS 1.3 e ECDHE para segurança e performance)
ssl_ciphers TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:EECDH+CHACHA20:EECDH+AESGCM:EECDH+AES:SHA256+AESGCM:SHA256+AES;

# Curvas elípticas para criptografia (X25519 é preferível)
ssl_ecdh_curve X25519:secp384r1;

# Cache de sessão SSL para melhor performance
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;

# OCSP Stapling (comentado, mas pode ser ativado para melhor performance e privacidade)
#ssl_stapling on;
#ssl_stapling_verify on;
ssl_stapling off; # Desativado por padrão para simplificar, mas considere ativar

# Resolver DNS para OCSP Stapling e outras resoluções (Cloudflare + Google, IPv4/IPv6)
resolver 1.1.1.1 8.8.8.8 [2606:4700:4700::1111] [2001:4860:4860::8888] valid=3600s;
resolver_timeout 5s;

# Parâmetros adicionais recomendados para segurança
ssl_prefer_server_ciphers on;
ssl_buffer_size 4k;

Agora, atualize o arquivo /opt/stacks/proxy/nginx/templates/nginx.template com a configuração completa. Este template agora inclui blocos server separados para HTTP (redirecionamento para HTTPS) e para os ambientes de produção e homologação (HTTPS).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# /opt/stacks/proxy/nginx/templates/nginx.template
# Template Nginx completo para proxy reverso, incluindo redirecionamento HTTP para HTTPS,
# e roteamento para os contêineres Jekyll de produção e homologação.

# Bloco HTTP: Redireciona todo o tráfego HTTP para HTTPS e lida com desafios ACME
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    # O server_name _; aceita qualquer nome de host para o desafio ACME e redirecionamento
    server_name _;

    # Roteamento específico para os desafios do Let\'s Encrypt
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    # Redirecionamento permanente (301) de HTTP para HTTPS para todas as outras requisições
    location / {
        return 301 https://$host$request_uri;
    }
}

# Bloco HTTPS para o Ambiente de Produção (seu-dominio.com, www.seu-dominio.com)
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on; # Habilita HTTP/2 para melhor performance
    server_name ${PRIMARY_DOMAIN} www.${PRIMARY_DOMAIN}; # Define os domínios para este bloco

    # Caminhos para os certificados SSL obtidos pelo Certbot
    ssl_certificate /etc/letsencrypt/live/${PRIMARY_DOMAIN}/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/${PRIMARY_DOMAIN}/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/${PRIMARY_DOMAIN}/chain.pem;

    # Inclui as configurações de segurança SSL/TLS comuns
    include /etc/nginx/templates/ssl_params.conf;

    # Cabeçalhos de Segurança HTTP (melhoram a segurança do site)
    add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; # HSTS
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin";
    proxy_hide_header X-Powered-By; # Oculta o cabeçalho X-Powered-By para maior segurança

    location / {
        # Proxy para o contêiner Jekyll de produção
        # \'jekyll-chirpy-prd\' é o nome do contêiner definido no .gitlab-ci.yml
        # O Nginx se comunica com ele através da rede Docker \'proxy-net\'
        proxy_pass http://jekyll-chirpy-prd:80;
        # Inclui os parâmetros comuns de proxy
        include /etc/nginx/templates/proxy_params.conf;
    }
}

# Bloco HTTPS para o Ambiente de Homologação (homolog.seu-dominio.com)
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    
    server_name homolog.${PRIMARY_DOMAIN}; # Define o subdomínio para homologação

    # Caminhos para os certificados SSL (compartilhados com produção, pois são do mesmo domínio base)
    ssl_certificate /etc/letsencrypt/live/${PRIMARY_DOMAIN}/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/${PRIMARY_DOMAIN}/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/${PRIMARY_DOMAIN}/chain.pem;

    # Inclui as configurações de segurança SSL/TLS comuns
    include /etc/nginx/templates/ssl_params.conf;

    # Cabeçalhos de Segurança HTTP (ajuste conforme necessidade)
    add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin";
    proxy_hide_header X-Powered-By;

    location / {
        # Proxy para o contêiner Jekyll de homologação
        # \'jekyll-chirpy-hml\' é o nome do contêiner definido no .gitlab-ci.yml
        proxy_pass http://jekyll-chirpy-hml:80;
        # Inclui os parâmetros comuns de proxy
        include /etc/nginx/templates/proxy_params.conf;
    }
}

Reiniciando o Proxy com a Nova Configuração:

Após atualizar o nginx.template, você precisa reiniciar o contêiner Nginx para que ele carregue a nova configuração. O Certbot também pode ser ativado para renovação automática agora.

  1. Pare e remova os contêineres atuais:
    1
    2
    
    cd /opt/stacks/proxy
    docker compose down
    
  2. Edite o docker-compose.yml para ativar a renovação automática do Certbot: Descomente a linha entrypoint: no serviço certbot no seu docker-compose.yml.
    1
    2
    3
    4
    5
    6
    
    # ...
    certbot:
      # ...
      # Entrypoint para renovação automática. OBS: descomentar após a criação dos certificados
      entrypoint: "/bin/sh -c \'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;\'
    # ...
    
  3. Inicie os contêineres novamente:
    1
    
    docker compose up -d
    

    O Nginx agora estará servindo seu blog via HTTPS, roteando para os contêineres Jekyll apropriados.

Verificando a Configuração do Proxy e SSL

Após configurar o Nginx e obter os certificados, é fundamental verificar se tudo está funcionando como esperado em termos de segurança e acessibilidade.

  1. Teste de Acesso via curl: Use curl para verificar se o redirecionamento HTTP para HTTPS está funcionando e se o site responde corretamente.
    1
    2
    
    curl -I http://homolog.seu-dominio.com # Deve redirecionar para HTTPS
    curl -I https://homolog.seu-dominio.com # Deve mostrar cabeçalhos de resposta do site
    
  2. Análise de Segurança SSL (SSL Labs): Para uma análise aprofundada da configuração SSL do seu servidor, utilize a ferramenta online SSL Labs. Ela fornecerá um relatório detalhado sobre a qualidade da sua configuração SSL, incluindo protocolos, cifras e vulnerabilidades.
  3. Análise de Cabeçalhos de Segurança (Security Headers): Verifique se os cabeçalhos de segurança HTTP que você configurou no Nginx estão sendo enviados corretamente. Isso é importante para proteger seu site contra diversos ataques.
  4. Verificar se o HTTP/2 está ativo: Confirme se o HTTP/2 está sendo usado para as conexões HTTPS, o que melhora a performance do carregamento da página.
    1
    
    openssl s_client -connect homolog.seu-dominio.com:443 -alpn h2 < /dev/null 2>&1 | grep -E \'ALPN protocol|HTTP/2\'
    

    Você deve ver ALPN protocol: h2 na saída.

Testando o Acesso aos Sites

Finalmente, teste o acesso aos seus blogs nos ambientes de produção e homologação através de um navegador web:

  • Acesse o site de produção: https://seu-dominio.com
  • Acesse o site de homologação: https://homolog.seu-dominio.com

Ambos devem carregar corretamente via HTTPS, exibindo o conteúdo do seu blog Jekyll.

Gerenciando o Fluxo de Trabalho entre Homologação e Produção

Com o pipeline de CI/CD e o proxy reverso configurados, você tem uma infraestrutura robusta para gerenciar o desenvolvimento e a implantação do seu blog. A chave para aproveitar ao máximo essa configuração é adotar um fluxo de trabalho de Git que separe claramente os ambientes de desenvolvimento, homologação e produção.

Estratégia de Branches Recomendada

Uma estratégia de branches bem definida é essencial para garantir a estabilidade do ambiente de produção e permitir o desenvolvimento contínuo de novas funcionalidades.

  1. Branch main (Produção):
    • Propósito: Esta branch representa o código que está atualmente em produção e acessível publicamente. Ela deve ser sempre estável e funcional.
    • Atualizações: Recebe alterações apenas via merge da branch homolog (ou, em casos de emergência, via hotfix). Nunca faça commits diretos nesta branch.
    • Pipeline: O pipeline de CI/CD configurado para a branch main é responsável por construir e implantar o blog no ambiente de produção.
  2. Branch homolog (Homologação/Staging):
    • Propósito: Esta branch serve como um ambiente de pré-produção. Todas as novas funcionalidades, correções de bugs e alterações de conteúdo devem ser testadas e validadas aqui antes de serem promovidas para main.
    • Atualizações: Recebe alterações via merge de branches de feature ou bugfix.
    • Pipeline: O pipeline de CI/CD configurado para a branch homolog é responsável por construir e implantar o blog no ambiente de homologação.
  3. Branches de feature (Funcionalidade) / bugfix (Correção de Bug):
    • Propósito: Criadas a partir da branch homolog para desenvolver novas funcionalidades ou corrigir bugs específicos de forma isolada.
    • Atualizações: O desenvolvimento ocorre exclusivamente nestas branches. Uma vez concluídas e testadas localmente, são mescladas de volta para homolog.

Fluxo de Desenvolvimento Típico

Siga este fluxo para adicionar novas funcionalidades ou fazer alterações no seu blog:

  1. Iniciar uma Nova Funcionalidade/Correção: Sempre comece a partir da branch homolog para garantir que você esteja trabalhando com a versão mais recente do ambiente de homologação.
    1
    2
    3
    
    git checkout homolog # Garante que você está na branch homolog
    git pull # Puxa as últimas alterações da homolog
    git checkout -b feature/nome-da-sua-funcionalidade # Cria uma nova branch para sua funcionalidade
    
  2. Desenvolver e Testar Localmente: Faça as alterações necessárias no código do seu blog. Durante o desenvolvimento, você pode testar suas mudanças localmente usando o servidor de desenvolvimento do Jekyll.
    1
    
    bundle exec jekyll serve # Inicia o servidor Jekyll localmente (geralmente em http://localhost:4000)
    
  3. Enviar para Homologação: Quando a funcionalidade estiver pronta e testada localmente, faça commit das suas alterações e envie a branch de feature para o GitLab.
    1
    2
    3
    
    git add . # Adiciona todos os arquivos alterados
    git commit -m "feat: Implementa a nova funcionalidade X" # Mensagem de commit descritiva
    git push origin feature/nome-da-sua-funcionalidade # Envia a branch para o GitLab
    
  4. Criar um Merge Request para Homologação: No GitLab, crie um Merge Request (MR) da sua branch feature/nome-da-sua-funcionalidade para a branch homolog. Este é o momento para revisão de código por pares e discussões. Após a aprovação, o MR pode ser mesclado, o que acionará o pipeline de CI/CD para o ambiente de homologação.

  5. Testar no Ambiente de Homologação: Após o merge para homolog e a conclusão do pipeline, acesse https://homolog.seu-dominio.com para verificar as alterações. Realize testes completos para garantir que a nova funcionalidade funcione como esperado e não introduza regressões.

  6. Promover para Produção: Uma vez que as alterações foram validadas e aprovadas no ambiente de homologação, crie um novo Merge Request da branch homolog para a branch main. Este MR deve ser revisado e aprovado. Após o merge, o pipeline de CI/CD para a branch main será acionado, implantando as alterações no ambiente de produção.

  7. Verificar em Produção: Acesse https://seu-dominio.com para confirmar que as alterações foram aplicadas corretamente no ambiente de produção.

Resolução de Problemas e Hotfixes

Mesmo com um fluxo de trabalho robusto, problemas podem surgir. É importante ter um plano para lidar com eles.

  1. Rollback em Homologação: Se um problema for detectado no ambiente de homologação e você precisar reverter rapidamente para um estado anterior estável, você pode usar git reset --hard. Use este comando com extrema cautela, pois ele reescreve o histórico do Git.
    1
    2
    3
    
    git checkout homolog
    git reset --hard <hash-do-commit-anterior-estável> # Substitua pelo hash do commit desejado
    git push --force origin homolog # Força o push para reescrever o histórico remoto
    

    Isso reverterá a branch homolog para um commit anterior e acionará um novo pipeline para implantar essa versão.

  2. Hotfix para Produção: Para problemas críticos que afetam o ambiente de produção e exigem uma correção imediata, um hotfix pode ser necessário. O ideal é criar uma branch de hotfix a partir de main, aplicar a correção e mesclá-la de volta para main o mais rápido possível. Em seguida, a correção deve ser propagada para homolog para manter a consistência.
    1
    2
    3
    4
    5
    6
    
    git checkout main # Mude para a branch de produção
    git checkout -b hotfix/correcao-urgente # Crie uma branch de hotfix
    # Faça as correções necessárias aqui
    git add . # Adicione os arquivos corrigidos
    git commit -m "fix: Corrige problema crítico em produção" # Mensagem de commit
    git push origin hotfix/correcao-urgente # Envie a branch de hotfix
    
    • Crie um Merge Request da branch hotfix/correcao-urgente para main no GitLab. Após a aprovação e o merge, o pipeline de produção será acionado.
    • Não esqueça de aplicar o hotfix na branch homolog: Após o merge em main, mescle main para homolog para garantir que a correção também esteja presente no ambiente de homologação e em futuras branches de feature.
      1
      2
      3
      
      git checkout homolog
      git merge main # Mescla as alterações da main para homolog
      git push origin homolog
      

Conclusão

Parabéns! Você concluiu a configuração de um pipeline de CI/CD completo para o seu blog Jekyll, utilizando GitLab, Docker, Nginx e Certbot. Ao longo destas três partes, você aprendeu a:

  • Configurar um projeto Jekyll com o tema Chirpy no GitLab.
  • Criar um Dockerfile otimizado para construir seu blog em um contêiner.
  • Configurar variáveis de ambiente seguras no GitLab para integração com o Docker Hub.
  • Instalar e registrar um GitLab Runner na sua VPS.
  • Configurar um proxy reverso Nginx com Docker Compose para gerenciar o tráfego e obter certificados SSL.
  • Implementar um fluxo de trabalho de branches robusto para ambientes de homologação e produção.

Esta arquitetura oferece um ambiente de desenvolvimento e implantação altamente automatizado, seguro e eficiente. Você pode agora focar na criação de conteúdo para o seu blog, sabendo que o processo de publicação é simplificado e confiável. Lembre-se de manter suas dependências atualizadas e de revisar periodicamente suas configurações de segurança. O mundo do DevOps é vasto, e este tutorial é apenas o começo da sua jornada para construir e manter aplicações web modernas.

Recursos Adicionais

Para aprofundar seus conhecimentos e explorar mais sobre as tecnologias utilizadas neste tutorial, consulte as seguintes documentações:

This post is licensed under CC BY 4.0 by the author.