Traefik:v2
Traefik v2 에 대한 설명
Redirection http to https
- How to redirect http to https with Traefik 2.0 and Docker Compose labels? - Stack Overflow
- HTTP to HTTPS redirects with Traefik | Jens Knipper
--entrypoints.web.address=:80
--entrypoints.web.http.redirections.entryPoint.to=websecure
--entrypoints.web.http.redirections.entryPoint.scheme=https
--entrypoints.web.http.redirections.entrypoint.permanent=true
--entrypoints.websecure.address=:443
Example:
traefik:
image: traefik:v2.2
command:
- "--providers.docker"
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--entrypoints.websecure.address=:443"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Quick Start
version: "3.8"
services:
traefik:
image: "traefik:v2.4"
container_name: "traefik"
command:
#- "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
whoami:
image: "traefik/whoami"
container_name: "simple-service"
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web"
HTTPS with Let's Encrypt
TLS Challenge
version: "3.3"
services:
traefik:
image: "traefik:v2.10"
container_name: "traefik"
command:
#- "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
#- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
- "--certificatesresolvers.myresolver.acme.email=postmaster@example.com"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
ports:
- "443:443"
- "8080:8080"
volumes:
- "./letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
whoami:
image: "traefik/whoami"
container_name: "simple-service"
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.tls.certresolver=myresolver"
- 도메인을 해당 서버 IP로 연결하고
- 서버의 443 번 포트 인바운드 오픈
-
[email protected]
를 내 메일주소로 변경. -
whoami.example.com
를 내 도메인으로 변경. -
docker compose up -d
- 도메인으로 접속. (바로 접속 안되고 좀 기다려야함)
HTTP Challenge
version: "3.3"
services:
traefik:
image: "traefik:v2.10"
container_name: "traefik"
command:
#- "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.httpchallenge=true"
- "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
#- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
- "--certificatesresolvers.myresolver.acme.email=postmaster@example.com"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "./letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
whoami:
image: "traefik/whoami"
container_name: "simple-service"
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.tls.certresolver=myresolver"
- 도메인을 해당 서버 IP로 연결하고
- 서버의 80, 443 번 포트 인바운드 오픈
-
[email protected]
를 내 메일주소로 변경. -
whoami.example.com
를 내 도메인으로 변경. -
docker compose up -d
- 도메인으로 접속. (바로 접속 안되고 좀 기다려야함)
Load Balancer
주의할 점은 swarm에서 사용할 때 처럼 deploy:
안에 라벨을 적으면 안된다. 밖에 적어야 한다.
version: "3.3"
services:
traefik:
image: "traefik:v2.10"
restart: always
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.your_resolver.acme.tlschallenge=true"
- "--certificatesresolvers.your_resolver.acme.email=${ACME_EMAIL:?err}"
- "--certificatesresolvers.your_resolver.acme.storage=/letsencrypt/acme.json"
#-"--log.level=DEBUG"
ports:
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./letsencrypt:/letsencrypt"
master:
image: "ghcr.io/yourid/your-work:master"
restart: always
depends_on:
- traefik
deploy:
mode: replicated
replicas: 4
labels:
- "traefik.enable=true"
- "traefik.http.routers.your_master.rule=Host(`${FRONTEND_HOST:?err}`)"
- "traefik.http.routers.your_master.entrypoints=websecure"
- "traefik.http.routers.your_master.tls.certresolver=your_resolver"
- "traefik.http.services.your_master.loadbalancer.server.port=80"
command:
- "master"
- "--port=80"
- "--broker=${BROKER_URL:?err}"
PostgreSQL and Redis
version: "3.7"
services:
proxy:
image: traefik:latest
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
# Endpoints setup
- "--entrypoints.postgres.address=:5432" # PostgreSQL endpoint
- "--entrypoints.redis.address=:6379" # Redis endpoint
ports:
- "6969:8080" # Traefik dashboard
- "5432:5432" # PostgreSQL port
- "6379:6379" # Redis port
volumes:
- /var/run/docker.sock:/var/run/docker.sock
postgres:
image: postgres
restart: always
environment:
- POSTGRES_DB=${DB_NAME}
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASS}
volumes:
- ./appdata/postgres:/var/lib/postgresql/data
labels:
- "traefik.enable=true"
# routers
- "traefik.tcp.routers.postgres.rule=HostSNI(`*`)"
- "traefik.tcp.routers.postgres.entryPoints=postgres"
- "traefik.tcp.routers.postgres.service=postgres"
# services (needed for TCP)
- "traefik.tcp.services.postgres.loadbalancer.server.port=5432"
redis:
image: bitnami/redis:latest
restart: always
environment:
# ALLOW_EMPTY_PASSWORD is recommended only for development.
- ALLOW_EMPTY_PASSWORD=yes
- REDIS_DISABLE_COMMANDS=FLUSHDB,FLUSHALL
volumes:
- ./appdata/redis:/bitnami/redis/data
labels:
- "traefik.enable=true"
# routers
- "traefik.tcp.routers.redis.rule=HostSNI(`*`)"
- "traefik.tcp.routers.redis.entryPoints=redis"
- "traefik.tcp.routers.redis.service=redis"
# services (needed for TCP)
- "traefik.tcp.services.redis.loadbalancer.server.port=6379"
Troubleshooting
Filtering unhealthy or starting container
your-master-traefik-1 | time="2023-11-24T12:11:51Z" level=debug msg="Serving default certificate for request: \"api.your.run\""
your-master-traefik-1 | time="2023-11-24T12:11:51Z" level=debug msg="http: TLS handshake error from 121.167.254.11:51798: local error: tls: bad record MAC"
your-master-traefik-1 | time="2023-11-24T12:12:13Z" level=debug msg="Serving default certificate for request: \"api.your.run\""
your-master-traefik-1 | time="2023-11-24T12:12:13Z" level=debug msg="http: TLS handshake error from 121.167.254.11:43892: local error: tls: bad record MAC"
your-master-traefik-1 | time="2023-11-24T12:12:28Z" level=debug msg="Serving default certificate for request: \"api.your.run\""
your-master-traefik-1 | time="2023-11-24T12:12:28Z" level=debug msg="Provider event received {Status:health_status: unhealthy ID:3b062375ee2d62985a84103335c5153b928f51ac35e4c70aaf58546d6b300197 From:ghcr.io/yourid/your-api:latest Type:container Action:health_status: unhealthy Actor:{ID:3b062375ee2d62985a84103335c5153b928f51ac35e4c70aaf58546d6b300197 Attributes:map[com.docker.compose.config-hash:3566c90185ea8f97f365687e0179beec0d8910c49b2a393c47d6b350a91ad56e com.docker.compose.container-number:1 com.docker.compose.depends_on:traefik:service_started:false com.docker.compose.image:sha256:c1939588c20c7da364a34a7ca9f6ce31bf96c87b65d57a57b337653b35295ad3 com.docker.compose.oneoff:False com.docker.compose.project:your-master com.docker.compose.project.config_files:/home/your/Project/your-api/docker-compose.master.yml com.docker.compose.project.working_dir:/home/your/Project/your-api com.docker.compose.service:master com.docker.compose.version:2.18.1 image:ghcr.io/yourid/your-api:latest name:your-master-master-1 org.opencontainers.image.created:2023-11-24T07:37:17.039Z org.opencontainers.image.description:your api org.opencontainers.image.licenses:MIT org.opencontainers.image.revision:75336e4a42950a7e4cc90745a57391db1b37eb32 org.opencontainers.image.source:https://github.com/yourid/your-api org.opencontainers.image.title:your-api org.opencontainers.image.url:https://github.com/yourid/your-api org.opencontainers.image.version:0.0.7 traefik.enable:true traefik.http.routers.master.entrypoints:websecure traefik.http.routers.master.rule:Host(`api.your.run`) traefik.http.routers.master.tls.certresolver:resolver]} Scope:local Time:1700827948 TimeNano:1700827948848883214}" providerName=docker
your-master-traefik-1 | time="2023-11-24T12:12:28Z" level=debug msg="Filtering unhealthy or starting container" providerName=docker container=master-your-master-3b062375ee2d62985a84103335c5153b928f51ac35e4c70aaf58546d6b300197
your-master-traefik-1 | time="2023-11-24T12:12:28Z" level=debug msg="Filtering disabled container" container=traefik-your-master-1117e84b730dcf810f6202d45db7249f71a73b27f24ef507a907a534b40799f4 providerName=docker
your-master-traefik-1 | time="2023-11-24T12:12:28Z" level=debug msg="Filtering disabled container" container=redis-your-redis-0fe2d35f7ade83c3c18c81cc2692768aa8b8c83c60bf05514f4fb834ab2ccada providerName=docker
your-master-traefik-1 | time="2023-11-24T12:12:28Z" level=debug msg="Configuration received: {\"http\":{},\"tcp\":{},\"udp\":{}}" providerName=docker
your-master-traefik-1 | time="2023-11-24T12:12:28Z" level=debug msg="Skipping unchanged configuration." providerName=docker
docker ps -a
명령으로 확인해보면 다음과 같이 unhealthy 상태가 확인된다:
...
3b062374ee2d ghcr.io/yourid/your-api:latest "python -OO -m your_…" 9 minutes ago Up 9 minutes (unhealthy)
...
compose 의 healthcheck 명령 등을 확인하자.
See also
- traefik
- lets encrypt
- Osom-api#2 replicated master docker compose - 2 replicated docker compose 를 적용한 예제