Deploying frankenphp on render.com

1. The problem I’m having:

Hi there,

I’m trying to get a pretty standard Laravel app deployed on a Render web service instance with FrankenPHP.

Here’s my Dockerfile:

FROM dunglas/frankenphp 
RUN install-php-extensions \
 pdo \
 gd \
 intl \
 zip \
 opcache

RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
COPY . /app
RUN composer install --no-interaction --no-scripts --no-suggest
RUN php artisan config:cache
RUN php artisan route:cache
RUN php artisan migrate --force

# Line below needed otherwise build exits with a permissions error
RUN setcap -r /usr/local/bin/frankenphp

Locally, if I run (from the docs):

docker run -p 80:80 -p 443:443 -p 443:443/udp -v $PWD:/app dunglas/frankenphp

Everything works as expected.

On Render, when I deploy everything seems to build and start correctly, I even get the default Laravel uptime endpoint (/up) returning something positive as the healthcheck passes, however if I try to visit the site in a browser I get the “TOO MANY REDIRECTS” error.

I’ve tried clearing my cookies, different browsers and tweaking the ports exposed but nothing seems to help. I don’t really have anything special set up in the environment as shown below:

Screenshot 2024-08-21 at 15 12 39

I think the issue might be something to do with the default port binding and/or proxying from HTTPS → HTTP but I don’t know enough about this to get it working.

Any ideas welcomed! Thanks in advance

2. Error messages and/or full log output:

{"level":"info","ts":1724311880.1020823,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
{"level":"info","ts":1724311880.1030648,"msg":"adapted config to JSON","adapter":"caddyfile"}
{"level":"warn","ts":1724311880.103078,"msg":"Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":10}
{"level":"info","ts":1724311880.1043901,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
{"level":"info","ts":1724311880.1045024,"logger":"http.auto_https","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
{"level":"info","ts":1724311880.1045158,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"info","ts":1724311880.1072965,"msg":"FrankenPHP started 🐘","php_version":"8.3.10","num_threads":1}
{"level":"warn","ts":1724311880.1073344,"logger":"pki.ca.local","msg":"installing root certificate (you might be prompted for password)","path":"storage:pki/authorities/local/root.crt"}
{"level":"info","ts":1724311880.1077294,"msg":"warning: \"certutil\" is not available, install \"certutil\" with \"apt install libnss3-tools\" or \"yum install nss-tools\" and try again"}
{"level":"info","ts":1724311880.107743,"msg":"define JAVA_HOME environment variable to use the Java trust"}
{"level":"info","ts":1724311880.1972446,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc0002d8400"}
{"level":"info","ts":1724311880.3050828,"logger":"tls","msg":"cleaning storage unit","storage":"FileStorage:/data/caddy"}
{"level":"info","ts":1724311880.305352,"logger":"tls","msg":"finished cleaning storage units"}
{"level":"info","ts":1724311887.9194095,"msg":"certificate installed properly in linux trusts"}
{"level":"info","ts":1724311887.9196007,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
{"level":"info","ts":1724311887.9196875,"msg":"failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 7168 kiB, got: 416 kiB). See https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes for details."}
{"level":"info","ts":1724311887.9198284,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
{"level":"info","ts":1724311887.9198742,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
{"level":"info","ts":1724311887.9198818,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["localhost"]}
{"level":"info","ts":1724311887.9204469,"logger":"tls.obtain","msg":"acquiring lock","identifier":"localhost"}
{"level":"info","ts":1724311887.9207993,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1724311887.9208128,"msg":"serving initial configuration"}
{"level":"info","ts":1724311887.9785044,"logger":"tls.obtain","msg":"lock acquired","identifier":"localhost"}
{"level":"info","ts":1724311887.9786289,"logger":"tls.obtain","msg":"obtaining certificate","identifier":"localhost"}
{"level":"info","ts":1724311887.9799352,"logger":"tls.obtain","msg":"certificate obtained successfully","identifier":"localhost","issuer":"local"}
{"level":"info","ts":1724311887.980022,"logger":"tls.obtain","msg":"releasing lock","identifier":"localhost"}
{"level":"warn","ts":1724311887.9803834,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [localhost]: no OCSP server specified in certificate","identifiers":["localhost"]}

3. Caddy version:

v2.8.4 (this is from dunglas/frankenphp latest Docker image)

4. How I installed and ran Caddy:

Via dunglas/frankenphp

a. System environment:

Docker

b. Command:

Default CMD for dunglas/frankenphp

c. Service/unit/compose file:

As above

d. My complete Caddy config:

From frankenPHP

{
	{$CADDY_GLOBAL_OPTIONS}

	frankenphp {
		#worker /path/to/your/worker.php
		{$FRANKENPHP_CONFIG}
	}
}

{$CADDY_EXTRA_CONFIG}

{$SERVER_NAME:localhost} {
	#log {
	#	# Redact the authorization query parameter that can be set by Mercure
	#	format filter {
	#		request>uri query {
	#			replace authorization REDACTED
	#		}
	#	}
	#}

	root * public/
	encode zstd br gzip

	# Uncomment the following lines to enable Mercure and Vulcain modules
	#mercure {
	#	# Transport to use (default to Bolt)
	#	transport_url {$MERCURE_TRANSPORT_URL:bolt:///data/mercure.db}
	#	# Publisher JWT key
	#	publisher_jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG}
	#	# Subscriber JWT key
	#	subscriber_jwt {env.MERCURE_SUBSCRIBER_JWT_KEY} {env.MERCURE_SUBSCRIBER_JWT_ALG}
	#	# Allow anonymous subscribers (double-check that it's what you want)
	#	anonymous
	#	# Enable the subscription API (double-check that it's what you want)
	#	subscriptions
	#	# Extra directives
	#	{$MERCURE_EXTRA_DIRECTIVES}
	#}
	#vulcain

	{$CADDY_SERVER_EXTRA_DIRECTIVES}

	php_server
}

5. Links to relevant resources:

As linked to above

That screenshot link doesn’t work.

What do you mean? You must have a Caddyfile?

What do you mean? You must have logs. Caddy always emits logs to stdout.

1 Like

Thanks for responding, I’ve updated the original post with hopefully everything that was missing.

The screenshot up here still doesn’t work. Is it behind your private github account or something?

I still don’t see any evidence of a problem. Show a request with curl -v.

From your Caddy logs, it looks like Caddy issued a cert for localhost, meaning it’s listening for HTTPS with the hostname localhost. You probably mean to set the SERVER_NAME env var to change that to your actual domain.

I don’t know how <render.com> works.

1 Like

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