Poner certificado https en nginx con Let’s encrypt y Docker

Poner certificados https muchas veces nos da verdaderos dolores de cabeza, pero para solucionarnos este problema se crearon los certificados Let’s encrypt que de una manera sencilla nos permite utilizar certificados gratuitos y renovarlos periódicamente.

En esta entrada voy a explicar a poner el certificado en entornos con docker y lo primero que vamos a hacer es crear el docker-compose.yml donde crearemos el contenedor para el nginx.

version: '3'

services:
  nginx:
    image: nginx:latest
    ports:
      - 80:80
      - 443:443
    restart: always
    volumes:
      - ./nginx/conf.d/:/etc/nginx/conf.d/:ro

A continuación creamos el fichero de configuración del nginx ( ./nginx/conf.d/default.conf ) cambiando example.org pro nuestro dominio.

server {
    listen 80;
    listen [::]:80;

    server_name example.org www.example.org;
    server_tokens off;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://example.org$request_uri;
    }
}

Ahora arrancamos el contenedor y vemos como el nginx es accesible.

docker-compose up -d

El siguiente paso es crear el servicio certbot que se encargara de crear nuestro certificado editando el fichero docker-compose.yml.

version: '3'

services:

  webserver:
    image: nginx:latest
    ports:
      - 80:80
      - 443:443
    restart: always
    volumes:
      - ./nginx/conf.d/:/etc/nginx/conf.d/:ro
      - ./certbot/www/:/var/www/certbot/:ro
      - ./certbot/conf.d/:/etc/nginx/ssl/:ro

  certbot:
    image: certbot/certbot:latest
    volumes:
      - ./certbot/www/:/var/www/certbot/:rw
      - ./certbot/conf.d/:/etc/letsencrypt/:rw

Volvemos a lanzar el docker-compose para crear los directorios que utilizara certbot

docker-compose up -d

Una vez cambiado el docker-compose.yml lanzamos el comando para crear los certificados, cambiando el dominio example.org por el nuestro.

docker-compose run --rm  certbot certonly --webroot --webroot-path /var/www/certbot/ -d example.org

Una vez que ya tengamos los certificados creados editamos el fichero de configuración del nginx (./nginx/conf.d/default.conf) cambiando el dominio example.org por el nuestro.

En el ejemplo uso el nginx como proxy para servir un tomcat.

server {
    listen 80;
    listen [::]:80;

    server_name example.org www.example.org;
    server_tokens off;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://example.org$request_uri;
    }
}

server {
    listen 443 default_server ssl http2;
    listen [::]:443 ssl http2;

    server_name example.org;

    ssl_certificate /etc/nginx/ssl/live/example.org/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/live/example.org/privkey.pem;
    
    location / {
      proxy_pass      http://127.0.0.1:8080;
    }
}

Ya por ultimo paramos el contenedor del nginx y recreamos los contenedores.

docker stop nginx

docker-compose up -d

Y ya tendriamos nuestra web accesible con https y certificado seguro.

Como ultimo paso añado el comando que tenemos que utilizar cuando queramos renovar el certificado.

docker-compose run --rm certbot renew

Saltar error “rsync warning: some files vanished before they could be transferred”

Es muy común cuando sincronizamos ficheros con rsync encontrarnos este error (mas bien warning) rsync warning: some files vanished before they could be transferred

rsync warning: some files vanished before they could be transferred

Esto suele deberse a que rsync indexa los ficheros a sincronizar y cuando lo hace han desaparecido y suele ocurrir con ficheros temporales, los cuales son innecesarios pero nos da este error molesto.

Pues con este pequeño script os doy la solución para omitir estos errores, lo único que tenemos que hacer es usarlo cuando queramos sincronizar omitiendo ese warning.

cat rsync-vanished.sh

#!/bin/bash
(rsync "$@"; if [ $? == 24 ]; then exit 0; else exit $?; fi) 2>&1 | grep -v 'vanished'