DEV Community

0x5eva
0x5eva

Posted on

5

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
Enter fullscreen mode Exit fullscreen mode

The command to generate the new credentials:

htpasswd -nB docker-tutorial-user
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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! 😊

Additional information:
If you're operating inside the virtual network or just prefer to not expose the registry to the internet you have at least 3 options:

  1. Generate a self-signed certificate
  2. Use ready-to-go tools to set up a VPN with an internal SSL domain
  3. Set up an unencrypted Docker registry and add it to you docker client's daemon.json file
{
  "insecure-registries": ["docker-registry-internal-address:5000"]
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)

👋 Kindness is contagious

Explore this compelling article, highly praised by the collaborative DEV Community. All developers, whether just starting out or already experienced, are invited to share insights and grow our collective expertise.

A quick “thank you” can lift someone’s spirits—drop your kudos in the comments!

On DEV, sharing experiences sparks innovation and strengthens our connections. If this post resonated with you, a brief note of appreciation goes a long way.

Get Started