Skip to content

Adding support for database startup scripts - #1142

Closed
ikemtz wants to merge 11 commits into
docker-library:masterfrom
ikemtz:database-startup-scripts
Closed

Adding support for database startup scripts#1142
ikemtz wants to merge 11 commits into
docker-library:masterfrom
ikemtz:database-startup-scripts

Conversation

@ikemtz

@ikemtz ikemtz commented Jun 19, 2026

Copy link
Copy Markdown

There are instances where you want to run scripts when the container starts, and not just when the database is first created. Here are some examples where this feature would be useful:

  • You're starting an e2e (end-to-end) test run and you need to get the database to a "good" state.
  • You're using an ORM (object-relational-mapper) library like entity framework that generates an idempotent that should be run on every startup to ensure the database is in a good state.

This merge request adds this capability by creating a new "/docker-entrypoint-startdb.d/" folder; files placed in this folder will be run on every container startup.

NOTE: The DockerHub image page description will need to be updated, with text that looks similar to this:

Running scripts on database startup
Each time this container image is started, it will execute files with extensions .sh, .sql, .sql.gz, .sql.bz2, .sql.xz, and .sql.zst that are found in /docker-entrypoint-startdb.d. Files will be executed in alphabetical order. When parsing .sh files without the execute bit set, they are sourced rather than executed.

@tianon

tianon commented Jun 25, 2026

Copy link
Copy Markdown
Member

This ("always-initdb.d" functionality) is intentionally left for downstream images to implement. The root issue is that running scripts against a live database requires starting the server in a temporary local-only mode, doing the work, stopping it, then starting the real process -- and we're not willing to impose that overhead on every container startup for a feature most users don't need.

docker-entrypoint.sh is designed for exactly this kind of extension, though. The _is_sourced() / _main() guard at the bottom of the script exists so you can source it, call its exported functions directly, and build your own startup sequence around them. docker_process_init_files is the relevant public function -- its own docstring already uses /always-initdb.d/* as the example invocation:

# usage: docker_process_init_files [file [file [...]]]
#    ie: docker_process_init_files /always-initdb.d/*

A full custom entrypoint implementing this for MySQL (the equivalent for PostgreSQL is worked out in docker-library/postgres#496, and the same source pattern ships as docker-ensure-initdb.sh in that image):

#!/usr/bin/env bash
set -Eeuo pipefail

source /usr/local/bin/docker-entrypoint.sh

if [ "${1:0:1}" = '-' ]; then
	set -- mysqld "$@"
fi

if [ "$1" = 'mysqld' ] && ! _mysql_want_help "$@"; then
	mysql_check_config "$@"
	docker_setup_env "$@"
	docker_create_db_directories "$@"

	if [ "$(id -u)" = '0' ]; then
		exec gosu mysql "$BASH_SOURCE" "$@"
	fi

	if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
		docker_verify_minimum_env
		ls /docker-entrypoint-initdb.d/ > /dev/null
		docker_init_database_dir "$@"
		docker_temp_server_start "$@"
		mysql_socket_fix
		docker_setup_db
		docker_process_init_files /docker-entrypoint-initdb.d/*
		mysql_expire_root_user
		docker_temp_server_stop
	else
		docker_temp_server_start "$@"
		mysql_socket_fix
		docker_process_init_files /always-initdb.d/*
		docker_temp_server_stop
	fi
fi

exec "$@"

(See also: docker-library/postgres#267 (comment), docker-library/postgres#191 (comment), docker-library/postgres#821 (comment), docker-library/postgres#929, docker-library/postgres#955 (comment))

@tianon tianon closed this Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants