Setting Up a Coolify Build Server with Hetzner and a Self-Hosted Registry
Using a dedicated build server offloads resource-intensive image building from your main application server. Here’s how to set one up with a Hetzner server and a self-hosted Docker registry managed by Coolify.
1. Prepare Your Build Server on Hetzner
- Create a new server in Hetzner Cloud (Ubuntu recommended).
- Configure a Hetzner Cloud Firewall:
- Allow incoming Port 22 (TCP) for SSH access.
- Block other incoming ports.
- Note the server's IP address and SSH credentials.
2. Connect Build Server in Coolify
- In Coolify, go to Keys & Tokens and add the SSH Key for the build server.
- Then go to Servers.
- Click Add Server, toggle Use as Build Server.
- Enter the Hetzner server's IP address, SSH user, and choose the key you have just added.
- Coolify will connect and set it up.
3. Why You Need a Docker Registry
When using a build server, the created Docker image needs to be transferred to your main hosting server. This transfer happens via a Docker Registry.
You can use a hosted service (like GitHub Packages) or self-host one. We'll self-host using Coolify.
4. Self-Host Your Docker Registry (via Coolify)
Run the registry service on your main Coolify hosting server.
- In Coolify, create a new Project (e.g.,
Infrastructure
). - Add a Service within that project, select Docker Registry.
- Under Service, click on the edit button next to the domain and set it to, e.g.,
https://docker-registry.yourdomain.com:5000
. Start the service. - Set up Authentication:
- Go to the Persistent Storages tab for the registry service. Note the
Source Path
for the/auth/registry.password
. - Generate a user/password entry using
htpasswd -nbB YOUR_USERNAME YOUR_PASSWORD
. This can be run on your local machine. Copy the output string. - SSH into your Coolify hosting server. Edit the
auth/registry.password
file. Replace the content with the string fromhtpasswd
. Save the file. - In Persistent Storages, click on the Load from Server button and save.
- Deploy the Docker Registry service.
- Go to the Persistent Storages tab for the registry service. Note the
- Log in on both servers:
- SSH into your Hetzner build server. Run
docker login docker-registry.yourdomain.com -u YOUR_USERNAME -p YOUR_PASSWORD
. (Rundocker logout
first if needed). - SSH into your Coolify hosting server. Run the same login command.
- SSH into your Hetzner build server. Run
5. Configure Your Project for Build Server & Registry
Tell your application project where to build and where to push/pull the image.
- Go to your Project in Coolify.
- Find "Use a Build Server" and toggle it ON.
- Find the Docker Image field in the Docker Registry section. You must prefix the image name with your registry address and add slash.
- Change the value to
docker-registry.yourdomain.com:5000/milk
(replacemilk
with your image name). - Important: Without the
/
after the port/hostname (docker-registry.yourdomain.com:5000
), Docker automatically prefixes the url withdocker.io/library/
leading to the error:The push refers to repository [docker.io/library/docker-registry.yourdomain.com]
anddenied: requested access to the resource is denied
.
- Change the value to
Save settings and re-deploy. Coolify will now use the build server to build the image, push it to your self-hosted registry, and then the hosting server will pull it from there.