Trouble settting up Caddy with tricky PHP app

1. The problem I’m having:

Hi everyone, trying to use caddy for development internal sites and its work awesome with widely-used cms (like Wordpess), but i have in trouble with htaccess->to->Caddyfile transformations on some off the beaten track project

few days of attempts and searching in docs and forum but, sadly, i’m dont understand some moments, described in Caddifile as comments

2. Error messages and/or full log output:

Sometimes caddy runs, but app not works)

3. Caddy version:

2.6.4

4. How I installed and ran Caddy:

a. System environment:

x64, Manjaro

b. Command:

sudo caddy run

(Caddyfile exists in current folder)

c. Service/unit/compose file:

d. My complete Caddy config:

comments used as questions

internal.site:443 {
	root * "{host}"
	file_server
	tls internal
	encode zstd gzip
	log {
		output file "internal.api_error.log"
		level ERROR
	}

	# 1. site structure is multiple subfolders with own settings, so i need route directives for every entrypoint? 
	route /app/folder-1/www/ {
		# 2. rewrite all path to php files (not on sigle index.php entry). Its right form?
        @pathToPHP file {
			try_files {path}/ {path}.php =404
			split_path .php
		}
		rewrite @pathToPHP {file_match.relative}

        # 3. single path rewrite. Right?
		rewrite /api /api.php {file_match.relative}

        # 4. in htaccess example env variables (like APP_ROOT) used as part of rewrites. Can i use something like this one in Caddyfile?
		@phpFiles path *.php
		reverse_proxy @phpFiles "unix//var/run/php-fpm/php-fpm.sock" {
			transport fastcgi {
				split .php
				env PHP_VALUE "display_errors=on
					log_errors=on
					expose_php=off"

				env APP_ROOT "/relative-path-to-backend-app/www/"
				env STORAGE_ROOT "/relative-path-to-storage/folder/www/"
				env API_ROOT "../relative-path-to-api/www/"
				env DEBUG_ENABLED "true"

                # but how can I use it in rewrite?
			}
		}
	}
    route /app/folder-2/www/ {
        # ...
    }
    route /app/folder-3/www/ {
        # ...
    }
}

e. My .htaccess config:

Originally .htaccess file is looks like that in every separate app folder (like /app/folder-1/www/ )


# set env variables (used in site code)
SetEnvIf Request_URI ".*" APP_ROOT="/relative-path-to-backend-app/www/"
SetEnvIf Request_URI ".*" STORAGE_ROOT="/relative-path-to-storage/folder/www/"
SetEnvIf Request_URI ".*" API_ROOT="../relative-path-to-api/www/"
SetEnvIf Request_URI ".*" DEBUG_ENABLED="true"

# strip ending spash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/+$ %{ENV:APP_ROOT}$1 [R=301,L]

# seach index file in current app folder
RewriteRule ^index\.(html|htm|php)$ %{ENV:SITE_ROOT} [R=301,L]

# single rewrite

RewriteCond %{REQUEST_URI} /(api)/([^/]+)?$
RewriteRule .* %{ENV:APP_ROOT}%1.php?%2 [L,QSA]

# search php file in current app root folder - for path without extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ %{ENV:APP_ROOT}$1.php [L,QSA]

5. Links to relevant resources:

php_fastcgi expanded form

Path matching is exact. So this would only match the path /app/folder-1/www/ exactly, and nothing else. You probably meant to append a * to the the path.

Also you probably mean to use handle instead of route, they have different behaviour.

Uh, kinda. You might not need split_path .php, that’s only needed when you might have requests like /path/to/script.php/with/a/path/at/the/end (i.e. the file is script.php but you want to allow a path segment following the filename).

You might also want {path} first to allow routing to non-PHP files (CSS/JS/etc) along with file_server, otherwise it’ll 404 for static files that do exist.

You want just this rewrite /api /api.php

But keep in mind, your request path is /app/folder-1/www/ in here, so /api will never match.

You probably want either rewrite /app/folder-1/www/api {path}.php or you need to use uri strip_prefix (or handle_path instead of route) to strip the matched prefix away.

You can use the vars directive to set variables ahead of time then use it with placeholders.

Setting the values in the proxy directive is “too late”, the rewrites will already have happened by then, so there’s no way it could be used by anything else. There’s no mechanism for that in Caddy anyway. The env option is used just before writing to the fastcgi.

1 Like

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