Does the http.on directive exist in V2?

I’m using the on directive to manage a php application in a Docker container, basically the example from the V1 docs is what I use in the Caddyfile:

on startup php-fpm start

I was beginning to investigate upgrading to V2, but was unable to find anything like this in the current docs. Did I miss it, or is there different way to accomplish this in V2?

There’s no on in v2 yet. It might come eventually!

If you’re running in Docker, I’d highly recommend splitting your PHP-FPM and Caddy containers from eachother. That way, you can use the official Caddy docker image and not have to maintain it yourself. Also, you’ll be able to let Docker take care of starting PHP-FPM for you when you need it by running the container.

If you use docker-compose, then you’ll be able to connect to your FPM container like this from the Caddyfile:

php_fastcgi php-fpm:9000

This assumes you name your FPM service php-fpm in your docker-compose.yml.

1 Like

My reason for combining Caddy and php-fpm into a single image was originally because of this bug. I wanted to containerize the PHP app which means the root directory was not accessible outside of the container, only the data volume. I couldn’t use Caddy externally because it needed direct access the application files, so basically now everything is proxied.

It sounds like I should be able to just use the php_fastcgi directive by itself and not have to have a root directory? I suppose I’ll have to give it a try.

Here’s my current V1 Caddyfile. I haven’t looked at converting it yet. Any tips on what or what won’t work are welcome.

:2015
gzip

fastcgi / 127.0.0.1:9000 php {
  except public
}

# Static files have versions in their URLs, and can be cached indefinitely.
expires {
  match ^/public/ 1y
}

internal /forbidden

# User data is stored here by default.
rewrite /data {
  to /forbidden
}

# Nothing sensitive here, but there is no need to publish it.
rewrite /app {
  to /forbidden
}
rewrite /modules {
  to /forbidden
}
rewrite /resources {
  to /forbidden
}
rewrite /vendor {
  to /forbidden
}

# Rewrite all other requests onto the webtrees front-controller.
rewrite {
  if {path} not_starts_with /public
  if {path} not_starts_with /forbidden
  to /index.php
}

log / stdout {
  except /public
}
errors stdout

on startup php-fpm

Caddy still needs to be aware of the files in your PHP app. All you need to do is share the volumes between containers. Very standard practice.

fastcgi.index works only with http.root · Issue #1778 · caddyserver/caddy · GitHub is not a bug, that’s working exactly as intended. It’s impossible for the webserver to determine if the path is valid if it doesn’t know which files exist on disk. If Caddy was to ask fastcgi to handle a request for a file but the file doesn’t exist, then fastcgi would return an error.

I barely have a grasp of how php-fpm works… It look like I’ve misunderstood the documentation and the issue comments talking about running the FCGI server on a separate host.

root specifies the root directory used by the FastCGI server if different from the root directory of the virtual host. Useful if the FastCGI server is on a different server, chroot-jailed, and/or containerized.

So the paths may be different (different mount points, whatever), but Caddy still needs to see the files. OK.

I’ll look at sharing a volume between the containers, but maybe I’m not understanding how that would work. I don’t want to create an external persistent volume for the application files, they’re supposed to be part of the container image, so when I upgrade or downgrade versions the app updates as well. Are you suggesting to do this by using something the --volumes-from option?

It seems like most php based images out there use some sort of webserver to host the php software, instead of exposing php directly. Most are using apache or nginx, but I prefer Caddy so I’ve taken the same approach.

Maybe my simplest option would be to just continue as I am, but update my Dockerfile to use the new caddy image as a base. There’s even an example,

Most users deploying production sites will not want to rely on mounting files into a container, but will instead base their own images on caddy/caddy :

# note: never use the :latest tag in a production site
FROM caddy/caddy:v2.0.0

COPY Caddyfile /etc/caddy/Caddyfile
COPY site /site

Seems like I can just remove the multi-stage build portion where I download the caddy binary and use the docker image instead.

Here’s an example docker-compose.yml:

version: '3'

networks:
  frontend:
  backend:

volumes:
  caddy_data:
  caddy_config:
  app_code:

services:

  caddy:
    image: caddy/caddy:2.0.0-beta.20
    volumes:
      - app_code:/var/www
      - caddy_data:/data
      - caddy_config:/config
      - ./Caddyfile:/etc/caddy/Caddyfile
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - php-fpm
    networks:
      - frontend
      - backend

  php-fpm:
    image: php:7.3-fpm
    volumes:
      - app_code:/var/www
    expose:
      - "9000"
    networks:
      - backend

This isn’t exactly complete, but that’s the gist of it.

Your php-fpm service would have the code in it at /var/www, and because we have an app_code volume defined, the contents will be shared with the caddy service.

During development, typically I would use something like - ./:/var/www to make the contents of my current directory be in the /var/www directory inside the containers. This is so I don’t need to rebuild the image every time any PHP code changes.

In production, you’d do it like the above, where your php-fpm container could contain all the code, and it gets shared to Caddy.

1 Like

Thanks for the ideas.

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