How do I initialize/seed data into my container at runtime, before the daemon process starts up in my container?
There's a very common pattern used to initialize stateful data in a container at runtime. Use a shell script as the ENTRYPOINT of a container, and execute the necessary setup steps before passing control to a long-running process.
- Create a shell script with the following contents (named
docker-entrypoint.shin our example):
#!/bin/bash set -e if [ "$1" = 'postgres' ]; then chown -R postgres "$PGDATA" if [ -z "$(ls -A "$PGDATA")" ]; then gosu postgres initdb fi exec gosu postgres "$@" fi exec "$@"
- Your Dockerfile should then call this script. For example, the following Dockerfile is an excerpt from the postgres image:
FROM debian:stretch ... COPY docker-entrypoint.sh /usr/local/bin/ RUN ln -s /usr/local/bin/docker-entrypoint.sh / # backwards compat ENTRYPOINT ["docker-entrypoint.sh"] CMD ["postgres"]
You can see that when the container starts up, the command portion is interprated to be
sh -c 'docker-entrypoint.sh postgres'.
The script is invoked and given the argument
postgres. The script checks if the first argument sent to it is equal to the string
postgres, and if so, executes a series of instructions to set up a database. Finally, the
exec shell construct is invoked, so that the final command given becomes the container's PID 1.
$@ is a shell variable that means "all the arguments", so that leaves us with simply