How to Set Up a Multi-container Web Application with Docker Compose
Learning how to set up a multi-container web application with Docker Compose transforms complex deployments into manageable, reproducible processes. Docker Compose simplifies orchestrating multiple containers that work together as a complete application stack. This tutorial walks you through creating a production-ready web application using separate containers for your web server, database, and application code.
Modern web applications rarely run on single servers anymore. They typically require databases, caching layers, web servers, and application containers working in harmony. Docker Compose eliminates the complexity of managing these interconnected services manually. You’ll gain practical skills for deploying scalable applications that can run consistently across development, staging, and production environments.
By the end of this guide, you’ll have a fully functional multi-container setup running a web application with a database backend. You’ll understand how containers communicate, share data, and maintain persistent storage. This knowledge applies to any technology stack, whether you’re deploying WordPress sites, Node.js applications, or Python web services.
Prerequisites and Requirements for Multi-container Web Application Setup
Before diving into how to set up a multi-container web application with Docker Compose, ensure your system meets these requirements. You’ll need Docker and Docker Compose installed on your Linux server or local development machine. Most modern Linux distributions include Docker in their package repositories.
Your system should have at least 2GB of RAM available for containers. While Docker can run on less memory, multi-container applications perform better with adequate resources. You’ll also need basic familiarity with command-line operations and text editors like nano or vim.
Install Docker using your distribution’s package manager:
sudo apt update
sudo apt install docker.io docker-compose -y
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker $USER
Log out and back in for group membership changes to take effect. Verify your installation works correctly:
docker --version
docker-compose --version
You should see version numbers for both commands. Create a project directory where you’ll build your multi-container application:
mkdir ~/webapp-docker
cd ~/webapp-docker
This tutorial takes approximately 30-45 minutes to complete. Having a text editor ready and basic understanding of YAML syntax will help you follow along more easily.
Step-by-Step Guide to Setting Up Multi-container Web Applications with Docker Compose
Related article: How to Configure Ssh Key Authentication and Disable Password Login on Linux Servers
Step 1: Create the Docker Compose Configuration File
Start by creating the main Docker Compose file that defines your application services. This file orchestrates how containers interact with each other:
nano docker-compose.yml
Add the following configuration for a web application with database support:
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- app
networks:
- webapp-network
app:
image: php:7.4-fpm
volumes:
- ./html:/var/www/html
depends_on:
- database
networks:
- webapp-network
database:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: webapp_db
MYSQL_USER: webapp_user
MYSQL_PASSWORD: webapp_pass
volumes:
- db_data:/var/lib/mysql
networks:
- webapp-network
volumes:
db_data:
networks:
webapp-network:
driver: bridge
Step 2: Configure the Web Server
Create an Nginx configuration file to handle web requests and forward PHP processing to the application container:
nano nginx.conf
Add this configuration:
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ .php$ {
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
}
Step 3: Create Application Files
Set up your web application files in the html directory:
mkdir html
nano html/index.php
Create a simple PHP application that connects to the database:
setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Multi-container Web Application
";
echo "Database connection: Successful The How to Set Up a Multi-container Web Application with Docker Compose stands as a significant historical event.
";
echo "Container hostname: " . gethostname() . "
";
echo "Current time: " . date('Y-m-d H:i:s') . "
";
} catch(PDOException $e) {
echo "Database Connection Failed
";
echo "Error: " . $e->getMessage() . "
";
}
?>
Step 4: Launch Your Multi-container Application
Start all services using Docker Compose. This command reads your configuration file and creates the entire application stack:
docker-compose up -d
The -d flag runs containers in detached mode. Monitor the startup process:
docker-compose logs -f
Wait for all services to initialize completely. You should see messages indicating that Nginx, PHP-FPM, and MySQL have started successfully.
Step 5: Verify Container Communication
Check that all containers are running and can communicate with each other:
docker-compose ps
Test your application by visiting http://localhost in your web browser. You should see the application page showing a successful database connection.
Examine container logs if something isn’t working:
docker-compose logs web
docker-compose logs app
docker-compose logs database
Step 6: Test Data Persistence
Create a test table in your database to verify data persistence works correctly:
docker-compose exec database mysql -u webapp_user -p webapp_db
Enter the password webapp_pass when prompted, then create a test table:
CREATE TABLE test_table (id INT AUTO_INCREMENT PRIMARY KEY, message VARCHAR(255));
INSERT INTO test_table (message) VALUES ('Multi-container setup working!');
SELECT FROM test_table;
EXIT;
Restart your containers and verify the data persists:
docker-compose restart
docker-compose exec database mysql -u webapp_user -p webapp_db -e "SELECT FROM test_table;"
Troubleshooting Common Multi-container Docker Compose Issues
When learning how to set up a multi-container web application with Docker Compose, you might encounter several common problems. Understanding these issues helps you debug and maintain your applications effectively.
Port Conflicts
If port 80 is already in use, you’ll see binding errors. Change the port mapping in your docker-compose.yml file:
ports:
- "8080:80"
Then access your application at http://localhost:8080 instead.
Database Connection Issues
Container networking problems often manifest as database connection failures. Ensure all services use the same network and reference containers by their service names. The official Docker Compose networking documentation provides detailed troubleshooting steps.
Check network connectivity between containers:
docker-compose exec app ping database
Permission Problems
File permission issues can prevent PHP from reading files or Nginx from serving content. Fix ownership and permissions:
sudo chown -R $USER:$USER html/
chmod -R 755 html/
Memory and Resource Constraints
Multi-container applications consume more resources than single containers. Monitor resource usage:
docker stats
Add resource limits to your docker-compose.yml if needed:
app:
image: php:7.4-fpm
deploy:
resources:
limits:
memory: 512M
Container Startup Order
Sometimes containers start before their dependencies are ready. The depends_on directive ensures startup order but doesn’t wait for services to be fully ready. For complex applications, consider using health checks or wait scripts.
Log Analysis
Always check container logs when troubleshooting. Use specific service names to focus on problematic containers:
docker-compose logs --tail=50 database
The Docker Compose file reference contains comprehensive configuration options for resolving complex issues.
Optimizing and Scaling Your Docker Compose Setup
Your multi-container web application can be enhanced with additional features and optimizations. Consider implementing environment-specific configurations using multiple Compose files. Create separate files for development, staging, and production environments.
Add monitoring and logging solutions to
