Setup Caddy server
Self hosted PayloadCMS and PostgreSQL website on Docker
3 min read
Published Jun 17 2025, updated Jun 19 2025
Guide Sections
Guide Comments
We are going to install Caddy directly on the server and forward all requests to the servers localhost of the published ports. Caddy will handle all incoming traffic on 443, automatically setup SSL certificates and pass http traffic to the docker containers. Technically you can opt to install as a docker container and for the most part this works fine, however if you need things like self hosted analytics where the users original IP address is required for deriving the country and region of users etc. then you run in to problems as the referred IP will be of the docker internal IP, so I find it easier hosting Caddy outside of docker. If you don't need anything where the users IP details are required, then you can run in a docker container and use the <servicename>:<containersinternalportnumber> as the url to refer to, instead of <localhost>:<publishedportnumber> which we will be doing below, and that means you also don't actually need to publish ports for the web server and registry as it will be handled on the internal docker network.
Update the package index:
Make sure apt-transport-https and curl are installed:
Import Caddy’s official GPG key:
Add the Caddy repository:
Update package index again:
Install Caddy:
You can verify the install by running:
Starts the Caddy service immediately:
Enables Caddy to start automatically on boot:
Shows the current status of the Caddy service:
All reverse proxy rules etc are defined in the CaddyConfig file located /etc/caddy/Caddyfile
.
You need to add DNS entry for a domain that you want to point to the docker registry created in the last section.
eg. if you would like to use the subdomain registry.mydomainname.com to access it, set an A record on your mydomainname.com for registry.mydomainname.com to point to your public IP address. This needs doing on your domain registrar website.
Add a reverse proxy for the docker registry:
/etc/caddy/Caddyfile
You can clear out any other code in that file and just put the code you need. Anything with a # at the start is a comment line and ignored.
What the above is saying is anything that comes in on port 443, which Caddy is listening to on the public IP, Caddy will automatically obtain and sort out SSL certificates, and pass all traffic destined for registry.mydomainname.com over https, through to localhost:5000 which is the published registry docker container.
Reload the Caddy Config, without server downtime, after config changes:
Note: for a full start and stop of the server, but not required here:
You can test thats worked by logging in do the registry via docker on your main computer:
It will ask you for your username and password which you setup in the last section, if it is successful then its all working as expected.