Caddy for SPA & API

1. Caddy version (caddy version):

v2.3.0 h1:fnrqJLa3G5vfxcxmOH/+kJOcunPLhSBnjgIvjXV/QTA=

2. How I run Caddy:

a. System environment:

Ubuntu 20.04

b. Command:

caddy run --config ~/Caddyfile

c. Service/unit/compose file:

# None

d. My complete Caddyfile or JSON config:

:80 {

    root * /root/test/frontend/build
    file_server
    encode gzip

    reverse_proxy /api*  localhost:5000

    log {
        output file /var/log/caddy/access.log {
                roll_size 1mb
                roll_keep 4
                roll_keep_for 24h
        }
    }
}

3. The problem I’m having:

I am trying to seek advice/recommendation on how my Caddyfile should be set up. The above Caddyfile appears to do what I want based on some brief testing, but I am new to Caddy and would love to learn more from you.

My project consists of a React frontend app listening to port 3000 and a Python Flask app served by a Gunicorn server on port 5000. The React app (to be at https://mydomain.com) queries the Flask API server (to be at https://mydomain.com/api to retrieve data. No domain name has been purchased yet for this project, but I will get one real soon!

Several questions:

  1. Should Caddyfile use

    reverse_proxy /api*  localhost:5000
    

    or

    reverse_proxy /api*  0.0.0.0:5000
    

    Both appears to work in my case.

  2. Does the file_server directive apply/pair only to root * /root/test/frontend/build? Or is it also being applied to the reverse_proxy directive? If it is applied to reverse_proxy directive, should this be a concern?

  3. The API server listening on port 5000 is a Python Flask app being served using Gunicorn HTTP server. Does it make sense to replace Gunicorn with Caddy’s file_server? Is there a significant performance difference between Gunicorn and Caddy’s file_server?

4. Error messages and/or full log output:

5. What I already tried:

6. Links to relevant resources:

This one is more correct – localhost means 127.0.0.1 (ipv4) or ::1 (ipv6), and 0.0.0.0 means “all interfaces” but it has different meanings in different contexts:

The root directive basically just sets a variable called root that any other directive can later read if they care to know where to look for files. The reverse_proxy directive does not care about root because it proxies to other servers, so it doesn’t need to look for files on disk.

If it’s a flask app, that doesn’t sound like something the file server can replace. If you actually need to run python code, then you’ll need gunicorn or whatever equivalent to do that.

1 Like