DEV Community

Henri Sekeladi
Henri Sekeladi

Posted on

Dockerfile for PHP Laravel

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" ] 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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; } } } 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

www.conf

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 
Enter fullscreen mode Exit fullscreen mode

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;" 
Enter fullscreen mode Exit fullscreen mode

Build the Image

docker build . OR with tag docker build -t sampleapp:v1 . 
Enter fullscreen mode Exit fullscreen mode

Run a Container

docker container run -d -p 8080:80 [docker_image] docker container run -d -p 8080:80 sampleapp:v1 
Enter fullscreen mode Exit fullscreen mode

Hopefully this article helps you!

Top comments (0)