Wenn Sie jemals Probleme mit der Einrichtung von SSL in einer Docker-Umgebung hatten, sind Sie nicht allein. SSL kann für viele eine einschüchternde Hürde sein, aber es ist von entscheidender Bedeutung, Ihre Anwendung zu sichern, insbesondere wenn sie dem Internet ausgesetzt ist. In diesem Beitrag führe ich Sie durch das Hinzufügen von Nginx und Certbot für die Let's Encrypt SSL-Generierung in einem Docker-Setup. Dadurch können Sie Zertifikate automatisch erneuern und Ihre Umgebung mit minimalem Aufwand schützen.
Lass uns eintauchen!
In diesem Beispiel verwenden wir Nginx als Reverse-Proxy und Certbot zur Verwaltung von SSL-Zertifikaten. Unten finden Sie docker-compose.yml, ein Shell-Skript zum automatischen Neuladen von Nginx und die erforderlichen Konfigurationsdateien, um alles einzurichten.
Lassen Sie mich zunächst die Docker Compose-Konfiguration zum Einrichten von Nginx und Certbot zeigen.
# docker-compose.yml services: nginx: container_name: nginx image: nginx:latest restart: unless-stopped env_file: .env networks: - your-app-network # Update this with your application service network ports: - 80:80 - 443:443 depends_on: - your-app # Your application service volumes: - ./nginx/secure/:/etc/nginx/templates/ - /etc/localtime:/etc/localtime:ro - ./nginx/certbot/conf:/etc/letsencrypt - ./nginx/certbot/www:/var/www/certbot - ./nginx/99-autoreload.sh:/docker-entrypoint.d/99-autoreload.sh # Script to autoreload Nginx when certs are renewed certbot: image: certbot/certbot volumes: - ./nginx/certbot/conf:/etc/letsencrypt - ./nginx/certbot/www:/var/www/certbot entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'" # Renew certificates every 12 hours
Diese Docker Compose-Datei definiert zwei Dienste:
Der Certbot-Dienst läuft in einer Endlosschleife und erneuert Zertifikate alle 12 Stunden. Zertifikate werden in einem gemeinsamen Volume (./nginx/certbot/conf) gespeichert, sodass Nginx auf die neuesten Zertifikatsdateien zugreifen kann.
Nginx fungiert als Reverse-Proxy und verarbeitet sowohl HTTP- als auch HTTPS-Verkehr. Für die erste Anfrage benötigt Certbot HTTP (Port 80), um den Domänenüberprüfungsprozess abzuschließen.
# default.conf.template server { listen 80; server_name ${APP_DOMAIN}; location / { return 301 https://$host$request_uri; } location /.well-known/acme-challenge/ { root /var/www/certbot; } } server { listen 443 ssl; server_name ${APP_DOMAIN}; server_tokens off; client_max_body_size 20M; ssl_certificate /etc/letsencrypt/live/${APP_DOMAIN}/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/${APP_DOMAIN}/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / { proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Url-Scheme $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://my-app:3000; // Your app service name } }
In der Konfigurationsdatei oben führt Nginx Folgendes aus:
Nachdem die SSL-Zertifikate erneuert wurden, sollte Nginx neu geladen werden, um die aktualisierten Zertifikate anzuwenden. Um diesen Vorgang zu automatisieren, fügen Sie ein einfaches Skript zum automatischen Neuladen hinzu:
# 99-autoreload.sh #!/bin/sh while :; do # Optional: Instead of sleep, detect config changes and only reload if necessary. sleep 6h nginx -t && nginx -s reload done &
Dieses Skript wird im Nginx-Container ausgeführt und lädt Nginx alle 6 Stunden oder bei jeder Erneuerung des Zertifikats neu.
Erstellen Sie eine .env-Datei, um Ihren Domainnamen und Ihre E-Mail-Adresse für die Certbot-Registrierung zu speichern:
# .env file APP_DOMAIN=your-domain.com SSL_EMAIL=contact@your-domain.com
Bevor Nginx HTTPS-Verkehr bereitstellen kann, müssen Sie das anfängliche SSL-Zertifikat generieren. Verwenden Sie das folgende Bash-Skript (init-letsencrypt.sh), um das SSL-Zertifikat zu generieren:
#!/bin/bash # Source the .env file if [ -f .env ]; then export $(grep -v '^#' .env | xargs) fi if ! [ -x "$(command -v docker compose)" ]; then echo 'Error: docker compose is not installed.' >&2 exit 1 fi domains=(${APP_DOMAIN:-example.com}) rsa_key_size=4096 data_path="./nginx/certbot" email="${SSL_EMAIL:-hello@example.com}" # Adding a valid address is strongly recommended staging=0 # Set to 1 if you're testing your setup to avoid hitting request limits if [ -d "$data_path" ]; then read -p "Existing data found for $domains. Continue and replace existing certificate? (y/N) " decision if [ "$decision" != "Y" ] && [ "$decision" != "y" ]; then exit fi fi if [ ! -e "$data_path/conf/options-ssl-nginx.conf" ] || [ ! -e "$data_path/conf/ssl-dhparams.pem" ]; then echo "### Downloading recommended TLS parameters ..." mkdir -p "$data_path/conf" curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf >"$data_path/conf/options-ssl-nginx.conf" curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem >"$data_path/conf/ssl-dhparams.pem" echo fi echo "### Creating dummy certificate for $domains ..." path="/etc/letsencrypt/live/$domains" mkdir -p "$data_path/conf/live/$domains" docker compose -f "docker-compose.yml" run --rm --entrypoint "\ openssl req -x509 -nodes -newkey rsa:$rsa_key_size -days 1\ -keyout '$path/privkey.pem' \ -out '$path/fullchain.pem' \ -subj '/CN=localhost'" certbot echo echo "### Starting nginx ..." docker compose -f "docker-compose.yml" up --force-recreate -d nginx echo echo "### Deleting dummy certificate for $domains ..." docker compose -f "docker-compose.yml" run --rm --entrypoint "\ rm -Rf /etc/letsencrypt/live/$domains && \ rm -Rf /etc/letsencrypt/archive/$domains && \ rm -Rf /etc/letsencrypt/renewal/$domains.conf" certbot echo echo "### Requesting Let's Encrypt certificate for $domains ..." #Join $domains to -d args domain_args="" for domain in "${domains[@]}"; do domain_args="$domain_args -d $domain" done # Select appropriate email arg case "$email" in "") email_arg="--register-unsafely-without-email" ;; *) email_arg="--email $email" ;; esac # Enable staging mode if needed if [ $staging != "0" ]; then staging_arg="--staging"; fi docker compose -f "docker-compose.yml" run --rm --entrypoint "\ certbot certonly --webroot -w /var/www/certbot \ $staging_arg \ $email_arg \ $domain_args \ --rsa-key-size $rsa_key_size \ --agree-tos \ --force-renewal" certbot echo #echo "### Reloading nginx ..." docker compose -f "docker-compose.yml" exec nginx nginx -s reload
Zusammenfassend lässt sich sagen, dass die oben bereitgestellte Konfiguration Nginx als Reverse-Proxy für Ihre Docker-Anwendung einrichtet, wobei Let's Encrypt SSL-Zertifikate automatisch von Certbot verwaltet werden. Dieses Setup gewährleistet eine sichere Verbindung zu Ihrer Anwendung ohne den Aufwand manueller SSL-Erneuerungen.
Um Ihre Umgebung zum ersten Mal aufzurufen, verwenden Sie:
chmod a+x init-letsencrypt.sh ./init-letsencrypt.sh
Die folgenden Male können Sie Ihre Umgebung mit dem üblichen Docker-Compose-Befehl aufrufen:
docker-compose up -d
Stellen Sie sicher, dass Ihre Domain auf Ihren Server verweist und dass die Ports 80 und 443 geöffnet sind, um den Zugriff auf HTTP- und HTTPS-Verkehr zu ermöglichen.
Wenn Sie auf Probleme stoßen oder Verbesserungsvorschläge haben, lassen Sie es mich unten in den Kommentaren wissen! Gerne helfe ich bei der Fehlerbehebung oder erweitere bestimmte Themen.
Das obige ist der detaillierte Inhalt vonDie Herausforderung rund um SSL in Docker-Containern, über die niemand spricht. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!