DEV Community

syed kamruzzaman
syed kamruzzaman

Posted on

Dockerizing a Laravel App: Nginx, MySql, PhpMyAdmin, and Php-8.2

Image description

What is Docker?
Docker is an open-source platform that enables developers to automate the deployment, scaling, and management of applications using containerization. Containers package an application and its dependencies into a single, lightweight unit that runs consistently across different computing environments.

Why Do We Need Docker?

  1. Consistency Across Environments: Docker ensures that your application runs the same way regardless of where it’s deployed — whether on a developer’s local machine, a testing server, or in production. This eliminates the “it works on my machine” problem.

  2. Isolation: Containers encapsulate everything needed to run an application, ensuring that dependencies, libraries, and configurations are isolated from other applications. This isolation prevents conflicts between different applications on the same host.

  3. Scalability: Docker makes it easy to scale applications horizontally by running multiple container instances. This can be managed dynamically based on load and demand, leading to better resource utilization and performance.

  4. Efficiency: Containers are lightweight and share the host system’s kernel, making them more efficient than traditional virtual machines (VMs) which include a full operating system.

  5. Rapid Deployment: Docker containers can be quickly created, started, stopped, and destroyed. This rapid provisioning accelerates development, testing, and deployment cycles.

  6. Portability: Containers can run on any system that supports Docker, providing great flexibility in deployment choices, whether on-premises or in the cloud.

### Prerequisite Laravel App Setup with Docker

1. Install Docker

  • For Windows: Download and install Docker Desktop from the Docker website.
  • For macOS: Download and install Docker Desktop from the Docker website.
  • For Linux: Follow the instructions on the Docker website for your specific Linux distribution.

Ensure Docker is running by executing the following command in your terminal:

docker –version
Enter fullscreen mode Exit fullscreen mode

2. Install Docker Compose
Docker Compose is a tool for defining and running multi-container Docker applications. It’s often used for setting up complex environments with multiple services (like web servers, databases, etc.).

  • For Windows and macOS: Docker Compose is included with Docker Desktop.
  • For Linux: Install Docker Compose following the instructions on the Docker Compose installation page.

Verify the installation by running:

docker-compose –version
Enter fullscreen mode Exit fullscreen mode

### Set Up a Laravel Project
If you don’t have a Laravel project already, you can create a new one. If you already have a Laravel project, skip this step.

composer create-project laravel/laravel example-app
cd example-app
Enter fullscreen mode Exit fullscreen mode

### Dockerize Laravel application
1. Create a Dockerfile in your root project
A Dockerfile is a script that contains instructions on how to build a Docker image for your application.

Dockerfile

FROM php:8.2-fpm-alpine

ARG user
ARG uid

RUN apk update && apk add \
    curl \
    libpng-dev \
    libxml2-dev \
    zip \
    unzip \
    shadow  # Add shadow package to install useradd

RUN docker-php-ext-install pdo pdo_mysql \
    && apk --no-cache add nodejs npm

COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer

#USER root

#RUN chmod 777 -R /var/www/

RUN useradd -G www-data,root -u $uid -d /home/$user $user
RUN mkdir -p /home/$user/.composer && \
    chown -R $user:$user /home/$user
WORKDIR /var/www
USER $user
Enter fullscreen mode Exit fullscreen mode

Here we pass two Arguments one is user and the other is uid for create a new user and other permission.

2. Create a docker-compose folder. And inside this folder create the below folder

  • Mysql
  • Nginx
  • - ssl
  • Php
  • Redis
  • - data Like this way

Image description
Here are other files we will create later.

3. Create a docker-compose.yml file in your root project
docker-compose.yml

version: "3.7"

services:

####################################################################################################
# app
####################################################################################################
  app:
    build:
      args:
        user: developer
        uid: 1000
      context: ./
      dockerfile: Dockerfile
    image: app
    container_name: app-rifive-laravel
    restart: unless-stopped
    environment:
      VIRTUAL_HOST: laravel.test
    working_dir: /var/www/
    volumes:
      - ./:/var/www
      - ~/.ssh:/root/.ssh
    depends_on:
      - db
      - redis  
    networks:
      - laravel

####################################################################################################
# DATABASE (MySQL)
####################################################################################################
  db:
    image: mysql:8.0
    container_name: mysql-rifive-laravel
    restart: unless-stopped
    ports:
      - "3306:3306"
    environment:
      MYSQL_DATABASE: ${DB_DATABASE}
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_USER: ${DB_USERNAME}
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    volumes:
      - ./docker-compose/mysql/data:/var/lib/mysql
      - ./docker-compose/mysql/logs:/var/log/mysql
      - ./docker-compose/mysql/ql:/docker-entrypoint-initdb.d
    networks:
      - laravel
####################################################################################################
# Nginx
####################################################################################################      
  nginx:
    image: nginx:alpine
    container_name: nginx-rifive-laravel
    restart: unless-stopped
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./:/var/www
      - ./docker-compose/nginx:/etc/nginx/conf.d
      - ./docker-compose/nginx/ssl:/etc/nginx/conf.d/ssl
      - ./docker-compose/nginx/phpmyadmin.conf:/etc/nginx/conf.d/phpmyadmin.conf
    networks:
      - laravel

####################################################################################################
# phpMyAdmin
####################################################################################################      
  phpmyadmin:
    image: phpmyadmin/phpmyadmin:latest
    container_name: phpmyadmin-rifive-laravel
    ports:
        - 8080:80
    links:
        - db
    restart: unless-stopped
    environment:
        PMA_HOST: db
        #PMA_USER: ${DB_USERNAME}
        #PMA_PASSWORD: ${DB_PASSWORD}
        PMA_PORT: 3306
        PMA_ARBITRARY: 1
    networks:
        - laravel

 ####################################################################################################
# Redis
####################################################################################################
  redis:
    image: "redis:alpine"
    container_name: ri-rifive-redis
    restart: unless-stopped
    volumes:
        - ./docker-compose/redis/data:/data
    ports:
      - "6379:6379"
    networks:
      - laravel      
networks:
  laravel:
    driver: bridge
Enter fullscreen mode Exit fullscreen mode

here we create 5 image

  1. Laravel App
  2. Database MySQL
  3. Nginx
  4. PhpMyAdmin
  5. Redis

4. Create a Necessary file for nginx. Go to docker-compose/nginx Folder and create these files

laravel.conf

server {
    listen 80;
    server_name laravel.test;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name laravel.test;
    index index.php index.html;

    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/public;

    ssl_certificate /etc/nginx/conf.d/ssl/self-signed.crt;
    ssl_certificate_key /etc/nginx/conf.d/ssl/self-signed.key;

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

    location / {
        try_files $uri $uri/ /index.php?$query_string;
        gzip_static on;
    }
}
Enter fullscreen mode Exit fullscreen mode

phpMyAdmin.conf

server {
    listen 80;
    server_name phpmyadmin.laravel.test;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name phpmyadmin.laravel.test;
    index index.php index.html;

    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /usr/share/nginx/html;

    ssl_certificate /etc/nginx/conf.d/ssl/self-signed.crt;
    ssl_certificate_key /etc/nginx/conf.d/ssl/self-signed.key;

    location / {
        proxy_pass http://phpmyadmin:80;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
Enter fullscreen mode Exit fullscreen mode

**

::::Now run docker Container::::

**

docker compose up –build
Enter fullscreen mode Exit fullscreen mode

when build is complete then run this command

docker compose exec -it app sh
Enter fullscreen mode Exit fullscreen mode

Image description

Now you can see your shell terminal. If you run whoami command then you see developer as a user. Run below this command

cd docker-compose/nginx/ssl/
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout self-signed.key -out self-signed.crt
Enter fullscreen mode Exit fullscreen mode

This command creates two files in your docker-compose/nginx/ssl folder.

  1. self-signed.crt
  2. self-signed.key Like this picture

Image description

Now run this command

cd /var/www
php artisan migrate
Enter fullscreen mode Exit fullscreen mode

now you exit shell command and your application will be ready for run. Hit this URL

Laravel App

https://localhost
Enter fullscreen mode Exit fullscreen mode

PhpMyAdmin

http://localhost:8080/
Enter fullscreen mode Exit fullscreen mode

That’s all. Happy Learning :) .
[if it is helpful, giving a star to the repository 😇]

https://github.com/kamruzzamanripon/docker-laravel-nginx

Top comments (0)