Resolve real path on symlinked releases

1. Caddy version (caddy version):

v2.1.1 h1:X9k1+ehZPYYrSqBvf/ocUgdLSRIuiNiMo7CvyGUQKeA=

2. How I run Caddy:

/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile

a. System environment:

Debian 9.12, PHP 7.2.31 on a KVM machine.
Caddy installed from official deb package from https://apt.fury.io/caddy

b. Command:

/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile

c. Service/unit/compose file:

I use default caddy.service file, this one dist/caddy.service at master · caddyserver/dist · GitHub

d. My complete Caddyfile or JSON config:

cfl.man-at-work.it {
    encode zstd gzip
    root * /srv/www/cfl/current/public/

    tls mymail@example.com

    file_server
    php_fastcgi unix//run/php/php7.2-fpm.sock

    log {
        output file /var/log/caddy/cfl.log
    }
}

3. The problem I’m having:

I’m using Deployer to deploy my code to the server: Deployer uses a symlink based directory schema pointing current release (/srv/www/cfl/current/public/) to last successful deployed version.
Due to the nature of PHP opcache the new release path is not read by PHP because it’s cached and symlink path doesn’t change form PHP prospective.
A workaround for this issue is to restart php-fpm or manually flush opcache at every release.

Nginx has a special entry in config file that resolves symlinks and give php-fpm the real path of root directory called $realpath_root, so going from this config

fastcgi_index           index.php;
    fastcgi_param           SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    fastcgi_param           DOCUMENT_ROOT $document_root;

to this

fastcgi_index           index.php;
    fastcgi_param           SCRIPT_FILENAME  $realpath_root$fastcgi_script_name;
    fastcgi_param           DOCUMENT_ROOT $realpath_root;

Nginx resolve the real path of the symlink and pass it to php-fpm.

Is it possible to obtain the same behaviour in Caddy 2.1?

4. Error messages and/or full log output:

none

5. What I already tried:

Manually restarting php-fpm after each deploy works as expected.

6. Links to relevant resources:

Here the issue is explained way better than above:

https://tech.yappa.be/php-fpm-executing-old-code-after-symlink-deploy

I think you can use the env subdirective of php_fastcgi for this.

Sorry, on my phone so I can’t dig further.

I looked at fastcgi source code and I don’t think that setting root in env subdirective will help: there should be a filepath.EvalSymlinks somewhere to obtain the desired result.

Ah okay. It should be pretty easy to add a new subdirective to do that then, sounds like. If you’d like to write a PR, that’d be great!

Golang rookie here, but I’ll give it a try on weekend

1 Like

If you’re able to hard-code a change to make it work for your usecase, I can help you wire it up as a new configuration option.

Building from source is very easy - there’s a section in the docs that explains how to do it!

Let me know if you have any questions or need help!

Just opened a PR to solve this issue, any feedback is welcome!

2 Likes

Nice job, thanks for the contribution @endelwar!

2 Likes

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