# How to Deploy Laravel with Docker and Docker Compose

> URL: https://www.atlantic.net/dedicated-server-hosting/how-to-deploy-laravel-with-docker-and-docker-compose/ | Published: 2024-08-14 | Updated: 2024-08-19 | Author: Hitesh Jethva

Deploying applications with Docker has revolutionized the way developers build, ship, and run software. Laravel, a popular PHP framework known for its elegant syntax and powerful features, pairs exceptionally well with Docker to create a consistent and scalable development and production environment. By leveraging Docker and Docker Compose, you can streamline the deployment process, ensuring that your Laravel application runs smoothly across different environments.

In this guide, we will walk you through the process of deploying a Laravel application using Docker and Docker Compose.

## Prerequisites

- A server running Ubuntu with Docker and Docker Compose installed.
- A root user or a user with sudo privileges.

## Step 1 – Set Up Your Laravel Project

Install PHP and other required packages.

```bash
apt install composer php php-cli php-xml php-curl php-intl -y
```

Stop the Apache service.

```bash
systemctl stop apache2
```

If you don’t have a Laravel project yet, you can create one using Composer:

```bash
composer create-project --prefer-dist laravel/laravel laravel-docker
```

Navigate to the project directory

```bash
cd laravel-docker
```

## Step 2 – Create a Dockerfile

Create a Dockerfile in the root of your Laravel project. This file defines the image configuration for your Laravel application.

```bash
nano Dockerfile
```

Add the following lines:

```bash
# Use the official PHP image as a base image
FROM php:8.1-fpm

# Set working directory
WORKDIR /var/www

# Install system dependencies
RUN apt-get update && apt-get install -y \
    build-essential \
    libpng-dev \
    libjpeg-dev \
    libfreetype6-dev \
    locales \
    zip \
    jpegoptim optipng pngquant gifsicle \
    vim \
    unzip \
    git \
    curl \
    libzip-dev \
    libpq-dev \
    libonig-dev \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install -j$(nproc) gd

# Install PHP extensions
RUN docker-php-ext-install pdo pdo_mysql pdo_pgsql mbstring zip exif pcntl

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Copy the existing application directory contents to the working directory
COPY . /var/www

# Copy the existing application directory permissions to the working directory
COPY --chown=www-data:www-data . /var/www

# Change current user to www
USER www-data

# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
```

Save and close the file.

## Step 3 – Create a Docker Compose File

Create a **docker-compose.yml** file in the root of your project. This file defines the services (containers) to be run.

```bash
nano docker-compose.yml
```

Add the following configuration:

```bash
version: '3.8'
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: laravel-app
    container_name: laravel-app
    restart: unless-stopped
    tty: true
    environment:
      SERVICE_NAME: app
      SERVICE_TAGS: dev
    working_dir: /var/www
    volumes:
      - .:/var/www
      - ./docker-compose/php/local.ini:/usr/local/etc/php/conf.d/local.ini
    networks:
      - app-network

  webserver:
    image: nginx:alpine
    container_name: nginx-webserver
    restart: unless-stopped
    ports:
      - "8080:80"
    volumes:
      - .:/var/www
      - ./docker-compose/nginx:/etc/nginx/conf.d/
    networks:
      - app-network

  db:
    image: mysql:5.7
    container_name: mysql
    restart: unless-stopped
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_ROOT_PASSWORD: root
      MYSQL_PASSWORD: root
      MYSQL_USER: root
    ports:
      - "3306:3306"
    volumes:
      - dbdata:/var/lib/mysql
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  dbdata:
    driver: local
```

Save and close the file.

## Step 4 – Configure Nginx

Create a directory named **docker-compose/nginx** and add a configuration file named **default.conf** inside it.

```bash
mkdir -p docker-compose/nginx 
nano docker-compose/nginx/default.conf
```

Add the following configuration.

```bash
server {
    listen 80;
    index index.php index.html;
    server_name localhost;
    root /var/www/public;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }
}
```

Save the file.

## Step 5 – Environment Variables

Ensure you have a .env file set up in your Laravel project with appropriate configurations. For instance, set the database host to db (the name of the MySQL service in docker-compose.yml):

```bash
nano .env
```

Modify the following content:

```bash
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laravel
DB_PASSWORD=root
```

## Step 6 – Build and Run the Containers

Build and start the Docker containers using Docker Compose:

```bash
docker-compose up -d
```

This command will build the Docker images defined in the **Dockerfile** and **docker-compose.yml,** and then start the containers in detached mode.

Verify the running containers.

```bash
docker-compose ps
```

Output.

```bash
     Name                    Command                 State                     Ports                
----------------------------------------------------------------------------------------------------
laravel-app       docker-php-entrypoint php-fpm    Up           9000/tcp                            
mysql             docker-entrypoint.sh mysqld      Restarting                                       
nginx-webserver   /docker-entrypoint.sh ngin ...   Up           0.0.0.0:8080->80/tcp,:::8080->80/tcp
```

## Step 7 – Access the Application

Your Laravel application should now be accessible at **http://your-server-ip:8080.**

![](https://www.atlantic.net/wp-content/uploads/2024/07/p1.png)

## Step 8 – Stop the Containers

To stop the Docker containers, you can use:

```bash
docker-compose down
```

This will stop and remove the containers but preserve the data stored in the volumes.

## Conclusion

You’ve now set up a Laravel application with Docker and Docker Compose. This setup helps isolate the application and its dependencies, making it easier to manage and deploy. You can customize the configuration files further to suit your needs, such as adding more services, adjusting the Nginx configuration, or modifying the PHP environment settings. Try deploying a Laravel app with Docker on [dedicated server hosting](https://www.atlantic.net/dedicated-server-hosting/) from Atlantic.Net!
