My perfect php-fpm docker image. For everyone who uses docker in their web projects on php, the question arises of building a container for your project. Someone uses Apache-based containers with php as a module, but I, like most developers, prefer to build my container for a php-fpm-based application. The main problem is that the original php.
- I set up my docker-compose.yml file so one docker instance would use the composer/composer image and execute composer install within a shared container. All of the other images would then be able to access the vendor directory that composer created.
- In this docker file, we’ll install PHP packages on Ubuntu image with composer and will copy the www.conf and php-fpm.conf files from the host and add the content of the guest folders.
- Jumping through the history of that file you can easily find the version that last included php-7 in one of the steps. The digest listed there can then continue to be used in projects needing PHP 7 composer support in docker. Thes same process can be used for any docker image in the docker image library on docker hub.
Reading Time: 6 mins.
Docker Virtualization, known for its simple and convenient way of deploying applications is the best-to-go option for every developer and organisation. With its container-based technology, and built-in features such as docker-compose, docker images, docker volumes, docker hub and so on, it has further streamlined the development process as you can define the infrastructure along with volumes, networks and applications in a single file. Also, it offers the flexibility to run multiple applications on the provided host or directly executing the container within the host environment per se.
Here, in this article, a basic working environment will be created by setting Nginx as a web server and MySQL as the database, all within separate Docker containers. The entire stack including the config. files such as PHP, Nginx and MySQL will be defined in the docker-compose file.
- A Ubuntu 18.04 server with sudo (non-root user) privileges.
- Installed Docker and Docker Compose, if you haven’t installed yet, go to How to Install Docker on Ubuntu 18.04
Step 1: Creating the project folders
You need to create the following files and directories to get started with the demo project.
Step 2: Creating the required config. files
i) Nginx site configuration
Get started with the nginx folder using the command below
Next, open the file, site.conf using the below command.
Note: It is the fastcgi_pass php:9000; that guides Nginx on how to connect with PHP containers.
ii) Creating index.php file:
To get started with the webcontent folder, type:
Next create a file called index.php
To open the created index.php file, type:
iii) Creating php.ini file:
Since the php.ini file copied to the php container is used here, we can straightway make changes in the php.ini file. Post then just restart the container for the changes to get applied.
In case, if you make changes within the php code of the index.php file, you need not to restart the container. All the changes will immediately get applied once the browser page reloads. Here, “depends_on” – restricts the container from running before other container (on which it depends on)
Step 3: Creating docker-compose yaml file
In the docker yaml file, we are going to integrate the following services,
Next, open the yaml file using the below command.
Note: Make sure that you stick with the syntax to avoid errors as the docker yaml file is case sensitive.
Step 4: Proceeding with data persistence
Docker comes with a number of flexible features that ensure that every other required task can be done within the Docker software itself. One such powerful offering is Docker Volumes where you can persist (save data) the database, config files, applications, etc. In simple words, Docker Volumes helps in back up and persistence beyond the container’s lifecycle.
Now to get started with the MySQL database persistence using Docker Volume, go to docker-compose file wherein under the db service define a volume called dbdata.
Next add dbdata in the docker-compose yaml file as shown below:
Note: Include these lines at the end of the docker yaml file. Once you have included it, it will look like the following code.
Step 5: Running the docker container
First, we will run the docker yaml file using docker-compose followed by checking the docker container status, port and shell access.
Let’s run the yaml file, and it can be achieved via two commands.
i) Docker-compose up
We can run the docker yaml file using the Docker-compose up command but it will end up displaying increased logs or verbose.
ii) Docker-compose up -d
This Docker-compose up -d command helps you to quickly run the docker-compose yaml file without displaying any verbose.
Here, we are proceeding with the latter command.
Note: If you already have the images, you can directly use it in Docker. If not, download the image using the pull command from Docker Hub.
Post downloading the image from Docker Hub, the Docker containers will automatically be up and running.
Note – If the image is already in local you will get a following output directly
To check the docker container status, type:
To check the docker image status, type:
Step 6: Adding domain to etc hosts
Either you need to add a container ip address or localhost url in etc hosts. Here, we are going with the localhost url.
Open the etc file using the following command.
Note: Include the same domain, docker-demo.com as you used in the nginx site configuration.
Step 7: Verification
To directly access the docker container shell, enter the below command.
Hit the localhost domain which you have added in etc hosts.http://docker-demo.com
Just to emphazise, if you have noticed, it is the Docker that plays a vital role in simplifying the development process. Want to read more about Docker and its number of capabilities, read our blog post on A Brief Introduction to Docker and Its Terminologies Setting up a stack with Nginx as a web server and MySQL as the database with required PHP config. files is not an easy and one-step process. With Docker Compose which allows you to create multiple containers, you can define the infrastructure along with the required config. files within a single file using a single command.
Php Docker Image With Composer Command
For everyone who uses docker in their web projects on php, the question arises of building a container for your project. Someone uses Apache-based containers with php as a module, but I, like most developers, prefer to build my container for a php-fpm-based application.
The main problem is that [the original php-fpm] (https://hub.docker.com/_/php) does not contain many php modules for full work, as well as auxiliary software, which is regularly required.
The situation is aggravated if it is necessary to support several projects on the same stack. This is just my case, as I support and refine [usually more than 10k projects] (/ projects.html) on the Yii2 framework. They all use approximately the same stack: [Yii2 framework] (https://www.yiiframework.com/), php-fpm, nginx, memcached and the mysql or postgres database.
So, in the base container with php-fpm, you need to add the following php libraries:
- GD - necessarily compiled with WEBP support;
- IMAP - for sending mail;
- Zip - at least for working with backups;
- Intl - a necessary module for internationalization;
- Pdo_mysql - for working with Mysql;
- Pdo_pgsq l - for working with Postgresql;
- Memcached - for organizing caching;
- Xdebug - I disable it by default and activate it only during development.
In addition to these libraries, I put additional software:
Git ended up on this list because it is needed for composer. I install zip, since I use the [Yii2 backup module] (https://floor12.net/packages/yii2-module-backup.html), which uses zip for compression. [FFmpeg] (https://www.ffmpeg.org/) I install so that the [file handling module for Yii2] (https://floor12.net/packages/yii2-module-files.html) converts video files. I install console clients for mysql and postgresql for universality, since my applications work with both databases, and in some cases with two at the same time.
As a result, I get a universal and quite flexible php-container, which has everything you need to develop, launch a project in production or create a final image based on it.
For the convenience of supporting the two php branches that I need, I store them in different branches of the repository. I build them through gitlab CI and store them in the public domain in the same place, in [gitlab registry] (https://gitlab.com/floor12/images/container_registry/) .
After the development phase, when it is necessary to assemble the project into a separate image for launching in production, I usually create it based on the images mentioned above. Copy to container:
- project files necessary for work;
- php.ini config, which contains the optimal parameters for the project (at least increase
post_max_size, set the time zone);
- config for nginx, which in the future will be shared with a container running nearby;
- config for the database, if it needs any additional settings.
Then I start the installation of dependencies through
composer install --no-scripts --prefer-dist --optimize-autoloader. But at the same time, in the final assembly I also have packages from dev-dependencies ([codeception] (https://codeception.com/), debug and other components necessary for testing). Since when building applications in CI, I am testing a container that will go directly to production, it needs dev dependencies in it. After the tests, they can be removed from the container. I will talk about this in other articles.
If you want to slightly reduce the size of the final production image, it is possible to build it not on the basis of these images, but edit their original [dockerfile] (https://gitlab.com/floor12/images/-/blob/basic74/Dockerfile-basic) under yourself, removing the extra software from there. In addition, you can remove all unnecessary software from the container even after the application is built. But I do not use this approach. It’s more convenient for me that the images do not differ from each other for the convenience of supporting projects: sometimes you need to connect to the container and already have in it all the necessary tools for debugging and useful utilities.
Php Docker Image With Composer Studio Code
At the time of this writing, the image is being built using the dockerfile below. However, its current version can be found in the [repository on hitlab] (https://gitlab.com/floor12/images).