Skip to main content

Command Palette

Search for a command to run...

Day 8: Deploying with GitLab CI/CD & Docker Compose (WordPress + MySQL Stack)

Updated
β€’3 min read
Day 8: Deploying with GitLab CI/CD & Docker Compose (WordPress + MySQL Stack)

In today's blog, we automate deploying a WordPress and MySQL stack using Docker Compose through GitLab CI/CD. Additionally, we’ll discuss an important issue if you later switch WordPress to run on port 80.


πŸ“œ Docker Compose File β€” docker-compose.yaml

Here’s the stack configuration:

version: '3.8'

services:
  wordpress:
    image: wordpress
    restart: always
    ports:
      - 8080:80  # WordPress runs on port 8080
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - wordpress:/var/www/html

  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - db:/var/lib/mysql

volumes:
  wordpress:
  db:

βœ… Access WordPress: http://<YOUR_VM_IP>:8080


πŸ€– GitLab CI/CD Pipeline β€” .gitlab-ci.yml

stages:
  - deploy

deploy-job:
  stage: deploy
  image: alpine:latest

  before_script:
    - apk add --no-cache openssh sshpass

  script:
    - sshpass -p "$DOCKER_VM_PASSWORD" scp -o StrictHostKeyChecking=no docker-compose.yaml ${DOCKER_VM_USERNAME}@${DOCKER_VM_IP_ADDRESS}:/${DOCKER_VM_USERNAME}/docker-compose.yaml
    - sshpass -p "$DOCKER_VM_PASSWORD" ssh -o StrictHostKeyChecking=no ${DOCKER_VM_USERNAME}@${DOCKER_VM_IP_ADDRESS} "
        cd /${DOCKER_VM_USERNAME} && 
        docker compose -f docker-compose.yaml down &&
        docker compose -f docker-compose.yaml up -d
      "

  tags:
    - microk8s

βœ… Environment Variables Needed:

Variable NameDescription
DOCKER_VM_IP_ADDRESSRemote Docker server's IP
DOCKER_VM_USERNAMESSH username
DOCKER_VM_PASSWORDSSH password

⚠ Running WordPress on Port 80 - Beware of Redirection Issues

If you decide to change 8080:80 to 80:80 in your docker-compose.yaml to run WordPress on port 80, you might face a redirection issue.


❌ Reason for the Redirection

WordPress stores the site URL (with the port) in the database when it's first installed. For example, if you ran it on:

http://68.183.86.22:8080

WordPress stores this URL inside the wp_options table (fields: siteurl and home). So, when you shift to port 80, WordPress still tries to redirect to the old port.


πŸ” How to Check Stored URL in WordPress

  1. Connect to the MySQL container:
docker exec -it <db-container-name> mysql -u exampleuser -pexamplepass

Example:

docker exec -it root-db-1 mysql -u exampleuser -pexamplepass
  1. Run these SQL commands:
USE exampledb;
SELECT option_name, option_value FROM wp_options WHERE option_name IN ('siteurl', 'home');

You’ll likely see:

http://68.183.86.22:8080

βœ… How to Fix the Redirect

Update the siteurl and home directly in the database:

UPDATE wp_options SET option_value = 'http://68.183.86.22' WHERE option_name = 'siteurl';
UPDATE wp_options SET option_value = 'http://68.183.86.22' WHERE option_name = 'home';

docker restart <wordpress-container-name>

Example:

docker restart root-wordpress-1

🌐 Final Step:

  • Clear browser cache or try incognito mode.

  • Access your WordPress on:

http://68.183.86.22

🎯 Summary

βœ… GitLab CI/CD deploys your WordPress stack automatically
βœ… Docker Compose makes multi-container deployment simple
βœ… WordPress stores its base URL on first install
βœ… Update the database if you change the port later

More from this blog

DevOps Journey with M Hassan

174 posts

I am writing these blogs because I recently completed a comprehensive DevOps course where I gained in-depth knowledge of the topics mentioned. As I progressed through the course, I realized the importance of having a concise and accessible resource to revise and reinforce my understanding of each topic. Therefore, I decided to create cheat sheets in the form of blog posts. These cheat sheets will not only serve as a handy reference for myself but also benefit others who are also interested in mastering DevOps concepts. By documenting each topic and providing concise explanations, I aim to create a valuable resource that simplifies complex concepts and facilitates hands-on practice. This way, I can solidify my own understanding while helping others on their DevOps journey.