From 6122949babb4818184f99ab0c60adb6cdd0b59fc Mon Sep 17 00:00:00 2001 From: Michael Mayer Date: Thu, 5 Aug 2021 20:18:08 +0200 Subject: [PATCH] Docker: Improve cloud-init setup --- docker/examples/cloud-init/certs/ca.conf | 13 +++++++ docker/examples/cloud-init/certs/cert.conf | 8 ++++ docker/examples/cloud-init/certs/config.yml | 9 +++++ docker/examples/cloud-init/certs/openssl.conf | 25 ++++++++++++ docker/examples/cloud-init/docker-compose.yml | 31 ++++++++++++++- docker/examples/cloud-init/setup.sh | 31 +++++++++++++-- docker/examples/cloud-init/traefik.yaml | 39 +++++++++++++++++++ 7 files changed, 151 insertions(+), 5 deletions(-) create mode 100644 docker/examples/cloud-init/certs/ca.conf create mode 100644 docker/examples/cloud-init/certs/cert.conf create mode 100644 docker/examples/cloud-init/certs/config.yml create mode 100644 docker/examples/cloud-init/certs/openssl.conf create mode 100644 docker/examples/cloud-init/traefik.yaml diff --git a/docker/examples/cloud-init/certs/ca.conf b/docker/examples/cloud-init/certs/ca.conf new file mode 100644 index 000000000..0321bf9e6 --- /dev/null +++ b/docker/examples/cloud-init/certs/ca.conf @@ -0,0 +1,13 @@ +[req] +default_bits = 4096 +default_md = sha256 +distinguished_name = dn +prompt = no + +[dn] +C = DE +ST = Berlin +L = Berlin +O = Default CA +emailAddress = hello@example.com +CN = example.com diff --git a/docker/examples/cloud-init/certs/cert.conf b/docker/examples/cloud-init/certs/cert.conf new file mode 100644 index 000000000..d447ae735 --- /dev/null +++ b/docker/examples/cloud-init/certs/cert.conf @@ -0,0 +1,8 @@ +authorityKeyIdentifier=keyid,issuer +basicConstraints=CA:FALSE +keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment +subjectAltName = @alt_names + +[alt_names] +DNS.1 = *.example.com +DNS.2 = example.com \ No newline at end of file diff --git a/docker/examples/cloud-init/certs/config.yml b/docker/examples/cloud-init/certs/config.yml new file mode 100644 index 000000000..4551a58e7 --- /dev/null +++ b/docker/examples/cloud-init/certs/config.yml @@ -0,0 +1,9 @@ +tls: + stores: + default: + defaultCertificate: + certFile: "/certs/cert.crt" + keyFile: "/certs/cert.key" + certificates: + - certFile: "/certs/cert.crt" + keyFile: "/certs/cert.key" diff --git a/docker/examples/cloud-init/certs/openssl.conf b/docker/examples/cloud-init/certs/openssl.conf new file mode 100644 index 000000000..0f95aa959 --- /dev/null +++ b/docker/examples/cloud-init/certs/openssl.conf @@ -0,0 +1,25 @@ +[req] +default_bits = 4096 +prompt = no +default_md = sha256 +x509_extensions = v3_req +distinguished_name = dn + +[dn] +C = DE +ST = Berlin +L = Berlin +O = PhotoPrism +OU = Self-Signed +emailAddress = hello@example.com +CN = example.com + +[v3_req] +subjectAltName = @alt_names + +[SAN] +subjectAltName = @alt_names + +[alt_names] +DNS.1 = *.example.com +DNS.2 = example.com \ No newline at end of file diff --git a/docker/examples/cloud-init/docker-compose.yml b/docker/examples/cloud-init/docker-compose.yml index f8c7e5309..6fe132abb 100644 --- a/docker/examples/cloud-init/docker-compose.yml +++ b/docker/examples/cloud-init/docker-compose.yml @@ -39,8 +39,19 @@ services: security_opt: - seccomp:unconfined - apparmor:unconfined - ports: - - "2342:2342" # [local port]:[container port] + # ports: + # - "2342:2342" # [local port]:[container port] + labels: + - "traefik.enable=true" + - "traefik.http.services.photoprism.loadbalancer.server.port=2342" + - "traefik.http.routers.photoprism.entrypoints=websecure" + - "traefik.http.routers.photoprism.rule=PathPrefix(`/`)" + - "traefik.http.routers.photoprism.tls=true" + - "traefik.http.routers.photoprism.tls.domains[0].main=example.com" + - "traefik.http.routers.photoprism.tls.domains[0].sans=*.example.com" + # Uncomment if your server has a public host name for HTTPS: + # - "traefik.http.routers.photoprism.rule=Host(`photos.example.com`)" + # - "traefik.http.routers.photoprism.tls.certresolver=myresolver" environment: PHOTOPRISM_ADMIN_PASSWORD: "insecure" # PLEASE CHANGE: Your initial admin password (min 4 characters) PHOTOPRISM_ORIGINALS_LIMIT: 5000 # File size limit for originals in MB (increase for high-res video) @@ -73,6 +84,22 @@ services: - "./storage:/photoprism/storage" - "./backup:/var/lib/photoprism" + traefik: + image: traefik:v2.4 + container_name: traefik + restart: always + ports: + - "80:80" + - "443:443" + expose: + - "80" + - "443" + volumes: + - "/var/run/docker.sock:/var/run/docker.sock" + - "./traefik/:/data/" + - "./traefik.yaml:/etc/traefik/traefik.yaml" + - "./certs/:/certs/" + mariadb: image: mariadb:10.5 container_name: mariadb diff --git a/docker/examples/cloud-init/setup.sh b/docker/examples/cloud-init/setup.sh index a8182bffb..796d3f7cd 100755 --- a/docker/examples/cloud-init/setup.sh +++ b/docker/examples/cloud-init/setup.sh @@ -36,7 +36,8 @@ apt-get update apt-get -qq dist-upgrade # install dependencies -apt-get -qq install -y --no-install-recommends apt-transport-https ca-certificates curl software-properties-common +apt-get -qq install -y --no-install-recommends apt-transport-https ca-certificates \ + curl software-properties-common openssl # install docker if needed if ! command -v docker &> /dev/null @@ -59,11 +60,35 @@ fi # create user useradd photoprism -u 1000 -G docker -o -m -d /photoprism || echo "User 'photoprism' already exists. Proceeding." -mkdir -p /photoprism/originals /photoprism/import /photoprism/storage /photoprism/backup /photoprism/database +mkdir -p /photoprism/originals /photoprism/import /photoprism/storage /photoprism/backup \ + /photoprism/database /photoprism/traefik /photoprism/certs + +# download ssl config +curl -fsSL https://dl.photoprism.org/docker/cloud-init/certs/ca.conf > /photoprism/certs/ca.conf +curl -fsSL https://dl.photoprism.org/docker/cloud-init/certs/cert.conf > /photoprism/certs/cert.conf +curl -fsSL https://dl.photoprism.org/docker/cloud-init/certs/config.yml > /photoprism/certs/config.yml +curl -fsSL https://dl.photoprism.org/docker/cloud-init/certs/openssl.conf > /photoprism/certs/openssl.conf + +# create ca +openssl genrsa -out /photoprism/certs/ca.key 4096 +openssl req -x509 -new -nodes -key /photoprism/certs/ca.key -sha256 -days 365 \ + -out /photoprism/certs/ca.pem -config /photoprism/certs/ca.conf +openssl x509 -outform der -in /photoprism/certs/ca.pem -out /photoprism/certs/ca.crt + +# create certs +openssl genrsa -out /photoprism/certs/cert.key 4096 +openssl req -new -config /photoprism/certs/openssl.conf -key /photoprism/certs/cert.key \ + -out /photoprism/certs/cert.csr +openssl x509 -req -in /photoprism/certs/cert.csr -CA /photoprism/certs/ca.pem \ + -CAkey /photoprism/certs/ca.key -CAcreateserial \ + -out /photoprism/certs/cert.crt -days 365 -sha256 -extfile /photoprism/certs/cert.conf +openssl pkcs12 -export -in /photoprism/certs/cert.crt -inkey /photoprism/certs/cert.key \ + -out /photoprism/certs/cert.pfx -passout pass: # download service config -curl -fsSL https://dl.photoprism.org/docker/cloud-init/docker-compose.yml> /photoprism/docker-compose.yml +curl -fsSL https://dl.photoprism.org/docker/cloud-init/docker-compose.yml > /photoprism/docker-compose.yml curl -fsSL https://dl.photoprism.org/docker/cloud-init/jobs.ini > /photoprism/jobs.ini +curl -fsSL https://dl.photoprism.org/docker/cloud-init/traefik.yaml > /photoprism/traefik.yaml chown -Rf photoprism:photoprism /photoprism # start services using docker-compose diff --git a/docker/examples/cloud-init/traefik.yaml b/docker/examples/cloud-init/traefik.yaml new file mode 100644 index 000000000..7546d8069 --- /dev/null +++ b/docker/examples/cloud-init/traefik.yaml @@ -0,0 +1,39 @@ +# Uncomment to enable debug mode: +# log: +# level: DEBUG + +serversTransport: + insecureSkipVerify: true + rootCAs: + - "/certs/ca.crt" + +entryPoints: + web: + address: ":80" + http: + redirections: + entryPoint: + to: websecure + scheme: https + websecure: + address: ":443" + +certificatesResolvers: + myresolver: + acme: + email: info@example.com + storage: /data/letsencrypt.json + httpChallenge: + entryPoint: web + +providers: + file: + filename: "/certs/config.yml" + watch: true + docker: + exposedByDefault: false + watch: true + +api: + insecure: false + dashboard: false \ No newline at end of file