Docker
MySQL
Dockerfile
Database Import
SQL Dump

Setting up MySQL and importing dump within Dockerfile

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The easiest mistake in this area is trying to import a MySQL dump during the Docker image build itself. In most cases, you should not run a live MySQL server inside the Dockerfile; instead, build an image that contains initialization files and let the container import the dump at first startup.

Why Importing During docker build Is Usually Wrong

A Dockerfile builds an image layer by layer. It is not a normal long-running service environment. Starting MySQL during image build, waiting for it, importing a dump, and then freezing that state into an image is fragile and usually slower than necessary.

The official MySQL image already provides a cleaner mechanism: any .sql, .sql.gz, or executable init script placed in /docker-entrypoint-initdb.d/ is executed the first time the container initializes a fresh data directory.

A simple Dockerfile can extend the MySQL image and copy the dump into the init directory.

dockerfile
1FROM mysql:8.0
2
3ENV MYSQL_ROOT_PASSWORD=secret
4ENV MYSQL_DATABASE=appdb
5
6COPY dump.sql /docker-entrypoint-initdb.d/01-dump.sql

Then run it:

bash
docker build -t my-mysql .
docker run --name mydb -p 3306:3306 -d my-mysql

On the first startup, the MySQL entrypoint creates the database and imports the dump automatically.

Understand the “First Startup Only” Rule

The init directory is processed only when the MySQL data directory is empty. If you restart the same container or reuse the same volume, the scripts are not run again.

That behavior is usually what you want because initialization scripts should not destroy or duplicate real persisted data every time the container starts.

If you need to test initialization from scratch again, remove the old container and volume.

bash
docker rm -f mydb
docker volume rm mydb-data

A Better Runtime Setup With Volumes

In practice, it is usually cleaner to keep persistence outside the image.

bash
1docker run --name mydb \
2  -e MYSQL_ROOT_PASSWORD=secret \
3  -e MYSQL_DATABASE=appdb \
4  -v mydb-data:/var/lib/mysql \
5  -p 3306:3306 \
6  -d my-mysql

Now the image defines how the database is initialized, while the volume holds the actual database files.

Use docker-compose or Compose for Local Development

For local development, Compose often expresses the setup more clearly than a long docker run command.

yaml
1services:
2  db:
3    image: my-mysql
4    ports:
5      - "3306:3306"
6    environment:
7      MYSQL_ROOT_PASSWORD: secret
8      MYSQL_DATABASE: appdb
9    volumes:
10      - mydb-data:/var/lib/mysql
11
12volumes:
13  mydb-data:

This makes it easy to rebuild the image while keeping database persistence behavior explicit.

If You Really Need Post-Startup Import Logic

Sometimes you do not want the dump imported only on first initialization. In that case, write a custom entrypoint or a separate setup container that waits for MySQL to become ready and then runs mysql < dump.sql explicitly.

That is a runtime concern, not an image-build concern.

Common Pitfalls

The most common mistake is trying to run MySQL interactively inside the Dockerfile and import the dump during docker build.

Another common issue is forgetting that /docker-entrypoint-initdb.d/ runs only when the database directory is empty. Developers also often confuse image contents with persistent data and then wonder why restarting the container does not rerun the import.

Summary

  • Do not usually import a MySQL dump during the Dockerfile build stage.
  • Copy the dump into /docker-entrypoint-initdb.d/ and let the official MySQL entrypoint import it on first startup.
  • Remember that initialization scripts run only for a fresh data directory.
  • Use volumes for persistence so image and data lifecycle stay separate.
  • If you need repeatable runtime imports, use entrypoint or sidecar logic instead of build-time tricks.

Course illustration
Course illustration

All Rights Reserved.