- Updating PHP 5 (or any other) Apps with Docker
- PHP 7 Breaking Changes
- Docker PHP5 / PHP7 in parallel
- Docker Compose: Mounting the Code
- Full PHP5, PHP7 Dockerfiles
- How To Update Laravel Sail To PHP v8.1
- Update The docker-compose.yml File
- Method 1: PHP 8.1 Update Only
- Method 2: PHP 8.1 + mysql/mysql-server:8.0 Image Update
- Build The sail-8.1 Docker Image
- Top comments (0)
- Read next
- PHP Artisan Tinker: A Practical Guide for Laravel Developers
- Applying Content Security Policy in Symfony to Reduce XSS Risks
- Working with PHPUnit in VSCode
- How to automate tests by Github Workflow with Laravel Pint and PHP Pest
- How to Upgrade PHP to Latest Version
- 10 PHP Frameworks For Developers – Best of
- Upgrading PHP in macOS
- Upgrading PHP in Windows
- Upgrading PHP in Ubuntu
- Upgrading PHP in Docker
- Wrapping Up
Updating PHP 5 (or any other) Apps with Docker
PHP5, released in 2014, has reached its end of life in 2018, but many hosters continued to support it. If you have any custom PHP applications, you might still be running them on a server that has a PHP5 runtime.
The upgrade path for these applications might not be obvious, but I found a way that should make it easier, so in this article we’re going to have a look at running PHP simultaneously with PHP5 and PHP7 using docker and docker-compose .
PHP 7 Breaking Changes
PHP 7 introduced lots of breaking changes like different variable accessing, foreach loops and also deprecating and removing functions like:
- call_user_method()
- call_user_method_array()
- ereg() — Regular expression match
- eregi() — Case insensitive regular expression match
- ereg_replace() — Replace regular expression
- eregi_replace() — Replace regular expression case insensitive
Alright, so this means that we need to take all those functions and replace them with their new and improved counterpart, enter Docker!
Here’s the example PHP code we’ll use in this example ( index.php ):
// will not work in PHP7 $string = 'XYZ'; if (eregi('z', $string)) < echo "'$string' contains a 'z' or 'Z'!"; > // will work in PHP7 $string_new = 'XZY'; preg_match('/z|Z/', $string_new, $matches); if(count($matches)>0)< echo "'$string_new' contains a 'z' or 'Z'!"; > ?>
Docker PHP5 / PHP7 in parallel
For my case, I needed to port some code from PHP5 to PHP7, because running outdated software is an easy security vulnerability.
I needed a way to run the code in parallel with different PHP versions, to be sure that A: it still works, and B: it works as it did before.
Even though some changes are breaking like the removal of the eregi() function, the alternative function that you’re supposed to use, already works fine on PHP5.
So basically what I had to do was to get it running in both versions (for the most part). I created two directories for the different Dockerfiles and then used docker-compose up to run them both at once.
The Dockerfiles for the different PHP versions we can lock by the following differences:
# Base image FROM php:5.6-apache
# Base image FROM php:7.3-apache
The full Dockerfiles are pasted below.
Docker Compose: Mounting the Code
To mount our code into the different containers we’ll make use of the volumues property of our services. Lest’s have a look at our docker-compose.yml and break it down below:
version: "3.1" services: web1: build: docker/php5-6-apache2 container_name: php5-container volumes: - ./php-project-src:/var/www/html/public ports: - "8080:80" web2: build: docker/php7-3-apache2 container_name: php7-container volumes: - ./php-project-src:/var/www/html/public ports: - "8081:80"
As you can see it has two nearly identical sections describing the services web1 and web2 , which both mount the source code from the php-project-src directory into the container’s web server directory at /var/www/html/public and they each get their own Dockerfile from the different directory through the build property.
If I know run docker-compose up , I get the output of both docker containers and they’re listening on localhost:8080 and localhost:8081 .
Starting php5-container . done Starting php7-container . done Attaching to php7-container, php5-container php5-container | [Sun Feb 09 21:12:13.770033 2020] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.25 (Debian) PHP/5.6.40 configured -- resuming normal operations php5-container | [Sun Feb 09 21:12:13.770070 2020] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND' php7-container | [Sun Feb 09 21:12:13.782147 2020] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.38 (Debian) PHP/7.3.11 configured -- resuming normal operations
In my browser I can now see that the PHP7 container at port 8081 is not happy with me attempting to use the horrible and deprecated eregi function:
Fatal error: Uncaught Error: Call to undefined function eregi() in /var/www/html/public/index.php:5 Stack trace: #0 thrown in /var/www/html/public/index.php on line 5
While at http://localhost:8080 everything is tip top and the output is:
'XYZ' contains a 'z' or 'Z'! 'XZY' contains a 'z' or 'Z'!
That’s it, now we can work on the source code, comment and uncomment parts and hack away until our project is fully ported to PHP7!
If you found this useful, consider saying hello on twitter or joining a code stream on twitch 🙂
Full PHP5, PHP7 Dockerfiles
# Base image FROM php:5.6-apache # Fix debconf warnings upon build ARG DEBIAN_FRONTEND=noninteractive # Run apt update and install some dependancies needed for docker-php-ext RUN apt update && apt install -y apt-utils sendmail mariadb-client pngquant unzip zip libpng-dev libmcrypt-dev git \ curl libicu-dev libxml2-dev libssl-dev # Install PHP extensions # RUN docker-php-ext-install mysqli bcmath gd intl xml curl pdo_mysql pdo_sqlite hash zip dom session opcache # Update web root to public # See: https://hub.docker.com/_/php#changing-documentroot-or-other-apache-configuration ENV APACHE_DOCUMENT_ROOT /var/www/html/public RUN sed -ri -e 's!/var/www/html!$!g' /etc/apache2/sites-available/*.conf RUN sed -ri -e 's!/var/www/!$!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf # Enable mod_rewrite RUN a2enmod rewrite
# Base image FROM php:7.3-apache # Fix debconf warnings upon build ARG DEBIAN_FRONTEND=noninteractive # Run apt update and install some dependancies needed for docker-php-ext RUN apt update && apt install -y apt-utils sendmail mariadb-client pngquant unzip zip libpng-dev libmcrypt-dev git \ curl libicu-dev libxml2-dev libssl-dev sqlite3 # Install PHP extensions RUN docker-php-ext-install mysqli bcmath gd intl xml pdo_mysql hash dom session opcache # Update web root to public # See: https://hub.docker.com/_/php#changing-documentroot-or-other-apache-configuration ENV APACHE_DOCUMENT_ROOT /var/www/html/public RUN sed -ri -e 's!/var/www/html!$!g' /etc/apache2/sites-available/*.conf RUN sed -ri -e 's!/var/www/!$!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf # Enable mod_rewrite RUN a2enmod rewrite
Thank you for reading! If you have any comments, additions or questions, please tweet or toot them at me!
How To Update Laravel Sail To PHP v8.1
PHP 8.1 support added to Laravel Sail starting from v1.12.0. Meanwhile, they have replaced the mysql:8.0 Docker image with mysql/mysql-server:8.0 image in this pull request. Keeping all these things in mind, let’s update the Laravel Sail to the latest version to use PHP 8.1. First of all, update the Laravel Sail Composer package.
composer update laravel/sail
Update The docker-compose.yml File
Since Laravel Sail changed its MySQL Docker image, you can decide whether use it or continue with the mysql:8.0 image that you already have. If you decided not to continue with the updated image, follow Method 1 or otherwise, follow Method 2 as described below.
Method 1: PHP 8.1 Update Only
If you have valuable data in your development database and willing to continue using the mysql:8.0 Docker image without taking any risk or just want to use PHP 8.1, open the docker-compose.yml file and replace the 8.0 in the context: ./vendor/laravel/sail/runtimes/8.0 line to 8.1. Also, replace the 8.0 in the image: sail-8.0/app line to 8.1. So the final docker-compose.yml file should be similar to this.
version: '3' services: laravel.test: build: context: ./vendor/laravel/sail/runtimes/8.1 dockerfile: Dockerfile args: WWWGROUP: '$' image: sail-8.1/app
Method 2: PHP 8.1 + mysql/mysql-server:8.0 Image Update
- mysql
- pgsql
- mariadb
- redis
- memcached
- meilisearch
- minio
- mailhog
- selenium
However, only mention the services that you need using the —with .
php artisan sail:install --with mysql,mailhog,redis
Build The sail-8.1 Docker Image
Once you prepared the docker-compose.yml file, remove existing containers with the following command.
./vendor/bin/sail build --no-cache
Start the application in detached mode.
If you followed Method 2, you might not be able to start the MySQL container as it tries to use the old MySQL volume created with the mysql:8.0 image. Under that situation, remove the existing containers along with all the volumes.
Now start the application as usual.
Run the following commands to see whether the update is successful.
./vendor/bin/sail php -v PHP 8.1.0 (cli) (built: Nov 25 2021 20:22:22) (NTS) Copyright (c) The PHP Group Zend Engine v4.1.0, Copyright (c) Zend Technologies with Zend OPcache v8.1.0, Copyright (c), by Zend Technologies with Xdebug v3.1.1, Copyright (c) 2002-2021, by Derick Rethans
Print the Composer version.
./vendor/bin/sail composer --version Composer version 2.1.14 2021-11-30 10:51:43
./vendor/bin/sail node -v v16.13.1
Feel free to visit devtonight.com for more related content.
Top comments (0)
For further actions, you may consider blocking this person and/or reporting abuse
Read next
PHP Artisan Tinker: A Practical Guide for Laravel Developers
Applying Content Security Policy in Symfony to Reduce XSS Risks
Jarosław Szutkowski — May 14
Working with PHPUnit in VSCode
How to automate tests by Github Workflow with Laravel Pint and PHP Pest
Maniruzzaman Akash — May 13
How to Upgrade PHP to Latest Version
PHP7.4 has been released with a handful of new features — like the arrow function array_map(fn (Foo $foo) => $foo->id, $foo) , typed properties and array spread operator [‘foo’, . $foo, . $bar]; — and that it’s also faster compared to PHP7.3.
So if you’re thinking to update PHP on your machine, take a look at the following post in which I’ll show you how to do so in several ways.
10 PHP Frameworks For Developers – Best of
PHP, known as the most popular server-side scripting language in the world, has evolved a lot since the. Read more
Shortcuts to:
Upgrading PHP in macOS
To begin with, you’ll have to check the PHP version that’s currently installed in your system by typing the following command line:
As we can see below, we are currently using PHP 7.3.7 on our macOS.
Arguably the easiest way to install and update PHP on your macOS machine is by using Homebrew. Homebrew is a package manager for macOS though it is now also available in Linux and Windows too. With Homebrew, you can type the following command.
The process may take a bit long, however, once it’s done you can run the php -v command again. You should now see that the version is updated:
Upgrading PHP in Windows
If you’re using Windows, it’s much easier to run your PHP application on a pre-packaged localhost environments such as WAMP or MAMP. These applications comes with PHP pre-installed and configured. You will just need to update them to their latest version or install it using the built-in tool to get the latest PHP version.
In addition to that, both WAMP and MAMP provide an option within the application to switch PHP easily.
Upgrading PHP in Ubuntu
As mentioned previously, you should first check the PHP version that’s in your Ubuntu machine.
As you can see above, currently I have PHP7.3 installed. In Ubuntu, the PHP package can be installed from the ondrej/php respository. First, run the following command to tap the repository.
sudo add-apt-repository ppa:ondrej/php sudo apt-get update
Then, we can run the following commands which will install PHP7.4, some PHP extensions and packages, and the PHP CLI.
sudo apt-get install php7.4 php7.4-common php7.4-cli
That’s all. Your Ubuntu machine will successfully be running PHP7.4 and you can confirm by running the php -v command again.
Upgrading PHP in Docker
The latest PHP version is also available as an official Docker image. Docker is compatible in several different platforms including macOS, Windows, and Linux so you should be able to follow the same procedure for all these operating systems.
To do so, first I’d like to see if I have the Docker image for PHP7.4 in my machine.
It looks like that I don’t have it yet. Let’s type the following command to download the image. This command will download the Docker image for PHP7.4 in the Alpine Linux flavour which smaller than the Debian-based image thus also faster to download. You can find the full list of the Docker image available in Docker Hub.
docker pull php:7.4-fpm-alpine
Once downloaded, we could run it as standalone container with this command below:
docker run --rm -i -t php:7.4-fpm-alpine sh
The container should be up and running in a second and immediately creates a Shell session inside the container. If we run the php -v , we should be seeing that it is the PHP7.4 within the Docker container.
Wrapping Up
That’s all how to install and update PHP version to the latest. It’s not as complicated as you’d expected, isn’t it? Finally, PHP core development is progressing at a rapidly with PHP8 aimed for the next release by the end of this year with, of course, some interesting features and improvements. It’s an exciting time to be a PHP developer.