Docker Networking for Teams: Reverse Proxy, Subdomains, and Local Certificates
AI generated
Docker · Networking · Traefik · Reverse Proxy
Docker Networking for Teams:
Reverse Proxy, Subdomains, and Local Certificates

Port conflicts between projects, missing HTTPS in development, and confusing hostnames are classic pain points in team Docker networking. With Traefik as a central reverse proxy, mkcert for local HTTPS certificates, and cleanly isolated Docker networks, these problems can be solved once and for all.

14 min read Traefik · mkcert · Docker Networks · Service Discovery Docker Compose · Linux · macOS

1. Docker Networking: Basics and Network Types

Docker Networking is the system that determines how containers communicate with each other and with the outside world. During installation, Docker automatically creates three default networks: bridge, host, and none. Docker Networking via the default bridge network connects containers on the same host, but it offers no service discovery by name: containers must communicate via IP addresses, which can change with every restart. That makes the default bridge network unsuitable for any serious application.

User-defined bridge networks solve this problem: containers on the same user-defined network can reach each other by their container name or service name in Docker Compose. That is the foundation of working Docker Networking in Compose projects. Host network mode connects the container directly to the host's network: no Network Address Translation (NAT), no port forwarding, but also no isolation. On Linux, this delivers the best performance for applications that handle many connections, such as reverse proxies or high-throughput databases.

The overlay network is designed for multi-host environments and is used in Docker Swarm or Kubernetes. It lets containers on different hosts communicate as if they were on the same network. For local development and simple single-host production environments, the bridge network is the right choice. Understanding these basics is a prerequisite for clean Docker Networking in practice.

2. Network Isolation Between Projects

In Docker Compose, every project creates its own network by default, named <projectname>_default. Containers from different projects therefore cannot reach each other by hostname, which is an important security property of Docker Networking. Problems arise when services from different projects need to communicate, for example when a monitoring stack needs to observe containers from multiple projects. The solution is a shared external network that both Compose files reference.

Network isolation in Docker Networking also has security implications: a compromised container in one project cannot, by default, access services in other projects. Anyone who wants to protect databases, caches, or internal APIs from accidental access by other containers should run those services exclusively on internal networks with no port exposure. Combining project-specific networks for internal communication with a shared reverse proxy network for external access is the most proven pattern for professional Docker Networking.


# Create a shared external network for the reverse proxy
docker network create proxy-network

# docker-compose.yml: project with internal and external network
services:
  web:
    image: nginx:alpine
    networks:
      - proxy-network   # shared with Traefik for external access
      - internal        # project-internal communication
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.myapp.rule=Host(`myapp.localhost`)"

  db:
    image: postgres:16
    networks:
      - internal        # not exposed to proxy, internal only
    environment:
      POSTGRES_PASSWORD: secret

  redis:
    image: redis:7-alpine
    networks:
      - internal        # Only accessible within this project

networks:
  proxy-network:
    external: true      # Must be created before: docker network create proxy-network
  internal:
    driver: bridge
    internal: true      # No outbound internet access, fully isolated

3. Service Discovery in Docker Compose

Service discovery is one of the most practical features of Docker Networking in Compose projects. Containers on the same network can reach each other via the service name defined in the Compose file, not via IP addresses. In practice this means a PHP container connects to db:3306 instead of an IP address, and an Nginx container forwards requests to php-fpm:9000. These names are resolved internally by an embedded DNS server that Docker provides for every user-defined network.

An important detail about Docker Networking and service discovery: if a service in a Compose file is given an alias, it becomes reachable under that alias. This is useful when several projects use the same service name but need to be reachable under different hostnames, for example two Magento instances that both use db as their service name but run in separate project networks. Network aliases solve this problem elegantly without having to rename any containers.

4. Avoiding Port Conflicts

Port conflicts are one of the most common problems in Docker Networking for teams working on several projects at once. If three projects each try to bind port 80 and 443, the second and third project fail to start. The obvious fix, giving each project a different port, leads to URLs like localhost:8081 and localhost:8082, which are hard to remember and cannot realistically simulate HTTPS. The real solution is a central reverse proxy that holds port 80 and 443 and forwards requests to the correct project based on the hostname.

Without a reverse proxy, the recommendation for Docker Networking is to expose service ports only within the internal network, not bind them to the host. In the Compose file that means using expose: "80" instead of ports: "80:80". Containers on the same network can still reach the port, but the host port stays free. This prevents conflicts between projects and forces external access through the reverse proxy.

5. Traefik as a Central Reverse Proxy

For team-oriented Docker Networking, Traefik is the most compelling reverse proxy solution. The key difference from Nginx: Traefik automatically discovers new containers through the Docker API and configures itself based on container labels. No restart, no reload, and no manual configuration change is needed when a new project starts up. The Traefik process runs permanently and watches for new containers with matching labels on the shared proxy network.

Configuring Traefik for local Docker Networking is manageable: a single Compose stack for Traefik itself, joined to the shared proxy network, mounting the Docker socket, and exposing the dashboard UI on an internal port. Every project service then gets labels that tell Traefik which hostname the service should be reachable under, whether HTTPS is active, and which middleware to apply. Middleware for basic authentication, HTTP-to-HTTPS redirects, and rate limiting are all available as ready-made Traefik components.


# traefik/docker-compose.yml: central Traefik reverse proxy
services:
  traefik:
    image: traefik:v3.2
    command:
      - "--api.dashboard=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.docker.network=proxy-network"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      # Load TLS certificates from /certs directory
      - "--providers.file.directory=/certs"
      - "--providers.file.watch=true"
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"   # Traefik dashboard
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./certs:/certs:ro
    networks:
      - proxy-network
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.dashboard.rule=Host(`traefik.localhost`)"
      - "traefik.http.routers.dashboard.service=api@internal"

networks:
  proxy-network:
    external: true

6. Local Subdomains with /etc/hosts and dnsmasq

Local subdomains are the step that really make Docker Networking pleasant for teams: instead of localhost:8080, projects become reachable at myapp.localhost, shop.localhost, or api.localhost. For simple cases, a single entry in /etc/hosts is enough: 127.0.0.1 myapp.localhost. The downside is that every developer has to maintain this file manually, and wildcards like *.localhost are not supported.

The more elegant solution for Docker Networking with subdomains is dnsmasq: a local DNS server that resolves all requests for *.localhost to 127.0.0.1. On macOS, dnsmasq can be installed via Homebrew; on Linux, it is available in most distributions. Once configured, all subdomains work automatically without editing /etc/hosts. Modern browsers resolve *.localhost to 127.0.0.1 without dnsmasq, but other tools like curl and many development utilities do not; dnsmasq closes that gap.

7. Local HTTPS Certificates with mkcert

HTTPS in the local development environment is not a luxury but a necessity: cookies with the Secure flag, service workers, WebAuthn, and HTTP/2 only work over HTTPS. Docker Networking for a team therefore needs to support HTTPS, and with certificates the browser considers trustworthy. Self-signed certificates trigger browser warnings that get ignored in day-to-day work, until someone forgets to add an exception and wonders why the application will not load.

mkcert is the tool of choice for local HTTPS in Docker Networking setups. It creates a local Certificate Authority (CA) and installs it in the system truststore as well as the truststores of Chrome, Firefox, and other browsers. Certificates issued with this CA are accepted by the browser as trustworthy without any warning. A single command creates a certificate for any number of domains and wildcards: mkcert "*.localhost" "localhost" "127.0.0.1". The resulting certificate is loaded into Traefik and then applies to all subdomains.


# Install mkcert (once per developer machine)
# macOS: brew install mkcert
# Linux: see https://github.com/FiloSottile/mkcert

# Install the local CA into browser/system truststores
mkcert -install

# Generate wildcard certificate for all *.localhost subdomains
mkcert -key-file ./traefik/certs/local-key.pem \
       -cert-file ./traefik/certs/local-cert.pem \
       "*.localhost" "localhost" "127.0.0.1"

# Traefik TLS configuration file (./traefik/certs/tls.yml)
# tls:
#   certificates:
#     - certFile: /certs/local-cert.pem
#       keyFile: /certs/local-key.pem

# Project service labels for HTTPS routing
# Add to any service in any docker-compose.yml:
# labels:
#   - "traefik.enable=true"
#   - "traefik.http.routers.myapp-secure.rule=Host(`myapp.localhost`)"
#   - "traefik.http.routers.myapp-secure.entrypoints=websecure"
#   - "traefik.http.routers.myapp-secure.tls=true"

8. Running Multiple Projects at Once with Traefik

The final goal of professional Docker Networking for teams is running multiple projects on the same developer machine at once, without conflicts. With Traefik as the reverse proxy, mkcert for HTTPS, and dnsmasq for subdomains, the setup looks like this: Traefik runs permanently and manages port 80 and 443. Every project has its own Compose file and its own networks for internal communication, while also joining the shared proxy network. New projects simply start up; Traefik detects them automatically and forwards requests based on the hostname.

An important aspect of Docker Networking for teams: the Traefik configuration and the shared proxy network should be maintained in a separate repository or as part of a team onboarding script. New developers run a single setup script that starts Traefik, creates the proxy network, installs mkcert, and adds the CA to the truststore. After that, they can clone and start any project repository without needing to know any further networking configuration.

Approach Port Conflicts HTTPS Locally Multiple Projects
Direct port mapping Frequent Not possible Manual, cumbersome
Nginx as proxy Low Manual Restart on change
Traefik + mkcert None Automatic Automatic via labels
/etc/hosts only Low Browser warnings Manual entries

9. Networking Approaches Compared

Choosing the right Docker Networking strategy depends on team size, the number of projects active at once, and how closely the development environment needs to match production. A solo developer with a single project can get by with direct port mapping. A team of five developers actively working on six projects needs the full Traefik, mkcert, and dnsmasq infrastructure.

The critical criterion for Docker Networking is fidelity to production: the closer the local development environment resembles the production environment, the less often errors occur that cannot be reproduced locally. Enforcing HTTPS locally, using the same reverse proxy as in production, and replicating the same network topology are investments that pay off through fewer production incidents. In this respect, the Traefik-based approach to Docker Networking is clearly superior to direct port mapping.

Mironsoft

Docker infrastructure, networking, and development environments for teams

Want Docker Networking set up professionally for your team?

We build a complete Docker networking infrastructure with Traefik, local HTTPS certificates, and automatic service discovery, so your team can develop without port conflicts and without browser warnings.

Traefik setup

A central reverse proxy for all projects with automatic label-based configuration

HTTPS locally

mkcert integration for trustworthy local certificates without browser warnings

Onboarding script

One-click setup for new developers: networks, certificates, and proxy in a single step

10. Summary

Professional Docker Networking for teams solves the classic problems, namely port conflicts, missing HTTPS support, and hard-to-remember URLs, through a clear infrastructure: Traefik as a permanent central reverse proxy with automatic label-based configuration, mkcert for trustworthy HTTPS certificates without browser warnings, dnsmasq for automatic subdomain resolution, and cleanly isolated project networks for security and clarity. Together, these four components make it possible to run any number of projects at the same time.

The most important insight about Docker Networking is that the setup effort is a one-time cost that pays off across every future project. After the initial setup, each new project simply starts with docker compose up: Traefik detects the new service automatically, the certificate already covers every *.localhost domain, and the subdomain name is freely chosen via labels. This saves time on every new project and prevents configuration mistakes caused by copying port numbers between different Compose files.

Docker Networking for Teams: The Essentials at a Glance

Network Isolation

Every project gets its own networks. Databases stay on the internal network only. The shared proxy network is reserved for the reverse proxy.

Traefik as Proxy

Automatic configuration via container labels. No restart needed for new projects. Port 80 and 443 managed centrally.

HTTPS Locally

mkcert creates a local CA plus certificates. Browsers accept them without warnings. One certificate covers every *.localhost domain.

Onboarding

Setup script for new developers: docker network create, mkcert -install, start Traefik. After that, every project just works.

11. FAQ: Docker Networking for Teams

1Bridge vs. overlay in Docker Networking?
Bridge: containers on the same host. Overlay: containers on different hosts (Swarm/Kubernetes). For local development, bridge is enough.
2Why use internal: true for databases?
No outbound internet access, only project-internal reachability. Prevents accidental access from outside and outbound connections from the database container.
3How do I see which containers are on which network?
docker network inspect proxy-network or docker inspect my-container. All networks are listed under NetworkSettings.Networks.
4Why no service discovery on the default bridge?
No embedded DNS. Containers are only reachable via IP. User-defined bridge networks have a DNS server and allow communication via service names.
5Does mkcert need to be installed on every machine?
Yes, mkcert -install must be run once per machine to register the CA in the truststore. Certificate files themselves can be shared.
6How does Traefik detect new containers automatically?
Traefik listens on the Docker socket. New containers with traefik.enable=true are detected, and labels are turned into routing rules automatically, no restart required.
7Can Traefik also be used in production?
Yes. Let's Encrypt, load balancing, circuit breaking, rate limiting, and Prometheus metrics are all supported. The local configuration is a simplified production setup.
8What happens to networks on docker compose down?
Project-specific networks are removed. External networks (external: true) stay intact. The proxy network must be removed manually with docker network rm.
9How do I debug networking issues?
docker exec -it container ping other-container. nicolaka/netshoot as a debug container with nslookup, traceroute, and tcpdump.
10Does dnsmasq support wildcard domains?
Yes. address=/.localhost/127.0.0.1 routes all subdomains to 127.0.0.1. Also works for api.v2.localhost.