Code Monkey home page Code Monkey logo

docker-php-fpm's Introduction

yannoff/docker-php-fpm

Home for yannoff/php-fpm dockerhub repository sources.

A PHP-FPM docker image based on Alpine, with composer and offenbach installed.

Available tags

(1) Those PHP versions have now reached their EOL.

Usage

Building custom images

Dynamic builds allow for flexible, fine-tuned and featherweight images.
The recommended way is to use the repository URL as build context.

Example: Integration in a docker-compose stack

  • PHP version 8.0
  • gd and imap extensions
  • patch extra package install
  • Europe/Rome as timezone
  • laravel/installer as a composer global package
  • latest-preview version of composer
# docker-compose.yaml
fpm:
    build:
        context: https://github.com/yannoff/docker-php-fpm.git#:8.0
        args:
            TZ: Europe/Rome
            PHP_EXTS: gd imap
            APK_EXTRA: patch
            PHP_LIBS: laravel/installer
            COMPOSER_VERSION: latest-preview

Alternatively, building from the command-line:

docker                                     \
    build                                  \
    -t php8.0                              \
    --build-arg TZ="Europe/Rome"           \
    --build-arg PHP_EXTS="gd imap"         \
    --build-arg APK_EXTRA=patch            \
    --build-arg PHP_LIBS=laravel/installer \
    --build-arg COMPOSER_VERSION=latest-preview   \
    [email protected]:yannoff/docker-php-fpm.git#:8.0

Build arguments reference

The following build arguments are available:

Build arg Description Defaults
TZ The timezone to use for the container UTC
PHP_EXTS PHP extensions to be installed (2) pdo_mysql pdo_pgsql intl opcache bcmath
APK_BASE Base alpine packages to be installed bash git vim
APK_EXTRA Extra alpine packages to be installed -
PHP_LIBS PHP libraries to be installed as composer global dependencies -
COMPOSER_VERSION Specific composer version to be installed (3) 2.2.24
OFFENBACH_VERSION Alternative offenbach version to be installed (4) latest
OFFENBACH_FILENAME Alternative name for the offenbach executable offenbach
OFFENBACH_INSTALL_DIR Install dir for the offenbach executable /usr/bin

(2) See the mlocati/docker-php-extension-installer repository for the full list of supported extensions.
(3) May be latest-preview, latest-stable, or an exact version - eg: 2.4.0.
(4) The version must be an exact version, eg: 1.6.2. If left empty, the latest release will be used.

Using base images

On the other hand, the base pre-compiled images from dockerhub may be convenient to run php or composer commands on the fly, providing a minimal PHP ecosystem.

Example: Creating a new laravel empty project

docker                  \
    run                 \
    --rm                \
    -it                 \
    -u $UID:$GID        \
    -w /src             \
    -v $PWD:/src        \
    yannoff/php-fpm:8.0 \
    composer create-project --ignore-platform-reqs laravel/laravel acme

Since the base image may not contain all of the required PHP extensions, the --ignore-platform-reqs switch is recommended

Pre-compiled images defaults

Pre-compiled images are built with the following default values:

Build arg Value
TZ Europe/Paris
PHP_EXTS intl opcache
APK_BASE bash git vim
APK_EXTRA openssh
COMPOSER_VERSION 2.2.24

Helper scripts

A set of helper scripts are available in the bin directory.

Each of them allows to run any php command on-the-fly, including composer or offenbach commands.

Based on the BusyBox principle, the bin/php multi-call script is the main entrypoint.

The way it works is dead simple: php version is deduced from the called script name, as a consequence each php<version> symlink must point to the main php entrypoint script.

The version must be one of the following: 5.5, 5.6, 7.0, 7.1, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2

If invoked without any version suffix, the default PHP version will be used: either the PHP_VERSION environment variable (if set), the latest PHP GA release (currently 8.2) otherwise.

Usage examples

$ cd $HOME/bin
$ ln -s php php7.4
$ php7.4 --version
PHP 7.4.28 (cli) (built: Mar 29 2022 03:52:02) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.28, Copyright (c), by Zend Technologies

The following examples are given assuming that:

  • The php multi-call script is in one of the $PATH dirs
  • A symlink to it has been created for each php version

Install offenbach dependencies in the current dir

php8.1 offenbach install

Open a php interactive command prompt

php7.4 -a

Open a bash session

php8.0

Credits

Licensed under the MIT License.

This project uses the awesome mlocati/docker-php-extension-installer script for PHP extensions install.

docker-php-fpm's People

Contributors

yannoff avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar

docker-php-fpm's Issues

Implement optional standard user/group creation at build

Problem

Though in many scenarios, running the container as an arbitrary user may be perfectly acceptable, there are some use cases in which the user must be known to the system.

To list a few of them:

Composer

When composer is run as an arbitrary user, it will use /.composer for COMPOSER_HOME instead of ~/.composer, which may result in permission issues.

Moreover, it's impossible to chown that particular directory in the build, since the UID/GID of the user is unknown at this time.

The only remaining choice would be then to chmod the /.composer dir to 777 mode, which is, needless to say, the worth practice ever.

SSH

Every command or process using the SSH protocol will search the default ~/.ssh folder for private/public keys, known hosts, etc... which does not exist for an arbitrary user.

This is the case when the composer.json refers to private repositories with ssh-fashion urls, like [email protected].

Solution

Implement a USER build arg (plus an optional GROUP one) which will trigger - if not empty - the standard user / group creation during build with the given USER as user id / GROUP as group id.

If USER is set but GROUP has been left empty, the USER value will be used for the group id.

Ensure no base package is removed at build end

When removing the .build-deps virtual meta-package, some of the base packages ( ie. those meant to be shipped in the final image) may be accidentally removed, if matching one of the .build-deps list.

Example

$ docker build -t custom:8.0 --build-arg APK_ADD=make 8.0/

Problem

Since make is part of the .build-deps virtual package list, it will be removed whereas it should not.

Workaround

  1. List installed packages before adding the .build-deps dependencies
  2. Restore installed packages after .build-deps have been removed

All compilations fail with dockerhub automated builds on Alpine 3.14

Related to https://gitlab.alpinelinux.org/alpine/aports/-/issues/12396

Extract from the dockerhub build log:

Cloning into '.'...
Warning: Permanently added the RSA host key for IP address '140.82.114.4' to the list of known hosts.
Reset branch 'master'
Your branch is up-to-date with 'origin/master'.
KernelVersion: 4.4.0-1060-aws
Components: [{u'Version': u'19.03.8', u'Name': u'Engine', u'Details': {u'KernelVersion': u'4.4.0-1060-aws', u'Os': u'linux', u'BuildTime': u'2020-03-11T01:24:30.000000000+00:00', u'ApiVersion': u'1.40', u'MinAPIVersion': u'1.12', u'GitCommit': u'afacb8b7f0', u'Arch': u'amd64', u'Experimental': u'false', u'GoVersion': u'go1.12.17'}}, {u'Version': u'1.2.13', u'Name': u'containerd', u'Details': {u'GitCommit': u'7ad184331fa3e55e52b890ea95e65ba581ae3429'}}, {u'Version': u'1.0.0-rc10', u'Name': u'runc', u'Details': {u'GitCommit': u'dc9208a3303feef5b3839f4323d9beb36df0a9dd'}}, {u'Version': u'0.18.0', u'Name': u'docker-init', u'Details': {u'GitCommit': u'fec3683'}}]
Arch: amd64
BuildTime: 2020-03-11T01:24:30.000000000+00:00
ApiVersion: 1.40
Platform: {u'Name': u'Docker Engine - Community'}
Version: 19.03.8
MinAPIVersion: 1.12
GitCommit: afacb8b7f0
Os: linux
GoVersion: go1.12.17
Starting build of index.docker.io/yannoff/php-fpm:7.4...

(...)

checking pkg-config is at least version 0.9.0... yes
checking for cc... cc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether the compiler supports GNU C... yes
checking whether cc accepts -g... yes
checking for cc option to enable C11 features... none needed
checking how to run the C preprocessor... cc -E
checking for icc... no
checking for suncc... no
checking for system library directory... lib
checking if compiler supports -R... no
checking if compiler supports -Wl,-rpath,... yes
checking build system type... x86_64-pc-linux-musl
checking host system type... x86_64-pc-linux-musl
checking target system type... x86_64-pc-linux-musl
checking for PHP prefix... /usr/local
checking for PHP includes... -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib
checking for PHP extension directory... /usr/local/lib/php/extensions/no-debug-non-zts-20190902
checking for PHP installed headers prefix... /usr/local/include/php
checking if debug is enabled... no
checking if zts is enabled... no
checking for gawk... no
checking for nawk... no
checking for awk... awk
checking if awk is broken... no
checking for MySQL support for PDO... yes, shared
checking for the location of libz... no
checking for MySQL UNIX socket location...
checking for PDO includes... /usr/local/include/php/ext
checking for a sed that does not truncate output... /bin/sed
checking for ld used by cc... /usr/x86_64-alpine-linux-musl/bin/ld
checking if the linker (/usr/x86_64-alpine-linux-musl/bin/ld) is GNU ld... yes
checking for /usr/x86_64-alpine-linux-musl/bin/ld option to reload object files... -r
checking for BSD-compatible nm... /usr/bin/nm -B
checking whether ln -s works... yes
checking how to recognize dependent libraries... pass_all
checking for stdio.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for strings.h... yes
checking for sys/stat.h... yes
checking for sys/types.h... yes
checking for unistd.h... yes
checking for dlfcn.h... yes
checking the maximum length of command line arguments... 98304
checking command to parse /usr/bin/nm -B output from cc object...
sort: cannot read: conftest.nm: Operation not permitted
failed
checking for objdir... .libs
checking for ar... ar
checking for ranlib... ranlib
checking for strip... strip
checking if cc supports -fno-rtti -fno-exceptions... no
checking for cc option to produce PIC... -fPIC
checking if cc PIC flag -fPIC works... yes
checking if cc static flag -static works... yes
checking if cc supports -c -o file.o... yes
checking whether the cc linker (/usr/x86_64-alpine-linux-musl/bin/ld -m elf_x86_64) supports shared libraries... yes
checking whether -lc should be explicitly linked in... no
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... no
creating libtool
appending configuration tag "CXX" to libtool
configure: patching config.h.in
configure: creating ./config.status
config.status: creating config.h

make: /bin/sh: Operation not permitted


/bin/sh /usr/src/php/ext/pdo_mysql/libtool --mode=compile cc -I/usr/local/include/php/ext -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 -I. -I/usr/src/php/ext/pdo_mysql -DPHP_ATOM_INC -I/usr/src/php/ext/pdo_mysql/include -I/usr/src/php/ext/pdo_mysql/main -I/usr/src/php/ext/pdo_mysql -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DHAVE_CONFIG_H -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -c /usr/src/php/ext/pdo_mysql/pdo_mysql.c -o pdo_mysql.lo

make: *** [Makefile:193: pdo_mysql.lo] Error 127

Introduced by a bug in runc (opencontainers/runc#2151)

[builder] Base image don't pull anymore

Bug introdued in 871a4f2

$ ./build.sh         
Updating mlocati/php-extension-installer ...
Using default tag: latest
latest: Pulling from mlocati/php-extension-installer
Digest: sha256:31005240d4a6f6d02bafa672fa01877b537709099502db0b5def9c942f5b1cf4
Status: Image is up to date for mlocati/php-extension-installer:latest
docker.io/mlocati/php-extension-installer:latest
[build] Processing version 5.5...
Pulling php:-fpm-alpine base image...
invalid reference format

Extensions install process broken

The mlocati/docker-php-extension-installer script now fails on building PHP extensions.

### INSTALLING BUNDLED MODULE pdo_mysql ###
/usr/bin/install-php-extensions: line 1422: nproc: not found
usage: /usr/local/bin/docker-php-ext-install [-jN] ext-name [ext-name ...]
   ie: /usr/local/bin/docker-php-ext-install gd mysqli
       /usr/local/bin/docker-php-ext-install pdo pdo_mysql
       /usr/local/bin/docker-php-ext-install -j5 gd mbstring mysqli pdo pdo_mysql shmop

if custom ./configure arguments are necessary, see docker-php-ext-configure

Possible values for ext-name:
bcmath bz2 calendar ctype curl dba dom enchant exif fileinfo filter ftp gd gettext gmp hash iconv imap interbase intl json ldap mbstring mcrypt mssql mysql mysqli oci8 odbc opcache pcntl pdo pdo_dblib pdo_firebird pdo_mysql pdo_oci pdo_odbc pdo_pgsql pdo_sqlite pgsql phar posix pspell readline recode reflection session shmop simplexml snmp soap sockets spl standard sybase_ct sysvmsg sysvsem sysvshm tidy tokenizer wddx xml xmlreader xmlrpc xmlwriter xsl zip
/bin/sh: cmake: not found

Global packages install in the wrong dir

Since at build, the composer global require command is executed as root, the packages are installed to /root/.composer.

Problems:

  • This directory is not the one which is added to the PATH system var (namely /.composer/vendor/bin)
  • Standard (non-root) users don't have access to the /root/.composer/vendor/bin` directory

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.