Gitlab CI Series - Building PHP Containers with Docker and Gitlab
This tutorial expects you to have a basic understanding of Docker and a running Gitlab CI and working Docker registry with a Docker-Runner.
If you are a PHP developer, you will often need a PHP container, either for development or for your live servers. In an active test-driven environment you will also sometimes have the need to test your code with different PHP versions.
As our basic PHP setup stays the same between projects, we build PHP docker images of nearly every version. This tutorial shows you how we do this.
If you want, you can also use our PHP containers directly. See our PHP container registry for details.
The dockerfile
To keep our docker container small, we use the Alpine base images from the official PHP docker repository as a basis.
(you can find the complete dockerfile here)
1
| FROM php:7.4.0-fpm-alpine
|
Then we define some variables which will need later on:
3
4
5
6
| ENV COMPOSER_ALLOW_SUPERUSER=1 \
COMPOSER_DISABLE_XDEBUG_WARN=1 \
PHPREDIS_VERSION=5.1.1
ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so php
|
Let’s install some building dependencies:
9
10
11
12
| RUN set -xe \
&& apk add --no-cache --virtual .build-deps \
tzdata \
$PHPIZE_DEPS \
|
And some packages which we need to remain. Don’t combine this - as we will remove the apk set `.build-deps later on.
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
| && apk add gnu-libiconv --update-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/community/ --allow-untrusted \
&& apk add --no-cache \
openssl-dev \
bash \
freetype-dev \
libpng-dev \
libjpeg-turbo-dev \
sqlite-dev \
curl \
curl-dev \
libsodium-dev \
icu-dev \
libxml2-dev \
recode-dev \
libxslt-dev \
git \
postgresql-client \
postgresql-dev \
openssh-client \
libmcrypt-dev \
libmcrypt \
libzip-dev \
libgcrypt-dev \
oniguruma-dev \
&& apk --update --no-cache add grep \
|
Time to compile some extensions - we don’t need them all the time - but it doesn’t hurt to have them.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
| && docker-php-ext-configure gd \
--with-freetype=/usr/include/ \
&& docker-php-ext-install -j$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1)\
gd \
bcmath \
opcache \
iconv \
mysqli \
pdo \
pdo_mysql \
pdo_sqlite \
pdo_pgsql \
zip \
xml \
xsl \
intl \
json \
mbstring \
curl \
simplexml \
soap \
bcmath \
redis \
&& docker-php-ext-install sodium \
|
As mentioned earlier, time to clean up, so we have a nice small container.
64
65
| && apk del .build-deps \
&& rm -rf /tmp/* /var/cache/apk/*
|
Now it’s time to set some ini parameters we want to use:
66
67
68
69
70
71
72
73
74
| RUN echo "memory_limit = 128M" > /usr/local/etc/php/conf.d/custom.ini \
&& echo "max_execution_time = 60" >> /usr/local/etc/php/conf.d/custom.ini \
&& echo "error_reporting=E_ALL" >> /usr/local/etc/php/conf.d/custom.ini \
&& echo "log_errors=On" >> /usr/local/etc/php/conf.d/custom.ini \
&& echo "error_log = /proc/self/fd/2" >> /usr/local/etc/php/conf.d/custom.ini \
&& echo "expose_php = Off" >> /usr/local/etc/php/conf.d/custom.ini \
&& echo "pm.status_path = /status" >> /usr/local/etc/php-fpm.d/zz-docker.conf \
&& echo "ping.path = /ping" >> /usr/local/etc/php-fpm.d/zz-docker.conf \
&& echo "catch_workers_output = yes" >> /usr/local/etc/php-fpm.d/zz-docker.conf
|
As we need composer anyway, we install it right in the container:
75
76
| RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN composer global require hirak/prestissimo --no-plugins --no-scripts
|
Building it with Gitlab CI
Create a new project in your Gitlab and add the Dockerfile to it.
The next step is to create the `.gitlab-ci.yml file to let Gitlab build our container:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| image: docker:latest
services:
- docker:dind
before_script:
- docker login -u "gitlab-ci-token" -p "$CI_JOB_TOKEN" $CI_REGISTRY
7.4-fpm:
stage: build
tags:
- docker
script:
- docker build --pull -t "$CI_REGISTRY_IMAGE/fpm:7.4.0" -t "$CI_REGISTRY_IMAGE/fpm:7.4" "."
- docker push "$CI_REGISTRY_IMAGE/cli:7.4.0"
- docker push "$CI_REGISTRY_IMAGE/cli:7.4"
|
The tag docker
tells Gitlab to use one of our docker runners.
Push this to your project and watch Gitlab build your PHP container. It will be stored in the Docker registry of the project.
To use it in your own project (or to further extend it in a project) you can use your docker registry url and the project name. You find the complete urls in the registry. In our example it would be dockerhub.cwd.at/docker/php/fpm:7.4.0
Warning
If your project is not public - you will have to docker login
to your registry to use your container! (see https://docs.gitlab.com/ee/user/packages/container_registry/#using-with-private-projects for details)