How to create a Mongo Docker Image with default collections and data?

前端 未结 3 2051
春和景丽
春和景丽 2020-11-30 02:18

I need support here to build my own mongo docker image.

I have a list of scripts to create and insert data into the MongoDB that shall be called in my Dockerfile to

相关标签:
3条回答
  • 2020-11-30 03:05

    During a docker image build, each build command like RUN is launched in it's own docker container and then when the command completes the data is committed as an image. If you run dockviz images --tree while doing a build you will get the idea.

    In your case mongod has started and stopped long before you need it. You need to start mongo and run your scripts all in the one RUN step. You can achieve that by using a shell script that launches mongod and inserts your data.

    Your Dockerfile will run:

    RUN mongo_create_insert.sh
    

    Then mongo_create_insert.sh contains all your mongo dependent steps:

    #!/usr/bin/env bash
    
    mongod --fork --logpath /var/log/mongodb.log --dbpath /data/db/
    
    FILES=scripts/*-create.js
    for f in $FILES; do mongo mydb $f; done
    
    FILES=scripts/*-insert.js
    for f in $FILES; do mongo mydb $f; done
    
    mongod --shutdown
    

    As a side note, I tend to install Ansible in my base image and use that to provision Docker images in single RUN command rather than doing lots of shell RUN steps in a Dockerfile (which is just a glorified shell script in the end). You lose some of the build caching niceness but we've moved on from provisioning with shell scripts for a reason.

    0 讨论(0)
  • 2020-11-30 03:06

    According to the description of the image on DockerHub, there is a much cleaner and simpler solution for this.

    When a container is started for the first time it will execute files with extensions .sh and .js that are found in /docker-entrypoint-initdb.d. Files will be executed in alphabetical order. .js files will be executed by mongo using the database specified by the MONGO_INITDB_DATABASE variable, if it is present, or test otherwise. You may also switch databases within the .js script.

    First, the Dockerfile is as simple as

    FROM mongo:4
    COPY setup.sh /docker-entrypoint-initdb.d/
    COPY scripts /
    

    Then, in the setup.sh, add your user/collection creation script, for example

    mongo=( mongo --host 127.0.0.1 --port 27017 --quiet )
    mongo+=(
        --username="$MONGO_INITDB_ROOT_USERNAME"
        --password="$MONGO_INITDB_ROOT_PASSWORD"
        --authenticationDatabase="$rootAuthDatabase"
    )
    
    CREATE_FILES=/scripts/*-create.js 
    for f in $CREATE_FILES; do "${mongo[@]}" "$MONGO_INITDB_DATABASE" $f; done 
    
    INSERT_FILES=/scripts/*-insert.js 
    for f in $INSERT_FILES; do "${mongo[@]}" "$MONGO_INITDB_DATABASE" $f; done
    
    0 讨论(0)
  • 2020-11-30 03:10

    The problem was that information could not be saved on /db/data, so I've created a solution creating my own data directory.

    # Parent Dockerfile https://github.com/docker-library/mongo/blob/982328582c74dd2f0a9c8c77b84006f291f974c3/3.0/Dockerfile
    FROM mongo:latest
    
    # Modify child mongo to use /data/db2 as dbpath (because /data/db wont persist the build)
    RUN mkdir -p /data/db2 \
        && echo "dbpath = /data/db2" > /etc/mongodb.conf \
        && chown -R mongodb:mongodb /data/db2
    
    COPY . /data/db2
    
    RUN mongod --fork --logpath /var/log/mongodb.log --dbpath /data/db2 --smallfiles \
        && CREATE_FILES=/data/db2/scripts/*-create.js \
        && for f in $CREATE_FILES; do mongo 127.0.0.1:27017 $f; done \
        && INSERT_FILES=/data/db2/scripts/*-insert.js \
        && for f in $INSERT_FILES; do mongo 127.0.0.1:27017 $f; done \
        && mongod --dbpath /data/db2 --shutdown \
        && chown -R mongodb /data/db2
    
    # Make the new dir a VOLUME to persists it 
    VOLUME /data/db2
    
    CMD ["mongod", "--config", "/etc/mongodb.conf", "--smallfiles"]
    

    Thanks to @yosifkit from the docker-library/mongo Github project for pointing that the volume would store the data in the resulting image. I missed that on the documentation.

    0 讨论(0)
提交回复
热议问题