docker-compose mongodb phoenix, [error] failed to connect: ** (Mongo.Error) tcp connect: connection refused - :econnrefused
https://docs.docker.com/compose/compose-file/#depends_on explicitly says:
There are several things to be aware of when using depends_on:
- depends_on does not wait for db and redis to be “ready” before starting web - only until they have been started. If you need to wait for a service to be ready,
and advises you to implement the logic to wait for mongodb to spinup and be ready to accept connections by yourself: https://docs.docker.com/compose/startup-order/
In your case it could be something like:
CMD wait-for-db.sh && mix phx.server
where wait-for-db.sh
can be as simple as
#!/bin/bashuntil nc -z localhost 27017; do echo "waiting for db"; sleep 1; done
for which you need nc
and wait-for-db.sh
installed in the container.
There are plenty of other alternative tools to test if db container is listening on the target port.
UPDATE:
The network connection between containers is described at https://docs.docker.com/compose/networking/:
When you run docker-compose up, the following happens:
- A network called
myapp_default
is created, wheremyapp
is name of the directory wheredocker-compose.yml
is stored. - A container is created using phoenix’s configuration. It joins the network
myapp_default
under the namephoenix
. - A container is created using db’s configuration. It joins the network
myapp_default
under the namedb
.
Each container can now look up the hostname phoenix
or db
and get back the appropriate container’s IP address. For example, phoenix’s application code could connect to the URL mongodb://db:27017
and start using the Mongodb database.
It was an issue with my dev environment not connecting to the mongodb url specified in docker-compose. Instead of localhost, it should be db as named in my docker-compose.yml file
For clarity to dev env:
- modify config/dev.exs to (replace with correct vars)
username: System.get_env("PGUSER"), password: System.get_env("PGPASSWORD"), database: System.get_env("PGDATABASE"), hostname: System.get_env("PGHOST"), port: System.get_env("PGPORT"),
- create a dot env file on the root folder of your project (replace with relevant vars to the db service used)
PGUSER=some_userPGPASSWORD=some_passwordPGDATABASE=some_databasePGPORT=5432PGHOST=db
Note that we have added port.
Host can be localhost but should be mongodb or db or even url when working on a docker-compose or server or k8s.
will update answer for prod config...