First time using Docker + Sail + Caddy
. I copied the Caddy
setup from here. I have a local Laravel
dev project which uses 2x subdomains (sd1.project.local, sd2.project.local).
Everything looks fine on sail up
. I can see the certs created in the expected local stores, one for each subdomain. I then import the two certs to Chrome
.
I can get to the site, though Chrome
does not trust it. I have restarted Chrome
after the cert imports.
What have I missed / messed? Thanks!
The error of curl -vvv
on sd1.project.local
is:
$ curl -vvv https://sd1.project.local
* Trying 127.0.0.1:443...
* TCP_NODELAY set
* Connected to sd1.project.local (127.0.0.1) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (OUT), TLS alert, unknown CA (560):
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
The output of the sail up
command for caddy
is:
project-caddy-1 | {"level":"info","ts":1651470513.5381901,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":"caddyfile"}
project-caddy-1 | {"level":"warn","ts":1651470513.5383825,"logger":"caddyfile","msg":"Unnecessary header_up X-Forwarded-Host: the reverse proxy's default behavior is to pass headers to the upstream"}
project-caddy-1 | {"level":"warn","ts":1651470513.5384026,"logger":"caddyfile","msg":"Unnecessary header_up X-Forwarded-For: the reverse proxy's default behavior is to pass headers to the upstream"}
project-caddy-1 | {"level":"warn","ts":1651470513.5386436,"logger":"caddyfile","msg":"Unnecessary header_up X-Forwarded-Host: the reverse proxy's default behavior is to pass headers to the upstream"}
project-caddy-1 | {"level":"warn","ts":1651470513.5386622,"logger":"caddyfile","msg":"Unnecessary header_up X-Forwarded-For: the reverse proxy's default behavior is to pass headers to the upstream"}
project-caddy-1 | {"level":"warn","ts":1651470513.5391574,"msg":"Caddyfile input is not formatted; run the 'caddy fmt' command to fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":2}
project-caddy-1 | {"level":"warn","ts":1651470513.5395052,"logger":"admin","msg":"admin endpoint disabled"}
project-caddy-1 | {"level":"info","ts":1651470513.5397356,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc0001264d0"}
project-caddy-1 | {"level":"info","ts":1651470513.5441852,"logger":"http","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
project-caddy-1 | {"level":"warn","ts":1651470513.5442154,"logger":"http","msg":"server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server","server_name":"srv1","http_port":80}
project-caddy-1 | {"level":"info","ts":1651470513.5448365,"logger":"tls","msg":"cleaning storage unit","description":"FileStorage:/data/caddy"}
project-caddy-1 | {"level":"info","ts":1651470513.544853,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["sd1.project.local","sd2.project.local"]}
project-caddy-1 | {"level":"info","ts":1651470513.545812,"logger":"tls.obtain","msg":"acquiring lock","identifier":"sd1.project.local"}
project-caddy-1 | {"level":"info","ts":1651470513.5458567,"logger":"tls.obtain","msg":"acquiring lock","identifier":"sd2.project.local"}
project-caddy-1 | {"level":"info","ts":1651470513.5476136,"logger":"tls.obtain","msg":"lock acquired","identifier":"sd1.project.local"}
project-caddy-1 | {"level":"info","ts":1651470513.5479813,"logger":"tls","msg":"finished cleaning storage units"}
project-caddy-1 | {"level":"info","ts":1651470513.5485632,"logger":"tls.obtain","msg":"lock acquired","identifier":"sd2.project.local"}
project-caddy-1 | {"level":"info","ts":1651470513.5563135,"logger":"tls.obtain","msg":"certificate obtained successfully","identifier":"sd1.project.local"}
project-caddy-1 | {"level":"info","ts":1651470513.556336,"logger":"tls.obtain","msg":"releasing lock","identifier":"sd1.project.local"}
project-caddy-1 | {"level":"info","ts":1651470513.5574615,"logger":"tls.obtain","msg":"certificate obtained successfully","identifier":"sd2.project.local"}
project-caddy-1 | {"level":"info","ts":1651470513.557494,"logger":"tls.obtain","msg":"releasing lock","identifier":"sd2.project.local"}
project-caddy-1 | {"level":"warn","ts":1651470513.5588439,"logger":"pki.ca.local","msg":"installing root certificate (you might be prompted for password)","path":"storage:pki/authorities/local/root.crt"}
project-caddy-1 | 2022/05/02 05:48:33 define JAVA_HOME environment variable to use the Java trust
project-caddy-1 | 2022/05/02 05:48:33 not NSS security databases found
project-caddy-1 | {"level":"warn","ts":1651470513.561766,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [sd1.project.local]: no OCSP server specified in certificate","identifiers":["sd1.project.local"]}
project-caddy-1 | {"level":"warn","ts":1651470513.5634398,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [sd2.project.local]: no OCSP server specified in certificate","identifiers":["sd2.project.local"]}
project-caddy-1 | 2022/05/02 05:48:33 certificate installed properly in linux trusts
project-caddy-1 | {"level":"info","ts":1651470513.5809436,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
project-caddy-1 | {"level":"info","ts":1651470513.580976,"msg":"serving initial configuration"}
My docker-compose is:
# For more information: https://laravel.com/docs/sail
version: '3'
services:
project.local:
build:
context: ./vendor/laravel/sail/runtimes/8.0
dockerfile: Dockerfile
args:
WWWGROUP: '${WWWGROUP}'
image: sail-8.0/app
extra_hosts:
- 'host.docker.internal:host-gateway'
# ports:
# - "${APP_PORT:-80}:80"
environment:
WWWUSER: '${WWWUSER}'
LARAVEL_SAIL: 1
XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
GITHUB_TOKEN: '${GITHUB_TOKEN}'
FONTAWESOME_NPM_AUTH_TOKEN: '${FONTAWESOME_NPM_AUTH_TOKEN}'
volumes:
- '.:/var/www/html'
networks:
- sail
depends_on:
- redis
- mailhog
redis:
build:
context: "./Docker/Redis"
dockerfile: Dockerfile
privileged: true
command: sh -c "./init.sh"
ports:
- "${FORWARD_REDIS_PORT:-6379}:6379"
volumes:
- "sail-redis:/data"
networks:
- sail
healthcheck:
test: ["CMD", "redis-cli", "ping"]
retries: 3
timeout: 5s
mailhog:
image: "mailhog/mailhog:latest"
ports:
- "${FORWARD_MAILHOG_PORT:-1025}:1025"
- "${FORWARD_MAILHOG_DASHBOARD_PORT:-8025}:8025"
networks:
- sail
caddy:
build:
context: "./Docker/Caddy"
dockerfile: Dockerfile
args:
WWWGROUP: "${WWWGROUP}"
restart: unless-stopped
ports:
- "${APP_PORT:-80}:80"
- "${APP_SSL_PORT:-443}:443"
environment:
LARAVEL_SAIL: 1
HOST_DOMAIN: project.local
volumes:
- "./Docker/Caddy/file:/etc/caddy"
- ".:/srv:cache"
- "./Docker/Caddy/certificates:/data/caddy/certificates/local"
- "./Docker/Caddy/authorities:/data/caddy/pki/authorities/local"
- "sailcaddy:/data:cache"
- "sailcaddyconfig:/config:cache"
networks:
- sail
depends_on:
- project.local
networks:
sail:
driver: bridge
volumes:
sail-redis:
driver: local
sailcaddy:
external: true
sailcaddyconfig:
driver: local
My Caddifile
is:
{
admin off
# debug
on_demand_tls {
ask http://project.local/caddy
}
local_certs
default_sni project
}
:80 {
reverse_proxy project.local {
header_up Host {host}
header_up X-Real-IP {remote}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-For {remote}
header_up X-Forwarded-Port 443
# header_up X-Forwarded-Proto {scheme}
health_timeout 5s
}
}
:443 {
tls internal {
on_demand
}
reverse_proxy project.local {
header_up Host {host}
header_up X-Real-IP {remote}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-For {remote}
header_up X-Forwarded-Port 443
# header_up X-Forwarded-Proto {scheme}
health_timeout 5s
}
}
sd1.project.local {
reverse_proxy project.local
}
sd2.project.local {
reverse_proxy project.local
}
My Dockerfile
is:
FROM caddy:alpine
LABEL maintainer="Adrian Mejias"
ARG WWWGROUP
ENV DEBIAN_FRONTEND noninteractive
ENV TZ=UTC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apk add --no-cache bash \
&& apk add --no-cache nss-tools \
&& rm -rf /var/cache/apk/*
RUN addgroup -S $WWWGROUP
RUN adduser -G $WWWGROUP -u 1337 -S sail
COPY start-container /usr/local/bin/start-container
RUN chmod +x /usr/local/bin/start-container
ENTRYPOINT ["start-container"]
My start-container
is:
#!/usr/bin/env sh
if [ ! -z "$WWWUSER" ]; then
addgroup $WWWUSER sail
fi
if [ $# -gt 0 ];
then
# @todo find alpine equivilent of below
# exec gosu $WWWUSER "$@"
else
/usr/bin/caddy run --config /etc/caddy/Caddyfile --adapter caddyfile
fi