Chapter 1: Dokerize Laravel App with Nginx and Postgres.
Tags: laravel, docker, nginx, postgres
Published: 2022-03-27 07:04:00

I made this post as my notes that might be useful for me or anyone who reads this.

By using docker containers you can ship your app to anyone or to any machine without worrying about versioning errors, incompatible dependency, etc.

So, in this post, I have a Laravel app with Postgres as the database. We are using multiple databases in this case.

To make it easy, we will dockerize our Laravel app, database Postgres, and web server Nginx.

## Prerequisite
Before we get started, we need to add a new folder and a docker-compose file in our laravel app.

```
...rest of laravel dirs and files
|- docker-compose.yml [file]
|- infra
|--- app
|--- nginx
|------ conf
|--- pgsql
|------ script
```

Let's create an `infra` folder to store our docker configuration. Within `infra`, we have `app` to store laravel & PHP `Dockerfile`, `nginx` for web server, and `pgsql` for the database.

## PHP
We need these PHP dependencies to make our app run.

![Laravel Requirement](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0zo36ctikwyfdo04srx4.png)

So, let's check the dependencies in the docker image we are going to use.

```
docker run php:7.4-fpm php -m
```
We will see that some of the dependencies don't exist in the PHP image we are going to use. So let's create a custom image.

Create `Dockerfile` inside the `app` folder.
-> `/infra/app/Dockerfile`

```
FROM php:7.4-fpm

RUN apt-get update \
  && apt-get install -y \
  git \
  curl \
  libpng-dev \
  libonig-dev \
  libxml2-dev \
  zip \
  unzip \
  zlib1g-dev \
  libpq-dev \
  libzip-dev

RUN docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \
  && docker-php-ext-install pdo pdo_pgsql pgsql zip bcmath gd

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

EXPOSE 9000
```

Basically, this Dockerfile will install the PHP dependencies we need and also the composer, then it will expose our PHP app in port 9000.

You can customize the extension, if you need it you can install it, if you don't need it, you can remove it. You can see [here](https://gist.github.com/hoandang/88bfb1e30805df6d1539640fc1719d12) for the list of commands to install the PHP extension. 

## Create docker-compose 

Then we back to the root of the project and create `docker-compose.yml` there. 

```
version: "3.7"

networks:
  app-network:
    driver: bridge

services: 
  app:
    container_name: app
    build:
      context: ./infra/app
      dockerfile: Dockerfile
    image: php-laravel-7.0
    restart: unless-stopped
    tty: true
    working_dir: /var/www
    volumes: 
      - ./:/var/www
    networks: 
      - app-network
```

Basically you can copy this configuration.

We can name our container in `container_app` and image name in `image` as we want.

`./:/var/www` in `volumes` means that, we copy our laravel app from laravel root `./` to our container working directory `/var/www`.

---

```
networks:
  app-network:
    driver: bridge

. . . 

   networks: 
      - app-network
```
The piece of code above means that the app or the container `app` (`container_name: app`) can communicate with other services within the same app-network network. In the example we will also add `PGSQL` to docker-compose, so to connect with pgsql, it will use `app-network`.

You can read further more about network [here](https://docs.docker.com/network/).


...continue...