Skip to main content

Command Palette

Search for a command to run...

Deploy-Laravel-Framework-and-setup-mysql-using-Docker

Updated
4 min read
G

DevOps Engineer | 4 Years of Experience | K8s & Cloud Advocate Documenting my journey through the cloud-native wilderness. I turn my production-level challenges into step-by-step tutorials for the modern engineer. Exploring the "how" and "why" behind Kubernetes, Docker, and beyond. ☸️ 🐳 🚀

This is an example of a PHP-based Laravel application containing real-world examples (CRUD, auth, advanced patterns, etc.) that adheres to the RealWorld API spec.

This codebase was created to demonstrate a backend application built with the Laravel framework, including RESTful services, CRUD operations, authentication, routing, pagination, and more. We’ve gone to great lengths to adhere to the Laravel community style guides and best practices.

For more information on how this works with other frontends/backends, head over to the RealWorld repo.

How it works

The API is built with Laravel, making the most of the framework’s out-of-the-box features. The application uses a custom JWT authentication implementation located in app/Jwt.

Project Tasks

  • Write a Dockerfile and docker-compose.yml file for the Laravel services.

  • Mount volumes to persist:

    • a. Real-time log entries.

    • b. MySQL data.

Requirements

  • Laravel app repository (you can fork or clone it here: https://github.com/f1amy/laravel-realworld-example-app.git).

  • A server with Docker installed.

Docker is a platform for developers and system administrators to develop, deploy, and run applications with containers. Containers are isolated, lightweight environments that allow for consistent and reproducible builds.

Docker Compose is a tool for defining and running multi-container Docker applications. With a single docker-compose.yml file, you can define an entire application stack and start it with one command.

Steps to Dockerize the App

The repository comes with a default docker-compose.yml file, but we will be writing our own from scratch.

STEP 1 — Create an EC2 Instance/Server

Follow the official AWS guide to create an EC2 instance. Alternatively, you can run Docker on your desktop or via WSL Ubuntu. In this guide, I am using an EC2 server.

STEP 2 — SSH into your server

Use the following command to access your server:

Bash

ssh -i "your-keypair.pem" ec2-user@your-public-ip

Note: Replace ec2-user with ubuntu if you are using an Ubuntu image.

STEP 3 — Install Docker

Update the package index and install Docker (Amazon Linux 2):

Bash

sudo amazon-linux-extras update
sudo amazon-linux-extras install docker -y
sudo service docker start
sudo usermod -a -G docker ec2-user

STEP 4 — Clone the Laravel repo

Bash

git clone https://github.com/f1amy/laravel-realworld-example-app.git
cd laravel-realworld-example-app

Configuration

STEP 5: Create Docker Directory

We will keep our Docker configuration organized in a dedicated folder.

Bash

mkdir docker
cd docker
touch Dockerfile
touch entrypoint.sh
cd ..

STEP 6: Define Services in Docker Compose

Delete the contents of the existing docker-compose.yml and add the following:

YAML

version: '3.9'
services:
  php:
    build:
      context: ./docker
      target: php
      args:
        - APP_ENV=${APP_ENV}
    environment:
      - APP_ENV=${APP_ENV}
      - CONTAINER_ROLE=myapp
    working_dir: /var/www
    volumes:
      - ./:/var/www
    ports:
      - "8000:8000"
    depends_on:
      - mysql
      - redis

  mysql:
    image: mysql:8.0
    ports:
      - "3306:3306"
    environment:
      - MYSQL_DATABASE=${DB_DATABASE}
      - MYSQL_USER=${DB_USERNAME}
      - MYSQL_PASSWORD=${DB_PASSWORD}
      - MYSQL_ROOT_PASSWORD=${DB_PASSWORD}
    volumes:
      - db-data:/var/lib/mysql

  redis:
    image: redis:alpine
    command: redis-server --appendonly yes --requirepass "${REDIS_PASSWORD}"
    ports:
      - "6379:6379"

volumes:
  db-data:

Understanding the Compose File:

  • Version: Specifies the Docker Compose file format.

  • Services: Defines the containers (PHP, MySQL, Redis).

  • Build/Context: Points to the folder containing our Dockerfile.

  • Depends_on: Ensures MySQL and Redis start before the PHP application.

  • Volumes: db-data ensures your database information isn't lost when the container stops.

STEP 7: Write the Dockerfile

Navigate to docker/Dockerfile and add:

Dockerfile

FROM php:8.1 as php

RUN apt-get update -y && apt-get install -y \
    unzip \
    libpq-dev \
    libcurl4-gnutls-dev

RUN docker-php-ext-install pdo pdo_mysql bcmath

RUN pecl install -o -f redis \
    && rm -rf /tmp/pear \
    && docker-php-ext-enable redis

WORKDIR /var/www
COPY . .
COPY --from=composer:2.3.5 /usr/bin/composer /usr/bin/composer

ENV PORT=8000
ENTRYPOINT [ "docker/entrypoint.sh" ]

STEP 8: Write the Entrypoint Script

Navigate to docker/entrypoint.sh and add:

Bash

#!/bin/bash

if [ ! -f "vendor/autoload.php" ]; then
    composer install --no-progress --no-interaction
fi

if [ ! -f ".env" ]; then
    echo "Creating env file for env $APP_ENV"
    cp .env.example .env
else
    echo "env file exists"
fi

php artisan migrate --force
php artisan key:generate
php artisan config:clear
php artisan route:clear

php artisan serve --port=$PORT --host=0.0.0.0 --env=.env
exec docker-php-entrypoint "$@"

Make sure to give the script execution permissions: chmod +x docker/entrypoint.sh

Running the Application

STEP 9: Build and Launch

Before running, edit routes/index.php to ensure your routes are active. Then run:

Bash

docker-compose down && docker-compose up --build -d

STEP 10: Accessing the App

  1. Verify containers are running: docker-compose ps.

  2. Important: Open port 8000 in your AWS EC2 Security Group settings.

  3. Visit http://your-public-ip:8000 in your browser.

Summary

You have now successfully containerized a Laravel application with a MySQL database and Redis cache.

Thank you for reading!

For a deeper dive into these concepts, check out this Reference Video.

License

The MIT License (MIT). Please see LICENSE for more information.