Traefik容器代理工具
代理原理
请求流程
客户端访问域名和端口
用户在浏览器中访问 https://local.chenhaifeng.top:8010/api/。
请求通过 HTTPS 协议到达 local.chenhaifeng.top,解析到本地机器(127.0.0.1)。
Traefik 接收请求
Traefik 监听了 443 端口(websecure entrypoint)。
由于你的 traefik.http.routers.django.rule 定义了 Host(local.chenhaifeng.top),Traefik 匹配到这个路由规则。
Traefik 判断该路由需要通过 django 服务的 loadbalancer.server.port=8010 处理请求。
Traefik 转发到 Django 容器
Traefik 使用内部 Docker 网络将请求代理到 django_test 服务的 8010 端口。
Traefik 不需要暴露 8010 端口,因为它通过 Docker 网络直接与 django_test 通信。
Django 处理请求并返回响应
django_test 容器监听其内部的 8010 端口,处理 /api/ 请求。
响应通过 Docker 网络返回到 Traefik。
Traefik 返回响应给客户端
Traefik 接收来自 Django 的响应,并将其通过 HTTPS 返回给客户端。
使用
就是往想要代理的docker容器启动命令里添加labels, 或者后期update进去也可以, traefik会自动识别到全部容器的labels, 自动处理
需求
像把启动的一个django容器, 正常访问是127.0.0.1:8010,使用traefik代理实现https://local.chenhaifeng.top->就是访问到http://127.0.0.1:8010
准备:
- 1 我已经在阿里云有个域名local.chenhaifeng.top,
- 2 解析的ip是自己当前这台电脑的ip:192.168.1.80
- 3 申请了免费ssl证书并下载了apache版本的 里面有3个文件分别是
- local.chenhaifeng.top_chain.crt(不用)
- local.chenhaifeng.top.key(使用)
- local.chenhaifeng.top_public.crt(使用)
实现
1.docker-compose.yml (保险起见同时部署traefik, 和django)
version: '3.8'
services:
traefik:
image: traefik:latest
ports:
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./traefik.yml:/etc/traefik/traefik.yml:ro"
- "./ssl:/certs"
django_test:
build: .
image: django_test
labels:
- "traefik.enable=true"
- "traefik.http.routers.django_test.rule=Host(`local.chenhaifeng.top`)"
- "traefik.http.routers.django_test.entrypoints=websecure"
- "traefik.http.routers.django_test.tls=true"
- "traefik.http.services.django_test.loadbalancer.server.port=8010"
networks:
- default
networks:
default:
driver: bridge
部署django的dockerfile
FROM python:3.11
ENV PYTHONUNBUFFERED 1
WORKDIR /code/djangoblog/
COPY . .
RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple && \
pip config set install.trusted-host mirrors.aliyun.com && \
pip install django
CMD ["python", "manage.py", "runserver", "0.0.0.0:8010"]
2.traefik.yml (配置文件)
providers:
docker:
#defaultRule: "Host(`{{ trimPrefix `/` .Name }}.docker.localhost`)"
exposedByDefault: false # 避免自动暴露所有容器
#file:
# directory: "/etc/traefik/config"
api:
insecure: true
entrypoints:
web:
address: ":80"
websecure:
address: ":443"
http:
tls:
domains:
- main: "local.chenhaifeng.top" # 主域名(可选)
tls:
certificates:
- certFile: "/certs/local.chenhaifeng.top_public.crt"
keyFile: "/certs/local.chenhaifeng.top.key"
测试
https://local.chenhaifeng.top
二. 代理代理多个不同的django容器, https域名代理到http
local.chenhaifeng.top -> 127.0.0.1 home.chenhaifeng.top -> 192.168.1.80 (apche证书下载好放到当前目录的ssl文件夹下)
确保外部网络存在:首先确认你定义的外部网络 shared_network 确实已经存在。如果没有,你可以先创建它:
docker network create shared_network
1. 启动t traefik的docker-compose.yml
version: '3.8'
services:
traefik:
image: traefik:latest
ports:
- "80:80"
- "443:443"
- "8080:8080" # 127.0.0.1:8080查看traefik的后台可以
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./traefik.yml:/etc/traefik/traefik.yml:ro"
- "./ssl:/certs" # 生成的ssl证书放到这里
networks:
- shared_network
networks:
shared_network:
external: true
2. traefik.yml 配置文件
providers:
docker:
#defaultRule: "Host(`{{ trimPrefix `/` .Name }}.docker.localhost`)"
exposedByDefault: false # 避免自动暴露所有容器
#file:
# directory: "/etc/traefik/config"
api:
insecure: true
entrypoints:
web:
address: ":80"
websecure:
address: ":443"
http:
tls:
domains:
- main: "local.chenhaifeng.top" # 主域名(可选)
tls:
certificates:
- certFile: "/certs/local.chenhaifeng.top_public.crt"
keyFile: "/certs/local.chenhaifeng.top.key"
- certFile: "/certs/home.chenhaifeng.top_public.crt"
keyFile: "/certs/home.chenhaifeng.top.key"
3. 容器django-1的docker-compose-django.yml(这个使用域名home.chenhaifen.top解析为127.0.0.1)
version: '3.8'
services:
django_test:
build: .
image: django_test
labels:
- "traefik.enable=true"
- "traefik.http.routers.django_test.rule=Host(`home.chenhaifeng.top`)"
- "traefik.http.routers.django_test.entrypoints=websecure"
- "traefik.http.routers.django_test.tls=true"
- "traefik.http.services.django_test.loadbalancer.server.port=8010"
networks:
- shared_network
networks:
shared_network:
external: true
4. 容器django2的django-compose.yml(这个使用域名local.chenhaifeng.top: 解析为192.168.1.80 当前电脑ip)
version: "3"
volumes:
backend_local_postgres_data: {}
backend_local_postgres_data_backups: {}
services:
django: &django
build:
context: ./backend
dockerfile: ./compose/local/django/Dockerfile
image: backend_local_django
labels:
- "traefik.enable=true"
- "traefik.http.routers.cews_django.rule=Host(`local.chenhaifeng.top`)"
- "traefik.http.routers.cews_django.entrypoints=websecure"
- "traefik.http.routers.cews_django.tls=true"
- "traefik.http.services.cews_django.loadbalancer.server.port=8020"
container_name: cews_django
depends_on:
- postgres
- redis
volumes:
- ./backend:/app:z
env_file:
- ./backend/.envs/.local/.django
- ./backend/.envs/.local/.postgres
- ./backend/.envs/.local/.mongo
# ports:
# - "8020:8020"
command: /start
networks:
- shared_network
postgres:
build:
context: ./backend
dockerfile: ./compose/production/postgres/Dockerfile
image: backend_production_postgres
# container_name: backend_local_postgres
ports:
- 5432:5432
volumes:
- backend_local_postgres_data:/var/lib/postgresql/data
- backend_local_postgres_data_backups:/backups
env_file:
- ./backend/.envs/.local/.postgres
# docs:
# image: backend_local_docs
container_name: backend_local_docs
networks:
- shared_network
# build:
# context: .
# dockerfile: ./compose/local/docs/Dockerfile
# env_file:
# - ./.envs/.local/.django
# volumes:
# - ./docs:/docs:z
# - ./config:/app/config:z
# - ./backend:/app/backend:z
# ports:
# - "9000:9000"
# command: /start-docs
redis:
image: redis:6
ports:
- 6379:6379
networks:
- shared_network
# container_name: backend_local_redis
celeryworker:
<<: *django
image: backend_local_celeryworker
container_name: cews_celeryworker
depends_on:
- redis
- postgres
ports: []
command: /start-celeryworker
networks:
- shared_network
celerybeat:
<<: *django
image: backend_local_celerybeat
container_name: cews_celerybeat
depends_on:
- redis
- postgres
ports: []
command: /start-celerybeat
networks:
- shared_network
flower:
<<: *django
image: backend_local_flower
container_name: cews_flower
ports:
- "5555:5555"
command: /start-flower
networks:
- shared_network
mongo:
image: mongo
restart: always
env_file:
- ./backend/.envs/.local/.mongo
ports:
- 27017:27017
networks:
- shared_network
mongo-express:
image: mongo-express
restart: always
ports:
- 8081:8081
env_file:
- ./backend/.envs/.local/.mongo
depends_on:
- mongo
networks:
- shared_network
networks:
shared_network:
external: true