diff --git a/.docker/Dockerfile b/.docker/Dockerfile index 13eb5732..ee2485d2 100644 --- a/.docker/Dockerfile +++ b/.docker/Dockerfile @@ -1,7 +1,7 @@ # the different stages of this Dockerfile are meant to be built into separate images # https://docs.docker.com/compose/compose-file/#target -ARG PHP_VERSION=8.0 +ARG PHP_VERSION=8.1 ARG NGINX_VERSION=1.17 # Build assets in disposable node image @@ -9,18 +9,27 @@ FROM node:11-alpine as armaforces_web_assets WORKDIR /tmp/app_build -COPY package.json package-lock.json webpack.config.js ./ +COPY --link package.json package-lock.json webpack.config.js ./ RUN npm install WORKDIR /tmp/app_build/assets/ -COPY assets ./ +COPY --link assets ./ RUN npm run build:ci # Build PHP application image FROM php:${PHP_VERSION}-fpm-alpine AS armaforces_web_php +# build for production +ENV APP_ENV=prod + +WORKDIR /www/app + +# php extensions installer: https://github.com/mlocati/docker-php-extension-installer +COPY --from=mlocati/php-extension-installer --link /usr/bin/install-php-extensions /usr/local/bin/ + +# persistent / runtime deps RUN apk add --no-cache \ acl \ fcgi \ @@ -29,62 +38,33 @@ RUN apk add --no-cache \ git \ ; -ARG APCU_VERSION=5.1.18 RUN set -eux; \ - apk add --no-cache --virtual .build-deps \ - $PHPIZE_DEPS \ - icu-dev \ - libzip-dev \ - zlib-dev \ - ; \ - \ - docker-php-ext-configure zip; \ - docker-php-ext-install -j$(nproc) \ + install-php-extensions \ intl \ zip \ - pdo_mysql \ - ; \ - pecl install \ - apcu-${APCU_VERSION} \ - ; \ - pecl clear-cache; \ - docker-php-ext-enable \ apcu \ 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 .api-phpexts-rundeps $runDeps; \ - \ - apk del .build-deps \ -; - -COPY --from=composer/composer:2-bin /composer /usr/bin/composer -RUN ln -s $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini -COPY .docker/php/conf.d/armaforces-web.ini $PHP_INI_DIR/conf.d/armaforces-web.ini + pdo_mysql \ + ; + +RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" +COPY --link .docker/php/conf.d/armaforces-web.ini $PHP_INI_DIR/conf.d/ +COPY --link .docker/php/conf.d/armaforces-web.prod.ini $PHP_INI_DIR/conf.d/ # https://getcomposer.org/doc/03-cli.md#composer-allow-superuser ENV COMPOSER_ALLOW_SUPERUSER=1 ENV PATH="${PATH}:/root/.composer/vendor/bin" -WORKDIR /www/app - -# build for production -ARG APP_ENV=prod +COPY --from=composer/composer:2-bin --link /composer /usr/bin/composer # prevent the reinstallation of vendors at every changes in the source code COPY composer.json composer.lock symfony.lock .env ./ RUN set -eux; \ - composer install --prefer-dist --no-dev --no-scripts --no-progress --no-suggest; \ + composer install --prefer-dist --no-dev --no-scripts --no-progress; \ composer clear-cache # copy only specifically what we need -COPY bin bin/ +COPY --link bin bin/ COPY config config/ COPY migrations migrations/ COPY public public/ @@ -97,12 +77,11 @@ RUN set -eux; \ composer dump-autoload --classmap-authoritative --no-dev; \ composer run-script --no-dev post-install-cmd; \ chmod +x bin/console; sync -VOLUME /www/app/var # copy assets manifests COPY --from=armaforces_web_assets /tmp/app_build/public/build/ public/build/ -COPY .docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint +COPY --link .docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint RUN chmod +x /usr/local/bin/docker-entrypoint # .env is copied again as COPY needs to copy at least one file @@ -129,20 +108,23 @@ CMD ["nginx", "-g", "daemon off;"] FROM armaforces_web_php AS armaforces_web_php_dev -ARG XDEBUG_VERSION=3.1.1 +ENV APP_ENV=dev +#VOLUME /www/app/var/ + +RUN rm $PHP_INI_DIR/conf.d/app.prod.ini; \ + mv "$PHP_INI_DIR/php.ini" "$PHP_INI_DIR/php.ini-production"; \ + mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" + RUN set -eux; \ - apk add --no-cache --virtual .build-deps $PHPIZE_DEPS; \ - pecl install xdebug-$XDEBUG_VERSION; \ - docker-php-ext-enable xdebug; \ - apk del .build-deps + install-php-extensions xdebug RUN apk add --no-cache \ nodejs \ npm ENV XDEBUG_INI_PATH=$PHP_INI_DIR/conf.d/docker-php-ext-xdebug.ini -COPY .docker/php/conf.d/docker-php-ext-xdebug.ini $XDEBUG_INI_PATH +COPY --link .docker/php/conf.d/docker-php-ext-xdebug.ini $XDEBUG_INI_PATH -COPY .docker/php/scripts/xon.sh /usr/bin/xon -COPY .docker/php/scripts/xoff.sh /usr/bin/xoff +COPY --link .docker/php/scripts/xon.sh /usr/bin/xon +COPY --link .docker/php/scripts/xoff.sh /usr/bin/xoff RUN chmod +x /usr/bin/xon /usr/bin/xoff diff --git a/.docker/php/conf.d/armaforces-web.ini b/.docker/php/conf.d/armaforces-web.ini index e06bc3be..90e554f0 100644 --- a/.docker/php/conf.d/armaforces-web.ini +++ b/.docker/php/conf.d/armaforces-web.ini @@ -1,13 +1,14 @@ -# Borrowed from https://github.com/api-platform/api-platform/blob/master/api/docker/php/conf.d/api-platform.ini - -apc.enable_cli = 1 +# Borrowed from https://github.com/api-platform/api-platform/blob/6ddd494ccec4dc5d0329c1ded75101e58b8747e4/api/docker/php/conf.d/app.ini +expose_php = 0 date.timezone = Europe/Warsaw -session.auto_start = Off -short_open_tag = Off +apc.enable_cli = 1 +session.use_strict_mode = 1 +zend.detect_unicode = 0 -# http://symfony.com/doc/current/performance.html +; https://symfony.com/doc/current/performance.html +realpath_cache_size = 4096K +realpath_cache_ttl = 600 opcache.interned_strings_buffer = 16 opcache.max_accelerated_files = 20000 opcache.memory_consumption = 256 -realpath_cache_size = 4096K -realpath_cache_ttl = 600 +opcache.enable_file_override = 1 diff --git a/.docker/php/conf.d/armaforces-web.prod.ini b/.docker/php/conf.d/armaforces-web.prod.ini new file mode 100644 index 00000000..a941b3bd --- /dev/null +++ b/.docker/php/conf.d/armaforces-web.prod.ini @@ -0,0 +1,2 @@ +;opcache.preload_user = www-data +;opcache.preload = /www/app/config/preload.php diff --git a/.docker/php/docker-entrypoint.sh b/.docker/php/docker-entrypoint.sh index 8efb0283..0efda4ad 100644 --- a/.docker/php/docker-entrypoint.sh +++ b/.docker/php/docker-entrypoint.sh @@ -9,19 +9,35 @@ if [ "${1#-}" != "$1" ]; then fi if [ "$1" = 'php-fpm' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then - PHP_INI_RECOMMENDED="$PHP_INI_DIR/php.ini-production" + setfacl -R -m u:www-data:rwX -m u:"$(whoami)":rwX var || true + setfacl -dR -m u:www-data:rwX -m u:"$(whoami)":rwX var || true + if [ "$APP_ENV" != 'prod' ]; then - PHP_INI_RECOMMENDED="$PHP_INI_DIR/php.ini-development" + composer install --prefer-dist --no-progress --no-interaction || true fi - ln -sf "$PHP_INI_RECOMMENDED" "$PHP_INI_DIR/php.ini" - mkdir -p var/cache var/log - setfacl -R -m u:www-data:rwX -m u:"$(whoami)":rwX var || true - setfacl -dR -m u:www-data:rwX -m u:"$(whoami)":rwX var || true + if grep -q DATABASE_URL= .env; then + echo "Waiting for database to be ready..." + ATTEMPTS_LEFT_TO_REACH_DATABASE=30 + until [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ] || DATABASE_ERROR=$(php bin/console dbal:run-sql -q "SELECT 1" 2>&1); do + sleep 1 + ATTEMPTS_LEFT_TO_REACH_DATABASE=$((ATTEMPTS_LEFT_TO_REACH_DATABASE - 1)) + echo "Still waiting for database to be ready... Or maybe the database is not reachable. $ATTEMPTS_LEFT_TO_REACH_DATABASE attempts left." + done + + if [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ]; then + echo "The database is not up or not reachable:" + echo "$DATABASE_ERROR" + exit 1 + else + echo "The database is now ready and reachable" + fi + fi if [ "$APP_ENV" = 'prod' ]; then php bin/console doctrine:migrations:migrate --allow-no-migration --no-interaction fi + fi exec docker-php-entrypoint "$@" diff --git a/.env b/.env index dfeabbe0..ccf4ef36 100644 --- a/.env +++ b/.env @@ -9,6 +9,7 @@ # Real environment variables win over .env files. # # DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES. +# https://symfony.com/doc/current/configuration/secrets.html # # Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2). # https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration diff --git a/.github/workflows/application.yml b/.github/workflows/application.yml index 8e7156d5..1b852f74 100644 --- a/.github/workflows/application.yml +++ b/.github/workflows/application.yml @@ -42,6 +42,11 @@ jobs: run: | make test-ci + - name: Failure logs + if: failure() + run: | + docker compose logs php + docker_release: name: Docker release runs-on: ubuntu-latest diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 2079091c..7fd3d17d 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -7,9 +7,10 @@ services: target: armaforces_web_php_dev volumes: - './:/www/app:rw' - - './var/import:/www/app/var/import:ro' - - './var/cache:/www/app/var/cache:rw' - - './var/log:/www/app/var/log:rw' + # If you develop on Mac or Windows you can remove the vendor/ and var/ directory + # from the bind-mount for better performance by enabling the next lines: + #- /www/app/vendor + #- /www/app/var environment: PHP_IDE_CONFIG: serverName=armaforces-web extra_hosts: diff --git a/docker-compose.test.yml b/docker-compose.test.yml index 68a5a54e..98b61a34 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -10,10 +10,9 @@ services: cache_from: - docker.pkg.github.com/armaforces/website/app_assets:dev - docker.pkg.github.com/armaforces/website/app_php:dev + environment: + APP_ENV: test volumes: - # Extract files from runtime for QA tools - - './var:/www/app/var' - - './vendor:/www/app/vendor' # Copy tests into runtime - './.env.test:/www/app/.env.test:ro' - './tests:/www/app/tests:ro'