I'm using Sails 0.12.3 and mongo 3.2.7
Here's my config/connections.js.
mongo: {
adapter: 'sails-mongo',
host: 'database',
port: 27017,
user: 'user', //optional
password: 'password', //optional
database: 'db' //optional
}
and my docker-compose.yml
version: '2'
services:
myservice:
//blabla
links:
- database
database:
image: 'mongo:latest'
container_name: 'database'
environment:
MONGODB_PASSWORD: "password"
MONGODB_USER: "user"
MONGODB_DATABASE: "db"
The problem comes whenever I build the containers with docker-compose up --build, the error comes from the sails-mongo
module.
error: A hook (`orm`) failed to load!
error: Error: Failed to connect to MongoDB. Are you sure your configured Mongo instance is running?
Error details:
{ MongoError: Authentication failed.
at Function.MongoError.create (/app/node_modules/mongodb-core/lib/error.js:31:11)
at commandCallback (/app/node_modules/mongodb-core/lib/topologies/server.js:929:66)
at Callbacks.emit (/app/node_modules/mongodb-core/lib/topologies/server.js:116:3)
at .messageHandler (/app/node_modules/mongodb-core/lib/topologies/server.js:282:23)
at Socket.<anonymous> (/app/node_modules/mongodb-core/lib/connection/connection.js:273:22)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at readableAddChunk (_stream_readable.js:172:18)
at Socket.Readable.push (_stream_readable.js:130:10)
at TCP.onread (net.js:542:20)
name: 'MongoError',
message: 'Authentication failed.',
ok: 0,
code: 18,
errmsg: 'Authentication failed.' }
Is there any extra configuration I need to just run the containers? I understand that Mongo doesn't create a database unless there's some data to store but I'm not sure if this is related at all.
First lets address your problem: Authentication failed
. sails-mongo cannot connect to mongodb. Why is that? I see that you provided some environment variables to the mongodb docker container:
environment:
MONGODB_PASSWORD: "password"
MONGODB_USER: "user"
MONGODB_DATABASE: "db"
However this is not documented in https://hub.docker.com/_/mongo/. The mongodb container is ignoring this values, thus no authentication is configured. sails-mongo will try to authenticate, however this fails because no such user exists. You can test it by simply commenting out user and password in config/connections.js
. Your service will be able to connect.
In https://hub.docker.com/_/mongo/ it is documented how you enable authentication:
docker run --name some-mongo -d mongo --auth
Adding user:
$ docker exec -it some-mongo mongo admin
connecting to: admin
> db.createUser({ user: 'jsmith', pwd: 'some-initial-password', roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] });
Successfully added user: {
"user" : "jsmith",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
To automate this you could put the user creation in a shell script and trigger it in docker compose.
There is another solution that you can apply. First ask yourself, why do you need authentication at all? Do you want to access the mongodb instance from any ip address? Then you need authentication. If not you might leave authentication disabled. If mongodb binds to localhost, nobody outside of localhost will be able to connect to it.
With docker you can harden this even further: any access to the mongodb instance is forbidden. Only containers that are on the same network as mongodb may connect.
Using docker-compose version 2 network feature:
version: "2"
services:
my-app:
image: myHubRepo/my-app:v1.X.Y
container_name: my-app
environment:
- MONGODB=mongodb:27017
- APP_PORT=80
- STAGE=production
expose:
- "80"
networks:
- back-tier
restart: always
mongodb:
image: mongo
volumes:
- mongodb-data:/data/db
networks:
- back-tier
restart: always
volumes:
mongodb-data:
driver: local
networks:
back-tier:
Mongodb is not accessible from outside of its very own container despite from containers that are on the same network back-tier
.
Adjust env/production.js
accordingly:
module.exports = {
connections: {
prodMongoDb: {
adapter: 'sails-mongo',
url: 'mongodb://' + process.env.MONGODB + '/my_app'
}
},
models: {
connection: 'prodMongoDb'
},
port: process.env.APP_PORT || 8080,
log: {
level: "warn"
}
};
For more information on networks with compose: https://docs.docker.com/compose/networking/