Docker services with localhost domains

When working locally with many Docker services that you can often find a service or application is unable to start due to ports already in use by another service. This most ofter occurs with web applications or databases and can be frustrating since it either requires finding and stopping running services or configuring local DNS to Docker container IP.

An alternative solution is to use Traefik reverse proxy service and replace Docker container exposed ports with a localhost domain name instead, without much effort.

I will demonstrate how to quickly setup Traefik and application with Docker Compose. The example application will be Nocodb which I was testing when I last encountered such a port conflict (8080 in this case) and provide a nocodb.localhost domain so it is isolated from other web services.

Docker Compose Setup

There is a pre-requisite of Docker engine with Compose plugin installed and I am storing these permanently running Docker services under ~/docker.

Traefik

We will create a compose file for Traefik reverse proxy based on the user guide.

The configuration will be tweaked to enable the Traefik dashboard. The dashboard will be available at traefik.localhost rather than port 8080 as in the example.

mkdir ~/docker/traefik/ && cd $_ && touch docker-compose.yml

Add the following service configuration to: docker-compose.yml:

services:
  reverse-proxy:
    image: traefik:v2.9
    restart: unless-stopped
    command:
      - --api.dashboard=true
      - --providers.docker
    ports:
      - "80:80"
    labels:
      - traefik.http.routers.dashboard.rule=Host(`traefik.localhost`)
      - traefik.http.routers.dashboard.service=api@internal
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

Start Traefik running in the background

docker compose up -d

Verify Traefik is running correctly at traefik.localhost.

Application configuration

Create the Compose configuration files for Nocodb

mkdir ~/docker/nocodb/ && cd $_ && touch docker-compose.yml docker-compose.override.yml

Add the following configuration to docker-compose.yml:

services:
  nocodb:
    image: nocodb/nocodb:latest
    restart: always
    volumes:
      - nc_data:/usr/app/data
volumes:
  nc_data:

In the Compose override file we will use container labels to specify the Traefik routing configuration. These will setup the domain name nocodb.localhost and expose server port 8080.

Warning: Extending multi-value options such as ports in an override file will append values to the original service options rather than replace. Therefore any service ports specified in the original compose configuration file should be removed to avoid port conflict.

Add the following configuration to docker-compose.override.yml

services:
  nocodb:
    labels:
      - traefik.http.routers.nocodb.rule=Host(`nocodb.localhost`)
      - traefik.http.services.nocodb.loadbalancer.server.port=8080
networks:
  default:
    name: traefik_default

Start the nocodb service:

docker compose up

You can now open the Nocodb instance at nocodb.localhost in browser.