In this article we will create an Image of Docker Container for Laravel application. In the main folder of laravel, we created a folder called docker. Inside that folder we created some file configuration. In this case we use postgreSQL as database server.
Let's begin..
Dockerfile
Dockerfile located on the main laravel project. We used debian bullseye as base image.
# basic container
FROM php:8.3-fpm-bullseye
# setup user as root
USER root
# set working directory
WORKDIR /var/www
# install postgresql client 15
RUN apt-get update \
&& apt-get -y install gnupg2 lsb-release wget curl \
&& sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' \
&& wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \
&& apt-get update
# install supervisor, postgresql libs and other libs of php
RUN apt-get install -y net-tools supervisor nginx -y \
&& apt-get install -y libpq-dev libgmp-dev \
&& apt-get install -y --no-install-recommends postgresql-client \
# gd
&& apt-get install -y libzip-dev zlib1g-dev libpng-dev \
&& docker-php-ext-configure gd \
&& docker-php-ext-install gd \
&& docker-php-ext-install gmp \
# Install Postgre PDO
&& docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \
&& docker-php-ext-install pdo pdo_pgsql pgsql \
# option for install mysql as database
# && docker-php-ext-install mysqli \
# && docker-php-ext-enable mysqli \
# opcache
&& docker-php-ext-enable opcache \
# exif
&& docker-php-ext-install exif \
&& docker-php-ext-install sockets \
&& docker-php-ext-install pcntl \
&& docker-php-ext-install bcmath \
# zip
&& docker-php-ext-install zip \
# clean repo
&& apt-get autoclean -y \
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /tmp/pear/
# copy files of laravel
COPY . /var/www
# copy configuration of php, nginx and php-fpm
COPY ./docker/local.ini /usr/local/etc/php/local.ini
COPY ./docker/nginx.conf /etc/nginx/nginx.conf
COPY ./docker/www.conf /usr/local/etc/php-fpm.d/www.conf
# create log files
RUN touch /var/www/storage/logs/schedule.log
RUN touch /var/www/storage/logs/queue.log
# copy supervisor configuration
COPY ./docker/supervisord.conf /etc/supervisor/conf.d/
# setup composer and laravel
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN composer install --working-dir="/var/www"
# change level security of openssl
RUN sed -i 's/SECLEVEL=2/SECLEVEL=1/g' /etc/ssl/openssl.cnf
# generate passport keys if needed
#RUN php artisan passport:keys
#export port of the application
EXPOSE 80
# set permission on laravel directory
RUN chmod +rwx /var/www
RUN chown -R www-data:www-data /var/www/storage
RUN chown -R www-data:www-data /var/www/bootstrap
RUN chmod -R 775 /var/www/storage
RUN chmod -R 775 /var/www/bootstrap
RUN ["chmod", "+x", "docker/post_deploy.sh"]
CMD [ "sh", "docker/post_deploy.sh" ]
local.ini
located on docker folder. Reconfigure upload_max_filesize
and some other value, included memory_limit
.
upload_max_filesize=40M
post_max_size=40M
max_execution_time=180
memory_limit=-1
date.timezone = "Asia/Jakarta"
expose_php = off
nginx.conf
located on docker folder. We setup one serverblock as default nginx virtualhost.
user root;
worker_processes auto;
events {
worker_connections 1024;
}
http {
access_log /dev/stdout;
include mime.types;
default_type application/octet-stream;
server {
# we use port 80 here to work with our docker config but you can configure it to any port you want, just remember to update the dockerfile accordingly
listen 80;
index index.php index.html;
# your application here
server_name app;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
add_header X-Frame-Options "SAMEORIGIN" always;
server_tokens off;
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
add_header X-XSS-Protection "1; mode=block";
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
# this should be the path of your public folder in laravel which from our dockerfile it would be /var/www/public
root /var/www/public;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_buffering off;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
}
}
supervisord.conf
located on docker folder. We included supervisor configuration to run our queue on laravel application.
[program:schedule-run]
process_name=%(program_name)s_%(process_num)02d
command=/bin/bash -c "while [ true ]; do (php /var/www/artisan schedule:run --verbose --no-interaction &); sleep 60; done"
autostart=true
autorestart=true
user=www-data
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/storage/logs/schedule.log
stopwaitsecs=60
[program:test-01-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/artisan queue:work --queue=listener,default --tries=10
autostart=true
autorestart=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/storage/logs/queue.log
located on docker folder. We also reconfigure php-fpm configuration.
[www]
user = www-data
group = www-data
listen = 127.0.0.1:9000
pm = static
pm.max_children = 300
pm.start_servers = 40
pm.min_spare_servers = 20
pm.max_spare_servers = 60
pm.max_requests = 500
post_deploy.sh
located on docker folder. We run supervisor, php-fpm and nginx on this script.
#!/bin/sh
# update application cache
php artisan optimize
# start the application
supervisord -c "/etc/supervisor/supervisord.conf" && php-fpm -D && nginx -g "daemon off;"
Build the Image
docker build .
OR with tag
docker build -t sampleapp:v1 .
Run a Container
docker container run -d -p 8080:80 [docker_image]
docker container run -d -p 8080:80 sampleapp:v1
Hopefully this article helps you!
Top comments (0)