A Complete Guide To Dockerize Laravel, Postgres, Nginx, MailServer, PGAdmin, Adminer, Redis, Npm

Reza Khademi
5 min readApr 21, 2024

--

A Complete Guide To Dockerize

Using docker for developing Laravel web-apps will prevent us from a headache of installation and configuration different services.

To get started, make sure you have Docker installed on your system, and let’s dive into it. (You can clone the complete repository at this Github repo.)

Let’s look at our file structure to have a better understand of what’s going on:

dockerfiles/
src/
postgresql/
docker-compose.yml
.env

Inside dockerfiles/ folder we will create these:

nginx/
nginx.dockerfile
php.dockerfile

The nginx/ folder is for default.conf and docker files are located here to create our custom images. Inside the nginx/ folder we have a regular config file (default.conf) as below:

Inside nginx.dockerfile we have:

First of all, we pull an alpine image and then we set user ID and group ID as a non-root user for docker and if you wonder why, because if our container was running as root and we generated a file from our container through a volume back to our Docker host then the file will be owned by root:root.

By default, UID and GID are 1000 but in a multi-user environment you may end up with something different. After adding user, by using ADD docker command (which exists on the line 16th of nginx.dockerfile):

At highlighted line we will copy default.conf file to desired location of nginx image.

Inside php.dockerfile we have:

Until now we have our docker files and if you recall our files structure, we need to determine the docker-compose.yml:

dockerfiles/
src/
postgresql/
docker-compose.yml
.env

The docker-compose file will have our desired containers as shown below, and we are going to explain it.

The defined services will have the same network named laravel, which will allow them to communicate with each other without any issues.

On build section we will define the working directory as context and the name of related dockerfile as nginx.dockerfile. So docker compose will go to context directory and use nginx.dockerfile.

First of all we will launch an instance of nginx running in a container and using the created nginx configuration and defined image on ./dockerfile.

We will set UID/GID which we discussed earlier and expose port 80:80 (left one is one our system and right one is on docker). Binding ./src on host to /var/www/html will give access to nginx to serve our Laravel website and depends_on section indicates that this service needs a list of services to run, and without them, nothing goes to happen.

What does delegated mean on/var/www/html:delegated ?

  • Use delegated on Volumes: whenever docker container performs changes, host is in read only mode.
  • Use cached on Volumes: when the host performs changes, the container is in read only mode.
  • Default: whenever both container and host actively and continuously perform changes on data.

The tty flag is a related concept to stdin, stdout. A pseudo terminal (also known as a tty) connects a user's terminal with ability of the stdin and stdout stream through a shell such as bash.

The “${DB_DATABASE}” means docker automatically look into .env file on the same directory to complete desired key-values.

Earlier, we wrote everything that will be needed on the php.dockerfile, so this is a simple section for this container. We just need to make sure the context directory and dockerfile are correct. Port 9000 will be exposed for our application, and the ./src directory will be linked to the container to load our future Laravel web app.

The only thing that is important to know is entrypoint option. This instruction will be used to provide executables that will always execute when the container is launched.

What now?

Next, navigate in your terminal to the directory you cloned above repository and spin up the containers for the web server by running docker-compose up -d --build app.

The following containers are built for our web server, with their exposed ports detailed:

  • nginx:80
  • postgresql:5432
  • app :9000
  • redis:6379
  • adminer:8081
  • pgadmin — :8090
  • mailhog — :1025

Now we can use our ./src folder by one these instructions:

  • Clone your Laravel project or copy all of the files directly into this src directory.
  • Install a brand new Laravel project by running docker compose run --rm composer create-project laravel/laravel . in your terminal inside the ./src folder.

Three additional containers are included that handle Composer, NPM and Artisan commands without having to have these platforms installed on your local computer.

Use the following command examples from your project root, modifying them to fit your particular use case.

  • docker-compose run --rm composer update
  • docker-compose run --rm npm run dev
  • docker-compose run --rm artisan migrate

Access container as interactive shell and see output:

docker exec -it <container id> sh

Our docker application is accessible through http://localhost.

Makefile

There is a makefile which can help you to run every docker or artisan command easily.

If you're not familiar with GNU Makefile it's ok and you can still use this repository (even you can delete makefile), but with makefile you can manage different commands easier and better!

Before using a makefile just install it from GNU Makefile and run make command in repository root directory and you will see a help result to use it.

Some of make commands example to simplify workflow are:

# run docker compose up -d
make up

# run docker compose down --volumes
make down-volumes

# run migrations
make migrate

# run tinker
make tinker

# run artisan commands
make art db:seed

That’s it.

READ MORE:

--

--

Responses (1)