简体   繁体   中英

Bad Gateway for WordPress containers behind Traefik reverse proxy in docker-compose

Firstly, I'd like to say that I'm not a server admin. I'm a web programmer tasked with setting up a development server and I have no idea what I'm doing. I may not be doing things according to best practice or the way you might do them. Unfortunately, with Traefik, there are 3 ways to do everything and so 2/3 of the answers that I've come across aren't compatible with my implementation and I can't figure out how to make them work. Furthermore, this isn't my only (or even primary) job duty.

Here's the setup:

Single-server docker environment on a Linode server with Ubuntu 20.04

I have one stack with Traefik, Traefik Hub, Portainer, and WhoAmI configured and working (mostly) correctly. I don't have the DNS challenge working right with Let's Encrypt, but I don't really care about that at this point. I don't really need a wildcard certificate.

I created a mariadb container. We're mostly a WordPress shop and I'd like to have one container for all the databases we work with rather than configuring a database on an environment-by-environment basis.

I created an external bridge network, named "maverick-net" and all of the stacks are connected to it.

I have a self-hosted GitHub runner listening for changes to the "dev" branch of the project. The runner pulls down the latest repo, writes GitHub secrets to a local.env file, runs composer install and then docker-compose up -d . (That's the reason behind the obscenely-long bind mount paths.)

I'm trying to make the code for these WordPress projects reusable as much as possible, so there's a lot of.env variables in the different files. At some point I'll probably move those over to docker secrets, but at this point it's a development server and not as critical.

My issue is that I haven't been able to get a WordPress site up and running, and I keep hitting a "Bad Gateway" error. When I curl the URL from inside the traefik container, I get... wait for it... "Bad Gateway."

Clearly there's something I'm missing, but I've been slamming my head against a brick wall for weeks trying different approaches to get this running and I need help. There has to be something I'm not getting about docker networks in general because my wp-cli container never has been able to connect to the database, regardless of whether I start it in the same stack or if i try to connect to it on the maverick-net network.

My traefik stack (side note, I'd really like to split these command entries into static and dynamic config files, but that's a task for another day):

 version: "3.9" secrets: linode_token: file: "../secrets/linode_token.secret" services: traefik: container_name: traefik image: "traefik:latest" command: - --log.level=DEBUG - --log.filePath=./traefik.log - --accessLog=true - --accessLog.filePath=./access.log - --accessLog.bufferingSize=100 - --accessLog.filters.statusCodes=400-499 - --api - --api.dashboard=true - --api.insecure=false - --entrypoints.web.address=:80 - --entrypoints.websecure.address=:443 - --providers.docker - --providers.docker.watch=true - --providers.docker.exposedbydefault=false - --certificatesresolvers.leresolver.acme.dnsChallenge=true - --certificatesresolvers.leresolver.acme.dnsChallenge.provider=linodev4 - --certificatesresolvers.leresolver.acme.httpchallenge=true - --certificatesresolvers.leresolver.acme.httpchallenge.entrypoint=web - --certificatesresolvers.leresolver.acme.email=xxxxxxxxxxx@xxxxxxxxx.xxx - --certificatesresolvers.leresolver.acme.storage=./acme.json #- --certificatesresolvers.leresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory - --certificatesresolvers.leresolver.acme.caserver=https://acme-v02.api.letsencrypt.org/directory - --experimental.hub=true - --hub.tls.insecure=true - --metrics.prometheus.addrouterslabels=true ports: - "80:80" - "443:443" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ~/certs-data/acme.json:/data/letsencrypt/acme.json -./static.yml:/static.yml:ro -./configs:/configs - ~/certs-data/:/data/letsencrypt/ secrets: - "linode_token" environment: TZ: America/Chicago LINODE_TOKEN_FILE: "/run/secrets/linode_token" labels: - "traefik.enable=true" - "traefik.docker.network=maverick-net" - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)" - "traefik.http.routers.http-catchall.entrypoints=web" - "traefik.http.routers.http-catchall.middlewares=redirect-to-https" - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" - "traefik.http.routers.traefik.tls.certresolver=leresolver" - "traefik.http.routers.traefik.rule=Host(`XXXXX.XXXXXXXXXX.XXX`)" - "traefik.http.routers.traefik.entrypoints=websecure" - "traefik.http.routers.traefik.service=api@internal" - "traefik.http.routers.traefik.middlewares=traefik-auth" - "traefik.http.middlewares.traefik-auth.basicauth.users=XXXX:$$apr1$$XXXXX$$XXXXXXXXXXXXXXX" - "traefik.http.routers.api.entrypoints=websecure" networks: - maverick-net hub-agent: image: ghcr.io/traefik/hub-agent-traefik:experimental pull_policy: always container_name: hub-agent restart: on-failure command: - run - --hub.token=XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX - --auth-server.advertise-url=http://hub-agent - --traefik.host=traefik - --traefik.tls.insecure=true volumes: - /var/run/docker.sock:/var/run/docker.sock:ro depends_on: - traefik networks: - maverick-net portainer: image: portainer/portainer-ce:latest command: -H unix:///var/run/docker.sock container_name: portainer restart: always volumes: - /var/run/docker.sock:/var/run/docker.sock - portainer_data:/data labels: # Frontend - "traefik.enable=true" - "traefik.http.routers.frontend.rule=Host(`XXXXX.XXXXXXXXXX.XXX`)" - "traefik.http.routers.frontend.entrypoints=websecure" - "traefik.http.services.frontend.loadbalancer.server.port=9000" - "traefik.http.routers.frontend.service=frontend" - "traefik.http.routers.frontend.tls.certresolver=leresolver" networks: - maverick-net whoami: image: "traefik/whoami" container_name: "whoami" labels: - "traefik.enable=true" - "traefik.http.routers.whoami.rule=Host(`XXXXX.XXXXXXXXXX.XXX`)" - "traefik.http.routers.whoami.entrypoints=websecure" - "traefik.http.routers.whoami.tls.certresolver=leresolver" networks: - maverick-net volumes: portainer_data: networks: maverick-net: external: true

My mariadb stack:

 version: "3" networks: # enable connection with Traefik maverick-net: external: true services: mariadb: container_name: mariadb image: mariadb:10.7 restart: always volumes: - "/home/xxxxxxxxxx/docker/mariadb/data:/var/lib/mysql" expose: - "3306" env_file: .env environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PWD} MYSQL_USER: ${ADMIN_DB_USER} MYSQL_PASSWORD: ${ADMIN_DB_PWD} networks: - maverick-net

And finally my WordPress stack:

 version: '3.8' networks: maverick-net: external: true # volumes: # db_data: services: # mariadb: # container_name: ${WORDPRESS_DB_NAME}-db # image: mariadb:10.7 # restart: always # volumes: # - "db_data:/var/lib/mysql" # env_file: .env # environment: # MYSQL_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD} # MYSQL_USER: ${ADMIN_DB_USER} # MYSQL_PASSWORD: ${ADMIN_DB_PWD} wordpress: container_name: ${WORDPRESS_DB_NAME}-wp image: wordpress:6.0.2-fpm volumes: - type: bind source: ${PROJECT_ROOT}/${WORDPRESS_DB_NAME}/${PROJECT_NAME}/${PROJECT_NAME}/wp target: /var/www/html restart: always env_file: .env environment: WORDPRESS_DB_HOST: mariadb MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD} WORDPRESS_DATABASE_USER: ${WORDPRESS_DB_USER} WORDPRESS_DATABASE_PASSWORD: ${WORDPRESS_DB_PASSWORD} WORDPRESS_DATABASE_NAME: ${WORDPRESS_DB_NAME} labels: # The labels are useful for Traefik only - "traefik.enable=true" - "traefik.docker.network=maverick-net" # Get the routes from https - "traefik.http.routers.${WORDPRESS_DB_NAME}.rule=Host(`${DEV_URL}`)" - "traefik.http.routers.${WORDPRESS_DB_NAME}.entrypoints=websecure" - "traefik.http.routers.${WORDPRESS_DB_NAME}.tls.certresolver=leresolver" networks: - maverick-net wordpress-cli: container_name: ${WORDPRESS_DB_NAME}-cli image: wordpress:cli volumes: - type: bind source: ${PROJECT_ROOT}/${WORDPRESS_DB_NAME}/${PROJECT_NAME}/${PROJECT_NAME}/wp target: /var/www/html env_file: .env environment: WORDPRESS_DB_HOST: mariadb MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD} WORDPRESS_DATABASE_USER: ${WORDPRESS_DB_USER} WORDPRESS_DATABASE_PASSWORD: ${WORDPRESS_DB_PASSWORD} WORDPRESS_DATABASE_NAME: ${WORDPRESS_DB_NAME} networks: - maverick-net depends_on: - wordpress

I am trying to figure out how to do this too.

As far as I know, you can connect to containers in the same network by using their service name.

So for example you are trying to curl to the Wordpress container from the Traefik Container.

curl 'http://wordpress/'

Should work.

In another project I use an nginx container with php-fpm. I need to send my curl requests to the nginx container, because the php-fpm container does not handle server requests directly:

// does not work
curl 'http://php-debug/index.html'
// result
curl: (7) Failed to connect to php-debug port 80: Connection refused

// https also does not work
curl 'https://php-fpm/index.html'
// result
curl: (7) Failed to connect to php-fpm port 443: Connection refused

// This does work
curl 'http://nginx/index.html'
// result
<HTML...

For some reason https: curl requests fail, but on http I get the correct result so for local development I think it's ok.

If you are interested in a more managed solution, you can check out warden.dev. It contains a template for Wordpress too (which I use succesfully for local development). I have been using this exclusively. If you have questions how to setup WP CLI on this solution, feel free to contact me.

It comes with portainer, traefik, ssl and dns and mailhog. Configuration is pretty straight forward, I can set up a new project within an hour and connect to the database and containers in my IDE.

https://docs.warden.dev/environments/types.html#wordpress

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM