Deploying modern applications on Docker typically involves orchestrating a multi-tier architecture (e.g., a web frontend, an application API, and a database backend). Rather than running each layer in a single monolithic container, the microservices design pattern isolates each component into its own dedicated container.
To deploy a multi-container application on Docker, three primary parameters must be configured:
Service Dependency and Startup Order:
Web applications require their database backends to be active and ready before initialization. In Docker Compose, the depends_on instruction defines the boot order.
Container Network Inter-connectivity:
Containers on the same user-defined network communicate using automatically registered DNS hostnames. For example, a PHP application container can connect to MySQL by using the container name mysql_host as the DB server address.
Data Persistence via Volume Bind Mounts:
Containers are ephemeral; any files written inside them are lost when the container terminates. Map directories on the host (e.g., /var/lib/mysql for databases, /var/www/html for website assets) to locations inside the container to persist data.
graph TD
Client[Client Browser] -->|Port 8089| Web["Web Server (php_host / Port 80)"]
subgraph Docker Network
Web -->|Internal Query: port 3306| DB["Database (mysql_host / Port 3306)"]
end
subgraph Host Storage
WebVol["/var/www/html/"] -->|Bind Mount| Web
DBVol["/var/lib/mysql/"] -->|Bind Mount| DB
end
When deploying standard database images (like MySQL or MariaDB), environment variables are passed to initialize security credentials and create default databases:
MYSQL_ROOT_PASSWORD: Sets the password for the superuser root account.MYSQL_DATABASE: Automatically creates a database with the specified name upon initialization.MYSQL_USER & MYSQL_PASSWORD: Creates a new database user and grants them all privileges on the created database.stapp03) (can vary in labs, e.g., stapp01, stapp02, stapp03)banner (associated with stapp03; tony for stapp01, steve for stapp02)/opt/docker/docker-compose.ymlphp_hostphp:apache8089 mapped to Container Port 80/var/www/html mapped to Container /var/www/htmlmysql_hostmariadb:latest3306 mapped to Container Port 3306/var/lib/mysql mapped to Container /var/lib/mysqlMYSQL_DATABASE: database_hostMYSQL_USER: app_userMYSQL_PASSWORD: password_userMYSQL_ROOT_PASSWORD: R00tP@ss!Establish an SSH connection from the Jump Host to App Server 3:
ssh banner@stapp03
Provide the server password when prompted.
Ensure that the target directory for the Docker Compose file exists:
sudo mkdir -p /opt/docker
Create and edit the Docker Compose configuration file:
sudo vi /opt/docker/docker-compose.yml
Add the following multi-container configuration:
version: '3.8'
services:
web:
image: php:apache
container_name: php_host
ports:
- "8089:80"
volumes:
- /var/www/html:/var/www/html
depends_on:
- db
restart: always
db:
image: mariadb:latest
container_name: mysql_host
ports:
- "3306:3306"
volumes:
- /var/lib/mysql:/var/lib/mysql
environment:
MYSQL_DATABASE: database_host
MYSQL_USER: app_user
MYSQL_PASSWORD: password_user
MYSQL_ROOT_PASSWORD: R00tP@ss!
restart: always
Save and close the file (:wq).
Start both containers in detached mode:
cd /opt/docker
sudo docker compose up -d
Ensure both containers are active and in the Up state:
docker compose ps
Expected Output:
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
mysql_host mariadb:latest "docker-entrypoint.s…" db 5 seconds ago Up 5 seconds 0.0.0.0:3306->3306/tcp
php_host php:apache "docker-php-entrypoi…" web 5 seconds ago Up 5 seconds 0.0.0.0:8089->80/tcp
Inspect the database server configuration and test container network communication:
# Query PHP container logs to verify database handshake
docker logs php_host
# Perform connection check from Jump Host to App Server port
curl -I http://localhost:8089
Log out of the Application Server:
exit