Skip to content

Instantly share code, notes, and snippets.

@x-yuri
Last active March 29, 2024 08:47
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save x-yuri/c229b3f9e8282ea12cecbbe923cc61c1 to your computer and use it in GitHub Desktop.
Save x-yuri/c229b3f9e8282ea12cecbbe923cc61c1 to your computer and use it in GitHub Desktop.
mongo + docker

mongo + docker

mongo >= 6: init-mongo.js + MONGO_INITDB_DATABASE in .env-mongo
mongo < 6: init-mongo.sh + no MONGO_INITDB_DATABASE in .env-mongo

.env:

MONGO_USER=user
MONGO_PASSWORD=userpasswd
MONGO_DB=foo

.env-mongo:

MONGO_INITDB_ROOT_USERNAME=root
MONGO_INITDB_ROOT_PASSWORD=rootpasswd
MONGO_INITDB_DATABASE=foo

docker-compose.yml:

services:
  app:
    build: .
    command: sh -euc '
        wait4ports tcp://mongo:27017
        ; carton exec perl a.pl'
    init: yes
    env_file: .env
    volumes:
      - .:/app

  mongo:
    # image: mongo:3.0-wheezy
    # image: mongo:3.2-jessie
    # image: mongo:3.4-jessie
    # image: mongo:3.6-jessie
    # image: mongo:4.0-bionic
    # image: mongo:4.2-bionic
    # image: mongo:4.4-focal
    # image: mongo:5-focal
    image: mongo:6-jammy
    env_file: [.env-mongo, .env]
    volumes:
      - mongo:/data/db
      # - ./init-mongo.sh:/docker-entrypoint-initdb.d/init-mongo.sh
      - ./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js

volumes:
  mongo:

Dockerfile:

FROM alpine:3.17
RUN apk add perl-app-cpanminus build-base perl-dev wait4ports \
    && cpanm Carton
WORKDIR /app

cpanfile:

requires 'MongoDB', '2.2.2';

a.pl:

use strict;
use warnings;
use MongoDB;
use Data::Dumper;

my $client = MongoDB->connect('mongodb://mongo', {
    username => $ENV{'MONGO_USER'},
    password => $ENV{'MONGO_PASSWORD'},
    db_name => $ENV{'MONGO_DB'},
});
print Dumper $client->db('foo')->run_command([connectionStatus => 1]);
my $collection = $client->ns('foo.bar');
my $result = $collection->insert_one({some => 'data'});
my $data = $collection->find_one({_id => $result->inserted_id});
print Dumper $data;

init-mongo.js:

db.getSiblingDB('admin').auth(
    process.env.MONGO_INITDB_ROOT_USERNAME,
    process.env.MONGO_INITDB_ROOT_PASSWORD
);
db.createUser({
    user: process.env.MONGO_USER,
    pwd: process.env.MONGO_PASSWORD,
    roles: ["readWrite"],
});

init-mongo.sh:

q_MONGO_USER=`jq --arg v "$MONGO_USER" -n '$v'`
q_MONGO_PASSWORD=`jq --arg v "$MONGO_PASSWORD" -n '$v'`
mongo -u "$MONGO_INITDB_ROOT_USERNAME" -p "$MONGO_INITDB_ROOT_PASSWORD" admin <<EOF
    use foo;
    db.createUser({
        user: $q_MONGO_USER,
        pwd: $q_MONGO_PASSWORD,
        roles: ["readWrite"],
    });
EOF

# process >= 6
# mongosh - mongo >= 5
# _getEnv() - mongo == 4.4

# _getEnv() is undocumented
# https://stackoverflow.com/a/67037065/52499
# mongo -- "$MONGO_DB" <<EOF
#     db.getSiblingDB('admin').auth(
#         _getEnv('MONGO_INITDB_ROOT_USERNAME'),
#         _getEnv('MONGO_INITDB_ROOT_PASSWORD'),
#     );
#     db.createUser({
#         user: _getEnv('MONGO_USER'),
#         pwd: _getEnv('MONGO_PASSWORD'),
#         roles: ["readWrite"],
#     });
# EOF
$ docker-compose up
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment