Dockerizing a Laravel App: Nginx, MySql, PhpMyAdmin, and Php-8.2
Tags: laravel, nginx, mysql, phpmyadmin
Published: 2024-07-08 18:13:47


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p2ki2ogjgj76toy14afi.jpg)

**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](https://docs.docker.com/build-cloud/).
- For macOS: Download and install Docker Desktop from the [Docker website](https://docs.docker.com/build-cloud/).
- For Linux: Follow the instructions on the [Docker website](https://docs.docker.com/build-cloud/) for your specific Linux distribution.

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

```
docker –version
```
**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
```

**### 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
```

**### 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
```
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ebj1heqr4jeoun68mdd.png)
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
```
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;
    }
}
```
**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;
    }
}
```
**

## ::::Now run docker Container::::
**

```
docker compose up –build
```
**when build is complete then run this command**

```
docker compose exec -it app sh
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/avy5lxagev7rgm5lk185.png)

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
```

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oat0vo09jy79g2ngn7nc.png)

Now run this command

```
cd /var/www
php artisan migrate
```

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

**Laravel App**

```
https://localhost
```
**PhpMyAdmin**

```
http://localhost:8080/
```

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

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