Docker Pitfalls

I was trying to set up a service with multiple containers, and I had a few problems. I found solutions to these, and here are a few mistakes that I overcame:

Running services on the host

If you have a application container and services which you need to use, such as a database, try to put them in containers themselves, instead of on the host. This makes it much easier to communicate. More about that later. I use docker compose to run multiple containers at once. For example, if you want to run a MongoDB database and an application, you can do:

version: "3"

services:
  mongodb:
    image: mongo:latest
    container_name: mongodb
    restart: unless-stopped
    environment:
      - MONGO_INITDB_ROOT_USERNAME=root
      - MONGO_INITDB_ROOT_PASSWORD=password
    volumes:
      - ./db:/data/db

  app:
    image: app
    container_name: app
    restart: unless-stopped
    depends_on:
      - mongodb

Replace the variables as you see fit, this is just an example.

Using DNS to connect to other services

Another benefit of using containers for everything is that Docker assigns DNS names to each container on the same network, if you specify a network name manually or use compose. In the previous example, assume the app has a config.json file, where you specify the database connection. To connect to the mongodb instance, you can just use its container_name:

{
    [...]
    "db": {
        "host": "mongodb",
        "port": 27017,
        "name": "database",
        "user": "root",
        "password": "password"
    }
    [...]
}

This means you don’t have to fiddle with IP’s between containers. The hostname is set by the container_name property in compose.

Note: you’ll need to specify a network name manually to have DNS work. So you can’t just run docker run app and have DNS work.

Building to the right image

Some apps, like one I was working with, might have a config file that’s actually built into the image itself. This means you’ll need to rebuild the config each time you want to change the configuration. However, if you run docker build . without specifying the tag, it’ll build into an unnamed image. This is a problem, because the compose file will try to use the original image name, so your config changes won’t work. You’ll need to run docker build -t app . to build the image with the right name.