Multiple services with same php-fpm mapping in docker-compose

1. Caddy version (caddy version):

2.4.5

2. How I run Caddy:

a. System environment:

Docker via docker-compose. Ubuntu 21.04

b. Command:

docker-compose up

c. Service/unit/compose file:

version: '3.3'
services:
  caddy:
    container_name: caddy
    build: ./caddy
    ports:
      - "80:80"
      - "443:443"
      - "80:80/udp"
      - "443:443/udp"
    volumes:
      - ${CONFIG_PATH}/caddy/Caddyfile:/etc/caddy/Caddyfile
      - ${CONFIG_PATH}/var/caddy:/root/.caddy
      - ${CONFIG_PATH}/caddy/data:/data
      - ${CONFIG_PATH}/caddy/config:/config
# BEGIN SECTION THAT IS CAUSING PROBLEMS -----------------
      - ${WWW_PATH}/${HOST_1}:/var/www/html**
      - ${WWW_PATH}/${HOST_2}:/var/www/html**
# END SECTION THAT IS CAUSING PROBLEMS -------------------
    restart: always
  wp1:
    # build: .
    image: wordpress:fpm-alpine
    container_name: ${HOST_1}-wp
    hostname: $SITE_1
    networks:
      - $DEFAULT_NETWORK
    depends_on:
      - db1
    environment:
      WORDPRESS_DB_PASSWORD: $DB_PASSWORD
      WORDPRESS_DB_HOST: db1
      WORDPRESS_DB_USER: $DB_USER
      WORDPRESS_DB_NAME: $DB_NAME
    volumes:
      - ${WWW_PATH}/${HOST_1}:/var/www/html
    restart: always

  db1:
    image: $DB_IMAGE
    container_name: ${HOST_1}-wp-db
    networks:
      - $DEFAULT_NETWORK
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
      MYSQL_USER: $DB_USER
      MYSQL_PASSWORD: $DB_PASSWORD
      MYSQL_DATABASE: $DB_NAME
    volumes:
      - ${CONFIG_PATH}/mysql/${HOST_1}:/var/lib/mysql
    restart: always
  wp2:
    # build: .
    image: wordpress:fpm-alpine
    container_name: ${HOST_2}-wp
    hostname: $SITE_2
    networks:
      - $DEFAULT_NETWORK
    depends_on:
      - db2
    environment:
      WORDPRESS_DB_PASSWORD: $DB_PASSWORD
      WORDPRESS_DB_HOST: db2
      WORDPRESS_DB_USER: $DB_USER
      WORDPRESS_DB_NAME: $DB_NAME
    volumes:
      - ${WWW_PATH}/${HOST_2}:/var/www/html
    restart: always

  db2:
    image: $DB_IMAGE
    container_name: ${HOST_2}-wp-db
    networks:
      - $DEFAULT_NETWORK
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
      MYSQL_USER: $DB_USER
      MYSQL_PASSWORD: $DB_PASSWORD
      MYSQL_DATABASE: $DB_NAME
    volumes:
      - ${CONFIG_PATH}/mysql/${HOST_2}:/var/lib/mysql
    restart: always

d. My complete Caddyfile or JSON config:

{$SITE_1} {
    root * /var/www/html
    php_fastcgi {$DOCKER_HOST_1}:{$FPM_PORT}
    file_server
}

{$SITE_2} {
    root * /var/www/html
    php_fastcgi {$DOCKER_HOST_2}:{$FPM_PORT}
    file_server
}

3. The problem I’m having:

TL;DR: Can’t get multiple Wordpress Docker instances to function if using -fpm versions

When using php-fpm, Caddy points to the same volume mapping (/var/www/html) in docker-compose.yml. When defining the Caddy service in compose, specifying different source volumes does not give it anything to distinguish the target volume since it is the same.

Is there a clean way to use the official Wordpress fpm images with docker-compose, and tell Caddy that the var/www/html paths are in different containers? :man_shrugging:

4. Error messages and/or full log output:

No error message. It just serves the same root directory for all domains specified in Caddy

5. What I already tried:

This works fine if I use regular WP (not PHP-FPM).

PHP-FPM works if I build unique containers with unique tags, then change the target volume path inside the container. For instance, if the containers’ /var/www/html paths are internally renamed to /var/ww1/html and /var/ww2/html, I can provide the caddy service volume mapping which looks like this:

      # - ${WWW_PATH}/${HOST_1}:/var/www1/html
      # - ${WWW_PATH}/${HOST_2}:/var/www2/html

Requiring a separate container build for each WP service feels super kludgy. And in benchmarks, PHP-FPM seems to be significantly faster (in the ballpark of 300%).

6. Links to relevant resources:

My earlier thread on Docker / WP configs

Please upgrade to v2.4.6!

This is an issue with php-fpm in general, it doesn’t just affect Caddy, but also Nginx which uses the same approach. It’s just unfortunate that the official Wordpress container doesn’t make it possible to move the site root easily.

Here, you can use /var/www/html/wp1 and /var/www/html/wp2 respectively.

Then in your Caddyfile, you could do this:

{$SITE_1} {
	root * /var/www/html/wp1
	php_fastcgi {$DOCKER_HOST_1}:{$FPM_PORT} {
		root /var/www/html
	}
	file_server
}

{$SITE_2} {
	root * /var/www/html/wp2
	php_fastcgi {$DOCKER_HOST_2}:{$FPM_PORT} {
		root /var/www/html
	}
	file_server
}

I’ve not verified that this works in some time, but the idea is that Caddy sees the files at /var/www/html/wp1 for file_server and but when Caddy’s fastcgi transport sends the request to the Wordpress container to run the PHP code, it uses the root /var/www/html instead to build the full file paths.

2 Likes

Done

Works! Thanks!!!

1 Like

This topic was automatically closed after 30 days. New replies are no longer allowed.