Note: This project is a fork from the original Docker Lemp Stack Development Tool The main difference is that the tool is originally conceived to work with Laravel in the backend (API Rest) and Vue + Vite in the frontend. This Fork is intended to work only with a monolithic Laravel project.
This repository represents a rich template for deploying development environments using dockers. We are building a Laravel web application with all the associated services ready to run.
We are using Docker Compose
with NGINX
, PHP-FPM
, MariaDB
and phpMyAdmin
services. Laravel
is being used to develop the web app in a monolith project. Each service and application source is containerized using dockers.
Note: Initially this repository is intended to be used as development containers, a new way of using Dockers containers with development environments installed inside them, and not in your main system, in a service infrastructure context very similar to the existing one in productions environments.
This project has been mainly created for Unix (Linux/MacOS). Perhaps it could work on Windows if you use WSL (Windows Subsystem for Linux)
All requisites should be available for your distribution. The most important are :
- WSL 2 (Windows users)
- Git
- Docker
- Docker Compose
- Visual Studio Code (You can use whatever IDE allows you to work inside containers)
Check if docker-compose
is already installed by entering the following command:
which docker-compose
Check Docker Compose compatibility :
This services use the following ports.
Server | Port |
---|---|
MariaDB | 3306 |
PHPMyAdmin | 8080 |
Nginx | 8000 |
Service | URL | Observations |
---|---|---|
Laravel Web App | http://localhost:8000/ | Laravel web app served from Artisan. (Dev) |
Laravel Web App | http://localhost:8001/ | Laravel web app served from FPM. (Production) |
phpMyAdmin | http://localhost:8080 |
- Nginx is being used to do reverse proxy to route the Laravel web application and phpMyAdmin services.
- The Laravel web application is configured to be served in the development environment from both Artisan and FPM. This is to check that everything works correctly and to be able to test in the development environment. In the
.devcontainer/webapp/docker-entrypoint.sh
path you can configure how to serve the application during development.
Here are some summary guidelines for using this repository to start a new project or include your Laravel and Vue projects in this architecture.
git clone https://github.com/jraicr/docker-lemp-laravel.git myProject
After cloning you can change or remove the remote origin from this repository and set up your own for the project. How to use git is beyond the scope of this document.
Related links
First you must add to your .bashrc
or .zshrc
file the following variable exports:
- Open
.bashrc
or.zshrc
with a text editor like nano:
cd ~
nano .bashrc
- Write the following lines at the end of the file:
export UID="$UID"
export USERNAME="$USER"
export PWD="$PWD"
Secondly you should be editing the docker compose environment file to setup the services:
-
Copy
.devcontainer/.example.env
to.devcontainer/.env
Here you will configure everything you need to make the container services work correctly: -
You must configure
PROJECT_NAME
variable. -
You can change
NGINX_HOST
variable, it is set tolocalhost
by default. If you need to change NGINX configuration you are able to do it from the file.devcontainer/webserver/config/nginx/conf.d/default.conf.template.nginx
-
Change database connection root and user passwords within the variables
CONFIG_MARIADB_ROOT_PASSWORD
andCONFIG_MARIADB_PASSWORD
.- You can also set the username variable
CONFIG_MARIADB_USER
from MariaDB, wich user is being used in Laravel by default.
- You can also set the username variable
-
-
Configure Laravel environment variables (more info)
ℹ️ See configuration for more details.
- To generate a new Laravel project uses this command from the project root:
sh -c bash_tools/scripts/generate_new_laravel_project.sh
ℹ️ See Laravel web app project for more details if you need to includes existing projects.
- Compose up command:
docker compose -f ".devcontainer/docker-compose.yml" up -d --build
- Compose down command:
docker compose -f ".devcontainer/docker-compose.yml" down
If you are using VS Code as your main IDE, alternatively you can open the project folder and do a right click on docker-compose file in order to manage it. This require to have installed Docker VSCode extension. After composing up the containers you should be able to connect to web services in your web browser.
To start working inside a container from VS Code
you will need Remote Development extension pack (if you are in windows you will need WSL 2) you can press F1 and type Attach to running container
then select the webapp container to start working inside it. You can also do it from the Dockers view in VS Code and doing a right click on the container you are interested to work in and select Attach Visual Studio Code
.
ℹ️ See developing inside a container for more details.
In the following sections we will discuss the architecture configurations in more depth.
First of all we need to make sure that we have some environment variables available on our own computer. To do this follow the steps below.
- Open .bashrc or .zshrc with a text editor like nano:
cd ~
nano .bashrc
- Write the following lines at the end of the file:
export UID="$UID"
export USERNAME="$USER"
export PWD="$PWD"
The env variables file used for docker-compose and containers are found in .devcontainer/.env
here you can configure all the services. In case you want to change any port you are recommended to only set the external ports where you are going to connect to the services.
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# DOCKER COMPOSE ENV VARS #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
### DOCKER-COMPOSE ENV ###
# ℹ https://docs.docker.com/compose/environment-variables/#the-env-file
PROJECT_NAME=curso-laravel # ✏️ Writes here your project name
COMPOSE_PROJECT_NAME=${PROJECT_NAME}_devcontainer
### NGINX Webserver ###
# Port to connect to Web App service routed by nginx
WEB_APP_EXTERNAL_PORT=8000 # (http://localhost:8000)
WEB_APP_FPM_EXTERNAL_PORT=8001 # This is the Web App served with FPM (http://localhost:8001)
### MariaDB ###
# Port to connect to the database server
MARIADB_EXTERNAL_PORT=3306
### PHP MY ADMIN ###
# Port to connect to phpMyAdmin
PHPMYADMIN_EXTERNAL_PORT=8080 # (http://localhost:8080)
# It is recommended to not touch internal ports in the following docker configuration
### WEB APP ###
# Port used by the Web App container for internal docker network
WEB_APP_EXPOSE_PORT=8080
WEB_APP_FPM_EXPOSE_PORT=9001
Note: Be sure to change the name of the project in the
.devcontainer/.env
file. Many docker parameters are built from this name. Also, the source code of laravel project will be located in named folders:projectName_webapp
.
In the nexts sections we are going to configure variables that will be passed to their respectives containers using their own .env file located in:
.devcontainer/webapp/.webapp.env
devcontainer/mariadb/.mariadb.env
.devcontainer/webserver/.webserver.env
You won't need to edit any of this files unless you wish to expose other configuration options that are not provided by default. Just continue editing the .devcontainer/.env
file.
The most important variable to take into account is NGINX_HOST
, it is set to localhost by default.
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# NGINX CONTAINER ENV VARS #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Environment Variables for NGINX Docker Container
CONFIG_NGINX_HOST=localhost # ✏️ You can edit this (e.g.: NGINX_HOST=rai.ddns.net)
CONFIG_WEB_APP_CONNECTION_PORT=${WEB_APP_EXPOSE_PORT}
CONFIG_WEB_APP_FPM_CONNECTION_PORT=${WEB_APP_FPM_EXPOSE_PORT}
Here you can change the root and user passwords. By default MARIADB_USER
is set to dev
but you can change it for whatever username you want.
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# DB CONTAINER ENV VARS #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Environment Variables for MariaDB Docker Container
# More info: https://mariadb.com/kb/en/mariadb-docker-environment-variables/
CONFIG_MARIADB_CONNECTION=mysql
CONFIG_MARIADB_HOST=${PROJECT_NAME}_mariadb
CONFIG_MARIADB_ROOT_USER=root
CONFIG_MARIADB_ROOT_PASSWORD=qwerty # ✏️ CHANGE THIS PASSWORD
CONFIG_MARIADB_USER=dev
CONFIG_MARIADB_PASSWORD=dev # ✏️ CHANGE THIS PASSWORD
CONFIG_MARIADB_ROOT_HOST=172.0.0.0/255.0.0.0
CONFIG_MARIADB_DATABASE=${PROJECT_NAME}_bd
The database will be created using PROJECT_NAME
as prefix.
Show webapp configuration section
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# WEB_APP CONTAINER ENV VARS #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
### Environment Variables for Web App container ###
### Docker Entrypoint Configuration ###
CONFIG_WEB_APP_LISTENING_PORT=${WEB_APP_EXPOSE_PORT} # Serves Laravel project using artisan in this port
CONFIG_WEB_APP_FPM_LISTENING_PORT=${WEB_APP_FPM_EXPOSE_PORT} # Serves Laravel project using FPM in this port
### PHP OPcache Configuration
CONFIG_PHP_OPCACHE_ENABLE=1
CONFIG_PHP_OPCACHE_MAX_ACCELERATED_FILES="10000"
CONFIG_PHP_OPCACHE_MEMORY_CONSUMPTION="256M"
CONFIG_PHP_OPCACHE_MAX_WASTED_PERCENTAGE="10"
# ❌ USE VALUE "1" ONLY IN DEVELOPMENT ENVIRONMENTS ❌
# This allows us to make changes to our code. If you’re using a Docker volume,
# it means that OPcache will respect file timestamps and your changes will reflect immediately.
# In a production environment that’s not ideal and we are losing the cache features from OPcache.
CONFIG_PHP_OPCACHE_VALIDATE_TIMESTAMPS="1"
### Laravel Configuration ###
# More info: https://laravel.com/docs/9.x/configuration
LARAVEL_APP_NAME=${PROJECT_NAME}_API
LARAVEL_APP_ENV=local
LARAVEL_APP_DEBUG=true
LARAVEL_APP_URL=http://${CONFIG_NGINX_HOST}
LARAVEL_LOG_CHANNEL=stack
LARAVEL_LOG_DEPRECATIONS_CHANNEL=null
LARAVEL_LOG_LEVEL=debug
LARAVEL_DB_CONNECTION=mysql
LARAVEL_DB_HOST=${CONFIG_MARIADB_HOST}
LARAVEL_DB_PORT=3306
LARAVEL_DB_DATABASE=${CONFIG_MARIADB_DATABASE}
LARAVEL_DB_USERNAME=${CONFIG_MARIADB_USER}
LARAVEL_DB_PASSWORD=${CONFIG_MARIADB_PASSWORD}
LARAVEL_BROADCAST_DRIVER=log
LARAVEL_CACHE_DRIVER=file
LARAVEL_FILESYSTEM_DISK=local
LARAVEL_QUEUE_CONNECTION=sync
LARAVEL_SESSION_DRIVER=file
LARAVEL_SESSION_LIFETIME=120
LARAVEL_MEMCACHED_HOST=127.0.0.1
LARAVEL_REDIS_HOST=127.0.0.1
LARAVEL_REDIS_PASSWORD=null
LARAVEL_REDIS_PORT=6379
LARAVEL_MAIL_MAILER=smtp
LARAVEL_MAIL_HOST=mailhog
LARAVEL_MAIL_PORT=1025
LARAVEL_MAIL_USERNAME=null
LARAVEL_MAIL_PASSWORD=null
LARAVEL_MAIL_ENCRYPTION=null
LARAVEL_MAIL_FROM_ADDRESS="hello@example.com"
LARAVEL_MAIL_FROM_NAME="${LARAVEL_APP_NAME}"
LARAVEL_AWS_ACCESS_KEY_ID=
LARAVEL_AWS_SECRET_ACCESS_KEY=
LARAVEL_AWS_DEFAULT_REGION=us-east-1
LARAVEL_AWS_BUCKET=
LARAVEL_AWS_USE_PATH_STYLE_ENDPOINT=false
LARAVEL_PUSHER_APP_ID=
LARAVEL_PUSHER_APP_KEY=
LARAVEL_PUSHER_APP_SECRET=
LARAVEL_PUSHER_HOST=
LARAVEL_PUSHER_PORT=443
LARAVEL_PUSHER_SCHEME=https
LARAVEL_PUSHER_APP_CLUSTER=mt1
LARAVEL_VITE_PUSHER_APP_KEY="${LARAVEL_PUSHER_APP_KEY}"
LARAVEL_VITE_PUSHER_HOST="${LARAVEL_PUSHER_HOST}"
LARAVEL_VITE_PUSHER_PORT="${LARAVEL_PUSHER_PORT}"
LARAVEL_VITE_PUSHER_SCHEME="${LARAVEL_PUSHER_SCHEME}"
LARAVEL_VITE_PUSHER_APP_CLUSTER="${LARAVEL_PUSHER_APP_CLUSTER}"
### OCTANE Configuration ###
LARAVEL_OCTANE_SERVER=swoole
In this block you can configure the environment variables needed by the webapp container and used by Laravel. The latter will ignore the values in the original .env
file, located in the Laravel source code folder, if we setup the same variable name in the file .devcontainer/webapp/.webapp.env
. Besides this, we expose variables to config the php OPcache extension
.
Note: The APP key that Laravel generates with artisan will not be configured in this file and Laravel will read it from its own .env. We do this to save us configuration steps, when Laravel already fills in this data for us.
- More information about Laravel environment configuration
- More information about OPcache environment configuration
The configuration file is located in .devcontainer/webserver/config/etc/nginx/conf.d/default.conf.template.nginx
. If you need to change some NGINX
configuration you can do it here.
You can find the php configuration files in the directory devcontainer/webapp/config/etc/php/conf.d
In this path you can configure the php.ini
file, as well as the port to which XDebug
connects, among other options. Some of the OPcache
config values are taken from the environment variables configured in .devcontainer/.env
The configuration files in the path .devcontainer/webapp/config/etc/php-fpm.d/
are for PHP's FPM service.
You are free to add more configuration files to PHP by mounting a new volume - inside the webapp container - in the docker-compose.yml
file. You can see the current ones as an example:
webapp:
(...)
volumes:
- ../${PROJECT_NAME}_webapp:/app # Laravel Project
- ./webapp/config/etc/php/conf.d/php.ini-development.ini:/usr/local/etc/php/php.ini # PHP Config
- ./webapp/config/etc/php-fpm.d/www.conf:/usr/local/etc/php-fpm.d/www.conf # PHP-FPM Config
- ./webapp/config/etc/php-fpm.d/zz-docker.conf:/usr/local/etc/php-fpm.d/zz-docker.conf # PHP-FPM Config
- ./webapp/config/etc/php/conf.d/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini # PHP XDebug Config
- ./webapp/config/etc/php/conf.d/opcache.ini:/usr/local/etc/php/conf.d/opcache.ini # PHP OPcache config
- ./webapp/docker-entrypoint.sh:/docker-entrypoint.sh # Web app Docker entrypoint script
(...)
The .devcontainer/webapp/docker-entrypoint.sh
file is executed as soon as the web app container is raised. By default the Laravel application is served using Artisan and FPM at the same time, later both are routed with nginx. You can edit the file to decide how to serve the application during development.
Remember that in production environments it is desirable to serve the Laravel application with FPM or other options such as Laravel Octane with Swoole.
The user root
from the database can only be accessed from the same networks that belong to the docker network. It is well configured so you dont need to worry even if you are running WSL 2 on Windows, you will be able to access it from your Windows host using your favourite mariaDB client
or using phpMyAdmin
.
phpMyAdmin
is useful to manage our database through the web browser. By default you can access it only from localhost.
Each time the mariaDB container
is up it will be executing automatically the file in .devcontainer/mariadb/config/db/docker-entrypoint-initdb.d/db_init.sql
. For the moment it is used in the starting point to create phpMyAdmin configuration tables and to assign privileges to them to the user configured in the variable MARIADB_USER
from the mariaDB environment variables container file .mariadb.env
. If you think this tables should be created in another moment or context, you are free to edit this if you know what you are doing.
Note: It is strongly recommended to not deploy phpMyAdmin in production environments. It is useful to work only inside development environments.
Over time I will be adding to this project other docker compose options, more suitable for deployment in production environments. Feel free to adapt compose for production environments but be aware of security warnings, such as avoiding phpMyAdmin deployments.
The image used in the webapp container is used to work with the latest version of Laravel framework.
Before composing up the containers it is important to have ready the folder with the project, since the webapp container will be mounting this folder as a volume.
You can generate a new Laravel project using the bash script .bash_tools/scripts/generate_new_laravel_project.sh
. It will use a docker image to generate the full project.
- To generate a new Laravel project uses this command from the project root:
sh -c bash_tools/scripts/generate_new_laravel_project.sh
You can add your projects creating git submodules, for example, that points to the project. Remember that folder must be named ${PROJECT_NAME}_webapp
. As said before, PROJECT_NAME
can be set in ./devcontainer/.env
.
Write this commands to create git submodules from the project root:
git submodule add https://github.com/user/MyLaravelAPP ProjectName_webapp
As the repositorie where the project is located do not include the dependency files it needs (or at least it shouldn't), we have prepared a script that will help you with this task.
- Run this command from the root of the project to install the composer dependencies needed by Laravel:
sh -c bash_tools/scripts/install_composer_dependencies.sh
It will also copy the Laravel configuration file .env.example
to .env
and then generate an API key for the application.
Note: Do not run these scripts if your project was previously generated with
generate_new_laravel_project.sh
as this is generated with all the dependencies they need.
Monorepositories: I think it is possible to work in a monorepo using this setup, instead of using git submodules, since the project is isolated in a folder and with its own docker-based environment tools. So, to do this you just put in the project the source code from your Laravel project. It is up to you to decide how to manage the workflow with git and your project.
Feel free to contribute to this project with any changes. Make a fork of the repository and clone it on your computer, make changes as you see fit and create a pull request.