Single Page Application and backend API

1. Caddy version (caddy version):

v2.2.1 h1:Q62GWHMtztnvyRU+KPOpw6fNfeCD3SkwH7SfT1Tgt2c=

2. How I run Caddy:

As systemd service

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target

[Service]
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

a. System environment:

Linux dragonfly 4.19.0-11-amd64 #1 SMP Debian 4.19.146-1 (2020-09-17) x86_64 GNU/Linux

d. My complete Caddyfile or JSON config:

I will provide relevant virtual host

demo.dascr.org {
	basicauth * {
	[... ommited ...]
	}

	reverse_proxy /api/* localhost:8000
	reverse_proxy /images/* localhost:8000
	reverse_proxy /uploads/* localhost:8000
	reverse_proxy /ws/* localhost:8000

	root * /var/www/demo.dascr
    encode gzip

    try_files {path} {file} /index.html
	file_server

	header {
	# enable HSTS
	Strict-Transport-Security max-age=31536000;

	# disable clients from sniffing the media type
	X-Content-Type-Options nosniff

	# clickjacking protection
	X-Frame-Options DENY

	# keep referrer data off of HTTP connections
	Referrer-Policy no-referrer-when-downgrade
	}

	log {
		output file /var/log/caddy/demo.dascr.org.access.log {
			roll_size 1gb
			roll_keep 5
			roll_keep_for 720h
		}
	}
}

3. The problem I’m having:

I am trying to provide access to a backend api and a frontend single page application (Svelte) from one single virtual host. The frontend access is working fine but somehow the line with try_files seams to interfere with the reverse_proxy settings.

So now I am looking for the right combination of reverse_proxy for the backend api and something like a rewrite rule for the frontend.

4. Error messages and/or full log output:

No error message. Just 404 not found in Browser when subpath

5. What I already tried:

Different combination of matchers and such.

6. Links to relevant resources:

Got it working:

demo.dascr.org {
	root * /var/www/demo.dascr
	encode gzip

	basicauth * {
		ommitted
	}

	handle /api/* {
		reverse_proxy localhost:8000
	}

	handle /images/* {
		reverse_proxy localhost:8000
	}

	handle /uploads/* {
		reverse_proxy localhost:8000
	}

	handle /ws/* {
		reverse_proxy localhost:8000
	}

	handle {
		try_files {path} {file} /index.html
		file_server
	}

	header {
	# enable HSTS
	Strict-Transport-Security max-age=31536000;

	# disable clients from sniffing the media type
	X-Content-Type-Options nosniff

	# clickjacking protection
	X-Frame-Options DENY

	# keep referrer data off of HTTP connections
	Referrer-Policy no-referrer-when-downgrade
	}

	log {
		output file /var/log/caddy/demo.dascr.org.access.log {
			roll_size 1gb
			roll_keep 5
			roll_keep_for 720h
		}
	}
}
1 Like

Glad you figured it out! Thanks for following up.

Instead of four separate handles, you can used a named matcher to use just one instead:

@proxied path /api/* /images/* /uploads/* /ws/*
handle @proxied {
    reverse_proxy localhost:8000
}

You can also move root to inside the handle with file_server, since they belong together (root is necessary for try_files and file_server, but isn’t useful for proxy).

1 Like

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