Über den Author / Firma / Nginx, PHP-FPM und Let’s Encrypt per Docker-Compose aufsetzen

Nginx, PHP-FPM und Let’s Encrypt per Docker-Compose aufsetzen

~4 Min. Lesezeit

Um einen LAMDA Server einfach aufzusetzen, wie in meinem Fall auf Amazon EC2, geht es am Einfachsten mit Docker-Compose. Damit lassen sich die einzelnen Container schnell aktualisieren und System unabhängig betreiben.

Als Erstes installieren wir auf der neuen EC2 Instanz (ich verwende ein Ubuntu 18.4) gewisse Dinge:

apt update && apt upgrade
apt install -y mysql-client curl python unzip

Ich installiere alles in das /opt Verzeichnis und erstelle dazu diverse weitere Verzeichnisse die benötigt werden:

mkdir -p /opt/www/cache /root/.aws /opt/www/log/certbot /opt/www/log/nginx /opt/www/log/php /opt/www/certbot/conf /opt/www/certbot/www

Jetzt installieren wir Docker und Docker-Compose.

apt-get install -y apt-transport-https ca-certificates gnupg-agent software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose

Als nächstes benötigen wir je nach gewünschten Diensten die Dockerfiles:

/opt/docker/php/Dockerfile:

FROM php:fpm-alpine
RUN apk update && apk add --no-cache python sudo && docker-php-ext-install mysqli &&\
    mkdir -p /var/log/php /etc/nginx/cache /root/scripts

/opt/docker/nginx/Dockerfile:

FROM nginx:alpine
RUN apk update && apk add --no-cache logrotate &&\
    mkdir -p /var/log/nginx /etc/nginx/cache /var/www/certbot

Die beiden Container müssen wir nun erstellen:

cd /opt/docker/nginx/
docker build --progress=plain -t my-nginx --force-rm -f Dockerfile .
cd /opt/docker/php/
docker build --progress=plain -t my-php --force-rm -f Dockerfile .

Nun können bereits die Webdateien in das Verzeichnis /opt/www kopiert werden.

Leider startet der Nginx nicht ohne Zertifikate. Let’s Encrypt kann aber Zertifikate nur ausstellen bei lauffähigem Nginx. Daher erstellen wir einmalige Wegwerf-Self-Signed-Zertifikate für jede Domain die wir nutzen wollen:

openssl rand -writerand /root/.rnd
mkdir -p /opt/www/certbot/conf/live/FULLDOMAINNAME
openssl req -x509 -nodes -newkey rsa:1024 -days 90 -keyout '/opt/www/certbot/conf/live/FULLDOMAINNAME/privkey.pem' -out '/opt/www/certbot/conf/live/FULLDOMAINNAME/fullchain.pem' -subj '/CN=localhost'
rm /root/.rnd

Wir erstellen folgendes Script /opt/www/certbot/conf/start.sh und ersetzen FULLDOMAINNAME wieder überall

if [ ! -d "/opt/www/certbot/conf/accounts" ]; then
	echo "No Lets Encrypt Account found, wait 5s and start getting Certifications..."
	sleep 5s
	mv /etc/letsencrypt/live/FULLDOMAINNAME /etc/letsencrypt/live/FULLDOMAINNAME-tmp
	certbot certonly --webroot -w /var/www/certbot --email marketing@sintratec.com --no-eff-email -d FULLDOMAINNAME --cert-name FULLDOMAINNAME --rsa-key-size 4096 --agree-tos --force-renewal --expand --allow-subset-of-names
	if [ ! -d "/etc/letsencrypt/live/staging.sintratec.com" ]; then
	mv /etc/letsencrypt/live/FULLDOMAINNAME-tmp /etc/letsencrypt/live/FULLDOMAINNAME.com
	else
	rm -R /etc/letsencrypt/live/FULLDOMAINNAME-tmp
	fi
fi

Und geben ihm Ausführrechte:

chmod 740 /opt/www/certbot/conf/start.sh

Was nun noch fehlt, sind die Konfigurationsdateien, welche man hier für PHP und Nginx runterladen kann: etc.zip, was ins /opt Verzeichnis entpackt werden kann. Im Nginx sites/ Ordner, müssen noch die entsprechenden Domains eingetragen werden, welche ausgeliefert werden sollten (siehe FULLDOMAINNAME).

Jetzt erstellen wir noch die Datei /opt/docker-compose.yml mit folgendem Inhalt:

version: '3.2'
services:
  php:
    container_name: php
    image: my-php:latest
    restart: always
    volumes:
    - type: bind
      source: /opt/www
      target: /var/www
      bind-propagation: rshared
    - type: bind
      source: /opt/etc/php
      target: /usr/local/etc
      bind-propagation: rshared
    - type: bind
      source: /opt/www/cache
      target: /etc/nginx/cache
      bind-propagation: rshared
    - type: bind
      source: /opt/www/log/php
      target: /var/log/php
      bind-propagation: rshared
    - type: bind
      source: /opt/scripts/client
      target: /root/scripts
      bind-propagation: rshared
    - type: bind
      source: /opt/git/etc/aws
      target: /root/.aws
      bind-propagation: private
  nginx:
    container_name: nginx
    image: my-nginx:latest
    ports:
      - "80:80"
      - "443:443"
    command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
    restart: always
    depends_on:
      - php
    volumes:
    - type: bind
      source: /opt/www
      target: /var/www
      bind-propagation: rshared
    - type: bind
      source: /opt/etc/nginx/conf.d
      target: /etc/nginx/conf.d
      bind-propagation: rshared
    - type: bind
      source: /opt/etc/nginx/sites
      target: /etc/nginx/sites
      bind-propagation: rshared
    - type: bind
      source: /opt/etc/nginx/cert
      target: /etc/nginx/cert
      bind-propagation: rshared
    - type: bind
      source: /opt/etc/nginx/nginx.conf
      target: /etc/nginx/nginx.conf
      bind-propagation: rshared
    - type: bind
      source: /opt/www/cache
      target: /etc/nginx/cache
      bind-propagation: rshared
    - type: bind
      source: /opt/www/log/nginx
      target: /var/log/nginx
      bind-propagation: rshared
    - type: bind
      source: /opt/www/certbot/conf
      target: /etc/letsencrypt
      bind-propagation: rshared
    - type: bind
      source: /opt/www/certbot/www
      target: /var/www/certbot
      bind-propagation: rshared
  certbot:
    container_name: certbot
    image: certbot/certbot
    restart: always
    depends_on:
      - nginx
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
    volumes:
    - type: bind
      source: /opt/www/certbot/conf
      target: /etc/letsencrypt
      bind-propagation: rshared
    - type: bind
      source: /opt/www/certbot/www
      target: /var/www/certbot
      bind-propagation: rshared
    - type: bind
      source: /opt/www/log/certbot
      target: /var/log/letsencrypt
      bind-propagation: rshared

Achtung, MySQL wird nicht mitgeliefert, kann aber einfach eingebaut werden.

Das Docker Konstrukt wird mit folgendem Befehl gestartet:

docker-compose -f /opt/docker-compose.yml up --force-recreate -d ; Startet Docker Container
docker exec `docker ps -a -f name=certbot -q` /etc/letsencrypt/start.sh ; Let's Encrypt soll Zertifikate requesten
docker exec `docker ps -a -f name=nginx -q` nginx -s reload ; Neue Zertifikate im Nginx laden

oder gestoppt:

docker-compose -f /opt/docker-compose.yml down ; Docker beenden
docker ps -a | grep Exit | cut -d ' ' -f 1 | xargs sudo docker rm ; Falls Docker nicht sauber beenden, kann man sie damit löschen

Fehlerdateien sind im /opt/log der Container zu finden.

About Stefan

Ein männlicher IT Nerd, durchstöbert das Web nach speziellen Gadgets, unentbehrlicher Software und Alles was man im IT Sektor nicht verpassen darf. Immer hilfsbereit wenn Probleme zu lösen sind oder das Unmögliche umgesetzt werden sollte.

Weitere interessante Artikel

Plesk mit Yubikey OTP absichern

~0 Min. LesezeitPlesk ist eine Serververwaltung, welche leider kein Yubikey Support bietet. Dies nutzen wir …

Autodiscover und autoconfig für Mails bei Plesk

~0 Min. LesezeitPlesk ist eine Serververwaltungsoberfläche, welche leider keine Autokonfiguration für die Mails anbietet. Die …

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

eMail-Benachrichtigung bei weiteren Kommentaren.
Auch möglich: Abo ohne Kommentar.