Home Technical Support Docker Compose, Registry, and Networking: Multi-Container Setups

Docker Compose, Registry, and Networking: Multi-Container Setups

Last updated on Sep 08, 2026

Docker Compose, Registry, and Networking: Multi-Container Setups

The Docker Compose, Docker Registry, and Docker Networking exercises cover multi-container orchestration, image registries, and network drivers. These exercises appear across 4 courses. This article covers common failures and how to fix them.


Table of Contents

  1. Docker Compose: Containers Exiting with Code 0
  2. Docker Compose File Location Matters
  3. Docker Registry: Tagging Before Push
  4. Docker Registry: Insecure Registry Error
  5. Docker Hub Login and Push
  6. Network Drivers: Bridge, Macvlan, None
  7. Removing a Network with Active Containers
  8. Common Questions

Docker Compose: Containers Exiting with Code 0

No Main Process Means Instant Exit

After docker compose up -d, containers may immediately show Exited (0):

$ docker compose ps -a
NAME            STATUS
myubuntu        Exited (0) 5 seconds ago
myalpine        Exited (0) 5 seconds ago

This happens because the base images (ubuntu, alpine) have no default foreground process.

Fix: Add a process to keep the container running. Options include:

services:
  ubuntu:
    image: ubuntu:24.04
    stdin_open: true
    # or
    command: sleep infinity

The stdin_open: true flag (equivalent to -i) keeps stdin open, preventing the container from exiting.


Docker Compose File Location Matters <a name="compose-location>

Compose Looks for docker-compose.yml in Current Directory

cd ~/ && docker compose up -d

If you run docker compose up from the wrong directory, it won't find the compose file. The exercise typically asks you to create the file at /opt/docker-compose.yml:

docker compose -f /opt/docker-compose.yml up -d

Fix: Always specify -f /path/to/docker-compose.yml or cd to the directory containing the file.

Compose YAML Structure

name: pdso-training
services:
  webserver:
    image: nginx
    container_name: webserver
    ports:
     - 8080:80
    volumes:
     - data:/usr/share/nginx/html
volumes:
  data:

Common mistake: Incorrect indentation under ports and volumes lists. YAML is strict about indentation.


Docker Registry: Tagging Before Push

Image Must Be Tagged with Registry URL

You can't push an image to a registry without first tagging it with the registry address:

# Start local registry:
docker run -d -p 5000:5000 --restart=always --name registry registry:2

# Tag the image with registry URL prefix:
docker tag django.nv:1.0 localhost:5000/django.nv:1.0

# Now push:
docker push localhost:5000/django.nv:1.0

Common mistake: Trying to push django.nv:1.0 directly without the localhost:5000/ prefix. Docker doesn't know which registry to push to.

Verify the Push

curl localhost:5000/v2/_catalog
# Output: {"repositories":["django.nv"]}

Docker Registry: Insecure Registry Error <a name="registry-insecure>

Local Registry Uses HTTP, Not HTTPS

A local registry on localhost:5000 uses plain HTTP. Docker by default refuses to push to non-TLS registries:

http: server gave HTTP response to HTTPS client

Fix: For lab environments, configure Docker to trust the insecure registry by adding to /etc/docker/daemon.json:

{
  "insecure-registries": ["localhost:5000"]
}

Then restart Docker: systemctl restart docker. In the lab environment, this is typically pre-configured.


Docker Hub Login and Push <a name="dockerhub-push>

Login to Docker Hub

docker login
# or
docker login -u your-docker-username -p your-docker-password

The exercise verifies login by checking for /root/.docker/config.json.

Push to Docker Hub Requires Username Prefix

Docker Hub images must be prefixed with your username:

docker tag django.nv:1.0 yourdockerusername/django.nv:1.0
docker push yourdockerusername/django.nv:1.0

Common mistake: Trying to push django.nv:1.0 without the username prefix. Docker Hub rejects pushes to images you don't own.


Network Drivers: Bridge, Macvlan, None

Network Driver Comparison

Driver Use Case External Access
bridge (default) Isolated container networking with NAT Port mapping required
macvlan Containers get their own MAC addresses, appear as physical devices Direct IP on network
none Complete network isolation None

none Network = No Connectivity

docker run -d --name ubuntu --network=none -it ubuntu:24.04
docker exec ubuntu apt update
Temporary failure resolving 'archive.ubuntu.com'

This is expected behavior — the container has no network stack.

Bridge Network with Custom Subnet

docker network create app --subnet "172.16.0.0/16"

Verify:

docker inspect app | jq '.[].IPAM.Config'

Removing a Network with Active Containers

Can't Remove a Network with Connected Containers

docker network rm app
Error response from daemon: error while removing network: network app id xxx has active endpoints

Fix: Disconnect or remove the container first:

docker network disconnect app myubuntu
# or
docker stop myubuntu && docker network rm app

Key concept: Removing a network doesn't automatically disconnect or stop attached containers.

Connecting a Container to a Network After Creation

docker network connect app myubuntu

Verify:

docker inspect myubuntu | jq '.[].NetworkSettings.Networks.app'

Common Questions

Question Answer
My compose containers exit immediately. Add stdin_open: true or command: sleep infinity to keep them running.
docker push to localhost:5000 fails with HTTPS error. Configure Docker's insecure-registries or check that the lab environment has it pre-configured.
How do I verify an image was pushed to my local registry? Run curl localhost:5000/v2/_catalog.
What happens to containers when I remove their network? Nothing. Containers keep running. Remove or disconnect them first.
My container can't reach the internet. Check which network it's attached to. --network=none means no connectivity.
How do I create a network with a specific subnet? docker network create <name> --subnet "172.16.0.0/16".

Wrap-Up

Docker Compose, Registry, and Networking exercises cover multi-container orchestration:

  • Compose containers need a foreground process — use stdin_open: true or command: sleep infinity.
  • Always tag images with the registry URL before pushing (localhost:5000/image:tag).
  • Docker Hub requires your username prefix on image names.
  • Bridge is the default network driver; none means zero connectivity; macvlan gives containers physical-network-level addresses.
  • You can't remove a network while containers are connected to it.

The DevSecOps Box is stateless — all networks, containers, and images are lost on page refresh.