How to Build a Multi-container Web Application with Docker Compose and Mysql

Learning how to build a multi-container web application with Docker Compose and MySQL is essential for modern web development. This comprehensive tutorial will walk you through creating a scalable application architecture using containerization technology. You’ll discover how to orchestrate multiple services, including a web server, database, and application layer, all working together seamlessly.

Docker Compose simplifies the management of multi-container applications by allowing you to define your entire stack in a single YAML file. This approach provides consistency across development, testing, and production environments. By the end of this tutorial, you’ll have a fully functional web application running in containers with persistent data storage.

This guide covers everything from initial setup to deployment, including best practices for security and performance optimization. You’ll learn to configure networking between containers, manage environment variables, and implement data persistence strategies that ensure your application remains reliable and maintainable.

Prerequisites and Requirements for Building Multi-container Applications

Before you begin learning how to build a multi-container web application with Docker Compose and MySQL, ensure you have the necessary tools and knowledge in place.

You’ll need Docker Engine installed on your system. Download it from the official Docker documentation for your operating system. Docker Compose comes bundled with Docker Desktop installations, but Linux users may need to install it separately.

Your system should have at least 4GB of RAM and 10GB of free disk space. This ensures smooth container operations and adequate storage for images and volumes. A basic understanding of YAML syntax, command-line interfaces, and web development concepts will help you follow along more effectively.

You should be familiar with basic Docker commands like docker run, docker build, and docker ps. Knowledge of SQL databases and web server configurations will also prove beneficial throughout this process.

The estimated completion time for this tutorial is approximately 45-60 minutes, depending on your experience level and internet connection speed for downloading container images.

Step-by-Step Guide to Build Multi-container Web Application with Docker Compose

Another fascinating historical case is: How to Configure Nginx Reverse Proxy with Ssl Termination and Load Balancing

Step 1: Create the project directory structure

Start by creating a dedicated directory for your multi-container application. This organization keeps all related files together and makes project management easier.

mkdir docker-webapp
cd docker-webapp
mkdir app database nginx-config
touch docker-compose.yml app/index.php app/Dockerfile

This structure separates your application code, database configurations, and web server settings into logical directories. The docker-compose.yml file will orchestrate all services.

Step 2: Configure the web application container

Create a simple PHP web application that will connect to your MySQL database. Open app/index.php and add the following code:

<?php
$host = 'mysql-db';
$username = 'webapp_user';
$password = 'secure_password';
$database = 'webapp_db';

try {
    $pdo = new PDO("mysql:host=$host;dbname=$database", $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    echo "<h1>Database Connection Successful!</h1>";
    
    $stmt = $pdo->query("SELECT NOW() as current_time");
    $result = $stmt->fetch();
    echo "<p>Current database time: " . $result['current_time'] . "</p>";
} catch(PDOException $e) {
    echo "Connection failed: " . $e->getMessage();
}
?>

Step 3: Create the application Dockerfile

Build a custom PHP container with necessary extensions. Create app/Dockerfile with these contents:

FROM php:8.1-apache
RUN docker-php-ext-install pdo pdo_mysql
COPY . /var/www/html/
EXPOSE 80

This Dockerfile extends the official PHP Apache image and installs MySQL PDO extensions required for database connectivity.

Step 4: Configure the Docker Compose file

Create your docker-compose.yml file to define all services and their relationships:

version: '3.8'
services:
  web:
    build: ./app
    ports:
      - "8080:80"
    depends_on:
      - mysql-db
    environment:
      - DB_HOST=mysql-db
    networks:
      - webapp-network

  mysql-db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root_password
      MYSQL_DATABASE: webapp_db
      MYSQL_USER: webapp_user
      MYSQL_PASSWORD: secure_password
    volumes:
      - mysql-data:/var/lib/mysql
      - ./database:/docker-entrypoint-initdb.d
    networks:
      - webapp-network

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx-config/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - web
    networks:
      - webapp-network

volumes:
  mysql-data:

networks:
  webapp-network:
    driver: bridge

Step 5: Configure Nginx as a reverse proxy

Create nginx-config/default.conf to route traffic to your PHP application:

server {
    listen 80;
    server_name localhost;

    location / {
        proxy_pass http://web:80;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Step 6: Initialize the database schema

Create database/init.sql to set up your initial database structure:

CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO users (username, email) VALUES 
('john_doe', '[email protected]'),
('jane_smith', '[email protected]');

Step 7: Launch the multi-container application

Build and start all services using Docker Compose:

docker-compose up -d --build

The --build flag ensures your custom PHP container is built, while -d runs containers in detached mode.

Step 8: Verify the deployment

Check that all containers are running properly:

docker-compose ps

You should see three services running: web, mysql-db, and nginx. Visit http://localhost in your browser to see your application.

Troubleshooting Common Issues When Building Multi-container Applications

When working on how to build a multi-container web application with Docker Compose and MySQL, you may encounter several common issues that can disrupt your deployment.

Database connection failures often occur due to timing issues. MySQL containers need time to initialize before accepting connections. Add health checks to your docker-compose.yml:

mysql-db:
  image: mysql:8.0
  healthcheck:
    test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
    timeout: 20s
    retries: 10

Port conflicts happen when services try to bind to already occupied ports. Change the external port mapping if port 80 or 8080 are in use:

ports:
  - "8081:80"  # Use port 8081 instead

Volume permission issues can prevent MySQL from writing data. Ensure proper ownership by adding user specifications to your MySQL service configuration.

Network connectivity problems between containers usually stem from incorrect service names in connection strings. Always use the service name defined in docker-compose.yml as the hostname. For detailed networking troubleshooting, consult the Docker networking documentation.

If containers fail to start, check logs using docker-compose logs service-name to identify specific error messages and resolve configuration issues accordingly.

Optimizing and Scaling Your Multi-container Setup

After successfully implementing how to build a multi-container web application with Docker Compose and MySQL, you can enhance performance and scalability through various optimization techniques.

Implement container resource limits to prevent any single service from consuming excessive system resources:

web:
  build: ./app
  deploy:
    resources:
      limits:
        cpus: '0.50'
        memory: 512M
      reservations:
        memory: 256M

Configure environment-specific settings using multiple compose files. Create docker-compose.prod.yml for production overrides:

version: '3.8'
services:
  mysql-db:
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mysql_root_password
    secrets:
      - mysql_root_password

secrets:
  mysql_root_password:
    file: ./secrets/mysql_root_password.txt

Scale your web application horizontally by running multiple instances:

docker-compose up -d --scale web=3

This command creates three web container instances behind your Nginx load balancer. Monitor container performance using docker stats to identify bottlenecks and optimize resource allocation.

Consider implementing container health checks, automated backups for your MySQL data, and log aggregation solutions for production deployments. The <a href="https://dev.mysql.com/doc/refman/8.0/en/docker-mysql

Similar Posts