knex: Why can't I do knex migrate:latest using Docker-Composer?
I have the following docker-compose.yml where I’m starting two services:
- postgres
- nodejs app
After the Postgres DB is up I try to run knex migrate:latest to create the DB structure. But for some reason the migration keep telling me that is unable to connect. This is strange because:
- I’m able to connect to the DB using Postico and work with the DB no problem.
- The nodejs app is able to connect because I get an error message telling me that the table that I’m trying to select from dose not exists.
- I’m able to ping the DB container from the Web container
Question
What am I missing?
File: docker-compose.yml
version: '2'
services:
postgres:
image: "postgres"
ports:
- "5433:5432"
networks:
- curted
environment:
POSTGRES_DB: dbname
POSTGRES_USER: admin
POSTGRES_PASSWORD: admin
volumes:
- database:/var/lib/postgresql/data
example.com:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
networks:
- example
working_dir: /code
environment:
DATABASE_URL: postgres://admin:admin@172.18.0.2:5433/dbname
NODE_ENV: local
command: bash -c "sleep 10 && npm run knex migrate:latest --file knexfile.js"
depends_on:
- postgres
networks:
curted:
driver: bridge
volumes:
database:
The knexfile.js
module.exports = {
local: {
client: 'pg',
connection: process.env.DATABASE_URL,
ssl: false,
migrations: {
tableName: 'knex_migrations'
}
},
staging: {
client: 'pg',
connection: process.env.DATABASE_URL,
ssl: true,
migrations: {
tableName: 'knex_migrations'
},
pool: {
min: 1,
max: 2
}
},
production: {
client: 'pg',
connection: process.env.DATABASE_URL,
ssl: true,
migrations: {
tableName: 'knex_migrations'
},
pool: {
min: 1,
max: 2
}
}
};
Erro Message
curted.com_1 | > CuratedProducts@1.0.0 knex /home/app
curted.com_1 | > knex "migrate:latest"
curted.com_1 |
curted.com_1 | Using environment: local
curted.com_1 | Error: connect ECONNREFUSED 172.18.0.2:5433
curted.com_1 | at Object.exports._errnoException (util.js:1022:11)
curted.com_1 | at exports._exceptionWithHostPort (util.js:1045:20)
curted.com_1 | at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1090:14)
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 28 (6 by maintainers)
Hey guys, I found the reason and the solution. The solution is generally speaking the same as @Bram-Zijp . Here is my knexfile.js:
The key is to set
hostwith the name of the db service in docker-compose. Settingportto empty string or 3306 both will okay ( I don’t know why but it works).The ECONNREFUSED error means the web app cannot connect the db, and I’ve tried many hosts and ports but all the tries failed, like
localhost:3306and0.0.0.0:13306and so on. The reason is thelocalhost:3306actually refers the container itself, not the docker host.Plus, make sure the migration is executed after db fully initializing.
References:
OK. I’ll dig deeper, and will let you know.
A little late to the party, but I thought I’d share a Node script that I run when using docker-compose with a Knex migration service.
This is a file called
index.jsthat is run bynpm start, in a directory calleddboff of the root directory of my project. Thedocker-compose.ymlfile looks like this:I was running the migrate commands from my terminal instead of from inside the docker container. When I ran the migration from within the container which is hosting the node.js app it migrated fine.
I use this in my knexfile.js as connection:
this is my docker-compose.yml
docker exec CONTAINER_NAME sh -c "npm run migrate"The migrate script in my package.json looks like this:"migrate": "knex migrate:rollback && knex migrate:latest && knex seed:run",Hope this helps those who are struggling.
@davidgatti I have the same issue and resolve it by following code: (I run following code in web container in the startup script, and DB in other contaiter on which web container depends)
Below are some logs:
The logs show that DB is not ready in the first three connecting tries. So if we run knex migration just one time, it will be failed in most cases. But I do set timeout parameters (acquireTimeout & bailAfter) in knexfile.js like this:
I expect that knex will keep trying to connect DB in 30 seconds. But it’s not. Is this a knex bug? or Is there any other proper parameter can control the timeout/retrying?