How to Persist MongoDB Users in Docker: Solving Authentication Issues


4 views

html

When working with MongoDB in Docker containers, a common frustration occurs when users created during the build process mysteriously disappear when the container starts. The error message UserNotFound: Could not find user indicates the authentication data isn't persisting as expected.

The fundamental issue lies in how MongoDB Docker images handle initialization. When you create users during Docker build (using RUN commands), these changes get written to the ephemeral container layer, which doesn't persist when the final container runs.

MongoDB's official Docker image provides two reliable ways to handle user creation:

Method 1: Using /docker-entrypoint-initdb.d/

The most straightforward solution is to place your initialization scripts in the special directory that MongoDB's entrypoint processes during container startup:

FROM mongo:3.2
COPY create_ddbb.js /docker-entrypoint-initdb.d/

Method 2: Environment Variables

For simple cases, you can use environment variables:

docker run -d \
  -e MONGO_INITDB_ROOT_USERNAME=admin \
  -e MONGO_INITDB_ROOT_PASSWORD=secret \
  -e MONGO_INITDB_DATABASE=foobar \
  mongo:3.2

Here's a full implementation that properly persists users:

# Dockerfile
FROM mongo:3.2

COPY init.js /docker-entrypoint-initdb.d/

# init.js
db = db.getSiblingDB('foobar');
db.createUser({
  user: "appuser",
  pwd: "apppassword",
  roles: [ { role: "readWrite", db: "foobar" } ]
});
  • Initialization scripts only run when the database doesn't exist
  • For existing databases, you'll need to connect and manually create users
  • Always check MongoDB logs to verify user creation

If you still face issues, verify:

docker exec -it mongodb_container mongo -u appuser -p apppassword --authenticationDatabase foobar

Check logs for any initialization errors:

docker logs mongodb_container

When working with MongoDB in Docker containers, many developers encounter a frustrating issue: users created during container initialization seem to disappear when the container restarts. This typically happens because:

  • The initialization script runs but doesn't persist the authentication data
  • The MongoDB instance isn't properly configured for authentication
  • The storage volume isn't correctly mounted

Here's a more reliable way to create and persist MongoDB users in Docker:

FROM mongo:3.2

COPY create_ddbb.js /docker-entrypoint-initdb.d/

VOLUME /data/db

CMD ["mongod", "--auth"]

Place your initialization script in the correct location with proper syntax:

// /docker-entrypoint-initdb.d/create_ddbb.js
db = db.getSiblingDB('foobar');
db.createUser({
    user: "myuser",
    pwd: "mypassword",
    roles: [{
        role: "readWrite",
        db: "foobar"
    }]
});

When starting your container, ensure you:

docker run -d \
  --name some-mongo \
  -v mongo-data:/data/db \
  -e MONGO_INITDB_ROOT_USERNAME=root \
  -e MONGO_INITDB_ROOT_PASSWORD=example \
  mongo:3.2 --auth

To test if your user was created successfully:

docker exec -it some-mongo mongo -u myuser -p mypassword --authenticationDatabase foobar
  • Not using the official /docker-entrypoint-initdb.d/ directory for initialization scripts
  • Forgetting to mount a persistent volume for data storage
  • Not enabling authentication with the --auth flag
  • Trying to authenticate against the wrong database

For more complex setups with multiple users:

// init-mongo.js
db = db.getSiblingDB('admin');
db.createUser({
    user: "admin",
    pwd: "adminpassword",
    roles: ["root"]
});

db = db.getSiblingDB('appdb');
db.createUser({
    user: "appuser",
    pwd: "apppassword",
    roles: ["readWrite"]
});