diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index e80e11f891..bd5b47583f 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -41,8 +41,9 @@ jobs: # Assets should-build-assets: ${{ steps.changed-assets-files.outputs.any_changed == 'true' || null }} # Docker - should-build-and-push-docker: ${{ steps.changed-api-docker-files.outputs.any_changed == 'true' || steps.changed-selfserve-docker-files.outputs.any_changed == 'true' || steps.changed-internal-docker-files.outputs.any_changed == 'true' || null }} + should-build-and-push-docker: ${{ steps.changed-api-docker-files.outputs.any_changed == 'true' || steps.changed-selfserve-docker-files.outputs.any_changed == 'true' || steps.changed-internal-docker-files.outputs.any_changed == 'true' || steps.changed-cli-docker-files.outputs.any_changed == 'true' || null}} should-build-and-push-api-docker: ${{ steps.changed-api-docker-files.outputs.any_changed == 'true' || steps.changed-api-files.outputs.any_changed == 'true' || null }} + should-build-and-push-cli-docker: ${{ steps.changed-cli-docker-files.outputs.any_changed == 'true' || steps.changed-api-files.outputs.any_changed == 'true' || null }} should-build-and-push-selfserve-docker: ${{ steps.changed-selfserve-docker-files.outputs.any_changed == 'true' || steps.changed-selfserve-files.outputs.any_changed == 'true' || null }} should-build-and-push-internal-docker: ${{ steps.changed-internal-docker-files.outputs.any_changed == 'true' || steps.changed-internal-files.outputs.any_changed == 'true' || null }} # Terraform accounts @@ -77,12 +78,16 @@ jobs: with: files: | app/cdn/** - # since_last_remote_commit: true - uses: tj-actions/changed-files@v44 id: changed-api-docker-files with: files: | infra/docker/api/** + - uses: tj-actions/changed-files@v44 + id: changed-cli-docker-files + with: + files: | + infra/docker/cli/** - uses: tj-actions/changed-files@v44 id: changed-selfserve-docker-files with: @@ -140,6 +145,7 @@ jobs: runs-on: ubuntu-latest outputs: api: ${{ steps.api-version.outputs.version }} + cli: ${{ steps.cli-version.outputs.version }} selfserve: ${{ steps.selfserve-version.outputs.version }} internal: ${{ steps.internal-version.outputs.version }} assets: ${{ steps.assets-version.outputs.version }} @@ -151,6 +157,10 @@ jobs: uses: ./.github/actions/get-app-version with: project-path: app/api infra/docker/api + - id: cli-version + uses: ./.github/actions/get-app-version + with: + project-path: app/api infra/docker/cli - id: selfserve-version uses: ./.github/actions/get-app-version with: @@ -167,6 +177,7 @@ jobs: run: | echo "#### App versions:" >> $GITHUB_STEP_SUMMARY echo "**API**: \`${{ steps.api-version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY + echo "**CLI**: \`${{ steps.cli-version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY echo "**Selfserve**: \`${{ steps.selfserve-version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY echo "**Internal**: \`${{ steps.internal-version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY echo "**Assets**: \`${{ steps.assets-version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY @@ -201,7 +212,7 @@ jobs: - selfserve - internal exclude: - - project: ${{ (needs.orchestrator.outputs.should-build-api || needs.orchestrator.outputs.should-build-and-push-api-docker) && 'ignored' || 'api' }} + - project: ${{ (needs.orchestrator.outputs.should-build-api || needs.orchestrator.outputs.should-build-and-push-api-docker || needs.orchestrator.outputs.should-build-and-push-cli-docker) && 'ignored' || 'api' }} - project: ${{ (needs.orchestrator.outputs.should-build-selfserve || needs.orchestrator.outputs.should-build-and-push-selfserve-docker) && 'ignored' || 'selfserve' }} - project: ${{ (needs.orchestrator.outputs.should-build-internal || needs.orchestrator.outputs.should-build-and-push-internal-docker) && 'ignored' || 'internal' }} uses: ./.github/workflows/php.yaml @@ -227,17 +238,19 @@ jobs: matrix: project: - api + - cli - selfserve - internal exclude: - project: ${{ needs.orchestrator.outputs.should-build-and-push-api-docker && 'ignored' || 'api' }} + - project: ${{ needs.orchestrator.outputs.should-build-and-push-cli-docker && 'ignored' || 'cli' }} - project: ${{ needs.orchestrator.outputs.should-build-and-push-selfserve-docker && 'ignored' || 'selfserve' }} - project: ${{ needs.orchestrator.outputs.should-build-and-push-internal-docker && 'ignored' || 'internal' }} uses: ./.github/workflows/docker.yaml with: project: ${{ matrix.project }} version: ${{ needs.get-version.outputs[matrix.project] }} - app-artefact-name: ${{ matrix.project}} + app-artefact-name: ${{ matrix.project == 'cli' && 'api' || matrix.project }} push: true permissions: contents: read diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index eaae1944cc..c012d5731e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -21,8 +21,9 @@ jobs: # Assets should-build-assets: ${{ steps.changed-assets-files.outputs.any_changed == 'true' || null }} # Docker - should-build-docker: ${{ steps.changed-api-docker-files.outputs.any_changed == 'true' || steps.changed-selfserve-docker-files.outputs.any_changed == 'true' || steps.changed-internal-docker-files.outputs.any_changed == 'true' || null }} + should-build-docker: ${{ steps.changed-api-docker-files.outputs.any_changed == 'true' || steps.changed-selfserve-docker-files.outputs.any_changed == 'true' || steps.changed-internal-docker-files.outputs.any_changed == 'true' || steps.changed-cli-docker-files.outputs.any_changed == 'true' || null }} should-build-api-docker: ${{ steps.changed-api-docker-files.outputs.any_changed == 'true' || steps.changed-api-files.outputs.any_changed == 'true' || null }} + should-build-cli-docker: ${{ steps.changed-cli-docker-files.outputs.any_changed == 'true' || steps.changed-api-files.outputs.any_changed == 'true' || null }} should-build-selfserve-docker: ${{ steps.changed-selfserve-docker-files.outputs.any_changed == 'true' || steps.changed-selfserve-files.outputs.any_changed == 'true' || null }} should-build-internal-docker: ${{ steps.changed-internal-docker-files.outputs.any_changed == 'true' || steps.changed-internal-files.outputs.any_changed == 'true' || null }} # Terraform accounts @@ -68,6 +69,12 @@ jobs: files: | infra/docker/api/** # since_last_remote_commit: true + - uses: tj-actions/changed-files@v44 + id: changed-cli-docker-files + with: + files: | + infra/docker/cli/** + # since_last_remote_commit: true - uses: tj-actions/changed-files@v44 id: changed-selfserve-docker-files with: @@ -190,13 +197,13 @@ jobs: - selfserve - internal exclude: - - project: ${{ (needs.orchestrator.outputs.should-build-api || needs.orchestrator.outputs.should-build-api-docker) && 'ignored' || 'api' }} + - project: ${{ (needs.orchestrator.outputs.should-build-api || needs.orchestrator.outputs.should-build-api-docker || needs.orchestrator.outputs.should-build-cli-docker) && 'ignored' || 'api' }} - project: ${{ (needs.orchestrator.outputs.should-build-selfserve || needs.orchestrator.outputs.should-build-selfserve-docker) && 'ignored' || 'selfserve' }} - project: ${{ (needs.orchestrator.outputs.should-build-internal || needs.orchestrator.outputs.should-build-internal-docker) && 'ignored' || 'internal' }} uses: ./.github/workflows/php.yaml with: project: ${{ matrix.project }} - should-upload-artefact: ${{ !!needs.orchestrator.outputs[format('should-build-{0}-docker', matrix.project)] }} + should-upload-artefact: ${{ !!(needs.orchestrator.outputs[format('should-build-{0}-docker', matrix.project)] || (matrix.project == 'api' && needs.orchestrator.outputs.should-build-cli-docker)) }} artefact-name: ${{ matrix.project}} retention-days: 1 permissions: @@ -216,17 +223,19 @@ jobs: matrix: project: - api + - cli - selfserve - internal exclude: - project: ${{ needs.orchestrator.outputs.should-build-api-docker && 'ignored' || 'api' }} + - project: ${{ needs.orchestrator.outputs.should-build-cli-docker && 'ignored' || 'cli' }} - project: ${{ needs.orchestrator.outputs.should-build-selfserve-docker && 'ignored' || 'selfserve' }} - project: ${{ needs.orchestrator.outputs.should-build-internal-docker && 'ignored' || 'internal' }} uses: ./.github/workflows/docker.yaml with: project: ${{ matrix.project }} version: ${{ needs.get-version.outputs[matrix.project] }} - app-artefact-name: ${{ matrix.project}} + app-artefact-name: ${{ matrix.project == 'cli' && 'api' || matrix.project }} push: false permissions: contents: read diff --git a/infra/docker/cli/Dockerfile b/infra/docker/cli/Dockerfile new file mode 100644 index 0000000000..e183431dec --- /dev/null +++ b/infra/docker/cli/Dockerfile @@ -0,0 +1,55 @@ +# hadolint global ignore=DL3018,SC2086 +FROM ghcr.io/dvsa/dvsa-docker-images/php/8.0/cli:0 AS cli + +# hadolint ignore=DL3002 +USER root + +RUN apk add --no-cache pcre-dev~=8.45 $PHPIZE_DEPS \ + && pecl install igbinary apcu \ + && pecl install -D "enable-redis-igbinary='yes' enable-redis-lzf='no' enable-redis-zstd='no'" redis \ + && docker-php-ext-enable igbinary apcu redis \ + && apk del pcre-dev $PHPIZE_DEPS + +# Install icu-dev, intl, pdo_mysql, opcache +RUN apk add --no-cache icu-dev \ + && docker-php-ext-configure intl \ + && docker-php-ext-install pdo_mysql opcache intl + +# PHP config file +COPY ./php.ini ${PHP_INI_DIR}/conf.d/zzzz-php.ini + +EXPOSE 8080 + +FROM cli AS production + +ADD ./api.tar.gz /var/www/html + +# `chown` and `chmod` flags do not work with `ADD` command when adding a tarball. +# https://github.com/docker/docs/issues/7305 +RUN chown -R root:www-data /var/www/html \ + # Reset the permissions of the application files. + && chmod -R 644 /var/www/html \ + # Add owner (`root`) and group (`www-data`) execute permissions on directories. + && find /var/www/html -type d -exec chmod 755 {} \; \ + # Add group (`www-data`) write permissions to the cache directory files. + && chmod -R 664 /var/www/html/data/cache \ + # Add group (`www-data`) write permissions on the cache directories. + && find /var/www/html/data/cache -type d -exec chmod 775 {} \; + +USER www-data + +FROM cli AS development + +RUN apk add --no-cache $PHPIZE_DEPS \ + && pecl install xdebug-3.1.5 \ + && docker-php-ext-enable xdebug \ + && apk del $PHPIZE_DEPS + +RUN echo "[xdebug]" >> ${PHP_INI_DIR}/conf.d/1000-php.ini \ + && echo "xdebug.log=/tmp/xdebug.log" >> ${PHP_INI_DIR}/conf.d/1000-php.ini \ + && echo "xdebug.remote_log=/tmp/xdebug.log" >> ${PHP_INI_DIR}/conf.d/1000-php.ini \ + && echo "xdebug.mode=debug" >> ${PHP_INI_DIR}/conf.d/1000-php.ini \ + && echo "xdebug.client_host=host.docker.internal" >> ${PHP_INI_DIR}/conf.d/1000-php.ini \ + && echo "xdebug.start_with_request=yes" >> ${PHP_INI_DIR}/conf.d/1000-php.ini + +USER www-data diff --git a/infra/docker/cli/php.ini b/infra/docker/cli/php.ini new file mode 100644 index 0000000000..37ca50e514 --- /dev/null +++ b/infra/docker/cli/php.ini @@ -0,0 +1,29 @@ +; PHP's initialization file, generally called php.ini, is responsible for +; configuring many of the aspects of PHP's behavior. +; For more information on the config file, please see: +; https://www.php.net/manual/en/index.php + +[PHP] +; Maximum amount of memory a script may consume +; https://php.net/memory-limit +memory_limit=2G + +[session] +; Handler used to serialize data. php is the standard serializer of PHP. +; https://php.net/session.serialize-handler +session.serialize_handler=igbinary + +[opcache] +; The maximum number of keys (and therefore scripts) in the OPcache hash table +; The Allowed value is between 200 and 100000. +opcache.max_accelerated_files=4000 + +; Validate timestamps of scripts on each request. +opcache.validate_timestamps=1 + +; Specifies the frequency at which OPcache checks for changes to PHP scripts +; in the filesystem. The value is in seconds. +opcache.revalidate_freq=60 + +; Enable the cli +opcache.enable_cli=1 diff --git a/infra/terraform/modules/account/ecr.tf b/infra/terraform/modules/account/ecr.tf index 4351420e99..51f4c011c8 100644 --- a/infra/terraform/modules/account/ecr.tf +++ b/infra/terraform/modules/account/ecr.tf @@ -1,5 +1,5 @@ locals { - repositories = var.create_ecr_resources ? ["api", "selfserve", "internal"] : [] + repositories = var.create_ecr_resources ? ["api", "cli", "selfserve", "internal"] : [] } module "ecr" {