π³ π Dockerized PHP/LARAVEL stack: Nginx, PHP, MySQL, MongoDB, Traefik, Redis, Authelia, Netdata, Portainer
Use this repository to get started with developing your Laravel application in a Docker container.
This is a personal collection of Docker images and services(Nginx, PHP-FPM, Traefik, Authelia, Netdata, New Relic, Portainer, MySQL, Redis, MongoDB, Queue, Scheduler, and GoAccess) for applications in Laravel.
tree --sort=name --dirsfirst -a -I ".git|.DS_Store"
.
βββ nginx
βΒ Β βββ configs
βΒ Β βΒ Β βββ addon.d
βΒ Β βΒ Β βΒ Β βββ 10-realip.conf
βΒ Β βΒ Β βββ nginx.d
βΒ Β βΒ Β βΒ Β βββ 10-deny-ips.conf
βΒ Β βΒ Β βΒ Β βββ 10-security-headers.conf
βΒ Β βΒ Β βΒ Β βββ 20-gzip-compression.conf
βΒ Β βΒ Β βΒ Β βββ 20-open-file-descriptors.conf
βΒ Β βΒ Β βΒ Β βββ 30-buffers.conf
βΒ Β βΒ Β βΒ Β βββ 40-logs.conf
βΒ Β βΒ Β βΒ Β βββ 50-timeouts.conf
βΒ Β βΒ Β βΒ Β βββ 60-misc.conf
βΒ Β βΒ Β βΒ Β βββ 70-proxy.conf
βΒ Β βΒ Β βββ snippets
βΒ Β βΒ Β βΒ Β βββ cache-static.conf
βΒ Β βΒ Β βΒ Β βββ deny.conf
βΒ Β βΒ Β βΒ Β βββ http-to-https-non-www.conf
βΒ Β βΒ Β βΒ Β βββ no-caching.conf
βΒ Β βΒ Β βΒ Β βββ php-fpm-common.conf
βΒ Β βΒ Β βΒ Β βββ php-fpm.conf
βΒ Β βΒ Β βΒ Β βββ resolver-docker.conf
βΒ Β βΒ Β βΒ Β βββ resolver-global.conf
βΒ Β βΒ Β βΒ Β βββ ssl-certificates.conf
βΒ Β βΒ Β βΒ Β βββ ssl.conf
βΒ Β βΒ Β βΒ Β βββ www-to-non-www.conf
βΒ Β βΒ Β βββ .gitignore
βΒ Β βΒ Β βββ fastcgi.conf
βΒ Β βΒ Β βββ mime.types
βΒ Β βΒ Β βββ nginx.conf
βΒ Β βββ geoip2
βΒ Β βΒ Β βββ cronjob
βΒ Β βββ logrotate
βΒ Β βΒ Β βββ conf.d
βΒ Β βΒ Β βΒ Β βββ nginx
βΒ Β βΒ Β βββ cronjob
βΒ Β βΒ Β βββ logrotate.conf
βΒ Β βββ .dockerignore
βΒ Β βββ Dockerfile
βΒ Β βββ DockerfileCertbot
βΒ Β βββ docker-entrypoint.sh
βββ php
βΒ Β βββ configs
βΒ Β βΒ Β βββ conf.d
βΒ Β βΒ Β βΒ Β βββ opcache.ini
βΒ Β βΒ Β βΒ Β βββ xdebug.ini
βΒ Β βΒ Β βββ fpm
βΒ Β βΒ Β βΒ Β βββ pools
βΒ Β βΒ Β βΒ Β βΒ Β βββ www.conf
βΒ Β βΒ Β βΒ Β βββ global.conf
βΒ Β βΒ Β βββ php-local.ini
βΒ Β βΒ Β βββ php-production.ini
βΒ Β βββ logrotate
βΒ Β βΒ Β βββ conf.d
βΒ Β βΒ Β βΒ Β βββ php
βΒ Β βΒ Β βΒ Β βββ php-fpm
βΒ Β βΒ Β βΒ Β βββ storage-app
βΒ Β βΒ Β βββ cronjob
βΒ Β βΒ Β βββ logrotate.conf
βΒ Β βββ queue
βΒ Β βΒ Β βββ templates
βΒ Β βΒ Β βΒ Β βββ laravel-horizon.conf.tpl
βΒ Β βΒ Β βΒ Β βββ laravel-worker.conf.tpl
βΒ Β βΒ Β βββ supervisord.conf
βΒ Β βββ vscode
βΒ Β βΒ Β βββ launch.json
βΒ Β βββ Dockerfile
βΒ Β βββ docker-entrypoint.sh
βββ scripts
βΒ Β βββ envs
βΒ Β βΒ Β βββ deploy.env
βΒ Β βΒ Β βββ docker.env
βΒ Β βΒ Β βββ renew.env
βΒ Β βββ cloudflare-ips-ufw.sh
βΒ Β βββ cron-renew-certs.sh
βΒ Β βββ deploy-version.sh
βΒ Β βββ loadbalancer-nginx.sh
βΒ Β βββ renew-certs.sh
βΒ Β βββ self-signed-SSL.sh
βΒ Β βββ update-app.sh
βββ services
βΒ Β βββ app
βΒ Β βΒ Β βββ .env.compose
βΒ Β βΒ Β βββ .env.container
βΒ Β βΒ Β βββ Makefile
βΒ Β βΒ Β βββ docker-compose.webserver.yml
βΒ Β βΒ Β βββ docker-compose.yml
βΒ Β βββ authelia
βΒ Β βΒ Β βββ configs
βΒ Β βΒ Β βΒ Β βββ .gitignore
βΒ Β βΒ Β βΒ Β βββ configuration.yml
βΒ Β βΒ Β βΒ Β βββ users.yml
βΒ Β βΒ Β βββ data
βΒ Β βΒ Β βΒ Β βββ .gitignore
βΒ Β βΒ Β βββ secrets
βΒ Β βΒ Β βΒ Β βββ jwt
βΒ Β βΒ Β βΒ Β βββ redis
βΒ Β βΒ Β βΒ Β βββ session
βΒ Β βΒ Β βββ docker-compose.yml
βΒ Β βββ goaccess
βΒ Β βΒ Β βββ html
βΒ Β βΒ Β βΒ Β βββ .gitignore
βΒ Β βΒ Β βββ .env.compose
βΒ Β βΒ Β βββ docker-compose.webserver.yml
βΒ Β βΒ Β βββ docker-compose.yml
βΒ Β βΒ Β βββ entrypoint.sh
βΒ Β βΒ Β βββ goaccess.conf
βΒ Β βββ mongodb
βΒ Β βΒ Β βββ ssl
βΒ Β βΒ Β βΒ Β βββ .gitignore
βΒ Β βΒ Β βββ .env.container
βΒ Β βΒ Β βββ docker-compose.yml
βΒ Β βΒ Β βββ mongod.conf
βΒ Β βββ mysql
βΒ Β βΒ Β βββ ssl
βΒ Β βΒ Β βΒ Β βββ .gitignore
βΒ Β βΒ Β βββ .env.container
βΒ Β βΒ Β βββ docker-compose.yml
βΒ Β βΒ Β βββ my.cnf
βΒ Β βββ netdata
βΒ Β βΒ Β βββ configs
βΒ Β βΒ Β βΒ Β βββ alarms
βΒ Β βΒ Β βΒ Β βΒ Β βββ cgroups.conf
βΒ Β βΒ Β βΒ Β βΒ Β βββ cpu.conf
βΒ Β βΒ Β βΒ Β βΒ Β βββ mysql.conf
βΒ Β βΒ Β βΒ Β βΒ Β βββ nginx.conf
βΒ Β βΒ Β βΒ Β βΒ Β βββ phpfpm.conf
βΒ Β βΒ Β βΒ Β βΒ Β βββ ram.conf
βΒ Β βΒ Β βΒ Β βΒ Β βββ web_log.conf
βΒ Β βΒ Β βΒ Β βββ modules
βΒ Β βΒ Β βΒ Β βΒ Β βββ go.d
βΒ Β βΒ Β βΒ Β βΒ Β βββ mysql.conf
βΒ Β βΒ Β βΒ Β βΒ Β βββ nginx.conf
βΒ Β βΒ Β βΒ Β βΒ Β βββ phpfpm.conf
βΒ Β βΒ Β βΒ Β βΒ Β βββ prometheus.conf
βΒ Β βΒ Β βΒ Β βΒ Β βββ redis.conf
βΒ Β βΒ Β βΒ Β βΒ Β βββ web_log.conf
βΒ Β βΒ Β βΒ Β βββ orchestrators
βΒ Β βΒ Β βΒ Β βΒ Β βββ go.d.conf
βΒ Β βΒ Β βΒ Β βββ health.conf
βΒ Β βΒ Β βΒ Β βββ netdata.conf
βΒ Β βΒ Β βββ docker-compose.yml
βΒ Β βββ newrelic
βΒ Β βΒ Β βββ docker-compose.yml
βΒ Β βΒ Β βββ infrastructure.sh
βΒ Β βββ nginx
βΒ Β βΒ Β βββ certs
βΒ Β βΒ Β βΒ Β βββ .gitignore
βΒ Β βΒ Β βββ servers
βΒ Β βΒ Β βΒ Β βββ additional
βΒ Β βΒ Β βΒ Β βΒ Β βββ goaccess.conf
βΒ Β βΒ Β βΒ Β βββ shared
βΒ Β βΒ Β βΒ Β βΒ Β βββ letsencrypt.conf
βΒ Β βΒ Β βΒ Β βββ templates
βΒ Β βΒ Β βΒ Β βΒ Β βββ app.conf.tpl
βΒ Β βΒ Β βΒ Β βΒ Β βββ spa.conf.tpl
βΒ Β βΒ Β βΒ Β βββ app.conf
βΒ Β βΒ Β βΒ Β βββ healthcheck.conf
βΒ Β βΒ Β βΒ Β βββ nginx-status.conf
βΒ Β βΒ Β βΒ Β βββ phpfpm-status.conf
βΒ Β βΒ Β βββ .env.compose
βΒ Β βΒ Β βββ .env.container
βΒ Β βΒ Β βββ Makefile
βΒ Β βΒ Β βββ docker-compose.certs.yml
βΒ Β βΒ Β βββ docker-compose.yml
βΒ Β βββ portainer
βΒ Β βΒ Β βββ docker-compose.yml
βΒ Β βββ queue
βΒ Β βΒ Β βββ .env.compose
βΒ Β βΒ Β βββ .env.container
βΒ Β βΒ Β βββ docker-compose.yml
βΒ Β βββ redis
βΒ Β βΒ Β βββ ssl
βΒ Β βΒ Β βΒ Β βββ .gitignore
βΒ Β βΒ Β βββ docker-compose.yml
βΒ Β βΒ Β βββ redis.conf
βΒ Β βββ scheduler
βΒ Β βΒ Β βββ .env.compose
βΒ Β βΒ Β βββ .env.container
βΒ Β βΒ Β βββ docker-compose.yml
βΒ Β βββ traefik
βΒ Β βββ .env.compose
βΒ Β βββ docker-compose.yml
βββ traefik
βΒ Β βββ dynamic
βΒ Β βΒ Β βββ 10-tls.yml
βΒ Β βΒ Β βββ WRR-service.yml
βΒ Β βΒ Β βββ dashboard.yml
βΒ Β βΒ Β βββ middlewares.yml
βΒ Β βΒ Β βββ routers.yml
βΒ Β βΒ Β βββ services.yml
βΒ Β βββ .gitignore
βΒ Β βββ traefik.yml
βββ .dockerignore
βββ .editorconfig
βββ .env.example
βββ .gitignore
βββ Makefile
βββ README.md
βββ docker-compose.yml
βββ systemd.services
8.0-fpm-alpine
v2.4
1.20-alpine
8.0
4.4
6.2
4.29
v1.31
2.5.1-alpine
[Installed PHP extensions](The following modules and extensions have been enabled, in addition to those you can already find in the official PHP image)
You are able to find all installed PHP extensions by running php -m
inside your workspace.
bcmath
calendar
Core
ctype
curl
date
dom
exif
fileinfo
filter
ftp
gd
gmp
hash
iconv
intl
json
libxml
mbstring
mysqli
mysqlnd
openssl
pcntl
pcre
PDO
pdo_mysql
pdo_sqlite
Phar
posix
readline
Reflection
session
SimpleXML
soap
sockets
sodium
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
xsl
zip
zlib
Additional non-core php extensions:
amqp
mongodb
ds
igbinary
newrelic
msgpack
redis
Xdebug
OPcache
docker
folder must match current repository folder
LOCAL_DOCKER_FOLDER
variable of the .env
environment fileapp
folder should contain Laravel application
APP_LOCAL_FOLDER
variable of the .env
environment fileThe organization of the folders should serve as a reference for organizing this repository Docker + Laravel Application:
.
βββ /var/www/
βββ docker
βββ your-app
βββ your-app-2
$ git clone https://github.com/AllysonSilva/laravel-docker docker && cd docker
make config-env docker_folder=./docker
LOCAL_DOCKER_FOLDER
variable in the .env
file must be the folder name of the docker projectObs: The .env
file is a copy of the .env.example
file, which is created from the initial make config-env
command.
.env
file and edit PROJECT_NAME
and DOMAIN
variables
DOMAIN
variable from the scripts/envs/deploy.env file must match the same value as the same variable from the .env
fileyourdomain.tld
within that same Docker folder and replace with your company's domain
docker
folder
cp scripts/envs/docker.env .
COMPOSE_PROJECT_NAME
, where it should have the same value as the variable PROJECT_NAME
in the .env
file
.env
file.dockerignore
file to a higher folder level with the command cp .dockerignore ..
.env
file and edit the variables APP_IMAGE
, APP_LOCAL_FOLDER
, APP_LIMITS_CPU
, APP_LIMITS_MEMORY
and APP_RESERVATIONS_MEMORY
APP_IMAGE
: Docker image tag that will be used in its creation through the docker-build-app
command and also used in the execution of PHP/Laravel containersAPP_LOCAL_FOLDER
: Name of the folder where the Laravel application is located. It should be ./folder-name-project-laravel
APP_LOCAL_FOLDER
variable in the .env
file must have the same name as the Laravel application foldercd ..
)
git clone --branch 8.x --single-branch https://github.com/laravel/laravel.git app
cd docker
make -f Makefile -f services/app/Makefile composer-install
vendor
folder will be with root
permission. To change the permission of the Laravel application folder to the machine user, use the command: sudo chown -R $USER:$USER ../app/
make -f Makefile -f services/app/Makefile npm-handle
make -f Makefile -f services/app/Makefile npm-handle npm_command="npm run prod"
make -f Makefile -f services/app/Makefile docker-build-app
Obs: If the server is not using Cloudflare as protection/Load balancing, then change the value of the real_ip_header
directive in the nginx/configs/addon.d/10-realip.conf
file from CF-Connecting-IP
to X-Forwarded-For
.
.env
file.env
file and edit the variables WEBSERVER_IMAGE
, WEBSERVER_PORT_HTTP
, WEBSERVER_PORT_HTTPS
, WEBSERVER_LIMITS_CPU
, WEBSERVER_LIMITS_MEMORY
and WEBSERVER_RESERVATIONS_MEMORY
WEBSERVER_IMAGE
: Docker image tag that will be used in its creation through the docker-build-webserver
command and also used in the execution of the NGINX/Webserver containersmake -f Makefile -f services/nginx/Makefile docker-build-webserver
DOCKER_PATH
variable in the .env
file)
cp scripts/envs/renew.env .
renew.env
file and edit the following variables:
RENEW_CERT_DOMAINS
: Domains/subdomains that will be in the certificate (separated by comma)
RENEW_CERT_COMMAND_TARGET
: Command that will be executed on the file in the services/nginx/Makefile
file, which can be:
gen-certs-cloudflare
: It uses the cloudflare DNS API to automatically insert the DNS TXTs records and thus generate the certificates
services/nginx/certs
folder named cloudflare.ini
containing dns_cloudflare_api_token = YOUR_TOKEN_AQUI
gen-certs
: Used for both HTTP and DNS validation
Webroot/HTTP
:
RENEW_CERT_IS_CHALLENGE_WEBROOT
to true
and variable RENEW_CERT_COMMAND_OPTIONS
to webroot=yes preferred_challenge=http-01
DNS
: Use this validation to generate DNS TXT records and enter manually. The value of the variable RENEW_CERT_COMMAND_OPTIONS
should be manual=yes preferred_challenge=dns-01
To create the certificates for the first time, as the domain is not active/available on the internet, then it is necessary to use the DNS challenge/plugin manually.
After correctly setting the variables, the renew.env
file should look like this:
RENEW_CERT_DOMAINS="*.domainA.tld,domainA.tld,sub.domainB.tld,domainC.tld"
[email protected]
RENEW_CERT_COMMAND_TARGET=gen-certs
RENEW_CERT_COMMAND_OPTIONS="manual=yes \
preferred_challenge=dns-01"
RENEW_CERT_DOMAINS
environment variable with the correct domainsRENEW_CERT_EMAIL
to the email that Let's Encrypt will use to warn of certificate expirationYou must build a custom certbot image, adding the host/server user so that the certificates don't have root
but server user permissions:
cd nginx/
docker build \
--tag company/certbot:v1 \
--build-arg TAG_IMAGE="certbot/certbot:v1.16.0" \
--file DockerfileCertbot \
.
# Back to docker root folder
cd ..
The above image was generated with the tag
company/certbot:v1
. This value must be updated in the WEBSERVER_CERTBOT_IMAGE
variable in the .env
file.
After, update the variable WEBSERVER_CERTBOT_IMAGE
with the name of the newly created image, then run the script ./scripts/renew-certs.sh and follow the steps to create the first certificates for the application.
To see the domains and certificate validity, run the command make -f Makefile -f services/nginx/Makefile get-certs
.
Before running the application, you must configure the docker networks for connection between containers
Two networks are created by default. One for all containers(compose_network
) and one for connecting traefik
to containers for proxy(traefik_network
), in the file docker-compose.yml
To run the docker-compose --compatibility up
command to create the networks and then the application containers, traefik
, nginx
and others to connect, it is necessary first to copy the contents of the file services/traefik/.env.compose and place at the end of the .env
file
After performing the above step, run the command docker-compose --compatibility up
to create the networks so that the containers can connect and traefik act as a proxy
docker network ls
and see if there are two networks with the name: ${VARIABLE_VALUE_PROJECT_NAME}_network
e ${VARIABLE_VALUE_PROJECT_NAME}_traefik_network
The traefik
network name, must be updated in the traefik/traefik.yml file in the providers.docker.network
directive. Replacing company_traefik_network
with the value ${VARIABLE_VALUE_PROJECT_NAME}_traefik_network
providers.docker.network
directive of the traefik/traefik.yml file, must have the same value as the TRAEFIK_DOCKER_NETWORK
variable in the .env
fileIf the server is not behind some proxy like cloudflare, then remove the websecure.forwardedHeaders.trustedIPs
directive
After the HTTPs certificates are created, run the command make docker-up context=traefik version=v0
Create the dhparam.pem
file for NGINX to use in the ssl_dhparam
directive, with the following command:
$ cd services/nginx/certs/
$ openssl dhparam -out dhparam.pem 4096
# Back to docker root folder
$ cd ../../../
Create rotate
folder in ./../app/storage/logs/
for log rotation, using logrotate
mkdir ./../app/storage/logs/logrotate
app
folder to the name of the correct folder where the Laravel application is locatedCopy scripts/envs/deploy.env file to docker root folder
cp scripts/envs/deploy.env .
DOMAIN
with the same value of the same variable in the .env
fileEdit the services/app/.env.container file, setting the variables for the laravel project, mainly APP_KEY
and APP_ENV
, which are mandatory in the entrypoint
docker of the application container
APP_KEY
: If the application key is not set, user sessions and other encrypted data will not be secure!APP_ENV=production
and APP_DEBUG=false
for production, and APP_ENV=local
APP_DEBUG=true
for developmentPHPFPM_MAX_CHILDREN
, PHPFPM_START_SERVERS
, PHPFPM_MIN_SPARE_SERVERS
and PHPFPM_MAX_SPARE_SERVERS
according to the capacity of the machine/serverSee if the domain is correct in the server_name
directive in the services/nginx/servers/app.conf file
Run the scripts/deploy-version.sh script to create the Laravel/PHP-FPM and Webserver/NGINX containers
git checkout ./services/nginx/servers
, so any changes to the NGINX virtualhost must be committed so that they cannot be lostAccess the application's domain and view the website in the browser with https://yourdomain.tld
Obs: When there are new changes in the code and with that, a new image is built, then, it is necessary to run or rerun the deploy script to update the PHP/APP containers with the new code of the new images.
# # NEW RELIC ENVs
NEW_RELIC_ENABLED
to true
NEW_RELIC_APPNAME
which represents the name of the application that will be rendered in the New Relic panelNEW_RELIC_LICENSE_KEY
variable with the license value generated previously. 40-character New Relic User Account Key
make docker-up context=newrelic
WITH_GEOIP2
variable to true
GEOIPUPDATE_ACCOUNT_ID
variable to the value that appears in Account/User ID
GEOIPUPDATE_LICENSE_KEY
variable to the value that appears in License key
Change the redis password in the requirepass
directive in the services/redis/redis.conf file
Configuration file, uses default port 6379
for non TLS/SSL connections, and port 6380
for encrypted TLS/SSL connections. To generate the certificates to use in the TLS/SSL connection, the following command must be run:
./scripts/self-signed-SSL.sh \
--service=redis \
--cert-ca-pass=keypassword \
--cert-server-pass=keypassword \
--cert-server-host=redis.yourdomain.tld \
--with-dhparam
127.0.0.1 redis.yourdomain.tld
to /etc/hosts
tls-key-file-pass
directive in the services/redis/redis.conf file to the value of the --cert-server- pass
Run the container using the command: make docker-up context=redis version=v1 service=redis scale=2
To access the Redis container database:
docker exec -it v1_company_redis_1 redis-cli -n 0 -p 6379 -a 'YOUR_REDIS_PASSWORD' --no-auth-warning
Uncomment the line containing authelia-forwardAuth@docker
in the traefik/dynamic/middlewares.yml file
traefik
dynamic settings are updated in real time. No need to restart the traefik
container
Open the file services/authelia/configs/configuration.yml and configure the following points:
yourdomain.tld
to the real domain of the companyv1_company_redis_1
Edit the passwords in the services/authelia/secrets folder
jwt
: Defines the secret used to craft JWT tokens leveraged by the identity verification processsession
: Authelia relies on session cookies to authenticate usersredis
: This is a session provider. Must be the same as the requirepass
directive in the file services/redis/redis.conf
Edit the user and password in the services/authelia/configs/users.yml file. See documentation
Run the container using the command: make docker-up context=authelia version=v0
Access Authelia with https://authelia.yourdomain.tld
The settings applied to the Netdata container are found in services/netdata/configs/netdata.conf
Edit the ExecStart
setting in the Docker service file /lib/systemd/system/docker.service
to the value ExecStart=/usr/bin/dockerd -H fd:// -H tcp://127.0.0.1:2375 --containerd=/run/containerd/containerd.sock
sudo systemctl daemon-reload
and sudo services restart docker
Set to true
the value of the variable WITH_NETDATA
in the ./deploy.env
file
Run the container using the command:
make docker-up context=netdata services=dockerproxy
make docker-up context=netdata services=netdata
Access Netdata with https://netdata.yourdomain.tld
Run the script to generate the certificates for use in the TLS/SSL connection:
./scripts/self-signed-SSL.sh \
--service=mongodb \
--cert-ca-pass=keypassword \
--cert-server-pass=keypassword \
--cert-server-host=mongodb.yourdomain.tld
127.0.0.1 mongodb.yourdomain.tld
to /etc/hosts
Open the services/mongodb/mongod.conf file and edit the certificateKeyFilePassword
setting which should match the --cert-server-pass
argument of the above script
Open the file services/mongodb/.env.container and edit the password, replacing YOUR_MONGODB_ROOT_PASSWORD
with the new password
Run the container using the command: make docker-up context=mongodb
Run the script below to retrieve the full name of the mongodb
container:
MONGODB_CONTAINER_NAME=$(docker ps -q --filter name="mongodb" --filter status=running --no-trunc --format="{{.Names}}")
Recover the external port to connect outside the server:
docker port ${MONGODB_CONTAINER_NAME} 27017/tcp
# `0.0.0.0:OUTSIDE_PORT`
openssl s_client -connect 127.0.0.1:OUTSIDE_PORT -tls1_3
To access the database using the container's own mongodb client, run the command:
docker exec -ti ${MONGODB_CONTAINER_NAME} mongo \
--username 'root' \
--authenticationDatabase 'admin' \
--password 'YOUR_MONGODB_ROOT_PASSWORD'
To create a user, use the following command:
$ use admin
$ db.createUser({user: 'app', pwd: 'passw0rd1', roles: ["userAdminAnyDatabase", "dbAdminAnyDatabase", "readWriteAnyDatabase"]})
# mongo --username "app" --password "passw0rd1" --authenticationDatabase "admin"
To access the database using the machine's mongodb client inside or outside the server, run the command:
mongo --tls \
--tlsCAFile ca.pem \
--tlsCertificateKeyFile client.pem \
--host localhost||SERVER_IP||SERVER_DATABASE_DNS \
--port MONGODB_PUBLIC_PORT \
--username 'app||root' \
--authenticationDatabase 'admin' \
--password 'passw0rd1||${MONGO_INITDB_ROOT_PASSWORD}'
Run the script to generate the certificates for use in the TLS/SSL connection:
./scripts/self-signed-SSL.sh \
--service=mysql \
--cert-server-host=mysql.yourdomain.tld
127.0.0.1 mysql.yourdomain.tld
to /etc/hosts
Open the file services/mysql/my.cnf and edit the MySQL settings
Open the services/mysql/.env.container file and edit the environment variable credentials
Run the container using the command: make docker-up context=mysql
To access the MySQL container database:
mysql -h 127.0.0.1||mysql.yourdomain.tld -P {OUTSIDE_PORT/3306} -uapp -p'YOUR_MYSQL_PASSWORD' \
--ssl-ca=services/mysql/ssl/ca.pem \
--ssl-key=services/mysql/ssl/client-key.pem \
--ssl-cert=services/mysql/ssl/client-cert.pem
make docker-up context=portainer
https://portainer.yourdomain.tld
.env.container
file and edit as desired:
CONTAINER_ROLE
environment variable when running the PHP container so that its value is queue
LARAVEL_QUEUE_MANAGER
: This environment variable defines the container context, and can have the following values:
artisan queue:work
queue:work
for queue managementartisan horizon
APP_KEY
and APP_ENV
are required when executing the containerContainer with PID 1 executed by supervisor to manage processes.
Run the container using the command: make docker-up context=queue
.env.container
file and edit as desired:
CONTAINER_ROLE
environment variable when running the PHP container so that its value is scheduler
APP_KEY
and APP_ENV
are required when executing the containerroot
as a cron service requestRunning a single scheduling command:
* * * * * /usr/local/bin/php ${REMOTE_SRC}/artisan schedule:run --no-ansi >> ${REMOTE_SRC}/storage/logs/scheduler.log 2>&1
exec /usr/sbin/crond -l 2 -f -L /var/log/cron.log
Run the container using the command: make docker-up context=scheduler
Open file .env
and edit the variable DOCKER_COMPOSE_WEBSERVER_OPTIONS
, adding the value of: -f services/goaccess/docker-compose.webserver.yml
Open file deploy.env(if it exists), and edit the variable DOCKER_COMPOSE_WEBSERVER_OPTIONS
, adding the value of: -f services/goaccess/docker-compose.webserver.yml
Copy the file services/nginx/servers/additional/goaccess.conf to a folder level, it should be in services/nginx/servers/goaccess.conf
server_name goaccess.yourdomain.tld
line, replacing yourdomain.tld
with the correct company domainCopy the contents of the services/goaccess/.env.compose file and place at the end of the .env
file
Restart/Recreate the NGINX/Webserver container with the command: make -f Makefile -f services/nginx/Makefile docker-up-webserver
Check and edit the GoAccess configuration file as preferred services/goaccess/goaccess.conf
Run the container GoAccess using the command: make docker-up context=goaccess
Access GoAccess with https://goaccess.yourdomain.tld
Install PHP Composer Dependencies in Project
make -f Makefile -f services/app/Makefile composer-install
Run NPM Commands
make -f Makefile -f services/app/Makefile npm-handle npm_command="npm run prod"
Replace "npm run prod" with "npm anything"
Build the APP/Laravel Image
make -f Makefile -f services/app/Makefile docker-build-app
Run/Recreate APP/Laravel containers
make -f Makefile -f services/app/Makefile docker-up-app
With the following options:
version
: Option used to specify a new version other than the currently running containersscale
: Total number of containers NGINX will use as HTTP load balancer in the upstream
directive
./scripts/loadbalancer-nginx.sh
so that you can update the app.conf
file of NGINX with the names/version of the new containersup_options
: Options that will be passed to the up
command. By default the options are: --force-recreate --no-build --no-deps --detach
options
: Options that are passed to the docker-compose
command like --verbose
or --log-level
for exampleRun/Recreate NGINX/Webserver containers
make -f Makefile -f services/nginx/Makefile docker-up-webserver
With the following options:
version
: Option used to specify a new version other than the currently running containersscale
: Total number of containers that will be executed, will be running ready to receive and handle requests through traefik
up_options
: Options that will be passed to the up
command. By default the options are: --force-recreate --no-build --no-deps --detach
options
: Options that are passed to the docker-compose
command like --verbose
or --log-level
for exampleBuild the NGINX/Webserver Image
make -f Makefile -f services/nginx/Makefile docker-build-webserver
Important: Before running the scripts/commands below it is necessary:
scripts/envs
folder to the docker root folderCOMPOSE_PROJECT_NAME
environment variable in the docker.env
file with the same value as the same variable in the .env
file./scripts/cron-renew-certs.sh
Use this command to set up a CRON schedule for automatic renewal of Let's Encrypt certificates
To add a schedule in CRON to renew HTTPs certificates every Sunday at 02:00, run the following command:
./scripts/cron-renew-certs.sh --timer=\"0 2 * * MON\" --path=/var/www/docker/ --add
Where:
--timer=
: Scheduling expression in CRON
--path=
: Docker folder path
-add
: Add a command that will execute ./scripts/renew-certs.sh to CRON which will be executed every time set in the --timer
option
To remove the schedule from CRON, run the command:
./scripts/cron-renew-certs.sh --remove
./scripts/deploy-version.sh
Use this command to update the number of running PHP/Laravel and NGINX/Webserver containers or to update the version of the containers with a new updated PHP/Laravel or NGINX/Webserver image
Before running the script/command it is necessary to update the environment variable DOMAIN
in the file deploy.env
, which must have the same value as the same variable in the file .env
To create 4 APP/Laravel and 2 Nginx/Webserver containers, run the following command:
./scripts/deploy-version.sh --new-version=v9 --num-nginx-scale=2 --num-php-scale=4
By default, if no option is passed as an argument in the command, then they will have the following values:
--new-version=
: Previous version + 1--num-nginx-scale=
: Value that is in the variable DOCKER_COMPOSE_WEBSERVER_SCALE
of the file services/nginx/.env.compose
--num-php-scale=
: Value that is in the variable DOCKER_COMPOSE_APP_SCALE
of the file services/app/.env.compose
./scripts/loadbalancer-nginx.sh
Use this command to update the
services/nginx/servers/app.conf
file or any other (web server, server blocks) in NGINX, with the names of the APP/Laravel containers that will be used in the NGINXupstream
directive used in HTTP load balancer handling
The script/command has the following options/arguments:
--not-reload-nginx
: If this option is not passed, then the NGINX processes inside the container will be reloaded, causing updates to the (web server, server blocks) .conf
files located in services/nginx/servers
to be published/visible on the internet
--php-container-name=
: Option used so that Docker can filter PHP/Laravel containers with the command docker ps --filter name="$PHP_CONTAINER_NAME"
^/v([0-9]+)${COMPOSE_PROJECT_NAME}_app_\d+
docker-up-app
command--nginx-container-name=
: Option used so that Docker can filter NGINX/Webserver containers with the command docker ps --filter name="$NGINX_CONTAINER_NAME"
^v\d+${COMPOSE_PROJECT_NAME}_webserver
--not-reload-nginx
option is not passed. Because NGINX containers will have to be retrieved to be updateddocker-up-webserver
command--loadbalancer-name=
: The value of this argument/option will be used to name the NGINX upstream
directive in the .conf
file
--filename-server=
: Name of the .conf
file that will be used to edit and add the upstream
directive with the names of the PHP/Laravel containers
.conf
file found in the services/nginx/servers
folderserver
directive, it must have the following content so that the file can be updated and the information will be added between the lines
###SET_UPSTREAM
###END_SET_UPSTREAM
The following is an example of using the script:
./scripts/loadbalancer-nginx.sh --loadbalancer-name=loadbalancer-xyz --filename-server=site.conf
./scripts/update-app.sh
- Use this command when OPcache is enabled in PHP/Laravel containers and you are also using volumes in the docker in Laravel application with the same PHP/Laravel containers
- In executing this script, a set of artisan commands will also be executed, such as:
route:cache
,config:cache
,view:cache
andmigrate
(if the--force-migrations
option is passed in script/command)- Also use to automate the project update process on the local machine using GIT
The script contains the following options/arguments:
--with-reload-phpfpm
: By default GIT updates in the project(git pull
), do not update PHP-FPM in containers so that OPcache is also updated, so passing this option will update PHP-FPM processes inside the container, through the sign SIGUSR2
--force-migrations
: By default the php artisan migrate --force
command will not be executed. Passing this option then the script also runs artisan migrate
on the project
--container-name=
: Name of the container that will be used in the docker command docker ps --filter name="$LARAVEL_CONTAINER_NAME"
to run the PHP-FPM process update and also run the artisan
commands
^/v([0-9]+)${COMPOSE_PROJECT_NAME}_app_\d+
docker-up-app
command--container-workdir=
: Option used in the --workdir
argument in the docker exec
command, which has the same value as the --path
argument, if --container-workdir
is not present in the command
--path=
: Absolute path to the folder where the Laravel project is located, so the script can perform a simple cd $WEBPATH_GIT
--branch=
: Name of the GIT branch the script will perform git checkout $BRANCH
--npm-run=
: NPM commands that will run on the machine itself within the Laravel project
The following is an example of using the script:
./scripts/update-app.sh --with-reload-phpfpm --force-migrations --path="/var/www/app" --branch=main
renew.env
file in the docker root folder
RENEW_CERT_DOMAINS
, adding the domains, subdomain, separated by comma that will be generated/renewedRENEW_CERT_EMAIL
variable for the email that should be sent certificate expiration notification by Let's Encryptcert.pem
, chain.pem
, fullchain.pem
and privkey.pem
) must be in the ./services/nginx/certs
folderdhparam.pem
in the same folder as the certificates
openssl dhparam -out ./services/nginx/certs/dhparam.pem 4096
renew.env
to generate certificates via HTTP challengeAdd the following content to the renew.env
file:
RENEW_CERT_COMMAND_TARGET=gen-certs
RENEW_CERT_IS_CHALLENGE_WEBROOT=true
RENEW_CERT_COMMAND_OPTIONS="webroot=yes preferred_challenge=http-01"
Run the ./scripts/renew-certs.sh
script and follow the steps of certbot certificate generation
renew.env
to generate certificates via DNS challengeAdd the following content to the renew.env
file:
RENEW_CERT_COMMAND_TARGET=gen-certs-cloudflare
Run the ./scripts/renew-certs.sh
script and follow the steps of certbot certificate generation
renew.env
to generate the certificates via the DNS plugin certbot-dns-cloudflareAdd the following content to the renew.env
file:
RENEW_CERT_COMMAND_TARGET=gen-certs-cloudflare
To use this challenge, you must create a file in the services/nginx/certs
folder named cloudflare.ini
containing dns_cloudflare_api_token = YOUR_TOKEN_AQUI
Run the ./scripts/renew-certs.sh
script and follow the steps of certbot certificate generation
renew.env
file with one of the three modes in the above menu
./scripts/cron-renew-certs.sh
If you find an issue, or have a special wish not yet fulfilled, please open an issue on GitHub providing as many details as you can (the more you are specific about your problem, the easier it is for us to fix it).
Pull requests are welcome, too π! Also, it would be nice if you could stick to the best practices for writing Dockerfiles.