devilbox
devilbox copied to clipboard
(Community Discussion) Run multiply PHP versions at the same time
Community Discussion: multiple PHP versions
Hi everybody,
hope you enjoy the devilbox so far. I was thinking about a new feature, which might be a bit difficult to get it done, could however be something very useful for some of you:
Feature
Be able to run multiple PHP-FPM container at the same time
Benefits
- test your site simultaneously with different PHP versions
- useful for migrating from one version to another
- useful for continuous integration tests against multiple versions
Feedback
Before I am going to wrap my head around this, I wanted to check back with you guys, If it is actually any useful for you. So if this is of any use for you, let me know. Also if you have something similar in mind, just give me a comment here.
There is a huge benefit to allowing multiple PHP versions. Setting a specific project to a different version of PHP other than the default is extremely useful. I personally don't need to test against multiple versions...but I can certainly see how that might be useful for some developers. The main benefit for me is that I can make sure a specific project is running the same version of PHP that is on the production server. My own server runs the same version of PHP for virtually every project...but that's not always the case for some of my other clients. While most of my projects run either PHP 7.0 or 7.1, I do have some that are still running on PHP 5.6. The ability to run a project on PHP 5.6 without having to spin up a completely different container is incredibly helpful. Definitely would welcome this feature for sure! :D
I think, this would be great. There are many projects running with a different php version, so this would make my work easier. At the moment, i have to upgrade a project from php 5 to 7. The php 5 project is not compatible with php7, so i have to switch the php version everytime when i will test the old one.
I don't know, how you will make this possible, but maybe you can combine it with server version.
Well, one way that might be possible is to setup handlers for each version installed. Pretty much the way most hosting providers do it. That way, if the default is set to PHP 7.0 but you want to use PHP 7.1 to test an application, all you would need to do is add the following to your .htaccess file:
AddHandler application/x-httpd-php71 .php .php5 .php4 .php3
Pretty straight-forward solution. However, I have no idea how this gets configured on a server. I'm assuming that you would install various versions and then just setup the handlers for each.
Hi guys, I thought about something like this, which would be do-able
1. .env
(Define the default PHP version):
DEFAULT_PHP_VERSION=php-fpm-5.6
TLD_SUFFIX=dev
2. Startup
This will startup 3 PHP container, httpd and DNS
docker-compose up php54, php56, php70 httpd dns
3. vHosts
The vhosts will be configured normally (default php version) and have duplicated vhosts for each php version with different domain suffices.
- Project name: test01
- vHost (default): test01.dev
- vHost (54): test01.php54.dev
- vHost (56): test01.php56.dev
- vHost (70): test01.php70.dev
4. Intranet
The devilbox intranet will be served via the default php version.
What do you think?
Hi, what about a possibility, to setup the php version in specific project?
@cytopia: I have a comment to the possibility to chose the php version over domain name (3. vHosts). This way is also possible for zendframework or laravel projects. But for projects made with wordpress it is not. The domain name is placed in database, so it would redirect to that. Maybe some other frameworks work the same way.
what about a possibility, to setup the php version in specific project?
This doesn't make any sense. If you have one project which should be server by php54 and one for php56, you will have to start both containers anyway and could also use both versions on both projects or?
Yes sure, the containers have to be started. When a project runs with php7, it is not nesseary to test it with php5. In most cases a project is build for a specific php version.
If it is easier for you to go this way
Project name: test01
vHost (default): test01.dev
vHost (54): test01.php54.dev
vHost (56): test01.php56.dev
vHost (70): test01.php70.dev
i think, this is somethink, we can live with ;)
If this proposal does the job that projects can be tested against multiple php versions in general then I would say lets go with this implementation.
All other improvements are very valid to follow, however getting it done in the most simple way at the beginning is prioritized, so we might find other flaws as early as possible as well.
Great! Please, be free to tell me, if i can make some tests.
Sounds really great, in case someone is upgrading a project from php version this new feature will give capability to test the entire functionally through php versions.
In the current stack which i'm working, we have projects since php 5.4 to 7.1. Some of those are only cli applications, i suppose that its in mind that each php container will have a shell like root_bash.sh or we could pass some flags.
@cytopia thanks for your work, devilbox it's a really amazing project !
Definitely can see the value in what is being discussed. For projects that need testing like this, this would indeed be the right approach.
However, I still think it would be good to be able to use handlers though. The need for different versions of PHP for different projects is a different problem than testing a single project with multiple versions of PHP.
If multiple versions of PHP are available, wouldn’t they all be accessible from different directories anyways? Handlers could be setup with each within the config of each container. If you had multiple projects and needed a different version of PHP that isn’t the default you could simply add a handler to your htaccess file and that would be it. Food for thought.
@jeffwhitfield not quite sure If I fully understood you.
If multiple versions of PHP are available, wouldn’t they all be accessible from different directories anyways?
No, one project in one directory would be accessible with multiple php versions only differentiated by different domains.
project | dir | php version | domain |
---|---|---|---|
test | /shared/httpd/test/htdocs/ | default | test.loc |
test | /shared/httpd/test/htdocs/ | 5.5 | test.php55.loc |
test | /shared/httpd/test/htdocs/ | 5.6 | test.php56.loc |
test | /shared/httpd/test/htdocs/ | 7.0 | test.php70.loc |
test | /shared/httpd/test/htdocs/ | 7.1 | test.php71.loc |
test | /shared/httpd/test/htdocs/ | 7.2 | test.php72.loc |
test | /shared/httpd/test/htdocs/ | 7.3 | test.php73.loc |
Does this make more sense? Or did you mean something else?
Let's say you have the following PHP CGI executables setup in the following directories:
/usr/lib/bin/php56-cgi
/usr/lib/bin/php70-cgi
/usr/lib/bin/php71-cgi
/usr/lib/bin/php72-cgi
Granted, the actual paths for each version might be different. Now, let's say the default is set for 7.2 but you have one project that needs to be set with 5.6 for some reason. You could then setup your Apache config like so:
ScriptAlias /php56-cgi /usr/lib/bin/php56-cgi
Action application/x-httpd-php56 /php56-cgi
Then, in the htaccess file for the project, you could simply add the hander:
<FilesMatch "\.php">
SetHandler application/x-httpd-php56
</FilesMatch>
Something like this would allow for simple overrides with any version of PHP. Basically just need to make sure that a default is set while allowing direct access to all other versions through the file system.
@jeffwhitfield unfortunately PHP is not installed on the httpd
container. PHP is delivered by its separate PHP-FPM container. So there must be something that will work with Apache and Nginx on remote PHP-FPM container.
Ah, I see. Still new to Docker so there's bits that I probably don't get. Access to each container would definitely pose a problem. That said, if there was a way for the httpd
container to access the PHP-FPM executables then using handlers might be do-able.
There is no need to physically access the PHP-FPM executables. It's done via an IP addresses/hostnam (hosts: php56
, php70
, php71
, ...) to interpret php files from the httpd
server.
@cytopia how is it registered on http site? is it registered in vhost or anywhere else?
General setup
The httpd
container (either Nginx or Apache) send all php requests to the php
container and receives the rendered code that then can be displayed.
---------- -------------
| httpd | ----->| PHP-FPM |
---------- -------------
Httpd directives (Apache)
# PHP-FPM Definition
<FilesMatch \.php$>
Require all granted
SetHandler proxy:fcgi://php:9000
</FilesMatch>
# enablereuse requires Apache 2.4.11 or later
<Proxy "fcgi://php:9000/" enablereuse=on max=10>
</Proxy>
The important line is SetHandler proxy:fcgi://php:9000
Where php
is the hostname of the PHP-FPM server and 9000
is the port of the PHP-FPM process on the php
host.
Httpd directives (Nginx)
# PHP-FPM Definition
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php?$ {
try_files $uri = 404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_intercept_errors on;
}
The important line is fastcgi_pass php:9000;
Where php
is the hostname of the PHP-FPM server and 9000
is the port of the PHP-FPM process on the php
host.
New idea
So basically instead of only having one PHP-FPM server with hostname php
, I was thinking of having all PHP-FPM servers with the following hostnames:
-
php56
-
php70
-
php71
-
php72
- ...
And there is not just one vhost, but as many vhost for one project as there are PHP-FPM container. Example:
- Project:
test
- TLD_SUFFIX:
loc
<VirtualHost *:80>
ServerName test.php54.loc
<FilesMatch \.php$>
Require all granted
SetHandler proxy:fcgi://php54:9000
</FilesMatch>
</VirtualHost>
<VirtualHost *:80>
ServerName test.php56.loc
<FilesMatch \.php$>
Require all granted
SetHandler proxy:fcgi://php56:9000
</FilesMatch>
</VirtualHost>
<VirtualHost *:80>
ServerName test.php70.loc
<FilesMatch \.php$>
Require all granted
SetHandler proxy:fcgi://php70:9000
</FilesMatch>
</VirtualHost>
...
One of them could also be the default vhost such as for PHP-FPM 7.1:
<VirtualHost *:80>
ServerName test.loc
<FilesMatch \.php$>
Require all granted
SetHandler proxy:fcgi://php71:9000
</FilesMatch>
</VirtualHost>
Does this make any sense?
Why not running php in different ports? Let's assume we use the php version as portnumber like 9056, 9070, 9071 , 9072 etc.
I think it should be possible to say one global setting for all vhosts (your example changed a little bit)
<VirtualHost *:80>
ServerName test.loc
<FilesMatch \.php$>
Require all granted
SetHandler proxy:fcgi://php:9071
</FilesMatch>
</VirtualHost>
and if someone needs a specific php version for a project, he could do it in the project vhost-gen project/.devilbox/apache24.conf
like
<VirtualHost *:80>
ServerName test.loc
<FilesMatch \.php$>
Require all granted
SetHandler proxy:fcgi://php:9056
</FilesMatch>
</VirtualHost>
could this be possible?
In this case you could let the php bin as php in the container. Please correct me, if i'm wrong, but in your case, it could be, that you have to name the php bin to php56, php71 etc. ?
What do you think about this?
P.S. I don't think, that a developer needs to test a project against different php versions. And if so, he could copy it in multiple folders and change the php version for that projects.
@mavimedia when using different ports then all PHP versions must be on the same machine php
(Note, this is not a binary, but a hostname of a Container running PHP-FPM).
So from what you are recommending, the user could specify a different hostname (instead of different port) via vhost-gen to accomplish exactly this.
Does this mean, that i can put a vhost-gen conf into the projects folder like the following (the global configuration is e.g. php71)
<VirtualHost *:80>
ServerName test.loc
<FilesMatch \.php$>
Require all granted
SetHandler proxy:fcgi://php56:9000
</FilesMatch>
</VirtualHost>
and it runs test.loc as php56 and additionally test.php56.loc, test.php70.loc, test.php71.loc etc.?
Not at the moment, as there is always only one PHP-FPM container running (hostname: php
), but this was the actual plan for running multiple PHP-FPM container. So once this is implemented: Yes.
However, you will still have to start all PHP-FPM container that you want to use.
Yes sure, that's clear, not now, but in future. Great! 👍
I'm trying to come away from using MAMP Pro and would find it much easier to transition if we could run a different php version per project like this. Would love to see it happen!
Just to be clear here. From what I have already come up with, it won't be possible to run different PHP versions on a per project base, but to be able to run multiple PHP versions at the same time and to have each of the projects be served by all currently started php versions like so: (If you would start PHP 54, 55 and 56):
-
project1.php54.loc
-
project1.php55.loc
-
project1.php56.loc
This would then be for all projects.
Yep, what you are doing is exactly what i want. I don't want multiple php versions per project, i just want to be able to specify which php version a project uses. So for example, i can work on 2 different projects at the same time without having to: docker down edit config, docker up; when i switch projects.
What would be great is to be able to use a per project config file to specify the php version to use, rather than part of the project url. Would that be possible?
First iteration would be to have a default php version specified in .env
over which all projects are reachable without *.php[0-9].*
part in the domain. Let's get this done first and then see how difficult it is to customize it per project
That sounds like a great idea. Thanks a million for replying to my requests!
You're welcome.
Any thoughts on using composer with different php versions, @cytopia ?
Some projects which use older php versions use different packages etc which may not be usable with never php versions and are therefore giving errors when composer install
etc.
@molteber so you would require multiple composer
versions for each PHP container?
Just realized that there is a configuration in composer for this kind of problem I was thinking about. Might be a neat hint to add in the documentation regarding multiple php versions running at the same time and using composer.
By just composer config platform.php <php_version_to_use>
the problem is solved (composer.json gets updated, but I can live with that)
https://getcomposer.org/doc/06-config.md#platform
I built a vagrant box that provided several php fpms and hhvm: https://github.com/Tuurlijk/TYPO3.Packer/blob/master/ansible/configuration/Development/websites.yml#L8
You could switch the upstream in nginx by using the magic regex servername with named variables.
This way you can get:
php53.somesite.dev.local
php56.somesite.dev.local
php70.somesite.dev.local
php72.somesite.dev.local
hhvm.somesite.dev.local
Putting the php part in front makes the naming easier I think. Leaving off the prefix would serve the site with the default php version.
Heard you could do the same for Apache using 'virtual document roots', but never checked that out.
I'm new to docker. Was thinking about sharing the php sockets by using a tmpfs volume. So you can connect directly to the sockets from the httpd service. Here is some info on that: https://medium.com/@shrikeh/setting-up-nginx-and-php-fpm-in-docker-with-unix-sockets-6fdfbdc19f91
About Customizing php version per project: If you ran all the different php frpm containers (or all that were configured), you could have a variable set in the project/.devilbox/nginx.yml that said PHP_VERSION: 7.2 and that would change the proxy address to go to the php-fpm-7.2 container
@cytopia I'm attempting to change the apache template to one that generates vhosts for php, php70 and php72, but vhost-gen does not resolve the DOCUMENT_ROOT vars in my ProxyPassMatch statements. Can you take a look?
###
### Basic vHost skeleton
###
vhost: |
<VirtualHost __DEFAULT_VHOST__:__PORT__>
ServerName __VHOST_NAME__
CustomLog "__ACCESS_LOG__" combined
ErrorLog "__ERROR_LOG__"
__REDIRECT__
__SSL__
__VHOST_DOCROOT__
__VHOST_RPROXY__
__PHP_FPM__
__ALIASES__
__DENIES__
__SERVER_STATUS__
# Custom directives
__CUSTOM__
</VirtualHost>
<VirtualHost __DEFAULT_VHOST__:__PORT__>
ServerName php70.__VHOST_NAME__
CustomLog "__ACCESS_LOG__" combined
ErrorLog "__ERROR_LOG__"
__REDIRECT__
__SSL__
__VHOST_DOCROOT__
__VHOST_RPROXY__
# PHP-FPM Definition
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php70:9000__DOCUMENT_ROOT__/$1
__ALIASES__
__DENIES__
__SERVER_STATUS__
# Custom directives
__CUSTOM__
</VirtualHost>
<VirtualHost __DEFAULT_VHOST__:__PORT__>
ServerName php72.__VHOST_NAME__
CustomLog "__ACCESS_LOG__" combined
ErrorLog "__ERROR_LOG__"
__REDIRECT__
__SSL__
__VHOST_DOCROOT__
__VHOST_RPROXY__
# PHP-FPM Definition
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php72:9000__DOCUMENT_ROOT__/$1
__ALIASES__
__DENIES__
__SERVER_STATUS__
# Custom directives
__CUSTOM__
</VirtualHost>
@cytopia Got it: https://github.com/devilbox/vhost-gen/pull/28
Downside is that I need to manually adjust the hosts file. But that's only once.
@Tuurlijk many thanks. Currently looking manually into it as CI seems to be not responding. What do you mean by manually adjust the hosts file once?
I need to add entries for all php versions to /etc/hosts on the host machine. But I don't think there is a way around that, except for some magic DNS entry, or adding the bind machine to the /etc/resolv.conf. Then bind could be made to handle all dns.
somesite.tld
hhvm.somesite.tld
php70.somesite.tld
php72.somesite.tld
Auto-DNS will make them available automatically without adding entries to /etc/hosts
:
Current documentation: https://devilbox.readthedocs.io/en/latest/configuration-global/auto-dns.html
Upcoming documentation: https://devilbox.readthedocs.io/en/restructure-documentation/intermediate/setup-auto-dns.html
@Tuurlijk adding a litte fix regarding missing function argument: https://github.com/devilbox/vhost-gen/pull/29
Error did not get caught as CI was somehow not starting
@cytopia Is this now possible? I'm not able to figure out from the discussion whether or not I can run multiple PHP versions. I'd definitely like to be able to do that!
@adrienne it will be possible, but not at the moment as there's quite some work ahead to implement this. I've already done some initial work, but will concentrate on open bugs first as I find that more important then adding more features. It should however not take forever to get this implemented :-)
@adrienne It may be easier to "hack" it for a single setup then it would be to make it available for everyone with configurable setup.
Here are a few steps that you could use to try doing this:
- copy the php block of the docker-compose.yml file into the overrides file.
- change php to php2
- change the ip to a different address
- change the docker image from using the version variable to the second php version you wish to use
- Setup a custom webserver conf template for the project you would like to run in the alternate version
- Change the proxy settings from going to php to php2
These instructions are not tested, but it should give you a baseline to have 1 subdomain running 1 a version different from the rest of the project.
Some frameworks have database defined base url's and url rewrite tables, using the PHP version in the domain isn't really an option in that situation.
A config file in the project root would be more usable, some hosting companies let you change the PHP version of apache using something like this in .htaccess: AddHandler application/x-httpd-php54 .php
Just adding it here for brainstorm purposes.
@adrienne It may be easier to "hack" it for a single setup then it would be to make it available for everyone with configurable setup.
Here are a few steps that you could use to try doing this:
copy the php block of the docker-compose.yml file into the overrides file.
- change php to php2
- change the ip to a different address
- change the docker image from using the version variable to the second php version you wish to use
Setup a custom webserver conf template for the project you would like to run in the alternate version
Change the proxy settings from going to php to php2
These instructions are not tested, but it should give you a baseline to have 1 subdomain running 1 a version different from the rest of the project.
I can confirm this instructions are working. This is the files that changed and it's content:
docker-compose.override.yml
version: '2.1'
services:
php56:
image: devilbox/php-fpm:5.6-work-0.72
hostname: php56
env_file:
- ./.env
environment:
- DEBUG_ENTRYPOINT=${DEBUG_COMPOSE_ENTRYPOINT}
- DEBUG_COMPOSE_ENTRYPOINT
- DOCKER_LOGS
- NEW_UID
- NEW_GID
- TIMEZONE
- ENABLE_MODULES=${PHP_MODULES_ENABLE}
- DISABLE_MODULES=${PHP_MODULES_DISABLE}
- ENABLE_MAIL=1
- FORWARD_PORTS_TO_LOCALHOST=80:httpd:80,443:httpd:443,3306:mysql:3306,5432:pgsql:5432,6379:redis:6379,11211:memcd:11211,27017:mongo:27017
- MYSQL_BACKUP_USER=root
- MYSQL_BACKUP_PASS=${MYSQL_ROOT_PASSWORD}
- MYSQL_BACKUP_HOST=mysql
dns:
- 172.16.238.100
extra_hosts:
docker.for.lin.host.internal: 172.16.238.1
docker.for.lin.localhost: 172.16.238.1
networks:
app_net:
ipv4_address: 172.16.238.90
volumes:
- ${DEVILBOX_PATH}/.devilbox/www:/var/www/default:ro${MOUNT_OPTIONS}
- ${HOST_PATH_HTTPD_DATADIR}:/shared/httpd:rw${MOUNT_OPTIONS}
- ${DEVILBOX_PATH}/log/php-fpm-5.6:/var/log/php:rw${MOUNT_OPTIONS}
- ${DEVILBOX_PATH}/mail:/var/mail:rw${MOUNT_OPTIONS}
- ${DEVILBOX_PATH}/backups:/shared/backups:rw${MOUNT_OPTIONS}
- ${DEVILBOX_PATH}/cfg/php-ini-5.6:/etc/php-custom.d:ro${MOUNT_OPTIONS}
- ${DEVILBOX_PATH}/cfg/php-fpm-5.6:/etc/php-fpm-custom.d:ro${MOUNT_OPTIONS}
- ${DEVILBOX_PATH}/mod/php-fpm-5.6:/usr/lib64/php/custom-modules:ro${MOUNT_OPTIONS}
- ${DEVILBOX_PATH}/cfg/php-startup-5.6:/startup.1.d:rw${MOUNT_OPTIONS}
- ${DEVILBOX_PATH}/autostart:/startup.2.d:rw${MOUNT_OPTIONS}
- ${DEVILBOX_PATH}/bash:/etc/bashrc-devilbox.d:rw${MOUNT_OPTIONS}
- ${DEVILBOX_PATH}/ca:/ca:rw${MOUNT_OPTIONS}
depends_on:
- bind
project/.devilbox/nginx.yml
---
###
### Basic vHost skeleton
###
vhost: |
server {
listen __PORT____HTTP_PROTO____DEFAULT_VHOST__;
server_name __VHOST_NAME__;
access_log "__ACCESS_LOG__" combined;
error_log "__ERROR_LOG__" warn;
__REDIRECT__
__SSL__
__VHOST_DOCROOT__
__VHOST_RPROXY__
__PHP_FPM__
__ALIASES__
__DENIES__
__SERVER_STATUS__
# Custom directives
__CUSTOM__
}
###
### vHost Type (normal or reverse proxy)
###
vhost_type:
# Normal vHost (-p)
docroot: |
# Define the vhost to serve files
root "__DOCUMENT_ROOT__";
index __INDEX__;
# Reverse Proxy (-r)
rproxy: |
# Define the vhost to reverse proxy
location __LOCATION__ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__;
}
###
### Optional features to be enabled in vHost
###
features:
# SSL Configuration
ssl: |
ssl_certificate __SSL_PATH_CRT__;
ssl_certificate_key __SSL_PATH_KEY__;
ssl_protocols __SSL_PROTOCOLS__;
ssl_prefer_server_ciphers __SSL_HONOR_CIPHER_ORDER__;
ssl_ciphers __SSL_CIPHERS__;
# Redirect to SSL directive
redirect: |
return 301 https://__VHOST_NAME__:__SSL_PORT__$request_uri;
# PHP-FPM will not be applied to a reverse proxy!
php_fpm: |
# PHP-FPM Definition
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php?$ {
try_files $uri = 404;
include fastcgi_params;
# https://stackoverflow.com/questions/1733306/nginx-errors-readv-and-recv-failed/51457613#51457613
fastcgi_keep_conn off;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_pass php56:__PHP_PORT__;
fastcgi_read_timeout __PHP_TIMEOUT__;
fastcgi_index index.php;
fastcgi_intercept_errors on;
}
alias: |
# Alias Definition
location ~ __ALIAS__ {
root __PATH__;
__XDOMAIN_REQ__
}
deny: |
# Deny Definition
location ~ __REGEX__ {
deny all;
}
server_status: |
# Status Page
location ~ __REGEX__ {
stub_status on;
access_log off;
}
xdomain_request: |
# Allow cross domain request from these hosts
if ( $http_origin ~* (__REGEX__) ) {
add_header "Access-Control-Allow-Origin" "$http_origin";
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
add_header 'Access-Control-Max-Age' 0;
return 200;
}
Then all you need to do is stop the containers with docker-compose kill
and re-run with docker-compose up
. You will see devilbox_php56_1
container when you do docker-compose ps
.
I have another possible feature that might be nice to roll into this.
I have 2 subdomains and they run different php.ini error warning levels. Would it be possible to run 2 php containers with a different php.ini file for them? Or is there an easier way of making php.ini changes based on apache/nginx virtualhost? Would that be 2 php-fpm pools?
Thanks
any news about this ?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Here is an example configuration that switches the PHP backend (upstream) based on the host name requested: https://github.com/Tuurlijk/docker-local/blob/master/.docker/web/default.conf
Prefix is the project name in my case. I support the following domains as default:
- prefix.dev.local
- prefix.xdebug.local
- prefix.blackfire.local
You can define as much php machines in your docker-compose.yml as you wish. Map them to the backends in your default.conf.
This way of setup is nice because I can generate a wildcard SSL root cert for *.dev.local, *.xdebug.local and *.blackfire.local. I could add more domains like *.php71.local or *.hhvm.local. I can switch the backend by changing the domain name. I use a single docker-local project set for each new project. I usually work on a project that requires a single PHP version. So if I need ad different version, I rebuild the php containers with that version.
This is however a different way from the way that devilbox is set up. A similar setup with prefixing the domain names is described above. But I need SSL support now, so I switched to using my docker-local setup that aims to be 'thin' and not to support all PHP and database versions pre-baked.
Any easier way to get this setup? Or news on it being a feature added in?
I'd love to have multiple sites with different PHP versions, under one Docker setup, rather than create multiple Docker setups.
@adrienne It may be easier to "hack" it for a single setup then it would be to make it available for everyone with configurable setup. Here are a few steps that you could use to try doing this:
copy the php block of the docker-compose.yml file into the overrides file.
- change php to php2
- change the ip to a different address
- change the docker image from using the version variable to the second php version you wish to use
Setup a custom webserver conf template for the project you would like to run in the alternate version
Change the proxy settings from going to php to php2
These instructions are not tested, but it should give you a baseline to have 1 subdomain running 1 a version different from the rest of the project.
I can confirm this instructions are working. This is the files that changed and it's content:
docker-compose.override.yml
version: '2.1' services: php56: image: devilbox/php-fpm:5.6-work-0.72 hostname: php56 env_file: - ./.env environment: - DEBUG_ENTRYPOINT=${DEBUG_COMPOSE_ENTRYPOINT} - DEBUG_COMPOSE_ENTRYPOINT - DOCKER_LOGS - NEW_UID - NEW_GID - TIMEZONE - ENABLE_MODULES=${PHP_MODULES_ENABLE} - DISABLE_MODULES=${PHP_MODULES_DISABLE} - ENABLE_MAIL=1 - FORWARD_PORTS_TO_LOCALHOST=80:httpd:80,443:httpd:443,3306:mysql:3306,5432:pgsql:5432,6379:redis:6379,11211:memcd:11211,27017:mongo:27017 - MYSQL_BACKUP_USER=root - MYSQL_BACKUP_PASS=${MYSQL_ROOT_PASSWORD} - MYSQL_BACKUP_HOST=mysql dns: - 172.16.238.100 extra_hosts: docker.for.lin.host.internal: 172.16.238.1 docker.for.lin.localhost: 172.16.238.1 networks: app_net: ipv4_address: 172.16.238.90 volumes: - ${DEVILBOX_PATH}/.devilbox/www:/var/www/default:ro${MOUNT_OPTIONS} - ${HOST_PATH_HTTPD_DATADIR}:/shared/httpd:rw${MOUNT_OPTIONS} - ${DEVILBOX_PATH}/log/php-fpm-5.6:/var/log/php:rw${MOUNT_OPTIONS} - ${DEVILBOX_PATH}/mail:/var/mail:rw${MOUNT_OPTIONS} - ${DEVILBOX_PATH}/backups:/shared/backups:rw${MOUNT_OPTIONS} - ${DEVILBOX_PATH}/cfg/php-ini-5.6:/etc/php-custom.d:ro${MOUNT_OPTIONS} - ${DEVILBOX_PATH}/cfg/php-fpm-5.6:/etc/php-fpm-custom.d:ro${MOUNT_OPTIONS} - ${DEVILBOX_PATH}/mod/php-fpm-5.6:/usr/lib64/php/custom-modules:ro${MOUNT_OPTIONS} - ${DEVILBOX_PATH}/cfg/php-startup-5.6:/startup.1.d:rw${MOUNT_OPTIONS} - ${DEVILBOX_PATH}/autostart:/startup.2.d:rw${MOUNT_OPTIONS} - ${DEVILBOX_PATH}/bash:/etc/bashrc-devilbox.d:rw${MOUNT_OPTIONS} - ${DEVILBOX_PATH}/ca:/ca:rw${MOUNT_OPTIONS} depends_on: - bind
project/.devilbox/nginx.yml
--- ### ### Basic vHost skeleton ### vhost: | server { listen __PORT____HTTP_PROTO____DEFAULT_VHOST__; server_name __VHOST_NAME__; access_log "__ACCESS_LOG__" combined; error_log "__ERROR_LOG__" warn; __REDIRECT__ __SSL__ __VHOST_DOCROOT__ __VHOST_RPROXY__ __PHP_FPM__ __ALIASES__ __DENIES__ __SERVER_STATUS__ # Custom directives __CUSTOM__ } ### ### vHost Type (normal or reverse proxy) ### vhost_type: # Normal vHost (-p) docroot: | # Define the vhost to serve files root "__DOCUMENT_ROOT__"; index __INDEX__; # Reverse Proxy (-r) rproxy: | # Define the vhost to reverse proxy location __LOCATION__ { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__; } ### ### Optional features to be enabled in vHost ### features: # SSL Configuration ssl: | ssl_certificate __SSL_PATH_CRT__; ssl_certificate_key __SSL_PATH_KEY__; ssl_protocols __SSL_PROTOCOLS__; ssl_prefer_server_ciphers __SSL_HONOR_CIPHER_ORDER__; ssl_ciphers __SSL_CIPHERS__; # Redirect to SSL directive redirect: | return 301 https://__VHOST_NAME__:__SSL_PORT__$request_uri; # PHP-FPM will not be applied to a reverse proxy! php_fpm: | # PHP-FPM Definition location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php?$ { try_files $uri = 404; include fastcgi_params; # https://stackoverflow.com/questions/1733306/nginx-errors-readv-and-recv-failed/51457613#51457613 fastcgi_keep_conn off; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_split_path_info ^(.+\.php)(.*)$; fastcgi_pass php56:__PHP_PORT__; fastcgi_read_timeout __PHP_TIMEOUT__; fastcgi_index index.php; fastcgi_intercept_errors on; } alias: | # Alias Definition location ~ __ALIAS__ { root __PATH__; __XDOMAIN_REQ__ } deny: | # Deny Definition location ~ __REGEX__ { deny all; } server_status: | # Status Page location ~ __REGEX__ { stub_status on; access_log off; } xdomain_request: | # Allow cross domain request from these hosts if ( $http_origin ~* (__REGEX__) ) { add_header "Access-Control-Allow-Origin" "$http_origin"; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; add_header 'Access-Control-Max-Age' 0; return 200; }
Then all you need to do is stop the containers with
docker-compose kill
and re-run withdocker-compose up
. You will seedevilbox_php56_1
container when you dodocker-compose ps
.
Thanks a lot for sharing theses snippets, it seems to work for me as i needed one of my website to run php5.6 while default version is 7.2
here is what i did to get a php5.6 shell (for composer and php cli compatibility):
- duplicate 'shell.sh' to 'shell56.sh' and give it execution right
- change content of 'shell56.sh':
#!/bin/sh
docker-compose exec --user devilbox php56 bash -l
I currently solve this issue by running multiple Devilbox instances in different IP addresses. Of course without using auto DNS.
I work in a system that has multiple subsystems that work on different PHP versions. So locally in my dev environment I have 3 subdomains to each one of these subsystems, and some of them call API funcions from the others, so currently I don't see how I could work this out with current devilbox...
So there it is: another use case for this issue.
I currently solve this issue by running multiple Devilbox instances in different IP addresses. Of course without using auto DNS.
That would work! Do you have a link on this? How to run multiple Devilbox instances in different IPs?
this may be helpful, but i couldn't get it to work https://devilbox.discourse.group/t/multiple-versions-of-php/352/5
i may have to switch to laradock for now https://medium.com/@msirius/1-n-php-versions-and-projects-via-laradock-51938b337071
Hi guys, I thought about something like this, which would be do-able
1.
.env
(Define the default PHP version):DEFAULT_PHP_VERSION=php-fpm-5.6 TLD_SUFFIX=dev
2. Startup
This will startup 3 PHP container, httpd and DNS
docker-compose up php54, php56, php70 httpd dns
3. vHosts
The vhosts will be configured normally (default php version) and have duplicated vhosts for each php version with different domain suffices.
- Project name: test01
- vHost (default): test01.dev
- vHost (54): test01.php54.dev
- vHost (56): test01.php56.dev
- vHost (70): test01.php70.dev
4. Intranet
The devilbox intranet will be served via the default php version.
What do you think?
did we implemented this in 1.9 .. i am still trying to have projects which different php-version running at same time !
did we implemented this in 1.9 .. i am still trying to have projects which different php-version running at same time !
Not yet. For now you can follow the instructions above to get this feature working: https://github.com/cytopia/devilbox/issues/146#issuecomment-457477860