I am trying to serve pictures using caddy with no success.
Let me share with you my setup/ stack:
Frontend : React
Backend : Node/Express
Hosted on a Hetzner Server
Webserver : Caddy
Backend and Frontend are both running in separate containers
(Caddy is one of those containers serving the static frontend after it has been built)
This is my docker-compose.yml file:
services:
frontend:
build: ./frontend
ports:
- "5002:5002"
- "443:443"
- "80:80"
# Retrieving the profile pictures from the server
volumes:
- "/srv/personioClone/profilePictures:/srv/personioClone/profilePictures"
backend:
build: ./backend
ports:
- "5001:5001"
# Saving the pictures on the server
volumes:
- "/srv/personioClone/profilePictures:/usr/src/app/profilePictures"
volumes:
profilePictures:
And this is my caddy configuration:
www.pilexlaflex.com {
# Set this path to your site's directory.
root * /var/www/html/build
handle_path /profilePicture/* {
root * /srv/personioclone/profilePictures
header Content-Type image/jpeg
file_server
}
# Fall back
try_files {path} /index.html
# Enable the static file server.
file_server
}
www.pilexlaflex.com:5002 {
reverse_proxy backend:5001
}
Based on my setup and my caddy config, I am supposed to serve a pictures if I write this URL: https://www.pilexlaflex.com/profilePicture/JoeRahme.jpg
However this is not working.
The only pictures that caddy is serving are the images located here: https://www.pilexlaflex.com/static/media/image.png
Please fill out the help topic template as per the forum rules.
I don’t see exactly how you’re running Caddy (unless Caddy is your frontend container?) Please show how you’re running Caddy, show your Caddy logs, show your Caddy version, etc.
Please use backticks ` or brackets <> around links in your post otherwise the forum transforms them into a link using the page’s title.
Thank you for your quick reply.
I have edited my previous message and added the backticks so you can see the actual url of the images I was trying to serve.
Regarding the rest of your questions:
Yes. The frontend container is actually Caddy serving the (static) frontend.
Here is the Dockerfile:
As you can, see I am using the latest image of Caddy.
Finally regarding logs, the only way I know to see Caddy logs is by doing : docker logs your_container_name
Now because of this issue : Too many certificates created - #2 by Mohammed90
I am now unable to create the Caddy container anymore ( maybe because the limit of SSL certificate has been reached) and cannot see the logs.
Maybe you can guide me and explain to me how to do it?
You need to persist the /data volume as per our docs, otherwise you’re throwing away your certs every time you recreate the Docker stack. See Keep Caddy Running — Caddy Documentation for our recommended setup.
You probably need this to be inside a handle block, because try_files has a higher directive order than handle_path so it gets sorted to run before it. That means that the path gets rewritten to /index.html for the images before it can get handled.
I just checked the documentation you shared and compared it with the way I am creating my docker compose and my docker file.
Question 1:
It seems that a Dockerfile is not needed? Do I simply create a docker-compose without a Dockerfile?
Please check the revised docker compose file and let me know if this is now correct:
services:
caddy:
image: caddy:builder-alpine
restart : unless-start
ports:
- "5002:5002"
- "443:443"
- "80:80"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- ./site:/srv
- caddy_data:/srv/personioClone/profilePictures
backend:
build: ./backend
ports:
- "5001:5001"
# Saving the pictures on the server
volumes:
- "/srv/personioClone/profilePictures:/usr/src/app/profilePictures"
volumes:
profilePictures:
Question 2:
Is it a best practice to have caddy in a container and serve the (static) frontend after it has been built?
What I have currently is a Backend service ( running in a container) and I was not sure if I had to put the frontend in a container or Caddy.
But after discussing with some people, I concluded that Caddy is a process and the frontend is not ( after being compiled). Therefore It made sense to me to have Caddy in a container.
Was I right?
Question 3:
Is my Caddy configuration now correct?
www.pilexlaflex.com {
# Set this path to your site's directory.
root * /var/www/html/build
# Handle specific path for profile pictures
handle_path /profilePicture/* {
root * /srv/personioclone/profilePictures
header Content-Type image/jpeg
file_server
}
# Handle the main site
handle {
try_files {path} /index.html
file_server
}
}
www.pilexlaflex.com:5002 {
reverse_proxy backend:5001
}
Yeah you could. You can just mount any files or config you need. A Dockerfile is probably only needed if you need to make a custom build of Caddy.
You’re still missing a /data volume, this is absolutely necessary to ensure you don’t lose your TLS certs when you recreate the container.
You probably don’t need the port 5002 mapping. Why not just use a different subdomain for that instead, like api.pilexlaflex.com or something? Or even you could serve it under a subpath like handle /api*, that way you don’t need a separate port.
Either way is valid. You could ship a container with the static frontend already built inside it, or you could just mount the frontend with a volume. Just depends what works best for you.
Caddy just needs access to the files to serve them, obviously. How you get those to Caddy doesn’t matter as much.
Correct, your frontend is just files served from disk. You could run Caddy on the host (not inside Docker) if you wanted to, but running it in Docker is also perfectly valid.
Seems fine. Does it work?
You probably don’t need the header Content-Type line, unless your files don’t use .jpg extensions. The file_server will set the content type correctly based on the file extensions, automatically (using the mailcap package preinstalled in the container, which installs the mime types files).
French Canadian, but not from Quebec but I work in English.
@francislavoie thank you for your help.
Everything is working now.
The main problem was the way I was using volumes .
I also followed your recommendation regarding the Caddyfile configuration.
The issue I encoutered regarding the volume syntax (Volumes | Docker Docs)
was that I felt that it was supposed to be as follows: