I've got a Docker image which accepts a DATABASE_URL
env and start the container with
docker run -p 3000:3000 -e DATABASE_URL=mysql://root:foobar@localhost:3309/app app_image
On startup the container should run migrations on a database bootstraped from a docker-compose.yml
file:
version: '3'
services:
database:
image: mysql:8.0
environment:
- MYSQL_DATABASE=app
- MYSQL_ROOT_PASSWORD=foobar
ports:
- "3309:3306"
volumes:
- db:/var/lib/mysql
volumes:
db:
Unfortunately, I always get Can't reach database at localhost:3309
. I assume it has something to do with the network settings - but how to configure these settings in order to make it work?
I've tried many different configurations (e.g. database
, 127.0.0.1
, etc. instead of localhost
) but couldn't make it work and I'm honestly running out of ideas.
Thanks!
CodePudding user response:
Some clarifications:
Unless you specifically bind containers to the same host e.g. --network host
or link them together in docker compose using links
Links documentation, container A will not be able to reach anything on container B via localhost
.
Docker compose, unless specified differently in the docker-compose.yaml
file, automatically creates a separate network for all of the containers that are managed by that compose file, its name is usually based on the folder the file is in.
You can view it using docker network ls
that means, any container not managed by that compose file, is not part of the same network by default.
One option easy enough option that you have (among many probably):
- Decide on a network name which the compose file and you container will agree on
- create this network beforehand (before starting the standalone container and the compose file), the network will probably be in bridge mode
docker network docs
docker network create -d bridge my-bridge-network
- add it to the compose file so that docker compose uses it instead of the auto-created one
networks:
- my-bridge-network
- when starting the stand-alone container, specify which network to attach it to
docker run -p 3000:3000 -e DATABASE_URL=mysql://root:foobar@database:3309/app --network my-bridge-network app_image
- notice that the IP/HOSTNAME for the database container is according to the service name in the compose file, you can change that using
hostname: some-other-hostname
in the yaml.
all containers should now be on the same network, each one has a different IP/Hostname using this method (so cant use localhost for inter-container communication)
Alternative option:
use network: host
for both the compose file and the stand-alone container, they can talk to each other using localhost.
i dont recommend this option, and cant find a good enough reason to use it over other options.