Skip to content

Instantly share code, notes, and snippets.

@asahasrabuddhe
Last active March 31, 2019 08:42
Show Gist options
  • Save asahasrabuddhe/aa2e2a994f32d5e4bb6010b59acb5e9e to your computer and use it in GitHub Desktop.
Save asahasrabuddhe/aa2e2a994f32d5e4bb6010b59acb5e9e to your computer and use it in GitHub Desktop.
Dockerize your PHP Laravel Development workflow
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html/public
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

Docker Workflow for PHP Laravel Development

Through this guide we will try to outline an ideal flow to begin development with PHP/Laravel using Docker. Following this guide would also address some of the common issues that are faced by most developer when adopting such a flow. Without further ado, let's begin.

Permissions

When working in an containerised environment, it becomes difficult to manage permissions effectively leading to some nasty errors. We would ideally want our filesystem configured in such a way that it would give us correct permissions to create/edit files on our favourite IDE and at the same time give us the flexiblity to use framework tools like Artisan, from inside the container and have everything behave correctly with one another. Fortunately, there is a simple solution. Following the script below will ensure that all permissions are set correctly and we are good to go.

The groups command reveals a list of groups the current user is a part of

groups $USER

Closely analyse the output of this command. Look for group name www-data in the listing. If www-data is present, your user is already a part of the www-data group and you can safely ignore the next command.

sudo usermod -aG www-data $USER

This command will add the current logged in user (you) into the www-data group. Close all open terminal instances and re-open a fresh new terminal for the changes to take effect. If things still do not work out, just reboot your machine :)

The first step will involve creating a new Laravel project for us to start developing with. In cases where you want to dockerize your existing application, you can skip this step.

docker container run -v $(pwd):/var/www/html --user $(id -u):www-data ajitemsahasrabuddhe/php-apache:bionic-7.3-dev composer create-project --prefer-dist laravel/laravel laravel-project

This command will take a while to finish, depending on your internet connection. Once this command finishes, you will have a fresh project created in a folder ```laravel-project`` in our working directory.

Moving on, we will now set correct permissions for our project directory where we would be keeping our code during the time of development. For me, this directory happens to be laravel-project. When following this guide, make sure to substitute this path with the path of your Projects directory.

sudo chown -hR www-data:www-data ./laravel-project

sudo find ./laravel-project -type f -exec chmod 664 {} \;
sudo find ./laravel-project -type d -exec chmod 775 {} \;
sudo find ./laravel-project -type d -exec chmod g+s {} \; 

What the above commands will do is, change the group of the Projects directory to the www-data. Next, we give read, write permissions to the owner (you) and all members of it's group. As we are already a member of the www-data group, we will simply inherit the appropriate permissions. The last commands sets the group ID on the directory so that any subsequent files and folders created within this directory are automatically owned by the group.

Next, we will go ahead and start setting up the remaining part of our development environment like database and adding other configurations to the mix. If you already have a working codebase, you can continue this tutorial from here and replace the laravel-project folder with your own code folder.

Configurations

Copy the other files from this gist i.e. docker-compose.yml, 000-default.conf, supervisor.conf, xdebug.ini into your project folder.

The docker-compose file will help us manage a default webserver container with php to run the application, a database instance to store data. In case of other software like redis, we can modify the docker-compose file to manage those containers as well.

The 000-default.conf provides default Apache configuration to enable Laravel to function.

The supervisor.conf is responsible for the core function of the container. It starts and manages the core processes like apache, cron etc. Additional processes like the queue:listen or horizon can be configured through here.

The xdebug.ini exposes the PHP debugger allowing us to debug the code line-by-line through popular IDEs like PHPStorm.

Run

Once all the configuration is in place and modified as per need, you can use the command docker-compose up -d to start the application. docker-compose down will stop all the containers when your work is done.

Please note that use of this image is considered in an environment where PHP / Apache / Nginx etc are not installed and available locally. Please ensure that you run all the commands in the context of the application like composer or php artisan etc from INSIDE the container. Doing so from the outside using the PHP available on your system can lead to undesirable results.

version: '3'
volumes:
myapp-db-vol:
services:
mysql:
image: mysql:5.7
volumes:
- myapp-db-vol:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: myApp@2019
MYSQL_DATABASE: myApp@2019
ports:
- 3308:3306
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
PMA_HOST: mysql
MYSQL_USER: root
MYSQL_PASSWORD: myApp@2019
ports:
- 8070:80
depends_on:
- mysql
www:
image: ajitemsahasrabuddhe/php-apache:bionic-7.3-dev
ports:
- 81:80
volumes:
- ./:/var/www/html
- ./000-default.conf:/etc/apache2/sites-available/000-default.conf
- ./supervisord.conf:/etc/supervisor/supervisord.conf
- ./xdebug.ini:/etc/php/7.2/apache2/conf.d/20-xdebug.ini
environment:
XDEBUG_CONFIG: remote_host=172.17.0.1
restart: always
depends_on:
- mysql
[supervisord]
nodaemon=true
logfile = /var/log/supervisord.log
logfile_maxbytes = 50MB
logfile_backups=10
pidfile = /var/run/supervisord.pid
[program:cron]
autorestart=true
command=sudo /usr/sbin/cron -f
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:apache2]
autorestart=true
command=/usr/local/bin/apache2-foreground
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
# optional config, can be enabled if using horizon
# [program:horizon]
# autorestart=true
# command=/usr/bin/php /var/www/html/artisan horizon
# stdout_logfile=/dev/stdout
# stdout_logfile_maxbytes=0
# stderr_logfile=/dev/stderr
# stderr_logfile_maxbytes=0
zend_extension=xdebug.so
xdebug.remote_enable=on
xdebug.remote_autostart=off
@soniraju
Copy link

Please update image name from ajitemsahasrabuddhe/php-apache:7.3-dev to ajitemsahasrabuddhe/php-apache:bionic-7.3-dev

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment