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.
Rocky Linux with Cloud-Init