是否可以在 nginx 反向代理 docker 上动态添加位置?
Is it possible to add locations dinamically on ngninx reverse proxy docker?
基础设施
我想创建一个具有以下结构的 docker:
我打算有一个 docker-compose
,里面有 3 个主要图像(一个数据库,一个 api 在端口 8080 上,一个前端在端口 443 上)。除此之外,我还有一些额外的 docker-compose 代表其他服务。
功能
我正在寻找的功能是能够从 nginx 反向代理(main docker-compose)内部创建辅助 docker-compose 文件的容器实例并映射该端口到一个唯一的子目录(能够创建相同 docker-compose 的多个实例很重要)。
我发现了什么
要完成其余功能,已找到一些资源:
使用traefik解决了这个问题,它允许我在不修改构建配置的情况下通过子目录向容器添加路由。
docker-compose.yml
会是这样的:
version: '3.7'
services:
traefik:
image: traefik:v2.2.0
ports:
- "${FRONT_HTTP_PORT:-80}:80"
- "${TRAEFIK_PORT:-8080}:8080"
environment:
- TRAEFIK_LOG_LEVEL=DEBUG
- TRAEFIK_PROVIDERS_DOCKER_EXPOSEDBYDEFAULT=false
- TRAEFIK_PROVIDERS_DOCKER=true
- TRAEFIK_PROVIDERS_DOCKER_NETWORK=traefik01
- TRAEFIK_API_INSECURE=true
- TRAEFIK_ENTRYPOINTS_FRONT=true
- TRAEFIK_ENTRYPOINTS_FRONT_ADDRESS=:${FRONT_HTTP_PORT:-80}
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
security_opt:
- label:type:docker_t
frontend:
build: ./frontend
expose:
- 80
labels:
- "traefik.enable=true"
- "traefik.http.routers.frontend.entrypoints=front"
- "traefik.http.routers.frontend.rule=PathPrefix(`/frontend{regex:$$|/.*}`)"
- "traefik.http.routers.frontend.middlewares=frontend-stripprefix"
- "traefik.http.middlewares.frontend-stripprefix.stripprefix.prefixes=/frontend"
- "traefik.http.routers.frontend.priority=2"
# - "traefik.http.routers.frontend.priority=1"
# - "traefik.frontend.rule=Host:ctf.itasahobby.com"
stdin_open: true
api:
build: ./api
expose:
- 80
links:
- database
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.entrypoints=front"
- "traefik.http.routers.api.rule=PathPrefix(`/api{regex:$$|/.*}`)"
- "traefik.http.routers.api.middlewares=api-stripprefix"
- "traefik.http.middlewares.api-stripprefix.stripprefix.prefixes=/api"
- "traefik.http.routers.api.priority=2"
database:
build: ./database
restart: always
networks:
default:
external:
name: testnetwork
然后要添加一个新容器,它必须包含相同的网络接口和标签才能设置路由,例如:
version: '3.7'
services:
app2:
image: httpd:2.4.41-alpine
expose:
- 80
labels:
- "traefik.enable=true"
- "traefik.http.routers.app2.entrypoints=front"
- "traefik.http.routers.app2.rule=PathPrefix(`/app2{regex:$$|/.*}`)"
- "traefik.http.routers.app2.middlewares=app2-stripprefix"
- "traefik.http.middlewares.app2-stripprefix.stripprefix.prefixes=/app2"
networks:
default:
external:
name: testnetwork
基础设施
我想创建一个具有以下结构的 docker:
docker-compose
,里面有 3 个主要图像(一个数据库,一个 api 在端口 8080 上,一个前端在端口 443 上)。除此之外,我还有一些额外的 docker-compose 代表其他服务。
功能
我正在寻找的功能是能够从 nginx 反向代理(main docker-compose)内部创建辅助 docker-compose 文件的容器实例并映射该端口到一个唯一的子目录(能够创建相同 docker-compose 的多个实例很重要)。
我发现了什么
要完成其余功能,已找到一些资源:
使用traefik解决了这个问题,它允许我在不修改构建配置的情况下通过子目录向容器添加路由。
docker-compose.yml
会是这样的:
version: '3.7'
services:
traefik:
image: traefik:v2.2.0
ports:
- "${FRONT_HTTP_PORT:-80}:80"
- "${TRAEFIK_PORT:-8080}:8080"
environment:
- TRAEFIK_LOG_LEVEL=DEBUG
- TRAEFIK_PROVIDERS_DOCKER_EXPOSEDBYDEFAULT=false
- TRAEFIK_PROVIDERS_DOCKER=true
- TRAEFIK_PROVIDERS_DOCKER_NETWORK=traefik01
- TRAEFIK_API_INSECURE=true
- TRAEFIK_ENTRYPOINTS_FRONT=true
- TRAEFIK_ENTRYPOINTS_FRONT_ADDRESS=:${FRONT_HTTP_PORT:-80}
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
security_opt:
- label:type:docker_t
frontend:
build: ./frontend
expose:
- 80
labels:
- "traefik.enable=true"
- "traefik.http.routers.frontend.entrypoints=front"
- "traefik.http.routers.frontend.rule=PathPrefix(`/frontend{regex:$$|/.*}`)"
- "traefik.http.routers.frontend.middlewares=frontend-stripprefix"
- "traefik.http.middlewares.frontend-stripprefix.stripprefix.prefixes=/frontend"
- "traefik.http.routers.frontend.priority=2"
# - "traefik.http.routers.frontend.priority=1"
# - "traefik.frontend.rule=Host:ctf.itasahobby.com"
stdin_open: true
api:
build: ./api
expose:
- 80
links:
- database
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.entrypoints=front"
- "traefik.http.routers.api.rule=PathPrefix(`/api{regex:$$|/.*}`)"
- "traefik.http.routers.api.middlewares=api-stripprefix"
- "traefik.http.middlewares.api-stripprefix.stripprefix.prefixes=/api"
- "traefik.http.routers.api.priority=2"
database:
build: ./database
restart: always
networks:
default:
external:
name: testnetwork
然后要添加一个新容器,它必须包含相同的网络接口和标签才能设置路由,例如:
version: '3.7'
services:
app2:
image: httpd:2.4.41-alpine
expose:
- 80
labels:
- "traefik.enable=true"
- "traefik.http.routers.app2.entrypoints=front"
- "traefik.http.routers.app2.rule=PathPrefix(`/app2{regex:$$|/.*}`)"
- "traefik.http.routers.app2.middlewares=app2-stripprefix"
- "traefik.http.middlewares.app2-stripprefix.stripprefix.prefixes=/app2"
networks:
default:
external:
name: testnetwork