usabilla / php-docker-template Goto Github PK
View Code? Open in Web Editor NEWDocker images for PHP applications, CLI and FPM with shared socket
Home Page: https://hub.docker.com/r/usabillabv/php
License: MIT License
Docker images for PHP applications, CLI and FPM with shared socket
Home Page: https://hub.docker.com/r/usabillabv/php
License: MIT License
Currently, we have Composer in our non-dev images, as shown below
php-docker-template/Dockerfile-cli
Lines 38 to 40 in f35fecd
We should move it to dev images, along with
php-docker-template/Dockerfile-cli
Lines 53 to 55 in f35fecd
This should be done in the next PHP circle release, as it will break our images.
Currently PHP-FPM outputs to stdout
and stderr
, but it does so in its own single-line format which stops projects from adopting the usabilla
format.
We should change their format to json and adhere to ADR-23.
Question: this is pretty opinionated for Usabilla, how do we separate from OSS?
This should take the ideas of #101 but port the entire thing to Actions so we can remove the external dependency.
Security and container scan can be done with Clair
Example with GitlabCI: https://docs.gitlab.com/ee/ci/examples/container_scanning.html
Most of the time, you'll need a storage layer for your app: relational or non relational.
I'd make the assumption and say that probably, the most popular storage layers you'll find in the wild are MySQL and Redis. What about including them?
Our PHP images are based on images from official repo.
As mentioned in the documentation, these images ship with the default ini configuration recommendations for both production and development.
These configurations, however, are not enabled by default in the official PHP images, as discussed here.
In order to have a sane baseline configuration guaranteed, we should enable the aforementioned ini recommendations for each environment (i.e. have the desired one available at this path $PHP_INI_DIR/php.ini
). Docker images extending the ones in this repository will still have the flexibility to override (parts of) that configuration by placing customized configurations in the $PHP_INI_DIR/conf.d/
directory.
The test scripts (e.g. https://github.com/usabilla/php-docker-template/blob/master/test-cli.sh) control test suites that are run for different tags. This happens based on custom markers.
However the number of different markers currently used across multiple test files is causing confusion. The way the tests are organised and run could benefit from a better structured and transparent approach.
We currently have no mechanism in place that can detect that we're building tags based on outdated images, e.g. an old alpine version.
From a security perspective it would be nice to have some tracking mechanism/automation to deal with this, so that we don't build on top of unsupported base images.
This was suggested by @rdohms, considering that we don't necessarily have an updated stack in our local env and sometimes we use the containers to run tests.
To decrypt secrets we use shush
(see also this comment). We should include it in the production image.
Once a version of PHP enters "Security Support" we no longer need to build it every week, but should try to only build once a new version is actually released.
PHP's release schedule: https://php.net/releases.
Wall-e can now handle broadcasting these problems to slack nicely, we just need to plug it in.
Using kubernetes and docker-compose it's simple to achieve this but what are the trade-offs involved here?
Currently the tests are running only against the "default" images, being php 7.2 with alpine 3.7, this happens because that's the version being spin up by docker-compose.
My suggestion is to read from the tag files (in tmp
) and do a text replace of all available tags, maybe just like the approach from build-php.sh
. It seems like docker-compose also accepts the yml file from the stdin, making it simple and avoiding creating temporary files
A new development script for xdebug and configs was added #57
It needs to be documented and also explain we're moving away from the dev tags in the projects
Since we're moving to Kubernetes we don't need to have a single container running multiple commands.
This architectural decision reduces the size of the images, allows us to better scale the consumers, and makes logging much easier.
The idea is to have a veeeery simple and functional example of a symfony project using our Docker images!
Just like this one: https://github.com/usabilla/php-docker-template/tree/master/docs/examples/hello-world-fpm
Which is a bare bones version on how to use it!
We'd like it to follow the same quality standards and look amazing!
There are too many things to consider when deploying a PHP Docker setup in Kubernetes, many of them related to good practices and others due to how PHP is designed, the intent of this issue is to list all of them and match whether we have both solved the issue and documented it.
pcntl
by default.php-docker-template/Dockerfile-fpm
Lines 20 to 21 in 7fd241a
preStop
which checks if the Nginx is dead before PHP-FPM: # Considering you have a mount between the nginx and php-fpm containers on `/var/run`
lifecycle:
preStop:
exec:
command: ["/bin/sh","-c","while test -e /var/run/nginx.pid; do sleep 1; done"]
WARNING: [pool www] child 12 said into stdout :
.Lines 67 to 68 in 436042e
We sometimes use very generic names for the virtual name we hand APK for build dependencies, for example:
There's a chance that something outside these scripts is using the same name so if, in the script, we do apk del .build-deps
we also remove the packages that were assigned to that virtual name outside the script. We can solve this by using more specific virtual names.
In order to improve build performance and enable more building features.
A good start: https://github.com/usabilla/php-docker-template/commits/enable-buildkit
Currently in the building process there's nothing that switches the user to the app
, meaning currently the images are shipped with root
user by default
Add USER app:app
at the end of the Dockerfile-cli, but this is a breaking change!
The problem:
For instance in the example below:
We see that we aren't locking the version pecl
is installing, this can lead to bugs and major versions being upgraded without the user's consent.
A proposed solution would be:
The script should take an argument (.i.e.: $1
or ENV
variable) which specifies the version to be installed.
A bonus is to be able to specify the version semantically, we have to check weather pecl supports it.
Not every php process has a webserver which can expose prometheus metrics, thus a sidecar container can be a google solution for it.
Just like JMX exporter works as a sidecar container, we can have a container which exposes the php metrics to be fetch by prometheus.
A Nginx container which takes a file with the metrics or that connects to php directly could achieve this.
As first option I'd say the file is the easiest to implement
So we can have beautiful code :)
So that we can reduce the compilation time of our images and reduce the amount of code we maintain.
Given that in most modern apps nodejs is present through tools like webpack or various is linters, I would like to have that as an option for this stack setup.
http://nginx.org/en/docs/http/ngx_http_realip_module.html
The nginx realip
module allows you to specify a trusted list of proxies to parse X-Forwarded-For
headers from so that the actual client IP address gets logged instead of the ingress controller's IP address. This is made a little complicated by the fact that the ingress controllers just have IP addresses on the pod network as for any other pod, and we don't necessarily want to treat everything running in Kubernetes as if it were a proxy, but it might be worth looking into at some stage.
When a new CVE comes up we tend to upgrade the package using apk upgrade --no-cache curl
for instance.
Since our images are based on official ones, eventually they get the upgraded package which causes us to remove the patches from our Dockerfiles
###> CVE: 1234 ###
###< CVE: 1234 ###
Otherwise we have no clue if the configuration is correct.
We tried to get rid of the newly-introduced if
statement inside the cors.conf
in order to avoid if
, since it is generally discouraged by nginx.
With the help of @stevenjm we came to the following:
# /etc/nginx/location.d-enabled/cors.conf
# Allow CORS if environment variable is set
add_header 'Access-Control-Allow-Origin' "http://127.0.0.1:8888" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' "*" always;
add_header 'Access-Control-Allow-Headers' "*" always;
add_header 'Access-Control-Expose-Headers' "*" always;
# /etc/nginx/conf.d/default.conf
map $request_method $rewrite_target {
default /index.php;
OPTIONS /NGINX_INTERNAL_HANDLE_OPTIONS;
}
server {
listen 80;
listen [::]:80;
server_name localhost;
root /opt/project/public;
charset UTF-8;
include /etc/nginx/location.d-enabled/*.conf;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location / {
rewrite ^ $rewrite_target last;
}
location = /NGINX_INTERNAL_HANDLE_OPTIONS {
return 204;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $document_root;
}
}
The map
could be moved into the cors.conf
and that file could, for example, live in the conf.d
directory, but I'll leave that to you guys to figure out.
Hello,
upstream fixed a bug in march docker-library/php#1264
the last changes here were in Feb, would it be possible to rebuild and publish the images based off the latest upstream docker php to include this bug fix.
Let me know if theres anything I can do to make this process quicker and easier for you.
Thank you kindly.
PHP fpm doesn't respect the standard POSIX signals, thus we have to translate signal 15
into 3
Provide a new entrypoint which makes this change
Every time we have to install an extension, the GPG keys are downloaded and used. That fails more often than not so we need to find a way to make this more reliable.
The intermediate solution that is now implemented is that we cache the GPG keys (2 for each minor version) in the image itself. It'd be nicer if we could lift this to a higher level, maybe into GitLab?
The idea is to have a veeeery simple and functional example of a Laravel project using our Docker images!
Just like this one: https://github.com/usabilla/php-docker-template/tree/master/docs/examples/hello-world-fpm
Which is a bare bones version on how to use it!
We'd like it to follow the same quality standards and look amazing!
Currently the default vhost is strict in the sense it forwards everything to fpm and doesn't handle static files for instance.
To replace it you can copy it from your project and replace the template one at: /etc/nginx/vhost.conf.template
Note it's still template since it'll have the variables replaced on the entrypoint
Also provide a working example
Just like on the nginx builder we'd like to make it possible to add custom/extra tags to build.
One use case for instance is when a new project adopt a beta version of php, 7.3-rc let's say, they could already use 7.3 as base and when it's finally released the migration is seamless
Hi there,
Would you be open to a PR to allow templating php-fpm config via env vars?
Something like this, as these are the values that would mostly likely need scaling/configuring:
pm = ${PHP_FPM_PM}
pm.max_children = ${PHP_FPM_PM_MAX_CHILDREN}
pm.start_servers = ${PHP_FPM_PM_START_SERVERS}
pm.min_spare_servers = ${PHP_FPM_PM_MIN_SPARE_SERVERS}
pm.max_spare_servers = ${PHP_FPM_PM_MAX_SPARE_SERVERS}
pm.process_idle_timeout = ${PHP_FPM_PM_PROCESS_IDLE_TIMEOUT}
pm.max_requests = ${PHP_FPM_PM_MAX_REQUESTS}
Thanks.
Since we provide a helper to install and configure Xdebug it'd be good to replace the PECL example in the documentation to another extension, also document how to use the Xdebug helper
CircleCI configuration can become really verbose and repetitive, here is a list of things that can be improved by either: Removing, downstream to Makefile, yaml anchors or CircleCI reusable commands
php-docker-template/.circleci/config.yml
Line 213 in 615c9f7
php-docker-template/.circleci/config.yml
Line 208 in 615c9f7
php-docker-template/.circleci/config.yml
Line 176 in 615c9f7
My recommendation is that we follow PHP's own lifecycle, we don't delete images but we stop building them as the PHP counterpart version reaches EOL!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.