ご質問・お見積り等お気軽にご相談ください
お問い合わせ

Setup Docker with Laravel 8 (Apache ,PostgreSQL)

Setup Docker with Laravel 8 (Apache ,PostgreSQL)

There are a lot of article about setting up Laravel with Docker but I couldn’t find anything which also had PostgreSQL and Apache.

So here’s how to do this with explanations to the best of my knowledge.

Folder Structure

This is how the folder structure will look :

 

  app
  |__laravel
  |   |__app
  |   |__bootstrap
  |   |__. . . .
  |   . . . .
  |   webpack.mix.js
  |__pgsql
  |   |__init
  |   |  |__
  |   |      0_schema.sql
  |   |__pgdata
  |   Dockerfile
  |__server
  |   |__
  |       Dockerfile
  docker-compose.yml

 

So there is three main folder inside the app directory and a docker-compose.yml file. I will explain all of these in their respective section below.

Setting up

Before going any further please make sure you have composer installed already. Otherwise, you can’t do the next steps. Although it’s possible to do this without installing the composer. But I haven’t done that way in this article.

laravel

First create the parent folder called app. Then open a command terminal and write the following code :

 

  1. cd app – Go the the app directory.
  2. composer create-project --prefer-dist laravel/laravel laravel – This will create a laravel 8 base.

For reference, this is how it will look inside the laravel folder :

 

  laravel
  |__app
  |__bootstrap
  |__config
  |__database
  |__public
  |__resources
  |__routes
  |__storage
  |__tests
  .editorconfig
  .env
  .env.example
  .gitattributes
  .gitignore
  artisan
  CHANGELOG.md
  composer.json
  package.json
  phpunit.xml
  readme.md
  server.php
  webpack.mix.js

 

With this the laravel portion is over. Now let’s setup the server, where we will run this laravel app.

server

Let’s create a new folder named server inside the parent folder app. And inside this folder create a Dockerfile with the following code:

FROM php:7.4.1-apache

# 1. development packages
RUN apt-get update \
 && apt-get install -y --no-install-recommends \
        nano \
        libicu-dev \
        git \
        zip \
        unzip \
        vim \
 && rm -rf /var/lib/apt/lists/*

# 2. apache configs + document root
ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf

# 3. mod_rewrite for URL rewrite and mod_headers for .htaccess extra headers like Access-Control-Allow-Origin-
RUN a2enmod rewrite headers

# 4. start with base php config, then add extensions
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"

ADD https://raw.githubusercontent.com/mlocati/docker-php-extension-installer/master/install-php-extensions /usr/local/bin/
RUN chmod uga+x /usr/local/bin/install-php-extensions && sync \
 && install-php-extensions bz2 \
        gettext \
        intl \
        exif \
        pdo_pgsql \
        bcmath \

 

 

So with this, I can build the container already apache installed and then add some configurations so that it can run the Laravel app properly and added some extensions for the database.

Next we will add configurations for the database.

pgsql

Now let’s create the pgsql folder inside the main parent folder app. Inside this, create two folder, one is init, another is pgdata. And the file Dockerfile. Note that the file doesn’t have any file extension.

The init folder is optional explained below. And pgdata is needed, so that any kind of settings changes for database is saved here.

Now put the following code in the file Dockerfile :

 

FROM postgres:12
// The following code is optional, for people in Japanese region
RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8
ENV LANG ja_JP.utf8
ENV TZ Asia/Tokyo

 

This will install the postgres version 12. and adding some regional changes for Japan.

init folder (optional)

You can add .sql files here to create tables when creating the database container. Here’s an example of inside 0_schema.sql :

create table unsubscribe_contacts (
  id serial UNIQUE
  , contact_id bigint default 0 not null
  , is_deleted boolean default false not null
  , updated_at timestamp default CURRENT_TIMESTAMP not null
  , created_at timestamp default CURRENT_TIMESTAMP not null
  , constraint unsubscribe_contacts_PKC primary key (id)
) ;

 

This will create a table inside the database when creating the container. And other informations related to the database will be added in the docker-compose.yml file. See the next sections for this.

 

docker-compose.yml

You have create a file called docker-compose.yml inside the parent folder app. This file will run all the docker files together and connect it in the same network. After creating this file, write the following code :

 

version: '3.7'

services: 
  server:
    build: ./server
    ports:
      - 80:80
    volumes:
      - ./laravel:/var/www/html

  pgsql:
        build: ./pgsql
        ports:
            - 5431:5432
        volumes:
            - ./pgsql/init:/docker-entrypoint-initdb.d  # When the container is created from image, the sql in here will run
            - ./pgsql/pgdata:/var/lib/postgresql  # Get the data from container to the host
        environment:
            - POSTGRES_PASSWORD=secret
            - POSTGRES_USER=postgres
            - POSTGRES_DB=mail # Write/change the database name in the .env file
            - DATABASE_HOST=localhost
            - POSTGRES_HOST_AUTH_METHOD=trust # No password is needed when this option is on

 

Now inside the parent app folder, run the following code to build and run :

 

docker-compose up --build

 

And with this every thing should run fine.

 

 

Warnings

  • As there is an active issue related to mount files in wsl2 to host. If this issue is still not solved, the server which will run the Laravel could be slow. If you find this problem, please rebuild the container with wsl1 and it should be fine.