Ravindra BagaleCourses & study guides मराठी

Chapter 73: DevOps Projects Part 3: Docker Websites, APIs, Compose, Registry and ECR

73.8 Project 24: WordPress and MySQL with volumes and backups

Friends, WordPress is a common Compose lab. Today we run WordPress with MySQL, keep data in named volumes, prove the install page with curl, and learn a simple volume backup pattern.

What you will build in this project

  1. wordpress + mysql services.
  2. Named volumes for both.
  3. curl on port 8080.
  4. mysqladmin ping and backup tip.

1. Start from a real company story

At a Pune media startup, a marketing site ran WordPress in a container with no volume. A recreate wiped two weeks of blog drafts the night before a launch.

The team rebuilt posts by hand. Rough cost: about ₹4 lakh in overtime and delayed ads.

Ravi added named volumes and a nightly volume tar to S3.

Today we practice that WordPress Compose lab.

compose.yamlwp + mysqlvolumeswpdata dbdataup -dcurl :8080backup tarvolume safe
Picture 1: WordPress + MySQL + volumes

Ravindra Bagale's Tip

Many students delete volumes with compose down -v by habit. That flag wipes data. Use plain down unless you mean to erase. Keep that habit.

2. Start and prepare

Step 1: Write compose

Why: Compose holds WP+DB. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: services wordpress mysql. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 1: dir

Type this:

mkdir -p /tmp/wp && echo ready

You will see:

ready

What it means: Folder.

Example 2: compose

Type this:

printf '%s\n' 'services:' '  db:' '    image: mysql:8.0' '    environment:' '      MYSQL_DATABASE: wordpress' '      MYSQL_USER: wp' '      MYSQL_PASSWORD: wppass' '      MYSQL_ROOT_PASSWORD: rootpass' '    volumes: ["dbdata:/var/lib/mysql"]' '  wordpress:' '    image: wordpress:6.4-php8.2-apache' '    ports: ["8080:80"]' '    environment:' '      WORDPRESS_DB_HOST: db:3306' '      WORDPRESS_DB_USER: wp' '      WORDPRESS_DB_PASSWORD: wppass' '      WORDPRESS_DB_NAME: wordpress' '    volumes: ["wpdata:/var/www/html"]' '    depends_on: [db]' 'volumes:' '  dbdata:' '  wpdata:' > /tmp/wp/compose.yaml && wc -l /tmp/wp/compose.yaml

You will see:

24 /tmp/wp/compose.yaml

What it means: Compose.

Example 3: mode

Type this:

stat -c '%a' /tmp/wp/compose.yaml

You will see:

644

What it means: Safe.

Step 2: Set MySQL env

Why: DB needs user db password. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: MYSQL_* vars. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 4: db img

Type this:

grep mysql /tmp/wp/compose.yaml | head -1

You will see:

image: mysql:8.0

What it means: Pinned.

Example 5: user

Type this:

grep MYSQL_USER /tmp/wp/compose.yaml

You will see:

MYSQL_USER: wp

What it means: User.

Example 6: lab note

Type this:

echo 'Lab passwords only; never reuse in real life'

You will see:

Lab passwords only; never reuse in real life

What it means: Habit.

Step 3: Set WordPress env

Why: WP needs DB host. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: WORDPRESS_DB_*. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 7: host

Type this:

grep WORDPRESS_DB_HOST /tmp/wp/compose.yaml

You will see:

WORDPRESS_DB_HOST: db:3306

What it means: Service DNS.

Example 8: name

Type this:

grep WORDPRESS_DB_NAME /tmp/wp/compose.yaml

You will see:

WORDPRESS_DB_NAME: wordpress

What it means: DB name.

Example 9: img wp

Type this:

grep wordpress: /tmp/wp/compose.yaml | head -1

You will see:

image: wordpress:6.4-php8.2-apache

What it means: Pinned WP.

3. Build the main pieces

Step 4: Named volumes

Why: Volumes keep posts. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: volumes wpdata dbdata. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 10: vols

Type this:

grep -E 'dbdata|wpdata' /tmp/wp/compose.yaml | head -4

You will see:

volumes lines

What it means: Two volumes.

Example 11: why

Type this:

echo 'Without volumes, posts and themes vanish on recreate'

You will see:

Without volumes, posts and themes vanish on recreate

What it means: Reason.

Example 12: ls tip

Type this:

echo 'docker volume ls | grep -E dbdata|wpdata'

You will see:

docker volume ls | grep -E dbdata|wpdata

What it means: Later.

Step 5: Up the stack

Why: up starts both. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: compose up -d. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 13: up

Type this:

cd /tmp/wp && docker compose -f compose.yaml up -d

You will see:

... Started

What it means: Up.

Example 14: ps

Type this:

cd /tmp/wp && docker compose -f compose.yaml ps

You will see:

wordpress ... db ...

What it means: Two.

Example 15: vol

Type this:

docker volume ls | grep -E 'dbdata|wpdata' | wc -l

You will see:

2

What it means: Volumes.

Step 6: Wait healthy

Why: WP needs DB ready. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: sleep + curl. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 16: wait

Type this:

sleep 15; echo waited

You will see:

waited

What it means: MySQL init.

Example 17: ps2

Type this:

cd /tmp/wp && docker compose -f compose.yaml ps --format '{{.Name}} {{.Status}}'

You will see:

... Up ...

What it means: Up.

Example 18: logs db

Type this:

cd /tmp/wp && docker compose -f compose.yaml logs db --tail 2

You will see:

ready for connections

What it means: DB ready.

4. Automate and verify

Step 7: curl install page

Why: Browser path. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: curl :8080. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 19: curl

Type this:

curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8080/

You will see:

200

What it means: Install/UI.

Example 20: title

Type this:

curl -s http://127.0.0.1:8080/ | grep -oi wordpress | head -1

You will see:

WordPress

What it means: Body.

Example 21: port

Type this:

cd /tmp/wp && docker compose -f compose.yaml port wordpress 80

You will see:

0.0.0.0:8080

What it means: Mapped.

Step 8: DB exec

Why: mysql proves data. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: mysql -e. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 22: mysql

Type this:

cd /tmp/wp && docker compose -f compose.yaml exec -T db mysql -uwp -pwppass wordpress -e 'show tables;' 2>/dev/null | head || echo 'empty_or_init'

You will see:

empty_or_init

What it means: OK early.

Example 23: root ping

Type this:

cd /tmp/wp && docker compose -f compose.yaml exec -T db mysqladmin -uroot -prootpass ping

You will see:

mysqld is alive

What it means: Alive.

Example 24: dbs

Type this:

cd /tmp/wp && docker compose -f compose.yaml exec -T db mysql -uroot -prootpass -e 'show databases;' | grep wordpress

You will see:

wordpress

What it means: DB exists.

Step 9: Backup volume tip

Why: Backup before change. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: docker run --volumes-from or volume backup. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 25: backup tip

Type this:

echo 'Backup: docker run --rm -v wp_dbdata:/v -v /tmp:/out alpine tar czf /out/dbdata.tgz -C /v .'

You will see:

Backup: docker run --rm -v wp_dbdata:/v -v /tmp:/out alpine tar czf /out/dbdata.tgz -C /v .

What it means: Pattern.

Example 26: list vol

Type this:

docker volume ls --format '{{.Name}}' | grep dbdata

You will see:

...dbdata

What it means: Name for backup.

Example 27: note

Type this:

echo 'Schedule backups before plugins or upgrades'

You will see:

Schedule backups before plugins or upgrades

What it means: Ops.

5. Harden and accept

Step 10: Logs

Why: Logs show boot. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: compose logs. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 28: logs wp

Type this:

cd /tmp/wp && docker compose -f compose.yaml logs wordpress --tail 3

You will see:

Apache ...

What it means: Boot.

Example 29: follow

Type this:

echo 'docker compose logs -f wordpress'

You will see:

docker compose logs -f wordpress

What it means: Follow.

Example 30: env

Type this:

cd /tmp/wp && docker compose -f compose.yaml exec -T wordpress printenv WORDPRESS_DB_HOST

You will see:

db:3306

What it means: Host.

Step 11: Restart test

Why: Restart must keep data. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: compose restart. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 31: restart

Type this:

cd /tmp/wp && docker compose -f compose.yaml restart && sleep 5 && curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8080/

You will see:

200

What it means: Survived.

Example 32: vol still

Type this:

docker volume ls | grep -E 'dbdata|wpdata' | wc -l

You will see:

2

What it means: Volumes stay.

Example 33: ps

Type this:

cd /tmp/wp && docker compose -f compose.yaml ps -q | wc -l

You will see:

2

What it means: Two up.

Step 12: Acceptance checklist

Why: Ravi signs off when WP answers and volume survives. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: All green. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 34: http

Type this:

curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8080/

You will see:

200

What it means: Green.

Example 35: alive

Type this:

cd /tmp/wp && docker compose -f compose.yaml exec -T db mysqladmin -uroot -prootpass ping

You will see:

mysqld is alive

What it means: DB.

Example 36: Sign-off

Type this:

echo 'Ravi: PASS'

You will see:

Ravi: PASS

What it means: Done.

Check yourself

Q1. Who fixed the Pune media wipe?

Ravi

Q2. WP host port?

8080

Q3. DB image?

mysql:8.0

Q4. Dangerous compose flag?

down -v

Q5. DB host env?

db:3306

Q6. Backup tool idea?

tar a named volume

Friends, you ran WordPress with durable volumes. Did you understand? Let us try it once more. Take a volume backup tar and restore it into a fresh stack.

Lab: try at home

  1. Write compose with WP and MySQL.
  2. Up and wait for DB.
  3. curl the UI.
  4. mysqladmin ping.
  5. Practice the volume backup command.

Recap

  • WORDPRESS_DB_HOST uses service DNS.
  • Named volumes keep posts.
  • down -v deletes data.
  • Lab passwords are not for production.
  • Backup before upgrades.