docker
docker-compose
static IP
networking
container management

Provide static IP to docker containers via docker-compose

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Docker Compose can assign a fixed IPv4 address to a container, but you should do it only when a stable IP is truly required. In most Compose setups, service names and built-in DNS are a better choice because they are simpler, more portable, and easier to maintain.

When a Static IP Is Appropriate

A static container IP makes sense when some external system insists on IP-based allowlists, when you are integrating with legacy software that cannot resolve container names, or when you need deterministic addresses in a lab environment.

For ordinary container-to-container communication, Docker already gives you DNS resolution by service name. If one container needs to reach PostgreSQL, using db:5432 is usually better than hard-coding 172.20.0.11:5432.

Use a Custom Bridge Network with IPAM

Static addresses require a user-defined network. The default bridge network does not give you the right place to manage fixed addresses from Compose.

A working example looks like this:

yaml
1services:
2  app:
3    image: nginx:alpine
4    networks:
5      app_net:
6        ipv4_address: 172.28.0.10
7
8  db:
9    image: postgres:16
10    environment:
11      POSTGRES_PASSWORD: example
12    networks:
13      app_net:
14        ipv4_address: 172.28.0.11
15
16networks:
17  app_net:
18    driver: bridge
19    ipam:
20      config:
21        - subnet: 172.28.0.0/24

Bring it up with:

bash
docker compose up -d
docker compose ps
docker inspect <container_name>

The important parts are the custom network, the ipam subnet, and the per-service ipv4_address entries.

Verify the Result

After the containers start, confirm that Docker assigned the addresses you requested:

bash
docker inspect app | grep -A5 'Networks'
docker inspect db | grep -A5 'Networks'

You can also test connectivity from one container to another:

bash
docker exec -it app ping -c 2 172.28.0.11
docker exec -it app ping -c 2 db

The second command is a useful reminder that DNS-based service discovery still works, even when you also assign fixed IPs.

Why Service Names Are Usually Better

A Compose file with hard-coded IPs is harder to reuse across machines and environments. If another local network already uses the same subnet, Docker may refuse to create the network or routing may become confusing.

Service names avoid most of those issues. Docker's embedded DNS lets containers find each other by service name on the same user-defined network, and the application configuration becomes more readable:

yaml
environment:
  DATABASE_URL: postgres://postgres:example@db:5432/app

That approach survives restarts, recreation, and scaling more gracefully than fixed addresses.

Limits and Caveats

Static IPs in Compose are not a replacement for production service discovery. If you later move to Swarm, Kubernetes, or a cloud platform, the networking model changes and those fixed local addresses usually do not carry over.

You also need to avoid collisions. Compose will not save you from assigning the same IP twice in the same subnet design. That becomes especially awkward when teams copy and modify Compose files independently.

Common Pitfalls

The biggest mistake is assigning a static IP on the default network and expecting it to work. You need a user-defined network with IPAM configuration.

Another mistake is using static IPs for containers that only need to talk to each other. Service names are built in and are usually the cleaner design.

It is also easy to pick a subnet that overlaps with your host VPN or office network. When that happens, container networking can fail in ways that look unrelated to Docker Compose.

Summary

  • Static IPs in Compose require a custom network with IPAM.
  • Add ipv4_address under each service on that network.
  • Verify the assigned address with docker inspect after startup.
  • Prefer service names and Docker DNS for normal container-to-container communication.
  • Use fixed container IPs only when an external requirement makes them necessary.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.