Can't get MotionEye to work with Caddy Reverse Proxy

1. Caddy version (caddy version):


2. How I run Caddy:

I’m using Caddy as a reverse proxy for several back-end applications at my house. I’ve historically had no issues with any other apps, but am struggling to get anything to work with Caddy V2 and Motioneye.

a. System environment:

NixOS, Systemd

b. Command:

This long path is how NixOS deals with applications that are defined in my static Nix configuration. For our purposes, ignore the random string in the path.

/nix/store/jyq9ldmrl2z0q62m949sngz0kz2lznh0-caddy-2.3.0/bin/caddy run --config /nix/store/2im2524iwm7sl3zfz0gazhz40q7mbgf6-caddy-config.json

c. Service/unit/compose file:

From my configuration.conf for defining the Caddy service on NixOS

services.caddy = {
    enable = true;
    email = "";
    config = '' {
        reverse_proxy /

d. My complete Caddyfile or JSON config: {
        reverse_proxy /

3. The problem I’m having:

I get an un-stylized screen for motioneye and no video (shown in attached screenshot). I had it working in Nginx, but can’t seem to do the same with Caddy.

5. What I already tried:

I’ve tried a bunch of various configurations I’ve found through my searching, unfortunately most of them seem to be targeted at Caddy v1 or don’t have anything to do with Motioneye. My original Nginx Configuration looked like this:


    listen 443 ssl;
    listen [::]:443 ssl;


    include /config/nginx/ssl.conf;

    location / {
	access_log off;
        set $upstream_app;
        set $upstream_port 8765;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";


Path matching in Caddy v2 is exact. This means that the first / only matches requests to exactly / and nothing else. To proxy all paths, use either * or omit the matcher argument altogether.

1 Like

This was absolutely the solution. Thank you!

For solution posterity and lazy Googling: {

I recommend removing /* altogether. When you use /* rather than * or simply omitting the matcher, you’re telling Caddy to do a path comparison on every request to check that it starts with /, but it always will, so it’s wasted CPU cycles (although it’s only a few nanoseconds per request at most).

Okay, I edited my post above. Thanks!

1 Like

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