Home > OS >  docker mechanism that allow container to not intialize postgres server while container starts?
docker mechanism that allow container to not intialize postgres server while container starts?

Time:11-25

i try to understand why, by executing this command :

docker run --rm -it postgres bash

container starts well, gives me a bash prompt, without intializing a postgres server.

In fact, when i only execute this :

docker run --rm -it postgres

container tries to intialize a postgres server and failed because a non provided '-e POSTGRES_PASSWORD' sequence which is absolutly normal.

But the question is : what is the mechanism in 'docker' or 'in the official postgres image' that tell container to :

  • not initialize a postgres server when an argument is provided at the end of 'docker run --rm -it postgres' sequence (like bash or psql..)
  • DO initialize a postgres server when NO argument is provided (docker run --rm -it postgres)

Thanks by advance.

CodePudding user response:

The postgres image Dockerfile is set up as

ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["postgres"]

When an image has both an ENTRYPOINT and a CMD, the command part is passed as additional parameters to the entrypoint. If you docker run postgres bash, the bash command overrides the command part but leaves the entrypoint intact.

This entrypoint wrapper script setup is a common and useful technique. The script can do anything it needs to do to make the container ready to use, and then end with the shell command exec "$@" to run the command it got passed as arguments. Typical uses for this include dynamically setting environment variables, populating mounted volumes, and (for application containers more than database containers) waiting for a database or other container dependency to be ready.

In the particular case of the postgres image, its entrypoint script does (simplified):

if [ "$1" = 'postgres' ] && ! _pg_want_help "$@"; then
    docker_setup_env
    docker_create_db_directories
    if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
        docker_init_database_dir
        docker_setup_db
        docker_process_init_files /docker-entrypoint-initdb.d/*
    fi
fi
exec "$@"

Since the entrypoint script is just a shell script and it does have the command as positional parameters, it can make decisions based on what the command actually is. In this case, if [ "$1" = 'postgres' ] – if the main container command is to run the PostgreSQL server – then do the first-time initialization, otherwise don't.

  • Related