GigHive bee gighive

Docker Compose Deployment Behavior Analysis

Date

October 25, 2025

Problem Statement

The Ansible community.docker.docker_compose_v2 task with “gentle” approach (state: present, build: always, recreate: always) was not reliably rebuilding containers when code changes were made.

Observed Issue

Root Cause Analysis

Manual Script (Working)

docker-compose down -v     # Nuclear: Complete removal
docker-compose build       # Explicit build step
docker-compose up -d       # Clean startup

Ansible Task (Failing)

community.docker.docker_compose_v2:
  state: present            # Gentle: Try to maintain state
  build: always
  recreate: always
  build_args: ["--no-cache"]

Why Gentle Approach Fails

1. State Management Conflicts

2. Volume Persistence

3. Build Order Dependencies

4. Image Caching Issues

Deployment Scenarios

Scenario 1: Initial Deployment

Scenario 2: Code Updates

Scenario 3: Configuration Changes

Scenario 4: Regular Restarts

Solution: Selective Container Rebuild Approach

Problem with Full Nuclear Approach

The initial “always nuclear” approach (state: absent) had a critical flaw:

Refined Strategy: Container-Specific Rebuild

# Step 1: Stop only Apache container (preserve MySQL)
- name: Stop Apache container for rebuild
  community.docker.docker_container:
    name: apacheWebServer
    state: absent
  ignore_errors: true

# Step 2: Conditionally stop MySQL (when either flag is true)
- name: Stop MySQL container for rebuild (when requested)
  community.docker.docker_container:
    name: mysqlServer
    state: absent
  when: rebuild_mysql | default(false) or rebuild_mysql_data | default(false)
  ignore_errors: true

# Step 3: Remove MySQL volume for nuclear rebuild (when requested)
- name: Remove MySQL volume for complete rebuild (when requested)
  community.docker.docker_volume:
    name: "files_mysql_data"
    state: absent
  when: rebuild_mysql_data | default(false)
  ignore_errors: true

# Step 4: Remove Apache image to force rebuild
- name: Remove Apache image to force rebuild
  community.docker.docker_image:
    name: ubuntu22.04apache-img:1.00
    state: absent
  ignore_errors: true

# Step 5: Start full stack
- name: Start Docker Compose stack
  community.docker.docker_compose_v2:
    project_src: ""
    state: present
    build: always

Configuration Control

In group_vars/gighive.yml:

rebuild_mysql: false       # Rebuild MySQL container (preserve data)
rebuild_mysql_data: false  # Rebuild MySQL container + wipe database (nuclear)

Command-line usage:

# Default: Apache only
ansible-playbook site.yml

# MySQL container rebuild (data preserved)
ansible-playbook site.yml -e "rebuild_mysql=true"

# MySQL nuclear rebuild (data wiped, CSV reimported)
ansible-playbook site.yml -e "rebuild_mysql_data=true"

Task conditions:

# MySQL container stop
when: rebuild_mysql | default(false) or rebuild_mysql_data | default(false)

# MySQL volume removal  
when: rebuild_mysql_data | default(false)

Flag Hierarchy and Logic

Important: rebuild_mysql_data: true is self-sufficient and implies container rebuild:

You do NOT need both flags set to true. The logic works as follows:

# Container stop condition
rebuild_mysql: false + rebuild_mysql_data: true  
# Result: false OR true = TRUE (container stops)

# Volume removal condition  
rebuild_mysql_data: true
# Result: TRUE (volume removed)

Benefits of Selective Container Approach

Safety

Flexibility

Reliability

Deployment Scenarios Handled

Scenario 1: Routine Application Updates (90% of cases)

Scenario 2: MySQL Container Updates

Scenario 3: MySQL Nuclear Rebuild

Scenario 4: Fresh VM Deployment

Scenario 5: Manual Nuclear Option

Trade-offs

Pros

Cons

Decision Rationale

Why Selective Container Over Full Nuclear

  1. Database Safety: Preserving customer data is paramount
  2. Production Readiness: Appropriate for live systems with valuable data
  3. Flexibility: Can handle both routine updates and major changes
  4. Performance: MySQL doesn’t restart unnecessarily

Why Selective Container Over Gentle

  1. Reliability: Apache always rebuilds with latest code changes
  2. Predictability: Consistent behavior across deployment scenarios
  3. Debugging: Clear understanding of what gets rebuilt
  4. Proven Pattern: Matches successful manual rebuild workflow

Configuration Design

Implementation Impact

Files Modified

Variable Resolution

Deployment Changes

Operational Benefits

Validation Criteria

Success Metrics

  1. File timestamps match between VM host and container after deployment
  2. Code changes always reflected in running containers
  3. Initial deployments work on clean systems
  4. Configuration changes properly applied

Test Cases

  1. Initial deployment on clean VM
  2. Code update deployment (MediaController.php changes)
  3. Configuration-only changes (environment variables)
  4. No-change redeployment (should still work)

This change supports the Database Viewer Implementation Plan Phase 1:

Future Considerations

Monitoring

Optimization Opportunities