Last active
November 26, 2024 07:55
-
-
Save waja/37202007b10837a7fc2e6eacacd9b335 to your computer and use it in GitHub Desktop.
Deploy Traefik as Frontend Proxy for Docker
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
DOCKER_BASE="${DOCKER_BASE:-/srv/docker}" | |
TRAEFIK_DIR="${TRAEFIK_DIR:-traefik}" | |
mkdir -p ${DOCKER_BASE}/${TRAEFIK_DIR}/container.conf | |
touch ${DOCKER_BASE}/${TRAEFIK_DIR}/container.conf/.env | |
ln -s container.conf/.env ${DOCKER_BASE}/${TRAEFIK_DIR}/ | |
cat > ${DOCKER_BASE}/${TRAEFIK_DIR}/container.conf/docker-compose.yml <<EOF | |
# Inspired by https://containo.us/blog/traefik-2-0-docker-101-fc2893944b9d/ | |
services: | |
traefik: | |
image: traefik:3.2 | |
command: | |
- --entrypoints.web.address=:80 | |
- --entrypoints.websecure.address=:443 | |
- "--log.level=INFO" | |
- --providers.docker=true | |
- --providers.docker.exposedbydefault=false | |
- --api=true | |
- --certificatesresolvers.default.acme.caserver=\${LEAPI:-https://acme-v02.api.letsencrypt.org/directory} | |
- --certificatesresolvers.default.acme.email=\${LEMAIL:[email protected]} | |
- --certificatesresolvers.default.acme.storage=/etc/traefik/acme.json | |
- --certificatesresolvers.default.acme.tlschallenge=true | |
- --providers.file.filename=/etc/traefik/traefik_providers.yaml | |
- --providers.file.watch=true | |
logging: | |
options: | |
max-size: "100M" | |
max-file: "10" | |
networks: | |
- system_traefik | |
environment: | |
- LC_ALL=C.UTF-8 | |
- TZ=Europe/Berlin | |
labels: | |
# Enable Traefik for it's own backend | |
- traefik.enable=true | |
# Dashboard | |
- traefik.http.routers.traefik.rule=Host(\`traefik.test.org\`) | |
- traefik.http.routers.traefik.entrypoints=websecure | |
- traefik.http.routers.traefik.tls=true | |
- traefik.http.routers.traefik.tls.certresolver=default | |
- traefik.http.routers.traefik.service=api@internal | |
# Basic auth for dashboard | |
- traefik.http.routers.traefik.middlewares=authtraefik@docker,default-security-headers@file | |
# middleware authtraefik | |
- traefik.http.middlewares.authtraefik.basicauth.users=\${DASHBOARD_USERS:-admin:\$\$apr1\$\$AAbCdQpX\$\$ajelS9mMisKRG.lqcY/uXU/} # user/password | |
ports: | |
- "80:80" | |
- "443:443" | |
restart: always | |
volumes: | |
- "./config/:/etc/traefik/" | |
- "/var/run/docker.sock:/var/run/docker.sock:ro" | |
networks: | |
system_traefik: | |
external: true | |
EOF | |
ln -s container.conf/docker-compose.yml ${DOCKER_BASE}/${TRAEFIK_DIR}/ | |
cat > ${DOCKER_BASE}/${TRAEFIK_DIR}/container.conf/production.yml <<EOF | |
services: | |
traefik: | |
labels: | |
# Allow watchtower to update this image | |
- com.centurylinklabs.watchtower.enable=true | |
# See https://docs.traefik.io/migration/v1-to-v2/#strip-and-rewrite-path-prefixes | |
- traefik.http.routers.traefik.rule=Host(\`$(hostname -f)\`) && (PathPrefix(\`/traefik\`) || HeaderRegexp(\`Referer\`, \`.*/traefik/.*\`)) | |
# Redefine middleware for router 'traefik' as we add more middlewares | |
- traefik.http.routers.traefik.middlewares=authtraefik@docker,traefik-dashboard-stripprefix@file,default-security-headers@file | |
EOF | |
cat > ${DOCKER_BASE}/${TRAEFIK_DIR}/container.conf/traefik.service <<EOF | |
[Unit] | |
Description=Traefik Proxy Service | |
After=network.target docker.service | |
Requires=docker.service | |
[Service] | |
Type=oneshot | |
RemainAfterExit=yes | |
Environment="WORK_DIR=/srv/docker/traefik/" | |
WorkingDirectory=/srv/docker/traefik/ | |
ExecStartPre=/bin/bash -c "/usr/bin/docker network inspect system_traefik &>/dev/null || /usr/bin/docker network create --driver bridge system_traefik" | |
ExecStartPre=-/usr/local/bin/docker-compose -f "\${WORK_DIR}/docker-compose.yml" -f "\${WORK_DIR}/container.conf/production.yml" down | |
ExecStart=/usr/local/bin/docker-compose -f "\${WORK_DIR}/docker-compose.yml" -f "\${WORK_DIR}/container.conf/production.yml" up -d | |
ExecStop=/usr/local/bin/docker-compose -f "\${WORK_DIR}/docker-compose.yml" -f "\${WORK_DIR}/container.conf/production.yml" down | |
[Install] | |
WantedBy=docker.service | |
EOF | |
ln -s ${DOCKER_BASE}/${TRAEFIK_DIR}/container.conf/traefik.service /etc/systemd/system/ | |
mkdir -p ${DOCKER_BASE}/${TRAEFIK_DIR}/config | |
cat > ${DOCKER_BASE}/${TRAEFIK_DIR}/config/traefik_providers.yaml <<EOF | |
--- | |
tls: | |
options: | |
default: | |
minVersion: VersionTLS12 | |
sniStrict: true | |
cipherSuites: | |
# TLS 1.2 cipher suites. | |
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 | |
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 | |
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 | |
# IE 11 and Safari < 9 + iOS <9, OSX < 10.11 | |
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA | |
# TLS 1.3 cipher suites. | |
- TLS_AES_128_GCM_SHA256 | |
- TLS_AES_256_GCM_SHA384 | |
- TLS_CHACHA20_POLY1305_SHA256 | |
# TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator that the client is doing version fallback. See RFC 7507. | |
- TLS_FALLBACK_SCSV | |
curvePreferences: | |
- CurveP521 | |
- CurveP384 | |
http: | |
middlewares: | |
redirect-web-to-websecure: | |
redirectScheme: | |
scheme: https | |
permanent: true | |
default-security-headers: | |
headers: | |
accessControlAllowMethods: | |
- GET | |
- POST | |
- DELETE | |
- OPTIONS | |
accessControlAllowOriginList: ["<origin>"] | |
accessControlMaxAge: 100 | |
browserXssFilter: true | |
contentTypeNosniff: true | |
forceSTSHeader: true | |
# frameDeny: true | |
# sslRedirect: true | |
stsIncludeSubdomains: true | |
stsPreload: true | |
stsSeconds: 315360000 | |
# contentSecurityPolicy: "default-src 'self' 'unsafe-inline';script-src 'self' 'unsafe-inline' 'unsafe-eval';img-src 'self' data:;font-src 'self' data:;connect-src 'self' ws: wss:" | |
# customRequestHeaders: | |
# X-Frame-Options: "SAMEORIGIN" | |
# customFrameOptionsValue: "SAMEORIGIN" | |
referrerPolicy: "same-origin" | |
permissionsPolicy: "vibrate=(self)" | |
traefik-dashboard-stripprefix: | |
stripPrefix: | |
prefixes: | |
- "/traefik" | |
services: | |
redirect-dummy: | |
loadBalancer: | |
servers: | |
- url: "" | |
routers: | |
# global redirect to https | |
# per domain see https://doc.traefik.io/traefik/migration/v1-to-v2/#http-to-https-redirection-is-now-configured-on-routers | |
web-to-websecure: | |
rule: "hostregexp(`.+`)" | |
service: "redirect-dummy@file" | |
entryPoints: | |
- "web" | |
middlewares: | |
- redirect-web-to-websecure@file | |
experimental: | |
fastProxy: {} | |
EOF | |
systemctl daemon-reload && systemctl enable traefik && systemctl start traefik |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
sed -i '/^WorkingDirectory/a ExecStartPre=/bin/bash -c "/usr/bin/docker network inspect system_traefik &>/dev/null || /usr/bin/docker network create --driver bridge system_traefik"' /srv/docker/traefik/container.conf/traefik.service && systemctl daemon-reload | |
sed -i '/image: traefik/a\ networks:\n - system_traefik' /srv/docker/traefik/container.conf/docker-compose.yml | |
sed -i s/traefik_default/system_traefik/g /srv/docker/*/container.conf/*.yml | |
sed -i s/traefik_default/system_traefik/g /srv/docker/portainer/data/compose/*/docker-compose.yml |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
BASEPATH="/srv/docker/traefik2/" | |
export TRAEFIK_DIR="traefik2" | |
# Download deployment script | |
wget -q https://gist.githubusercontent.com/waja/37202007b10837a7fc2e6eacacd9b335/raw/deploy_traefik.sh \ | |
-O /tmp/deploy_traefik.sh && \ | |
# Remove auto start of the traefik daemon | |
sed '/^systemctl/d' -i /tmp/deploy_traefik.sh && \ | |
sed -i '/etc\/systemd\/system\/$/d' /tmp/deploy_traefik.sh && \ | |
# Run deployment | |
bash /tmp/deploy_traefik.sh | |
# Migrate settings from old toml config | |
ADMIN_CRED="$(grep users ${BASEPATH}/../traefik/config/traefik.toml | cut -d \" -f2)" | |
EMAIL="$(grep email ${BASEPATH}/../traefik/config/traefik.toml | cut -d \" -f2)" | |
echo "LEMAIL=${EMAIL}" > ${BASEPATH}/.env | |
echo "#LEAPI=https://acme-staging-v02.api.letsencrypt.org/directory" >> ${BASEPATH}/.env | |
echo "DASHBOARD_USERS=${ADMIN_CRED}" >> ${BASEPATH}/.env | |
# Migrate old acme store to the new once | |
wget -q https://github.com/traefik/traefik-migration-tool/releases/download/v0.13.1/traefik-migration-tool_v0.13.1_linux_amd64.tar.gz -P /tmp | |
tar -xf /tmp/traefik-migration-tool_v0.13.1_linux_amd64.tar.gz -C /tmp | |
/tmp/traefik-migration-tool acme -i /srv/docker/traefik/config/acme.json -o /srv/docker/traefik2/config/acme-new.json | |
echo -e "You might want to the following:\nmv traefik traefik1 && mv traefik2 traefik && systemctl daemon-reload\ncd /srv/docker/traefik\ndocker-compose -f docker-compose.yml -f container.conf/production.yml pull\nsystemctl restart traefik && docker-compose -f docker-compose.yml -f container.conf/production.yml logs -f" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
BASEPATH="/srv/docker/traefik/" | |
sed -i "s/^ sslRedirect: true/# sslRedirect: true/" ${BASEPATH}/config/traefik_providers.yaml && \ | |
sed -i "s/^ featurePolicy: \"vibrate 'self'\"/ permissionsPolicy: \"vibrate=\(self\)\"/" ${BASEPATH}/config/traefik_providers.yaml && \ | |
sed -i "s/image: traefik:2.4/image: traefik:2.5/" ${BASEPATH}/container.conf/docker-compose.yml && \ | |
cd ${BASEPATH} && \ | |
docker-compose -f docker-compose.yml -f container.conf/production.yml pull && \ | |
systemctl restart traefik && docker-compose -f docker-compose.yml -f container.conf/production.yml logs -f |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
BASEPATH="/srv/docker/traefik/" | |
cp -a ${BASEPATH} /tmp/ && \ | |
sed -i 's/^ rule:.*/ rule: "hostregexp(`.+`)"/' ${BASEPATH}/config/traefik_providers.yaml && \ | |
sed -i "s/image: traefik:2.*/image: traefik:3.0/" ${BASEPATH}/container.conf/docker-compose.yml && \ | |
echo "Changes made:" && \ | |
( diff -Nuri --no-dereference /tmp/traefik/ ${BASEPATH} || true ) && \ | |
cd ${BASEPATH} && \ | |
docker-compose -f docker-compose.yml -f container.conf/production.yml pull && \ | |
systemctl restart traefik && docker-compose -f docker-compose.yml -f container.conf/production.yml logs -f |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
sed -i '/\[entryPoints.https.tls\]/a \ minVersion = "VersionTLS11"' /srv/docker/traefik/config/traefik.toml && systemctl restart traefik |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
sed -i s/VersionTLS11/VersionTLS12/ /srv/docker/traefik/config/traefik.toml && systemctl restart traefik |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
if [ $(ip -6 route | grep -c ^default) -eq 0 ]; then exit; fi | |
apt install socat || exit | |
cat > /etc/systemd/system/socat\@.service <<EOF | |
[Unit] | |
Description=ipv6 to ipv4 port forwarding | |
After=network.target | |
[Service] | |
Type=simple | |
ExecStart=/usr/bin/socat TCP6-LISTEN:%i,ipv6only=1,reuseaddr,fork TCP4:127.0.0.1:%i | |
[Install] | |
WantedBy=docker.service | |
EOF | |
systemctl daemon-reload | |
for PROTO in http https; do | |
systemctl enable socat@${PROTO}.service | |
systemctl start socat@${PROTO}.service | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment