Setting Up a Private Docker Registry with Coolify

Docker Registry is an application that handles storing and managing docker container images. It helps create a stable, well tested environment for your app that can be used both during both development and production. In this tutorial we'll walk through the process of setting up our own private docker registry and pushing images to it. Why would you need it? Sure, you could just host your app without it and manage deployments with a few bash scripts. That might work at first but as soon as your app grows, so do your requirements. You might need some kind of rollback mechanism, ensure environment consistency or improve reliability and repeatability. Besides, the build process often demands more compute resources than simply running the app, which could result in longer deployment durations. It's better to break the deployment into stages, handling all the preparations and code transformations before the app reaches the production server. Why would you use additional tools like Coolify for this? Well, technically, you are still able to manage images via terminal commands, but why bother doing this if there is already a battle-tested software that can help us to skip a few steps? Prerequisites VPS with Coolify installed Docker Desktop or the Docker CLI installed locally In this tutorial we'll be using v4.0.0-beta.390 which is the latest available release now Let’s log into the Coolify dashboard: Next, we need to add a new service: Select the Docker Registry service, then choose the server where you want to host it. After that you'll be redirected to the service configuration page: Here, we can change the name of the container and proceed with the setup. Don’t forget to click the save button after making any changes! If you're going to make the registry accessible from the internet, you can also edit the domain name that points to your server's address here. Now let's set up the login credentials. This is the default user: testuser:testpassword and being represented as testuser:$2y$05$/o2JvmI2bhExXIt6Oqxa7ekYB7v3scj1wFEf6tBslJvJOMoPQL.Gy It's defined both in the compose file and in persistent storage after the first launch of the container. You should change it immediately after installation for security reasons. To do this, we need to generate a new username:password pair. You can do it with the following command: You may need to install Apache utilities first: sudo apt update sudo apt install apache2-utils The command to generate the new credentials: htpasswd -nB docker-tutorial-user Once we have the generated string we can use it for authentication so let's update the value in the persistent storage: Now, let’s take a look at the compose file. The only optional change we might want to make here is to remove the existing credentials to ensure they won't be used anymore: services:   registry:     image: 'registry:2'     environment:       - SERVICE_FQDN_REGISTRY_5000       - REGISTRY_AUTH=htpasswd       - REGISTRY_AUTH_HTPASSWD_REALM=Registry       - REGISTRY_AUTH_HTPASSWD_PATH=/auth/registry.password       - REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/data     volumes:       -         type: bind         source: ./auth/registry.password         target: /auth/registry.password         isDirectory: false         content: 'testuser:$2y$05$/o2JvmI2bhExXIt6Oqxa7ekYB7v3scj1wFEf6tBslJvJOMoPQL.Gy'       -         type: bind         source: ./config/config.yml         target: /etc/docker/registry/config.yml         isDirectory: false         content: "version: 0.1\nlog:\n  fields:\n    service: registry\nstorage:\n  cache:\n    blobdescriptor: inmemory\n  filesystem:\n    rootdirectory: /var/lib/registry\nhttp:\n  addr: :5000\n  headers:\n    X-Content-Type-Options: [nosniff]\nhealth:\n  storagedriver:\n    enabled: true\n    interval: 10s\n    threshold: 3"       -         type: bind         source: ./data         target: /data         isDirectory: true Making the registry accessible After entering a valid domain that points at the server IP address and restarting the container we should be able to connect to the container with our client and push/pull images. If we didn't change the default settings for the proxy Coolify will automatically issue a valid SSL Let's encrypt certificate: If we still encounter a certificate error, try switching the default proxy to Caddy and restart the container Once you see the Login Succeeded message, you can start pushing and using your images!

May 9, 2025 - 17:00
 0
Setting Up a Private Docker Registry with Coolify

Docker Registry is an application that handles storing and managing docker container images. It helps create a stable, well tested environment for your app that can be used both during both development and production.

In this tutorial we'll walk through the process of setting up our own private docker registry and pushing images to it.

Why would you need it?

Sure, you could just host your app without it and manage deployments with a few bash scripts. That might work at first but as soon as your app grows, so do your requirements. You might need some kind of rollback mechanism, ensure environment consistency or improve reliability and repeatability.

Besides, the build process often demands more compute resources than simply running the app, which could result in longer deployment durations. It's better to break the deployment into stages, handling all the preparations and code transformations before the app reaches the production server.

Why would you use additional tools like Coolify for this?

Well, technically, you are still able to manage images via terminal commands, but why bother doing this if there is already a battle-tested software that can help us to skip a few steps?

Prerequisites

  1. VPS with Coolify installed

  2. Docker Desktop or the Docker CLI installed locally

In this tutorial we'll be using v4.0.0-beta.390 which is the latest available release now

Let’s log into the Coolify dashboard:
empty coolify page with the add new resource button in the center of the page

Next, we need to add a new service:

Add new resource in Coolify screen. docker registry option in the center

Select the Docker Registry service, then choose the server where you want to host it. After that you'll be redirected to the service configuration page:

Coolify service service stack settings page. There are: service name, connect to predefined network checkmark and other settings options

Here, we can change the name of the container and proceed with the setup.

Don’t forget to click the save button after making any changes!

If you're going to make the registry accessible from the internet, you can also edit the domain name that points to your server's address here.

Now let's set up the login credentials.
This is the default user:
testuser:testpassword

and being represented as

testuser:$2y$05$/o2JvmI2bhExXIt6Oqxa7ekYB7v3scj1wFEf6tBslJvJOMoPQL.Gy

It's defined both in the compose file and in persistent storage after the first launch of the container.
You should change it immediately after installation for security reasons.
To do this, we need to generate a new username:password pair. You can do it with the following command:

You may need to install Apache utilities first:

sudo apt update
sudo apt install apache2-utils

The command to generate the new credentials:

htpasswd -nB docker-tutorial-user

Terminal screenshot with the htpasswd command in inside, terminal asks for the password and then re-type password

Once we have the generated string we can use it for authentication
so let's update the value in the persistent storage:

Coolify service settings page screenshot. Content with the username:password is focused

Now, let’s take a look at the compose file.
The only optional change we might want to make here is to remove the existing credentials to ensure they won't be used anymore:

services:

  registry:

    image: 'registry:2'

    environment:

      - SERVICE_FQDN_REGISTRY_5000

      - REGISTRY_AUTH=htpasswd

      - REGISTRY_AUTH_HTPASSWD_REALM=Registry

      - REGISTRY_AUTH_HTPASSWD_PATH=/auth/registry.password

      - REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/data

    volumes:

      -

        type: bind

        source: ./auth/registry.password

        target: /auth/registry.password

        isDirectory: false

        content: 'testuser:$2y$05$/o2JvmI2bhExXIt6Oqxa7ekYB7v3scj1wFEf6tBslJvJOMoPQL.Gy'

      -

        type: bind

        source: ./config/config.yml

        target: /etc/docker/registry/config.yml

        isDirectory: false

        content: "version: 0.1\nlog:\n  fields:\n    service: registry\nstorage:\n  cache:\n    blobdescriptor: inmemory\n  filesystem:\n    rootdirectory: /var/lib/registry\nhttp:\n  addr: :5000\n  headers:\n    X-Content-Type-Options: [nosniff]\nhealth:\n  storagedriver:\n    enabled: true\n    interval: 10s\n    threshold: 3"

      -

        type: bind

        source: ./data

        target: /data

        isDirectory: true

Making the registry accessible

After entering a valid domain that points at the server IP address and restarting the container we should be able to connect to the container with our client and push/pull images.

If we didn't change the default settings for the proxy Coolify will automatically issue a valid SSL Let's encrypt certificate:

Coolify service domain editing screenshot. Domain input element is active

Terminal screenshot with a docker login example

If we still encounter a certificate error, try switching the default proxy to Caddy and restart the container

Once you see the Login Succeeded message, you can start pushing and using your images!