DEV Community

janak0ff
janak0ff

Posted on

Day 46: Deploy an App on Docker Containers

The Nautilus Application development team recently finished development of one of the apps that they want to deploy on a containerized platform. The Nautilus Application development and DevOps teams met to discuss some of the basic pre-requisites and requirements to complete the deployment. The team wants to test the deployment on one of the app servers before going live and set up a complete containerized stack using a docker compose fie. Below are the details of the task:

  1. On App Server 2 in Stratos Datacenter create a docker compose file /opt/data/docker-compose.yml (should be named exactly).
  2. The compose should deploy two services (web and DB), and each service should deploy a container as per details below:

For web service:

a. Container name must be php_host.

b. Use image php with any apache tag. Check here for more details.

c. Map php_host container's port 80 with host port 6200

d. Map php_host container's /var/www/html volume with host volume /var/www/html.

For DB service:

a. Container name must be mysql_host.

b. Use image mariadb with any tag (preferably latest). Check here for more details.

c. Map mysql_host container's port 3306 with host port 3306

d. Map mysql_host container's /var/lib/mysql volume with host volume /var/lib/mysql.

e. Set MYSQL_DATABASE=database_host and use any custom user ( except root ) with some complex password for DB connections.

  1. After running docker-compose up you can access the app with curl command curl <server-ip or hostname>:6200/

For more details check here.

Note: Once you click on FINISH button, all currently running/stopped containers will be destroyed and stack will be deployed again using your compose file.


Introduction

Welcome to Day 46 of my 100 Days of DevOps journey! Today, we're going to learn how to deploy a complete application using Docker Compose. Don't worry if you're new to this – I'll explain everything step by step in simple terms.


What is Docker Compose?

Think of Docker Compose like a recipe book for your applications. Instead of manually running multiple docker run commands, you write all the instructions in a single file, and Docker Compose does everything for you with one command.

Why Use Docker Compose?

  • One command to start everything
  • Easy to manage multiple containers
  • Consistent environment every time
  • Simple to share with your team

📋 Our Task Today

We need to deploy a web application with a database on App Server 2. The application has two parts:

  1. Web Server (PHP) – serves the website
  2. Database (MariaDB) – stores data

🔧 Step-by-Step Guide

Step 1: Connect to the Server

First, let's connect to our server:

ssh steve@stapp02
# Enter password: Am3ric@
Enter fullscreen mode Exit fullscreen mode

Once connected, switch to root user (administrator):

sudo su -
# Enter password: Am3ric@
Enter fullscreen mode Exit fullscreen mode

Step 2: Create the Working Directory

Let's create a folder for our Docker Compose file:

mkdir -p /opt/data
cd /opt/data
Enter fullscreen mode Exit fullscreen mode

Step 3: Install Docker Compose

Docker Compose might not be installed by default. Let's install it:

# Download Docker Compose
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# Make it executable
chmod +x /usr/local/bin/docker-compose

# Fix missing library (if needed)
yum install -y libxcrypt-compat

# Verify installation
docker-compose --version
Enter fullscreen mode Exit fullscreen mode

What's happening here?

  • curl downloads the Docker Compose binary
  • chmod makes it executable
  • yum install fixes any missing dependencies
  • The last command confirms it's working

Step 4: Create the Docker Compose File

Now, let's create our recipe file. Think of this as telling Docker what we want:

vi docker-compose.yml
Enter fullscreen mode Exit fullscreen mode

Add this content:

version: '3.8'

services:
  web:
    image: php:apache
    container_name: php_host
    ports:
      - "6200:80"
    volumes:
      - "/var/www/html:/var/www/html"

  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: dbuser
      MYSQL_PASSWORD: 'ComplexPassword123!'
      MYSQL_ROOT_PASSWORD: 'RootPassword123!'
Enter fullscreen mode Exit fullscreen mode

📖 Understanding the YAML File

Let me explain what each part means:

Web Service (the website)

web:
  image: php:apache          # Use PHP with Apache
  container_name: php_host   # Name our container
  ports:
    - "6200:80"              # Host port 6200 → Container port 80
  volumes:
    - "/var/www/html:/var/www/html"  # Share files between host and container
Enter fullscreen mode Exit fullscreen mode

DB Service (the database)

db:
  image: mariadb:latest      # Use MariaDB database
  container_name: mysql_host # Name our container
  ports:
    - "3306:3306"            # Host port 3306 → Container port 3306
  volumes:
    - "/var/lib/mysql:/var/lib/mysql"  # Store database data
  environment:               # Set up database
    MYSQL_DATABASE: database_host
    MYSQL_USER: dbuser
    MYSQL_PASSWORD: 'ComplexPassword123!'
    MYSQL_ROOT_PASSWORD: 'RootPassword123!'
Enter fullscreen mode Exit fullscreen mode

Step 5: Start the Application

Now the magic happens! Run this command to start everything:

docker-compose up -d
Enter fullscreen mode Exit fullscreen mode

What this does:

  • docker-compose – runs Docker Compose
  • up – starts the containers
  • -d – runs in background (detached mode)

Step 6: Verify Everything is Working

Check if our containers are running:

# List running containers
docker-compose ps
Enter fullscreen mode Exit fullscreen mode

Expected output:

   Name                 Command               State                    Ports                  
----------------------------------------------------------------------------------------------
mysql_host   docker-entrypoint.sh mariadbd    Up      0.0.0.0:3306->3306/tcp,:::3306->3306/tcp
php_host     docker-php-entrypoint apac ...   Up      0.0.0.0:6200->80/tcp,:::6200->80/tcp    
Enter fullscreen mode Exit fullscreen mode

Step 7: Test the Application

Finally, let's test if our application is working:

curl http://localhost:6200
Enter fullscreen mode Exit fullscreen mode

If everything is working, you should see the default Apache welcome page or your website content.


🎯 Understanding What We Just Built

Container Architecture

┌─────────────────────────────────────────────┐
│              App Server 2                    │
│                                               │
│  ┌──────────────────┐  ┌──────────────────┐   │
│  │   php_host       │  │   mysql_host     │   │
│  │                  │  │                  │   │
│  │  Port: 6200      │  │  Port: 3306      │   │
│  │  Website:        │  │  Database:       │   │
│  │  /var/www/html   │  │  /var/lib/mysql  │   │
│  └──────────────────┘  └──────────────────┘   │
│                                               │
│  ┌─────────────────────────────────────────┐   │
│  │   Host Volumes (persistent storage)     │   │
│  │   - /var/www/html (web files)           │   │
│  │   - /var/lib/mysql (database)           │   │
│  └─────────────────────────────────────────┘   │
└─────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Key Concepts Explained

1. Images vs Containers

  • Image: The blueprint/template (like a recipe)
  • Container: Running instance of an image (like the cooked meal)

2. Port Mapping

  • "6200:80" means: When you access port 6200 on your server, it goes to port 80 in the container
  • This is how we access services from outside the container

3. Volumes

  • Think of volumes as external hard drives
  • They keep your data even if containers are deleted
  • Both containers can access the same files

4. Environment Variables

  • Settings that configure the database
  • Like setting up a new user and database automatically

🔧 Troubleshooting Common Issues

Issue 1: Docker Compose Not Found

Error: docker-compose: command not found
Solution: Install Docker Compose (Step 3 above)

Issue 2: libcrypt.so.1 Error

Error: libcrypt.so.1: cannot open shared object file
Solution: yum install -y libxcrypt-compat

Issue 3: Permission Denied

Error: Permission denied while trying to connect to the Docker daemon
Solution: Add user to docker group:

usermod -aG docker steve
newgrp docker
Enter fullscreen mode Exit fullscreen mode

Issue 4: Port Already in Use

Error: port is already allocated
Solution: Change the host port in the YAML file or stop the other service


📊 Quick Reference: Docker Compose Commands

Command Description
docker-compose up -d Start containers in background
docker-compose down Stop and remove containers
docker-compose ps List running containers
docker-compose logs View container logs
docker-compose logs web View logs for web service
docker-compose restart Restart containers
docker-compose exec web bash Get shell inside web container

✅ Summary

Today we learned:

  1. What is Docker Compose – A tool to manage multiple containers
  2. How to write a docker-compose.yml – Define services, ports, volumes
  3. How to deploy – One command to start everything
  4. How to verify – Check containers and test the application

Quick Command Summary

# Create directory
mkdir -p /opt/data && cd /opt/data

# Create compose file
vi docker-compose.yml

# Start everything
docker-compose up -d

# Check status
docker-compose ps

# Test
curl http://localhost:6200
Enter fullscreen mode Exit fullscreen mode

Top comments (0)