Skip to main content

Command Palette

Search for a command to run...

🐳 Docker & Docker Compose: A Beginner’s Guide with WordPress & Laravel Examples

Updated
5 min read
🐳 Docker & Docker Compose: A Beginner’s Guide with WordPress & Laravel Examples
J

Hello! I'm a software developer with over 6 years of experience, specializing in React and WordPress plugin development. My passion lies in crafting seamless, user-friendly web applications that not only meet but exceed client expectations. I thrive on solving complex problems and am always eager to embrace new challenges. Whether it's building robust WordPress plugins or dynamic React applications, I bring a blend of creativity and technical expertise to every project.

Introduction

Docker simplifies application deployment by packaging software into containers—lightweight, isolated environments. This guide covers:

  1. Docker Basics → Images, Containers, Volumes, Networks

  2. Dockerfile → Building Custom Images

  3. Docker Compose → Managing Multi-Container Apps

  4. Hands-on Projects → WordPress & Laravel with MySQL

Docker Core Concepts Explained Clearly

🔹 Images vs. Containers

What's the Difference?

  • Image → A blueprint (like a .iso file for an OS).

    • Contains code, runtime, libraries, but cannot run by itself.

    • Example: nginx:alpine, mysql:8.0.

  • Container → A running instance of an image (like a live OS from an ISO).

    • Isolated, lightweight, and ephemeral (deleted when stopped unless using volumes).

When to Use Them?

  • Use images to define your app’s environment (via Dockerfile).

  • Use containers to actually run your app (via docker run or docker-compose up).


🔹 Volumes (Persistent Storage)

What is a Volume?

  • A way to store data outside containers so it persists even if the container is deleted.

  • Solves the problem of losing data (e.g., databases, uploaded files) when containers restart.

How Do Volumes Work?

  1. Creation → Volumes are created when:

    • You run docker volume create my_volume (manually).

    • Or when Docker Compose starts (volumes: section in docker-compose.yml).

  2. Data Transfer

    • When you mount a volume (-v my_volume:/path/in/container), Docker:

      • If the volume is new → Copies data from the container to the volume.

      • If the volume exists → Overwrites the container’s directory with the volume’s data.

  3. Accessing Data from Host

    • Named volumes (e.g., mysql_data) are stored in Docker’s storage directory:

      • Linux: /var/lib/docker/volumes/

      • Mac/Windows: Managed by Docker Desktop (not directly accessible by default).

    • Bind mounts (e.g., -v ./host_folder:/container_folder) let you directly edit files on your host.

When to Use Volumes?

Databases (MySQL, PostgreSQL) → Avoid losing data.
Uploaded files (WordPress media, Laravel storage).
Configuration files (e.g., Nginx configs).

Can I Access Data After docker-compose down?

Yes! Volumes persist unless explicitly deleted (docker volume rm or docker-compose down -v).


🔹 Networks (Container Communication)

What is a Docker Network?

  • A virtual network that lets containers talk to each other securely.

  • Solves the problem of isolated containers (they can’t communicate by default).

How Do Networks Work?

  1. Default Networks

    • bridge → Default network for standalone containers.

    • host → Shares the host’s network (rarely used).

  2. User-Defined Networks

    • Created via docker network create my_network.

    • Containers on the same network can:

      • Communicate using service names (e.g., db:3306).

      • Avoid port conflicts.

When to Use Networks?

Multi-container apps (e.g., Laravel + MySQL).
Microservices (frontend + backend containers).
Security → Isolate containers from the host.


🔹 Ports in Docker Compose (ports:)

Syntax: HOST_PORT:CONTAINER_PORT

services:
  web:
    ports:
      - "8000:80"  # Host:8000 → Container:80
  • Host port (8000) → The port on your local machine (http://localhost:8000).

  • Container port (80) → The port the app inside the container listens on.

When to Use Ports?

Exposing web servers (Nginx, Apache).
Accessing databases (e.g., 3306:3306 for MySQL).


🔹 Key Takeaways

  1. Images = Templates | Containers = Running instances.

  2. Volumes → Persist data (even after docker-compose down).

  3. Networks → Let containers communicate (e.g., app → db).

  4. PortsHOST:CONTAINER mapping (access apps from your machine).

Writing a Perfect Dockerfile

A Dockerfile defines how to build an image.

Example: Laravel Dockerfile

# Base image
FROM php:8.2-fpm

# Install dependencies
RUN apt-get update && apt-get install -y \
    git \
    zip \
    libzip-dev \
    && docker-php-ext-install pdo_mysql zip

# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Set working directory
WORKDIR /var/www/html

# Copy files
COPY . .

# Install PHP dependencies
RUN composer install

Key Directives:

  • FROM → Base image.

  • RUN → Executes commands.

  • COPY → Adds files.

  • WORKDIR → Sets the working directory.

Docker Compose for Multi-Container Apps

docker-compose.yml manages multiple services (e.g., app + database).

Example: WordPress + MySQL

version: '3.8'

services:
  db:
    image: mysql:5.7
    volumes:
      - mysql_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: wordpress
    networks:
      - app_network

  wordpress:
    image: wordpress:latest
    ports:
      - "8000:80"
    volumes:
      - wordpress_data:/var/www/html
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: root
      WORDPRESS_DB_PASSWORD: root
    networks:
      - app_network
    depends_on:
      - db

volumes:
  mysql_data:
  wordpress_data:

networks:
  app_network:
    driver: bridge

Key Sections:

  • services → Defines containers (e.g., db, wordpress).

  • volumes → Persistent storage.

  • networks → Connects containers.

  • depends_on → Ensures the database starts first.

Hands-on Projects

Project 1: WordPress with MySQL

  1. Save the above docker-compose.yml.

  2. Run: docker-compose up -d

  3. Access WordPress at http://localhost:8000.

Project 2: Laravel with MySQL

version: '3.8'

services:
  app:
    build: .
    ports:
      - "9000:9000"
    volumes:
      - .:/var/www/html
    networks:
      - app_network

  db:
    image: mysql:8.0
    volumes:
      - mysql_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
    networks:
      - app_network

volumes:
  mysql_data:

networks:
  app_network:
  1. Build and run: docker-compose up -d --build

  2. Access Laravel at http://localhost:9000

Best Practices

Use .dockerignore → Exclude unnecessary files (e.g., node_modules).
Leverage volumes → Avoid losing database data.
Use official images → More secure (e.g., mysql, wordpress).

Conclusion

You’ve learned:

  • How to write Dockerfiles and Compose files.

  • Key concepts: volumes, networks, multi-container apps.

  • Deployed WordPress & Laravel with MySQL.

🚀 Next Steps: Try adding Redis or Nginx to your setup!

More from this blog

L

Learn More About Programming

67 posts

I'm a developer with 6+ years of experience in React, React Native, and WordPress plugins, passionate about crafting user-friendly apps and solving challenges with creativity and expertise!