Practices and Pitfalls of Dockerizing Enterprise Applications — From Traditional Virtualization to Containerization

Introduction (Why Containerize Enterprise Applications)

In the era of cloud computing, the way enterprise applications are deployed and managed is undergoing a profound transformation. While traditional virtualization technology solved the resource isolation problem, it still has many pain points in terms of operational efficiency, resource utilization, and deployment speed. The rise of Docker container technology has provided a brand-new solution for the modernization of enterprise applications.

This article shares our practical experience in the containerization migration of an enterprise email system, including technology selection, infrastructure construction, the full process of migrating from OpenVZ virtualization to Docker, and various issues encountered in production along with their solutions. Through these practical cases, we hope to provide valuable reference for teams that are currently or planning to undertake containerization migration.

Core value brought by containerization:

  • Improved resource utilization: Compared to traditional VMs, containers share the kernel, significantly improving resource utilization
  • Faster deployment: Image standardization enables rapid application replication and deployment
  • Environmental consistency: Development, testing, and production environments are highly consistent, eliminating the “works on my machine” problem
  • Simplified operations: Standardized operational procedures reduce operational complexity
  • Elastic scaling: Rapid response to business changes, enabling elastic scaling

Docker Storage Driver Selection: overlay vs overlay2

Before containerized deployment, the choice of storage driver is a critical decision. Docker supports multiple storage drivers, among which overlay and overlay2 are the two most commonly used options.

Storage Driver Comparison

OverlayFS is a union file system that allows multiple file systems to be layered together, forming a unified view. In the Docker environment:

OverlayFS (Overlay)

  • Advantages: Earlier version support, better compatibility
  • Disadvantages: Poor performance when handling a large number of small files, does not support certain advanced features
  • Use cases: Earlier versions of Docker, scenarios with low performance requirements

OverlayFS (Overlay2)

  • Advantages: Better performance, support for more advanced features such as metadata copying
  • Disadvantages: Requires newer kernel version support
  • Use cases: Production environments, scenarios with high performance requirements

Practical Selection

In our practice, after performance testing and evaluation, we ultimately chose overlay2 as the primary storage driver:

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Check current storage driver
docker info | grep "Storage Driver"

# Modify Docker configuration to use overlay2
# Edit /etc/docker/daemon.json
{
  "storage-driver": "overlay2"
}

# Restart Docker service
systemctl restart docker

Main reasons for choosing overlay2:

  1. Performance advantage: Especially when handling a large number of small files in the enterprise email system, overlay2 performs significantly better than overlay
  2. Feature completeness: Supports more advanced features, providing a foundation for future feature expansion
  3. Community support: overlay2 is the mainstream choice recommended by the community, with rich documentation and case studies
  4. Future compatibility: Aligns with Docker’s technology development trends

Building the Base Docker Image

Containerized deployment of the enterprise email system first requires building a stable, secure base Docker image. This process involves base environment selection, system configuration optimization, security hardening, and more.

CentOS Base Environment

We chose CentOS 6 as the base image, primarily considering the following factors:

  • Compatibility: Core components of the enterprise email system have good compatibility with CentOS 6
  • Stability: CentOS 6 has undergone long-term production environment validation, ensuring stability
  • Community support: Rich documentation and community support

Dockerfile Base Structure

dockerfile
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Base image selection
FROM centos:6

# Maintainer information (redacted)
MAINTAINER Technical Team <[email protected]>

# Working directory setup
WORKDIR /opt/app

# System environment configuration
RUN yum update -y && \
    yum install -y \
    wget \
    curl \
    tar \
    gzip \
    unzip \
    which && \
    yum clean all

# Create necessary users and directories
RUN groupadd -r app && \
    useradd -r -g app -d /opt/app app && \
    mkdir -p /opt/app && \
    chown -R app:app /opt/app && \
    chmod 755 /opt/app

Timezone and Character Set Configuration

Enterprise email systems handle global user data, making correct timezone and character set configuration critical.

Timezone Configuration

dockerfile
1
2
3
# Set system timezone to Asia/Shanghai
RUN cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo 'Asia/Shanghai' > /etc/timezone

Character Set Configuration

dockerfile
1
2
3
4
5
6
7
# Set Chinese character set support
RUN localedef -i zh_CN -f UTF-8 zh_CN.UTF-8

# Set environment variables
ENV LC_ALL=zh_CN.UTF-8
ENV LANG=zh_CN.UTF-8
ENV LANGUAGE=zh_CN.UTF-8

Complete Environment Configuration

dockerfile
1
2
3
4
5
# Set key environment variables
ENV APP_HOME=/opt/app/
ENV JAVA_HOME=/opt/app/java/jre
ENV TOMCAT_HOME=/opt/app/java/tomcat
ENV PATH=$PATH:/opt/app/bin:/opt/app/sbin

Security Hardening

The security of the base image directly affects the security of the entire containerization solution. We performed security hardening in the following areas:

dockerfile
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# Remove unnecessary users and groups
RUN for user in $(cat /etc/passwd | cut -d: -f1 | grep -v root | grep -v app); do \
        userdel $user; 
    done && \
    for group in $(cat /etc/group | cut -d: -f1 | grep -v root | grep -v app); do \
        groupdel $group; 
    done

# Disable unnecessary services
RUN chkconfig --level 12345 telnet off && \
    chkconfig --level 12345 rsh off && \
    chkconfig --level 12345 rlogin off

# Set file permissions
RUN chmod 644 /etc/passwd /etc/group /etc/shadow /etc/gshadow && \
    chmod 600 /etc/shadow && \
    chmod 600 /etc/gshadow

Migrating from OpenVZ Virtualization to Docker

Migrating the enterprise email system from OpenVZ virtualization to Docker containers is a complex process involving data migration, environment adaptation, configuration conversion, and more. The following details the entire migration process.

Migration Flowchart

mermaid
flowchart TD
    A@{ shape: rounded, label: "Pre-migration Preparation" } --> B@{ shape: rounded, label: "Data Backup" }
    B --> C@{ shape: rounded, label: "Environment Analysis" }
    C --> D@{ shape: rounded, label: "Docker Image Build" }
    D --> E@{ shape: rounded, label: "Application Deployment Testing" }
    E --> F@{ shape: rounded, label: "Production Migration" }
    F --> G@{ shape: rounded, label: "Validation & Optimization" }
    
    A --> A1@{ shape: rounded, label: "Hardware Resource Assessment" }
    A --> A2@{ shape: rounded, label: "Network Planning" }
    A --> A3@{ shape: rounded, label: "Storage Planning" }
    
    B --> B1@{ shape: cyl, label: "Database Backup" }
    B --> B2@{ shape: doc, label: "Config File Backup" }
    B --> B3@{ shape: doc, label: "Data File Backup" }
    
    C --> C1@{ shape: rounded, label: "Dependency Analysis" }
    C --> C2@{ shape: rounded, label: "Port Mapping Planning" }
    C --> C3@{ shape: rounded, label: "Storage Requirements Assessment" }
    
    D --> D1@{ shape: rounded, label: "Base Image Selection" }
    D --> D2@{ shape: doc, label: "Dockerfile Authoring" }
    D --> D3@{ shape: rounded, label: "Image Build Testing" }
    
    E --> E1@{ shape: rounded, label: "Functional Testing" }
    E --> E2@{ shape: rounded, label: "Performance Testing" }
    E --> E3@{ shape: rounded, label: "Security Testing" }
    
    F --> F1@{ shape: rounded, label: "Canary Release" }
    F --> F2@{ shape: rounded, label: "Full Migration" }
    
    G --> G1@{ shape: rounded, label: "Performance Monitoring" }
    G --> G2@{ shape: rounded, label: "Issue Investigation" }
    G --> G3@{ shape: rounded, label: "Continuous Optimization" }
    
    classDef primary fill:#e3f2fd,stroke:#1976d2
    classDef storage fill:#e8f5e9,stroke:#4caf50
    classDef doc fill:#fff8e1,stroke:#ffa000
    classDef process fill:#f3e5f5,stroke:#9c27b0
    class A,B,C,D,E,F,G,A1,A2,A3,C1,C2,C3,D1,D3,E1,E2,E3,F1,F2,G1,G2,G3 primary
    class B1 storage
    class B2,B3,D2 doc

Database Export and Import

The database is the core of the enterprise email system, and the integrity and security of data migration are paramount.

Database Backup Script

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/bash
# Database backup function
BACKUP_MYSQL_DATA(){
    # Find MySQL configuration file
    if [[ -f /opt/app/bin/mysql_cm ]];then
        mysqlpwd=$(awk '/mysql/ {print $3}' /opt/app/bin/mysql_cm)
    elif [[ -f /opt/app/conf/datasources.cf ]];then
        mysqlpwd="-p$(cat /opt/app/conf/datasources.cf |awk -F'"' '/Password/ {print $2}'|head -n1)"
    else
        echo "Error: MySQL configuration file not found" >&2
        exit 1
    fi
    
    # Backup main database
    /opt/app/mysql/bin/mysqldump -uapp ${mysqlpwd} -h127.0.0.1 -P3308 \
        --opt --hex-blob cmxt > ${MyBackup}/cmxt_$(date +%Y%m%d).sql
    
    # Backup log database (schema only)
    /opt/app/mysql/bin/mysqldump -uapp ${mysqlpwd} -h127.0.0.1 -P3308 \
        --opt -d cmxt_log > ${MyBackup}/cmxt_log_$(date +%Y%m%d).sql
}

# Configuration file backup
cd /home/ && \
    sudo tar zcvf ${MyBackup}/app_conf_$(date +%Y%m%d).tar.gz \
        app/conf app/var/mainconfig

Database Restore Script

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/bin/bash
# Database restore function
RESTORE_MYSQL_DATA(){
    # Stop related services
    /opt/app/bin/appctl stop all
    
    # Restore main database
    /opt/app/mysql/bin/mysql -uapp -p${mysqlpwd} -h127.0.0.1 -P3308 cmxt < ${MyBackup}/cmxt_$(date +%Y%m%d).sql
    
    # Restore log database schema
    /opt/app/mysql/bin/mysql -uapp -p${mysqlpwd} -h127.0.0.1 -P3308 cmxt_log < ${MyBackup}/cmxt_log_$(date +%Y%m%d).sql
    
    # Start services
    /opt/app/bin/appctl start all
}

Writing the Dockerfile

The Dockerfile is the core of containerized builds, requiring comprehensive consideration of the base environment, dependency installation, configuration optimization, and more.

Complete Dockerfile Example

dockerfile
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# Base image
FROM centos:6

# Maintainer information
MAINTAINER Technical Team <[email protected]>

# Set timezone and character set
RUN cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    localedef -i zh_CN -f UTF-8 zh_CN.UTF-8

# Install base dependencies
RUN yum update -y && \
    yum reinstall glibc-common -y && \
    yum install -y \
    wget \
    curl \
    tar \
    gzip \
    unzip \
    which \
    && yum clean all

# Create user and working directory
RUN useradd -r -g app -d /opt/app app && \
    mkdir -p /opt/app && \
    chown -R app:app /opt/app && \
    chmod 755 /opt/app

# Set working directory
WORKDIR /opt/app

# Environment variables
ENV LC_ALL=zh_CN.UTF-8
ENV APP_HOME=/opt/app/
ENV JAVA_HOME=/opt/app/java/jre
ENV TOMCAT_HOME=/opt/app/java/tomcat

# Copy enterprise email system program (assumed to be already processed)
COPY app /opt/app/

# Set file permissions
RUN chown -R app.app /opt/app && \
    chmod 755 /opt/app

# Expose ports
EXPOSE 80 443 9900 25 465 8025 994 110 993 995 143

# Startup command
CMD ["/opt/app/bin/appctl", "start", "all"]

Optimized Dockerfile (Single-layer Build)

To control image size, we adopted a single-layer build approach:

dockerfile
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# Base image
FROM centos:6

# Maintainer information
MAINTAINER Technical Team <[email protected]>

# Complete all system configuration in one step
RUN cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    localedef -i zh_CN -f UTF-8 zh_CN.UTF-8 && \
    yum update -y && \
    yum reinstall glibc-common -y && \
    yum install -y \
    wget \
    curl \
    tar \
    gzip \
    unzip \
    which \
    && yum clean all && \
    useradd -r -g app -d /opt/app app && \
    mkdir -p /opt/app && \
    chown -R app:app /opt/app && \
    chmod 755 /opt/app

# Set working directory and environment variables
WORKDIR /opt/app
ENV LC_ALL=zh_CN.UTF-8
ENV APP_HOME=/opt/app/
ENV JAVA_HOME=/opt/app/java/jre
ENV TOMCAT_HOME=/opt/app/java/tomcat

# Copy enterprise email system program
COPY app /opt/app/

# Set file permissions
RUN chown -R app.app /opt/app && \
    chmod 755 /opt/app

# Expose ports
EXPOSE 80 443 9900 25 465 8025 994 110 993 995 143

# Startup command
CMD ["/opt/app/bin/appctl", "start", "all"]

Port Mapping and Networking

The enterprise email system involves multiple service ports. Proper planning of port mapping and network configuration is key to successful containerization.

Port Mapping Plan

Service TypePortProtocolDescription
HTTP80TCPWeb service
HTTPS443TCPWeb service
SMTP25TCPEmail sending
SMTPS465TCPEmail sending (SSL)
Submissions587TCPEmail sending (STARTTLS)
POP3110TCPEmail receiving
POP3S995TCPEmail receiving (SSL)
IMAP143TCPEmail receiving
IMAPS993TCPEmail receiving (SSL)
HTTP Proxy8025TCPHTTP proxy service
Admin Interface9900TCPWeb admin interface

Docker Network Configuration

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Create custom network
docker network create --driver bridge app-network

# Start container with specified network
docker run -d \
    --name app-server \
    --network app-network \
    -p 80:80 \
    -p 443:443 \
    -p 25:25 \
    -p 465:465 \
    -p 587:587 \
    -p 110:110 \
    -p 995:995 \
    -p 143:143 \
    -p 993:993 \
    -p 8025:8025 \
    -p 9900:9900 \
    -v /opt/app/conf:/opt/app/conf \
    -v /opt/app/logs:/opt/app/logs \
    -v /opt/app/data:/opt/app/data \
    app/as6-64bit-app

Advanced Network Configuration

For complex deployment environments, we can use Docker Compose to manage multi-container applications:

yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
version: '3.8'
services:
  app-server:
    image: app/as6-64bit-app
    container_name: app-server
    networks:
      - app-network
    ports:
      - "80:80"
      - "443:443"
      - "25:25"
      - "465:465"
      - "587:587"
      - "110:110"
      - "995:995"
      - "143:143"
      - "993:993"
      - "8025:8025"
      - "9900:9900"
    volumes:
      - /opt/app/conf:/opt/app/conf
      - /opt/app/logs:/opt/app/logs
      - /opt/app/data:/opt/app/data
    restart: unless-stopped
    environment:
      - TZ=Asia/Shanghai

  nginx-proxy:
    image: nginx:alpine
    container_name: nginx-proxy
    networks:
      - app-network
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /opt/app/conf/nginx.conf:/etc/nginx/nginx.conf
      - /opt/app/conf/ssl:/etc/nginx/ssl
    restart: unless-stopped

networks:
  app-network:
    driver: bridge

Production Environment Dockerization Pitfall Record

During the migration from the test environment to production, we encountered various unexpected issues. Here we share some key pitfalls and their solutions.

Issue 1: Data Persistence and Data Loss

Symptoms

After container restart, the enterprise email system’s data was lost, and users could not use the email service normally.

Analysis

  • Data files are stored inside the container by default, and data is lost when the container is deleted
  • No volume or bind mount was used for persistence
  • Docker containers are stateless by default

Solution

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# Use volumes for persistence
docker run -d \
    --name app-prod \
    -v /opt/app/data:/opt/app/data \
    -v /opt/app/conf:/opt/app/conf \
    -v /opt/app/logs:/opt/app/logs \
    app/as6-64bit-app

# Or use Docker managed volumes
docker volume create app-data
docker run -d \
    --name app-prod \
    -v app-data:/opt/app/data \
    -v app-conf:/opt/app/conf \
    -v app-logs:/opt/app/logs \
    app/as6-64bit-app

Best Practices

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# Recommended production configuration
docker run -d \
    --name app-prod \
    --restart=unless-stopped \
    --memory=8g \
    --cpus=4 \
    -v /opt/app/data:/opt/app/data \
    -v /opt/app/conf:/opt/app/conf \
    -v /opt/app/logs:/opt/app/logs \
    -v /opt/app/ssl:/opt/app/ssl \
    --log-opt max-size=100m \
    --log-opt max-file=3 \
    app/as6-64bit-app

Issue 2: Network Connection Problems

Symptoms

After container startup, external access to the enterprise email system’s various ports was not possible, and inter-service communication within the container also failed.

Analysis

  • Port mapping configuration errors
  • Firewall rules blocking
  • Docker network configuration issues
  • SELinux policy restrictions

Solution

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# 1. Check port mapping
docker port app-prod

# 2. Check firewall
firewall-cmd --list-ports
firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --add-port=443/tcp --permanent
firewall-cmd --add-port=25/tcp --permanent
firewall-cmd --add-port=465/tcp --permanent
firewall-cmd --reload

# 3. Check SELinux
getenforce
setenforce 0  # Temporarily disable
# Or configure SELinux policy
semanage port -a -t http_port_t -p tcp 80
semanage port -a -t https_port_t -p tcp 443

# 4. Check Docker network
docker network ls
docker network inspect app-network

Network Connectivity Testing

bash
1
2
3
4
5
6
7
8
# Test in-container network
docker exec app-prod ping 127.0.0.1
docker exec app-prod telnet localhost 80
docker exec app-prod telnet localhost 443

# Test inter-container communication
docker exec nginx-proxy ping app-prod
docker exec nginx-proxy telnet app-prod 25

Issue 3: Improper Resource Management

Symptoms

After the system ran for a while, container resource usage became too high, leading to degraded system performance and slow email service response.

Analysis

  • No memory limits set
  • CPU usage too high
  • Disk I/O bottleneck
  • Log files growing indefinitely

Solution

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# 1. Limit container resources
docker run -d \
    --name app-prod \
    --memory=8g \
    --memory-swap=10g \
    --cpus=4 \
    --cpuset-cpus=0-3 \
    app/as6-64bit-app

# 2. Set log rotation
docker run -d \
    --name app-prod \
    --log-opt max-size=100m \
    --log-opt max-file=3 \
    app/as6-64bit-app

# 3. Monitor resource usage
docker stats
docker top app-prod

Resource Monitoring Script

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/bin/bash
# Monitor container resource usage
echo "Container resource usage:"
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"

echo ""
echo "Container disk usage:"
docker system df

echo ""
echo "Container log size:"
docker logs app-prod --tail 1000 | wc -l

Issue 4: Complex Configuration Management

Symptoms

Configuration management across multiple environments (development, testing, production) was chaotic, configuration changes were difficult and error-prone.

Analysis

  • Configuration files placed directly inside containers
  • Different environment configurations mixed together
  • Configuration changes required rebuilding images
  • Lack of configuration version management

Solution

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 1. Use configuration file mapping
docker run -d \
    --name app-prod \
    -v /opt/app/config/prod.conf:/opt/app/conf/config.cf \
    app/as6-64bit-app

# 2. Use environment variables
docker run -d \
    --name app-prod \
    -e APP_DOMAIN=example.com \
    -e APP_ADMIN=[email protected] \
    -e APP_PASSWORD=secure_password \
    app/as6-64bit-app

# 3. Use configuration management tools
# Using Ansible to manage Docker configuration
---
- name: Configure App
  hosts: app_servers
  become: yes
  vars:
    app_config:
      domain: "example.com"
      admin_email: "[email protected]"
      max_users: 1000
  
  tasks:
    - name: Create config directory
      file:
        path: /opt/app/config
        state: directory
        mode: '0755'
    
    - name: Generate config file
      template:
        src: app_config.j2
        dest: /opt/app/config/prod.conf
    
    - name: Restart App container
      docker:
        name: app-prod
        state: restarted

Issue 5: Backup and Recovery Strategy

Symptoms

When system failures occurred, services could not be quickly restored, severely impacting business continuity.

Analysis

  • Lack of a complete backup strategy
  • Chaotic backup data management
  • Unclear recovery procedures
  • Lack of regular drills

Solution

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 1. Automated backup script
#!/bin/bash
# Automated backup of enterprise email system
BACKUP_DIR="/backup/app"
DATE=$(date +%Y%m%d_%H%M%S)

# Create backup directory
mkdir -p $BACKUP_DIR

# Backup database
/opt/app/bin/appctl stop all
/opt/app/mysql/bin/mysqldump -uapp -p'password' \
    --opt --hex-blob cmxt > $BACKUP_DIR/cmxt_$DATE.sql
/opt/app/mysql/bin/mysqldump -uapp -p'password' \
    --opt -d cmxt_log > $BACKUP_DIR/cmxt_log_$DATE.sql

# Backup configuration files
tar zcvf $BACKUP_DIR/conf_$DATE.tar.gz \
    /opt/app/conf /opt/app/var/mainconfig

# Backup data files
tar zcvf $BACKUP_DIR/data_$DATE.tar.gz \
    /opt/app/data /opt/app/logs

# Start services
/opt/app/bin/appctl start all

# Clean up old backups (retain 30 days)
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete
find $BACKUP_DIR -name "*.sql" -mtime +30 -delete

Backup Verification Script

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash
# Verify backup integrity
BACKUP_DIR="/backup/app"
DATE=$(date +%Y%m%d_%H%M%S)

# Check database backup
if [ -f "$BACKUP_DIR/cmxt_$DATE.sql" ]; then
    mysql -uapp -p'password' cmxt < $BACKUP_DIR/cmxt_$DATE.sql
    echo "Database backup verification successful"
else
    echo "Database backup file does not exist"
fi

# Check configuration file backup
if [ -f "$BACKUP_DIR/conf_$DATE.tar.gz" ]; then
    tar -tzf $BACKUP_DIR/conf_$DATE.tar.gz > /dev/null
    echo "Configuration file backup verification successful"
else
    echo "Configuration file backup does not exist"
fi

Summary

Through this practice of migrating the enterprise email system from OpenVZ virtualization to Docker containers, we gained many valuable experiences and lessons. Containerization technology provides strong technical support for the modernization of enterprise applications, but it also brings new challenges.

Key Takeaways

  1. Importance of Technology Selection

    • Choosing overlay2 over overlay for storage driver significantly improved performance
    • Choosing CentOS 6 as the base image ensured compatibility
    • Network architecture design considered scalability and security
  2. Standardized Data Management

    • Established a complete backup and recovery strategy
    • Achieved persistent data storage
    • Configuration management achieved version control and environment isolation
  3. Optimized Operations Processes

    • Containerized deployment achieved rapid delivery
    • Monitoring and alerting systems were improved
    • Failure recovery time was significantly reduced
  4. Team Capability Enhancement

    • Mastered the containerization technology stack
    • Established standardized operations procedures
    • Improved troubleshooting and resolution capabilities

Technology Evolution Direction

  1. Container Orchestration

    • Current single-container deployment model will evolve toward Kubernetes orchestration
    • Achieve automated scaling and self-healing capabilities
    • Support microservices architecture transformation
  2. Monitoring System

    • Establish Prometheus + Grafana monitoring system
    • Achieve multi-dimensional performance monitoring and alerting
    • Support distributed tracing and link analysis
  3. Security Hardening

    • Implement container security scanning and baseline checks
    • Establish a complete audit logging system
    • Support zero-trust architecture security policies

Lessons Learned

  1. Take It Step by Step

    • Start with non-core services as pilots
    • Validate thoroughly before rolling out to core services
    • Maintain rollback mechanisms to ensure business safety
  2. Documentation First

    • Detailed operation manuals and contingency plans
    • Continuous maintenance and updates of technical documentation
    • Building and improving the team knowledge base
  3. Thorough Testing

    • Functional testing, performance testing, and security testing are all indispensable
    • Stress testing should cover extreme scenarios
    • Regression testing ensures quality stability
  4. Team Collaboration

    • Close collaboration among development, operations, and testing teams
    • Establish effective communication mechanisms
    • Knowledge sharing and skill training

Through this containerization migration practice, we not only successfully migrated the enterprise email system to the Docker platform, but more importantly, established a complete containerization operations system. This system is not only applicable to the email system but can also be extended to the containerization transformation of other enterprise applications.

Containerization technology is an important tool for enterprise digital transformation, but it is not a silver bullet. Only by combining business needs, choosing the right technical solutions, and establishing sound operations systems can we truly leverage the advantages of containerization technology to create greater value for the enterprise.


Author Profile: The technical team focuses on enterprise application containerization transformation, with rich practical experience in virtualization and cloud-native technologies, dedicated to improving the stability and maintainability of enterprise applications through technical means.