Merge pull request #51 from dunglas/upgrade-docker

Upgrade Dockerfile
This commit is contained in:
Maxime Helias 2019-12-20 18:13:44 +01:00 committed by GitHub
commit 05cff5dd7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 183 additions and 110 deletions

View File

@ -1,9 +1,22 @@
**/*.log **/*.log
**/*.md
**/*.php~
**/._* **/._*
**/.dockerignore
**/.DS_Store **/.DS_Store
**/.gitignore **/.git/
**/.gitattributes **/.gitattributes
**/.gitignore
**/.gitmodules
**/Dockerfile
**/Thumbs.db **/Thumbs.db
.dockerignore .editorconfig
Dockerfile .env*
docker-compose.yaml .php_cs.cache
bin/*
!bin/console
docker/db/data/
helm/
public/bundles/
var/
vendor/

View File

@ -26,9 +26,9 @@ script:
- docker-compose build --pull - docker-compose build --pull
- docker-compose up -d - docker-compose up -d
- sleep 30 - sleep 30
- docker-compose exec -T app composer req sensiolabs/security-checker - docker-compose exec -T php composer req sensiolabs/security-checker
- docker-compose exec -T app bin/console security:check - docker-compose exec -T php bin/console security:check
- docker-compose run --no-deps -T app composer validate --no-check-publish - docker-compose run --no-deps -T php composer validate --no-check-publish
- curl http://localhost # Client - curl http://localhost # Client
- curl -k https://localhost # Client (HTTP/2) - curl -k https://localhost # Client (HTTP/2)
- docker-compose logs # Display logs if anything wrong - docker-compose logs # Display logs if anything wrong

View File

@ -1,80 +1,81 @@
# the different stages of this Dockerfile are meant to be built into separate images # the different stages of this Dockerfile are meant to be built into separate images
# https://docs.docker.com/develop/develop-images/multistage-build/#stop-at-a-specific-build-stage
# https://docs.docker.com/compose/compose-file/#target # https://docs.docker.com/compose/compose-file/#target
ARG PHP_VERSION=7.2
ARG NGINX_VERSION=1.15
### NGINX # https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact
FROM nginx:${NGINX_VERSION}-alpine AS symfony_docker_nginx ARG PHP_VERSION=7.4
ARG NGINX_VERSION=1.17
COPY docker/nginx/conf.d /etc/nginx/conf.d/ # "php" stage
COPY public /srv/app/public/ FROM php:${PHP_VERSION}-fpm-alpine AS symfony_php
### H2 PROXY
FROM alpine:latest AS symfony_docker_h2-proxy-cert
RUN apk add --no-cache openssl
# Use this self-generated certificate only in dev, IT IS NOT SECURE!
RUN openssl genrsa -des3 -passout pass:NotSecure -out server.pass.key 2048
RUN openssl rsa -passin pass:NotSecure -in server.pass.key -out server.key
RUN rm server.pass.key
RUN openssl req -new -passout pass:NotSecure -key server.key -out server.csr \
-subj '/C=SS/ST=SS/L=Gotham City/O=Symfony/CN=localhost'
RUN openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt
FROM nginx:${NGINX_VERSION}-alpine AS symfony_docker_h2-proxy
RUN mkdir -p /etc/nginx/ssl/
COPY --from=symfony_docker_h2-proxy-cert server.key server.crt /etc/nginx/ssl/
COPY ./docker/h2-proxy/default.conf /etc/nginx/conf.d/default.conf
### PHP
FROM php:${PHP_VERSION}-fpm-alpine AS symfony_docker_php
# persistent / runtime deps
RUN apk add --no-cache \ RUN apk add --no-cache \
git \ acl \
icu-libs \ fcgi \
zlib \ file \
jq gettext \
git \
jq \
;
ENV APCU_VERSION 5.1.12 ARG APCU_VERSION=5.1.18
RUN set -eux \ RUN set -eux; \
&& apk add --no-cache --virtual .build-deps \ apk add --no-cache --virtual .build-deps \
$PHPIZE_DEPS \ $PHPIZE_DEPS \
icu-dev \ icu-dev \
zlib-dev \ libzip-dev \
&& docker-php-ext-install -j$(nproc) \ zlib-dev \
intl \ ; \
zip \ \
&& pecl install \ docker-php-ext-configure zip --with-libzip; \
apcu-${APCU_VERSION} \ docker-php-ext-install -j$(nproc) \
&& docker-php-ext-enable --ini-name 20-apcu.ini apcu \ intl \
&& docker-php-ext-enable --ini-name 05-opcache.ini opcache \ zip \
&& runDeps="$( \ ; \
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions \ pecl install \
| tr ',' '\n' \ apcu-${APCU_VERSION} \
| sort -u \ ; \
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ pecl clear-cache; \
)" \ docker-php-ext-enable \
&& apk add --no-cache --virtual .api-phpexts-rundeps $runDeps \ apcu \
&& apk del .build-deps opcache \
; \
\
runDeps="$( \
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions \
| tr ',' '\n' \
| sort -u \
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
)"; \
apk add --no-cache --virtual .phpexts-rundeps $runDeps; \
\
apk del .build-deps
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
RUN ln -s $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini RUN ln -s $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini
COPY docker/app/conf.d/symfony.ini $PHP_INI_DIR/conf.d/symfony.ini COPY docker/php/conf.d/symfony.ini $PHP_INI_DIR/conf.d/symfony.ini
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
COPY docker/app/docker-entrypoint.sh /usr/local/bin/docker-app-entrypoint
RUN chmod +x /usr/local/bin/docker-app-entrypoint
WORKDIR /srv/app RUN set -eux; \
ENTRYPOINT ["docker-app-entrypoint"] { \
CMD ["php-fpm"] echo '[www]'; \
echo 'ping.path = /ping'; \
} | tee /usr/local/etc/php-fpm.d/docker-healthcheck.conf
# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser # https://getcomposer.org/doc/03-cli.md#composer-allow-superuser
ENV COMPOSER_ALLOW_SUPERUSER 1 ENV COMPOSER_ALLOW_SUPERUSER=1
# install Symfony Flex globally to speed up download of Composer packages (parallelized prefetching)
RUN set -eux; \
composer global require "symfony/flex" --prefer-dist --no-progress --no-suggest --classmap-authoritative; \
composer clear-cache
ENV PATH="${PATH}:/root/.composer/vendor/bin"
# Use prestissimo to speed up builds WORKDIR /srv/app
RUN composer global require "symfony/flex" --prefer-dist --no-progress --no-suggest --classmap-authoritative --no-interaction
# build for production
ARG APP_ENV=prod
# Allow to use development versions of Symfony # Allow to use development versions of Symfony
ARG STABILITY="stable" ARG STABILITY="stable"
@ -84,14 +85,58 @@ ENV STABILITY ${STABILITY:-stable}
ARG SYMFONY_VERSION="" ARG SYMFONY_VERSION=""
# Download the Symfony skeleton and leverage Docker cache layers # Download the Symfony skeleton and leverage Docker cache layers
RUN composer create-project "symfony/skeleton ${SYMFONY_VERSION}" . --stability=$STABILITY --prefer-dist --no-dev --no-progress --no-scripts --no-plugins --no-interaction RUN composer create-project "symfony/skeleton ${SYMFONY_VERSION}" . --stability=$STABILITY --prefer-dist --no-dev --no-progress --no-scripts --no-interaction; \
composer clear-cache
###> recipes ### ###> recipes ###
###< recipes ### ###< recipes ###
COPY . . COPY . .
RUN mkdir -p var/cache var/logs var/sessions \ RUN set -eux; \
&& composer install --prefer-dist --no-dev --no-scripts --no-progress --no-suggest --classmap-authoritative --no-interaction \ mkdir -p var/cache var/log; \
&& composer clear-cache \ composer dump-autoload --classmap-authoritative --no-dev; \
&& chown -R www-data var composer run-script --no-dev post-install-cmd; sync
VOLUME /srv/app/var
COPY docker/php/docker-healthcheck.sh /usr/local/bin/docker-healthcheck
RUN chmod +x /usr/local/bin/docker-healthcheck
HEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD ["docker-healthcheck"]
COPY docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint
RUN chmod +x /usr/local/bin/docker-entrypoint
ENTRYPOINT ["docker-entrypoint"]
CMD ["php-fpm"]
# "nginx" stage
# depends on the "php" stage above
FROM nginx:${NGINX_VERSION}-alpine AS symfony_nginx
COPY docker/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf
WORKDIR /srv/app
COPY --from=symfony_php /srv/app/public public/
# "h2-proxy-cert" stage
FROM alpine:latest AS symfony_h2-proxy-cert
RUN apk add --no-cache openssl
# Use this self-generated certificate only in dev, IT IS NOT SECURE!
RUN openssl genrsa -des3 -passout pass:NotSecure -out server.pass.key 2048
RUN openssl rsa -passin pass:NotSecure -in server.pass.key -out server.key
RUN rm server.pass.key
RUN openssl req -new -passout pass:NotSecure -key server.key -out server.csr \
-subj '/C=SS/ST=SS/L=Gotham City/O=Symfony/CN=localhost'
RUN openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt
### "h2-proxy" stage
FROM nginx:${NGINX_VERSION}-alpine AS symfony_h2-proxy
RUN mkdir -p /etc/nginx/ssl/
COPY --from=symfony_h2-proxy-cert server.key server.crt /etc/nginx/ssl/
COPY ./docker/h2-proxy/default.conf /etc/nginx/conf.d/default.conf

View File

@ -37,9 +37,9 @@ it's recommended to add a custom stage to the end of the `Dockerfile`.
```Dockerfile ```Dockerfile
# Dockerfile # Dockerfile
FROM symfony_docker_php as symfony_docker_php_dev FROM symfony_php as symfony_php_dev
ARG XDEBUG_VERSION=2.6.0 ARG XDEBUG_VERSION=2.8.0
RUN set -eux; \ RUN set -eux; \
apk add --no-cache --virtual .build-deps $PHPIZE_DEPS; \ apk add --no-cache --virtual .build-deps $PHPIZE_DEPS; \
pecl install xdebug-$XDEBUG_VERSION; \ pecl install xdebug-$XDEBUG_VERSION; \
@ -55,13 +55,13 @@ configuration remains untouched.
As example, an override could look like this: As example, an override could look like this:
```yaml ```yaml
version: '3.4' version: "3.4"
services: services:
app: php:
build: build:
context: . context: .
target: symfony_docker_php_dev target: symfony_php_dev
environment: environment:
# See https://docs.docker.com/docker-for-mac/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host # See https://docs.docker.com/docker-for-mac/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host
# See https://github.com/docker/for-linux/issues/264 # See https://github.com/docker/for-linux/issues/264
@ -73,34 +73,31 @@ services:
idekey=PHPSTORM idekey=PHPSTORM
# This should correspond to the server declared in PHPStorm `Preferences | Languages & Frameworks | PHP | Servers` # This should correspond to the server declared in PHPStorm `Preferences | Languages & Frameworks | PHP | Servers`
# Then PHPStorm will use the corresponding path mappings # Then PHPStorm will use the corresponding path mappings
PHP_IDE_CONFIG: serverName=symfony-docker PHP_IDE_CONFIG: serverName=symfony
``` ```
Then run: Then run:
````bash ```bash
docker-compose up -d docker-compose up -d
```` ```
If `docker-compose.yaml` and a `docker-compose.override.yaml` are present on the same directory level, Docker Compose combines the two files into a single configuration, applying the configuration in the `docker-compose.override.yaml` file over and in addition to the values in the `docker-compose.yaml` file. If `docker-compose.yml` and a `docker-compose.override.yml` are present on the same directory level, Docker Compose combines the two files into a single configuration, applying the configuration in the `docker-compose.override.yml` file over and in addition to the values in the `docker-compose.yml` file.
### Troubleshooting ### Troubleshooting
Inspect the installation with the following command. The requested Xdebug version should be displayed in the output. Inspect the installation with the following command. The requested Xdebug version should be displayed in the output.
```bash ```bash
$ docker-compose exec app php --version $ docker-compose exec php php --version
PHP 7.2.8 (cli) (built: Jul 21 2018 08:09:37) ( NTS ) PHP ...
Copyright (c) 1997-2018 The PHP Group with Xdebug v2.8.0 ...
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.2.8, Copyright (c) 1999-2018, by Zend Technologies
with Xdebug v2.6.0, Copyright (c) 2002-2018, by Derick Rethans
``` ```
### Editing Permissions on Linux ### Editing Permissions on Linux
If you work on linux and cannot edit some of the project files right after the first installation, you can run `docker-compose run --rm app chown -R $(id -u):$(id -g) .` to set yourself as owner of the project files that were created by the docker container. If you work on linux and cannot edit some of the project files right after the first installation, you can run `docker-compose run --rm php chown -R $(id -u):$(id -g) .` to set yourself as owner of the project files that were created by the docker container.
## Credits ## Credits

View File

@ -1,13 +1,18 @@
version: '3.4' version: "3.4"
services: services:
app: php:
build: build:
context: . context: .
target: symfony_docker_php target: symfony_php
args: args:
SYMFONY_VERSION: ${SYMFONY_VERSION:-} SYMFONY_VERSION: ${SYMFONY_VERSION:-}
STABILITY: ${STABILITY:-stable} STABILITY: ${STABILITY:-stable}
healthcheck:
interval: 10s
timeout: 3s
retries: 3
start_period: 30s
volumes: volumes:
# Comment out the next line in production # Comment out the next line in production
- ./:/srv/app:rw,cached - ./:/srv/app:rw,cached
@ -22,24 +27,24 @@ services:
nginx: nginx:
build: build:
context: . context: .
target: symfony_docker_nginx target: symfony_nginx
depends_on: depends_on:
- app - php
volumes: volumes:
# Comment out the next line in production # Comment out the next line in production
- ./docker/nginx/conf.d:/etc/nginx/conf.d:ro - ./docker/nginx/conf.d:/etc/nginx/conf.d:ro
- ./public:/srv/app/public:ro - ./public:/srv/app/public:ro
ports: ports:
- '80:80' - "80:80"
# This HTTP/2 proxy is not secure: it should only be used in dev # This HTTP/2 proxy is not secure: it should only be used in dev
h2-proxy: h2-proxy:
build: build:
context: . context: .
target: symfony_docker_h2-proxy target: symfony_h2-proxy
depends_on: depends_on:
- nginx - nginx
volumes: volumes:
- ./docker/h2-proxy/default.conf:/etc/nginx/conf.d/default.conf:ro - ./docker/h2-proxy/default.conf:/etc/nginx/conf.d/default.conf:ro
ports: ports:
- '443:443' - "443:443"

View File

@ -7,10 +7,10 @@ server {
} }
location ~ ^/index\.php(/|$) { location ~ ^/index\.php(/|$) {
#resolver 127.0.0.11; #resolver 127.0.0.11;
#set $upstream_host app; #set $upstream_host php;
#fastcgi_pass $upstream_host:9000; #fastcgi_pass $upstream_host:9000;
# Uncomment the previous lines and comment the next one to enable dynamic resolution (incompatible with Kubernetes) # Uncomment the previous lines and comment the next one to enable dynamic resolution (incompatible with Kubernetes)
fastcgi_pass app:9000; fastcgi_pass php:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$; fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params; include fastcgi_params;
# When you are using symlinks to link the document root to the # When you are using symlinks to link the document root to the

View File

@ -6,12 +6,14 @@ if [ "${1#-}" != "$1" ]; then
set -- php-fpm "$@" set -- php-fpm "$@"
fi fi
if [ "$1" = 'php-fpm' ] || [ "$1" = 'bin/console' ]; then if [ "$1" = 'php-fpm' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then
PHP_INI_RECOMMENDED="$PHP_INI_DIR/php.ini-production" PHP_INI_RECOMMENDED="$PHP_INI_DIR/php.ini-production"
if [ "$APP_ENV" != 'prod' ]; then if [ "$APP_ENV" != 'prod' ]; then
PHP_INI_RECOMMENDED="$PHP_INI_DIR/php.ini-development" PHP_INI_RECOMMENDED="$PHP_INI_DIR/php.ini-development"
fi fi
ln -sf "$PHP_INI_RECOMMENDED" "$PHP_INI_DIR/php.ini" ln -sf "$PHP_INI_RECOMMENDED" "$PHP_INI_DIR/php.ini"
mkdir -p var/cache var/log
# The first time volumes are mounted, the project needs to be recreated # The first time volumes are mounted, the project needs to be recreated
if [ ! -f composer.json ]; then if [ ! -f composer.json ]; then
@ -23,12 +25,11 @@ if [ "$1" = 'php-fpm' ] || [ "$1" = 'bin/console' ]; then
cp -Rp tmp/. . cp -Rp tmp/. .
rm -Rf tmp/ rm -Rf tmp/
elif [ "$APP_ENV" != 'prod' ]; then elif [ "$APP_ENV" != 'prod' ]; then
# Always try to reinstall deps when not in prod
composer install --prefer-dist --no-progress --no-suggest --no-interaction composer install --prefer-dist --no-progress --no-suggest --no-interaction
fi fi
# Permissions hack because setfacl does not work on Mac and Windows setfacl -R -m u:www-data:rwX -m u:"$(whoami)":rwX var
chown -R www-data var setfacl -dR -m u:www-data:rwX -m u:"$(whoami)":rwX var
fi fi
exec docker-php-entrypoint "$@" exec docker-php-entrypoint "$@"

View File

@ -0,0 +1,12 @@
#!/bin/sh
set -e
export SCRIPT_NAME=/ping
export SCRIPT_FILENAME=/ping
export REQUEST_METHOD=GET
if cgi-fcgi -bind -connect 127.0.0.1:9000; then
exit 0
fi
exit 1