Skip to main content
Docker Basics Tutorial
CHAPTER 11 Beginner

Dockerizing Databases

Updated: May 15, 2026
25 min read

# CHAPTER 11

Dockerizing Databases

1. Introduction

Installing a database engine directly onto your operating system leaves a permanent, heavy footprint. Background services consume RAM constantly, and completely uninstalling them is notoriously difficult. Dockerizing your databases solves this by granting you disposable, instantly provisionable data engines. In this chapter, we will master deploying robust, persistent database containers for MySQL, PostgreSQL, and MongoDB, entirely through Docker Compose.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Instantiate official database containers (MySQL, Postgres, MongoDB).
  • Inject initial configuration and passwords via Environment Variables.
  • Architect permanent data persistence using Named Volumes.
  • Understand how to execute automated database initialization scripts.
  • Connect a backend web application to a database container.

3. Beginner-Friendly Explanation

Imagine hiring an accountant (The Database).
  • The Traditional Way: You build the accountant a permanent office in your house. They move in, arrange all their filing cabinets, and live there forever. It is difficult to get them to leave.
  • The Docker Way: You rent an accountant on-demand. They teleport into your office, do the math, and leave their finalized paperwork in a locked safe (The Named Volume). You fire the accountant. The next day, you teleport a *brand new* accountant in. They open the locked safe, read yesterday's paperwork, and pick up exactly where the last one left off.

The database software is disposable; the data inside the Volume is permanent.

4. Injecting Environment Variables

A database container refuses to start if it doesn't have a secure password. You pass this critical information into the container at boot time using Environment Variables.
  • MySQL expects: MYSQLROOTPASSWORD
  • PostgreSQL expects: POSTGRESPASSWORD
  • MongoDB expects: MONGOINITDBROOTUSERNAME and MONGOINITDBROOT_PASSWORD

If you fail to provide these variables in your docker-compose.yml, the container will instantly crash with a helpful error in the logs.

5. Automated Initialization Scripts

A brilliant feature of official database images is the auto-initialization directory. If you map a SQL file (e.g., schema.sql) from your laptop into the special /docker-entrypoint-initdb.d/ folder inside a MySQL or Postgres container, the database will automatically execute that SQL file the very first time it boots up! This allows you to instantly seed your database with tables and dummy data for immediate local development.

6. Connecting GUIs to Containerized Databases

If the database is running inside Docker, how do you view the data using a graphical tool like DBeaver, pgAdmin, or MySQL Workbench? You must explicitly publish the database port to your host machine (ports: - "3306:3306"). Your GUI tool simply connects to localhost:3306, completely unaware that the database is secretly running inside a container.

7. Mini Project: Build a Resilient Database Stack

Let's build a Postgres database that seeds itself automatically.

Step-by-Step Tutorial:

  1. 1. Create a folder named db-project. Open your terminal and cd into it.
  1. 2. Create a file named init.sql with the following content:

sql
12
CREATE TABLE users (id SERIAL PRIMARY KEY, name VARCHAR(50));
INSERT INTO users (name) VALUES ('Alice'), ('Bob');
  1. 3. Create a docker-compose.yml file:
yaml
123456789101112131415
version: '3.8'
services:
  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=secret
      - POSTGRES_DB=company_db
    ports:
      - "5432:5432"
    volumes:
      - pg-data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
volumes:
  pg-data:
  1. 4. Run the stack: docker-compose up -d.
  1. 5. *The Magic:* Docker pulls Postgres, sets the admin password, creates a database named company_db, and automatically runs the init.sql file to create the users table!
  1. 6. Prove it by querying the container directly:
bash
1
docker exec -it db-project_db_1 psql -U admin -d company_db -c "SELECT * FROM users;"

*(You will see Alice and Bob printed in the terminal!)*

8. Real-World Scenarios

A new developer is tasked with fixing a bug in an e-commerce platform. The platform requires a complex MongoDB database filled with 50 collections of mock product data. The senior engineer provides a docker-compose.yml and a seed data folder. The new developer runs docker-compose up, and within 60 seconds, a fully populated, production-mirror database is running on their laptop, ready for testing.

9. Best Practices

  • Never Map Ports in Production: In the tutorial above, we mapped 5432:5432 so we could easily test it. If you deploy this docker-compose.yml to an AWS EC2 instance, you have just exposed your raw database to the entire global internet! In production, remove the ports mapping. The Web Server container will still be able to connect to the database via the internal Docker network, but hackers will be blocked.

10. Common Mistakes

  • Ignoring the Initialization Rules: The init.sql auto-execution feature ONLY runs the very first time the database container boots up (specifically, when the Named Volume is totally empty). If you edit your init.sql file and run docker-compose restart, nothing will happen! To force the script to run again, you must completely delete the Named Volume to simulate a fresh environment (docker-compose down -v).

11. Exercises

  1. 1. What is the specific folder path utilized within official MySQL/Postgres images to execute automated .sql seed scripts upon initialization?
  1. 2. Explain why failing to define a Named Volume in a docker-compose.yml containing a database service is considered an architectural failure.

12. FAQs

Q: Should I run production databases in Docker? A: Historically, experts said "No." Today, running databases in Docker is common, especially using Kubernetes. However, managed cloud databases (like Amazon RDS) are still strongly preferred for critical production data because AWS handles automated backups, patching, and multi-region disaster recovery for you. Use Docker databases primarily for local development and testing.

13. Interview Questions

  • Q: A junior developer commits a docker-compose.yml file mapping port 3306:3306 for a MySQL service intended for a production deployment. Explain the security implications of this configuration and how you would architect the network to secure the database.
  • Q: Describe the mechanical process of automatically seeding a containerized relational database with initial table structures and mock data without requiring manual user intervention after docker-compose up.

14. Summary

In Chapter 11, we conquered the complexity of database administration. We demonstrated how to instantly provision, configure, and destroy complex data engines like PostgreSQL without leaving residual clutter on our host operating systems. We utilized Environment Variables to inject secure credentials, mastered the auto-initialization directory to automate database seeding, and reinforced the paramount importance of Named Volumes to guarantee data permanence across container lifecycles.

15. Next Chapter Recommendation

We have successfully injected passwords using clear-text environment variables. But hardcoding password=secret in our files is a massive security risk. Proceed to Chapter 12: Docker Environment Variables and Secrets.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·