Eine lokale Entwicklungsumgebung für ein Projekt aufzusetzen sollte für uns Entwickler kein Neuland mehr sein und bereits zum Standard gehören.
Ziel ist stets, dass sich die lokale Umgebung nahezu identisch zum Produktivsystem verhält. Nur so kann gewährleisten werden, dass beim Migrieren von Änderungen keine ungewollten Nebeneffekte auftreten.

Vielleicht hattet ihr auch schon den Fall, dass ihr gerne für eure lokale Domain HTTPS aktivieren wolltet. Ich stand erst vor Kurzem vor diesem Problem, da ich in einem Projekt alle Möglichkeiten von HTTP2 testen wollte. Dazu ist eine sichere Verbindung mittels SSL von Nöten.

Bei selbst-signierten Zertifikaten spielen oft die Browser nicht mit und zeigen trotz Zertifikat eine unsichere Verbindung und demnach ein rotes Schlosssymbol an. Wie ihr das lösen könnt, habe ich euch in den folgenden 7 Schritten erläutert.


  1. Ordner für SSL Keys anlegen
  2. eigene Certificate Authority erstellen
  3. Zertifizierungsstelle im Browser hinterlegen
  4. Self Signed Key anlegen mit entsprechender Domain
  5. Domain unter /etc/hosts einfügen
  6. Datei docker-compose.yml anpassen
  7. Nginx Konfiguration anpassen



1) Ordner für SSL Keys anlegen

Für meine Projekte nutze ich immer einen docker Ordner, welcher alle Docker-bezogenen Dateien enthält. Hier liegt der neu erstellte Ordner ssl.

2) eigene Certificate Authority erstellen

Um ein eigenes Zertifikat zu signieren, benötigt man eine eigene Zertifizierungsstelle. Diese kann mittels openssl im Terminal angelegt werden. Zunächst erstellt man den privaten Schlüssel und vergibt ein Passwort (wird später noch benötigt).
Navigiere also zum erstellen ssl-Ordner und führe folgenden Command aus:

openssl genrsa -des3 -out SDWebDev.key 2048

SDWebDev entspricht hier dem Kürzel meiner Zertifizierungsstelle.

Als nächstes legt man für diesen Key ein Root-Zertifikat an. Hier werden einige Attribute wie Organisation, Einheit und Common Name abgefragt.

openssl req -x509 -new -nodes -key SDWebDev.key -sha256 -days 825 -out SDWebDev.pem

3) Zertifizierungsstelle im Browser hinterlegen

Damit die eigene Zertifizierungsstelle später anerkannt wird und ein grünes Schlosszeichen erscheint, muss der Key im jeweiligen Browser importiert werden.
Ich habe es jeweils für Chrome und Firefox hinterlegt.

Diese Möglichkeit findest du im Browser unter Einstellung -> Datenschutz & Sicherheit -> Zertifikate verwalten.
Navigiere hier zum Tab Zertifizierungsstellen und importiere das erstellte Root-Zertifikat (in meinem Fall SDWebDev.pem).

Es erscheint ein Popup, in dem man festlegen kann, für welche Bereiche das Zertifikat zulässig ist.

Chrome Einstellungen Datenschutz und Sicherheit
Chrome - Zertifizierungsstelle importieren

Nach erfolgreichem Import sollte deine eigene Zertifizierungsstelle in der Liste enthalten sein.

4) Self Signed Key anlegen mit entsprechender Domain

Als nächstes musst du einen Self Signed Key für das Projekt anlegen.
Schritt 1 ist hier das Erstellen eines privaten Schlüssels

openssl genrsa -out myproject.key 2048

Ich habe für Key und Zertifikat jeweils den Projektnamen myproject gewählt. Hier kannst du selbst wählen, wie du sie benennen möchtest.

Schritt 2 ist das Anlegen eines Certificate Signing Requests (CSR) mit folgendem Command:

openssl req -new -key myproject.key -out myproject.csr -subj '/CN=SDWebDev/O=SDWebDev/OU=IT' -extensions SAN -reqexts SAN -config <( \
   printf "[SAN]\nsubjectAltName=DNS:myproject.local\n[dn]\nCN=SDWebDev\n[req]\ndistinguished_name = dn\n[EXT]\nauthorityKeyIdentifier=keyid,issuer\nbasicConstraints=CA:FALSE\nsubjectAltName=DNS:myproject.local\nkeyUsage=digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment\nextendedKeyUsage=serverAuth")

Achte hier jeweils auf myproject.local. Diesen Wert solltest du mit deiner gewählten Domain ersetzen. Die Werte O und OU beschreiben jeweils deine Organisation und die Organisationseinheit.

Die Extension SAN ist hierbei sehr wichtig, damit es reibungslos im Chrome Browser funktioniert.
Für diese Extension legen wir noch die Datei myproject.ext an, welche ein paar wichtige Attribute wie die alternate names enthält.

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage=digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = myproject.local

Der letzte Schritt ist das Erstellen des Keys mit der zuvor selbst angelegten Zertifizierungsstelle.

openssl x509 -req -in myproject.csr -out myproject.crt -CA SDWebDev.pem -CAkey SDWebDev.key -CAcreateserial \
  -sha256 -days 3650 \
-extfile myproject.ext

5) Domain unter /etc/hosts einfügen

Damit die gewünschte Domain (in meinem Fall myproject.local) erkannt wird, muss ein Alias in der Datei /etc/hosts angelegt werden

127.0.0.1       myproject.local

6) Datei docker-compose.yml anpassen

Der SSL Ordner mit deinen Keys muss nun Nginx-Container von Docker gelesen werden können. Dazu reicht es ein Volume anzulegen, welches den Ordner docker/ssl referenziert.

Ebenso müssen die Ports 80 und 443 freigegeben sein.
Hier seht ihr meine beispielhafte Konfiguration:

# docker-compose.yaml
version: '3.3'

services:
  nginx:
    image: nginx:1.11.8-alpine
    ports:
      - "80:80"
      - "443:443"
    environment:
      APPLICATION_ENV: development
      VIRTUAL_HOST: myproject.local
    volumes:
      - ./myproject:/var/www/html
      - ./docker/nginx/config/site.conf:/etc/nginx/conf.d/default.conf
      - ./docker/ssl:/ssl
    links:
      - php

  php:
    build: ./docker/php
    ports:
      - "9000:9000"
    environment:
      APPLICATION_ENV: development
    volumes:
      - ./myproject:/var/www/html

7) Nginx Konfiguration anpassen

Damit HTTPS interpretiert werden kann, muss ebenfalls die Nginx-Konfiguration eurer Seite angepasst werden.
Das könnte dann so aussehen:

server {
    listen 80;
    listen [::]:80;
    server_name myproject.local;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name myproject.local;

    index  index.php index.html index.htm;
    root /var/www/html/;

    ssl on;
    ssl_certificate /ssl/myproject.crt;
    ssl_trusted_certificate /ssl/myproject.crt;
    ssl_certificate_key /ssl/myproject.key;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

    ssl_buffer_size 1369;
    ssl_session_tickets on;

    ssl_session_timeout 60m;
    ssl_session_cache shared:SSL:10m;

    charset utf-8;
    access_log /var/log/nginx/myproject-access.log;
    error_log /var/log/nginx/myproject-error.log;

    proxy_force_ranges on;

    tcp_nopush         on;
    tcp_nodelay        on;

    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_min_length 256;
    gzip_types text/plain application/javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/x-component text/xml application/atom+xml;

    etag off;
    chunked_transfer_encoding off;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass php:9000;
        fastcgi_param   APPLICATION_ENV  development;
        include /etc/nginx/fastcgi_params;
    }
}

Finish

Wenn ihr diese 7 Schritte durchgeführt habt, könnt ihr wie gewohnt eure Docker Container bauen und Starten.

docker-compose build
docker-compose up

Grünes Schlosszeichen in Chrome

Testet, ob SSL nun aktiv ist, indem ihr eure lokale Webseite öffnet. In meinem Fall https://myproject.local

TADA !!! Es erscheint ein grünes Schlosssymbol im Browser. Chrome und Firefox erkennen das Zertifikat als gültig an.

Ich hoffe ich konnte euch mit meiner Anleitung einiges an Recherche ersparen.
Viel Spaß damit !