Laravel + Docker: our successful experience
The article will discuss our experience of using Docker to quickly configure a scalable dev environment for web development. I will briefly talk about the tasks that confronted us and the tools that were chosen to solve these problems. The article can be marked with the tutorial icon, because you will find instructions on deploying the environment in it. Compared to similar articles, there will be less technical details and more real examples.
What tasks did we face?
It happens that a new developer connects to an existing team. To make him begin performing tasks (in other words, write code and check his work), it is not enough to get the source code. You need an environment that includes a web server, php compiler and database. This is a minimal set. Depending on the project, the environment may include:
- NoSQL
- Queue Server
- Full-text search engine;
- Caching solution;
- Pickers;
- Useful developer tools
All this must be installed locally for the developer, and be the same versions as for the rest of the team members. And here there are difficulties:
- After installation, you need to configure it;
- The software is already installed, but it is a different version;
- It is a long time;
And the fact that developers work on different platforms (windows, linux, os x) makes things even more complicated.
To solve the problem, was chosen Docker. Perhaps the main reason is that it easily fits into the existing infrastructure. It works great on Linux, and most of our developers work on this OS.
Alternative
Laravel provides its own solution for organizing a local environment called Homestead. This is a set of configs and scripts for Vagrant, with the help of which the necessary software is deployed in the VirtualBox virtual machine. But a Homestead description is beyond the scope of this article.
Laradock Project
In the beginning, this project was aimed solely at launching Laravel on Docker, which is reflected in its name. But as popularity grew in the php community, Laradock began to support other php projects: Symfony, CodeIgniter, WordPress, Drupal. The project is really popular, actively supported and developed:
Laradock is a set of pre-configured, independent Docker images that you can mount based on the requirements of your project. Well documented and extremely easy to use. To start components, we simply list them:
1 |
docker-compose up apache2 php-fpm mysql phpmyadmin |
or
1 |
docker-compose up nginx php-fpm mariadb adminer |
Note: there is no need to explicitly specify php-fpm, since when the php-fpm container web server starts, the container starts automatically.
The repository has more than 48 containers, including:
- Databases: MySQL, MariaDB, Percona, MongoDB, MSSQL, PostgreSQL
- Database Management: PhpMyAdmin, Adminer, PgAdmin
- Web servers: nginx, Apache2, Caddy
- PHP compilers: PHP FPM, HHVM
- Miscellaneous: Selenium, Jenkins, ElasticSearch, Kibana, Gitlab, Mailhog, MailDev, Laravel Echo, Phalcon
- Tools: PHP CLI, Composer, Git, Linuxbrew, Node, V8JS, Gulp, SQLite, xDebug, Envoy, Deployer, Vim, Yarn, Drush
Requirements and initial conditions
You will need:
- Git
- Docker
and the console in which the commands will be executed. The docker website has comprehensive documentation on installing for different platforms (links are also at the end of the article). If you have not already installed git, do it according to the instructions from the official site.
Git repository architecture: main project and Laradock
Laradock can be used in two versions:
- Separate laradock for each project
- One laradock for many projects
In the first case, the directory structure will look like this:
In the second, like this:
We always use the first option: one project – one laradock. It is this approach that provides flexibility and independence of one project from another.
The second important question is: create one common repository or two separate ones? In other words, do I need to add laradock files to the main repository with the project? The answer is necessary, but in the form of a submodule to the main repository. Docker environment is an auxiliary part of the project and it is not always required. For example, on staging and production servers, it is not necessary. When you deploy using git, the environment files will not get there.
The name of the environment directory
By default, container names use the name of the current directory as a suffix: laradock_nginx_1, laradock_mysql_1, etc. To avoid confusing data within volumes, unique directory names are required for your environments. This is easy to achieve if we stick to our chosen scheme: add the project name to the name of the directory with the environment, for example:
- laradock-mysite
- laradock-proj1
- laradock-mobapp
that is, the prefix “laradock” and the name of the directory with the project through a hyphen.
One site launch
How do we start the launch of the site?
As we mentioned in the third chapter, we use Laradoc to create the environment.
The startup process consists of the steps to configure the environment and the laravel application.
Project settings
Laradoc includes an example environment configuration file. We create a copy for our project.
1 |
cp env-example .env |
The .env options are pretty obvious. In the parameters we set database access, email parameters, access to third-party services, if we use it in our project.
Starting and stopping environment applications are done by docker-compose commands
1 |
docker-compose up |
and
1 |
docker-compose stop |
If necessary, in the start command, you can call the download of the necessary services. For example, three additional services will be loaded this way:
1 |
docker-compose up -d nginx percona adminer |
You can remove this command in a separate shell script so that you do not have to enter it manually each time.
The startup script can be called “start.sh”, or whatever you like:
1 |
#! / usr / bin / env bash |
docker-compose up -d nginx percona adminer;
1 |
The service stop script can be called “stop.sh”, or “down.sh”: |
1 |
#! / usr / bin / env bash |
1 |
docker-compose stop; |
Project Initialization
The transition to the container environment is performed by the command
docker-compose exec –user = laradock workspace bash
Deployment Errors
When installing Laradoc in a linux environment, there may be a problem with file permissions.
In this case, the files may have the wrong owner, or insufficient access rights.
Symptoms: when you try to start the environment with the docker-compose up command or go to the container with the docker-compose exec … command, as in the example above, errors similar to those
1 |
/ var / www / vendor does not exist and could not be created |
The stream or file “/var/www/storage/logs/laravel.log” could not be opened: failed to open stream: Permission denied
The reason for the error is that in the docker environment configuration example the User ID and User Group are hard-coded, by default 1000 and 1000 respectively.
If in our unix-system these IDs are already occupied by other entities, then you need to manually edit the configuration.
Error correction procedure
Check the user and group at the directories:
1 |
ls -la / var / www |
File and directory owners (User and User Group) must be laradock laradock.
If instead of laradock: laradock the owner and group are indicated by numbers (1001: 1001, 1001: 13002 and similar combinations), then you need to make changes to the settings files.
If your User ID and User Group (/ etc / passwd, / etc / group) do not match the specified ones, then for correct operation, you need to make changes to the following files:
/laradock/php-fpm/Dockerfile*, in a row «RUN usermod -u 1000 www-data» change 1000 to User ID /laradock/.env in rows WORKSPACE_PUID=1000 WORKSPACE_PGID=1000 WORKSPACE_PUID — User ID, WORKSPACE_PGID — User Group ID /laradock/workspace/Dockerfile*, in rows ARG PUID=10315 ARG PGID=10004 PUID — User ID, WORKSPACE_PGID — User Group IDAfter making the changes, rebuild the workspace and php-fpm again and then start the container:
1 |
docker-compose build workspace php-fpm |
If you encounter such a problem, then you need to check the access rights to the directories of the Laravel framework. Set permissions on directories for which write permissions are required:
1 2 |
sudo chgrp -R www-data storage bootstrap / cache; sudo chmod -R ug + rwx storage bootstrap / cache |
SSL certificates and https
Most likely your site in production will work according to a secure protocol. It makes sense to conduct local development on https. This is not very difficult to do, you need an SSL certificate and small settings. This article is described in more detail in How to Issue a Self-Signed SSL Certificate.
Running multiple sites
So, all projects work according to the scheme “One Laradock – one project”. But one project is not necessarily one site. Sometimes you need to run several sites at the same time, because they will interact with each other.
In this case, two laradock cannot be started at the same time, because in each of them a web server is launched that listens to port 80 – we get a conflict. But we have access to nginx config files, let’s configure it.
But first, a note on architecture and git repositories. In the case of several sites, we use the directory structure from the second option:
Git repository with laradock is no longer a submodule of another repository, but becomes completely independent.
Web server configuration will be shown using nginx as an example. In the laradock directory, go to nginx / sites. We see default.conf and several * .conf.example files. Based on default.conf or sample files, we create configurations for sites.
Pay attention to document root. By default, the root directive looks like this:
1 |
root / var / www / public; |
but should be like this:
1 |
root / var / www / site-1 / public; |
1 |
root / var / www / site-2 / public; |
Important!
Take a look at the contents of the .gitignore in this directory. All * .conf files except default.conf are ignored. You need to add the created files to the exceptions, do not ignore them.
Configure crontab so that the laravel scheduler can work correctly. To do this, add the paths in the workspace / crontab / laradock file:
1 2 |
* * * * * laradock / usr / bin / php / var / www / site-1 / artisan schedule: run >> / dev / null 2> & 1 |
1 2 |
* * * * * laradock / usr / bin / php / var / www / site-2 / artisan schedule: run >> / dev / null 2> & 1 |
For successful communication of sites inside containers, add aliases. In the docker-compose.yml file we find the section
### NGINX Server ###
and add an alias to each domain:
This is all you need to do to run a project with multiple domains. All by analogy with the ssl organization for one domain, which is described in the section above. Add a comment if you have any difficulties, I will answer it or describe the features in a separate article.
Additional features
In the Docker environment, it is possible to configure the applications we need. The Laradoc base configuration already includes application packages:
- Web Application Server Apache2, Caddy
- Caching Nginx, Varnish Web Applications
- Databases and caching services Mongo, Redis, Mssql, Mysql, Percona, Mariadb, Elasticsearch, Memcached, Redis, RethinkDb, Aerospike
- Web interfaces to the Adminer databases, PhpMyAdmin
- Haproxy load balancer
- Programming, shells and frameworks Php, Python, Symfony, Laravel, Node
- Utilities Php, Python, Symfony, Laravel, Node
- Package Manager Yarn, Composer
- Jenkins Testing Tool
- Terraform Application Infrastructure Configuration Tool
Lets briefly consider the most mentioned applications.
Rabbitmq
A mechanism for messaging between applications. The developer of this package defines its purpose as: “queue manager”, “message broker” or “message queueing”.
A message may contain any data set.
In the scenario of working with the queue manager, a message from one application – the sender – is saved until another application (recipient) connects and picks up (receives) the message from the queue.
Redis
Creating a data cache in RAM. It can also be used as a data warehouse along with a database server, or replacing it.
Redis supports strings, lists, sets, ordered sets, and hash tables.
The main drawback of radishes is data loss in the event of RAM cleaning, when the OS reboots, or when the equipment is turned off. Radish developers have envisioned a similar scenario: in AOF (Append Only File) mode, data is added to the disk file every second.
The main advantage of radishes is the fastest access to data with the speed of access to RAM.
Conclusion
Choosing Laravel + Docker for web development, we won the most valuable prize: time.
Following the development scenario in WAMP or LAMP, we had to spend time useless and nowhere.
Both WAMP and LAMP require a php developer to have a certain level of skill in areas that are not directly related to web development: configuring a web server, configuring php parameters, etc.
Using Laradoc allows us, once having created the entire project environment, to deploy it in a new workplace in the shortest possible time. And get to work right away.
In conclusion, we note the benefits of using Laradoc:
- unified infrastructure at each workplace: web server, sql server, a set of frameworks and libraries;
- rational use of working time;
- quick entry of a new developer into the project.
Write in the comments how your team works with the
environment, what tools and approaches you use.
Related Posts
Leave a Reply Cancel reply
Service
Categories
- DEVELOPMENT (103)
- DEVOPS (53)
- FRAMEWORKS (26)
- IT (25)
- QA (14)
- SECURITY (13)
- SOFTWARE (13)
- UI/UX (6)
- Uncategorized (8)