diff --git a/.github/workflows/base-image-build-pr-main-ci.yml b/.github/workflows/base-image-build-pr-main-ci.yml new file mode 100644 index 0000000..aac8469 --- /dev/null +++ b/.github/workflows/base-image-build-pr-main-ci.yml @@ -0,0 +1,105 @@ +name: Test, lint and build PHP base Image on Shared Core ECR +run-name: Test, lint and build PHP base Image on Shared Core ECR + +on: + pull_request: + branches: + - main + +jobs: + + php-base-image-build: + + runs-on: ubuntu-latest + + env: + AWS_REGION : ${{ vars.DVSA_AWS_REGION }} #Change to reflect your Region + AWS_ACCOUNT_ID: ${{ vars.AWS_ACCOUNT_ID_SHAREDCOREECR }} + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + + permissions: + id-token: write # This is required for requesting the JWT + contents: read # This is required for actions/checkout + + steps: + - uses: actions/checkout@v3 + + - name: Lint check on dockerfile + run: | + jq -c '.[]' build.json | while read -r results; do + build=$(echo "$results" | jq -r '.build') + repoName=$(echo "$results" | jq -r '.repoName') + dockerFile=$(echo "$results" | jq -r '.dockerFile') + if [ "$build" == "true" ]; then + #docker run --rm --privileged -v `pwd`:/root/ projectatomic/dockerfile-lint dockerfile_lint -f build/$repoName/$dockerFile + docker run --rm -i hadolint/hadolint hadolint -t error - < build/$repoName/$dockerFile + else + echo "Not linting - $repoName, build parameter equal to false" + fi + done + + #falfast - credential configuration only to detect failure on PR + - name: Configure AWS credentials from Test account + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.DEV_AWS_ROLE }} + aws-region: ${{ vars.DVSA_AWS_REGION }} + role-session-name: GitHub_to_AWS_via_FederatedOIDC + + #failfast - credential configuration only to detect failure on PR + - name: Login to Shared Core ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 + with: + mask-password: 'true' + + #Action can not be used, no good way to loop through action on Github yet + - name: Install snyk cli + run: | + npm install -g snyk + + + - name: Build the Docker image + run: | + SHA=$(git rev-parse --short HEAD) + + # Iterate over JSON objects in build.json + jq -c '.[]' build.json | while read -r results; do + + repoName=$(echo "$results" | jq -r '.repoName') + dockerFile=$(echo "$results" | jq -r '.dockerFile') + tag=$(echo "$results" | jq -r '.tag') + build=$(echo "$results" | jq -r '.build') + + if [ "$build" == "true" ]; then + echo "Building $repoName ..." + buildTag="$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$repoName:$tag-$SHA" + docker build -t "$buildTag" --file "./build/$repoName/$dockerFile" build/. + else + echo "Not building - $repoName, build parameter equal to false" + fi + done + + + - name: snyk scan api image + run: | + SHA=$(git rev-parse --short HEAD) + + # Iterate over JSON objects in build.json + jq -c '.[]' build.json | while read -r results; do + + repoName=$(echo "$results" | jq -r '.repoName') + tag=$(echo "$results" | jq -r '.tag') + build=$(echo "$results" | jq -r '.build') + + if [ "$build" == "true" ]; then + snyk container test $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$repoName:$tag-$SHA --severity-threshold=critical + else + echo "Not scanning - $repoName, build parameter equal to false" + fi + done + continue-on-error: true # critical vulnerability found fix and remove this tag + + + + diff --git a/.github/workflows/base-image-push-merge-main-cd.yml b/.github/workflows/base-image-push-merge-main-cd.yml new file mode 100644 index 0000000..0159f66 --- /dev/null +++ b/.github/workflows/base-image-push-merge-main-cd.yml @@ -0,0 +1,67 @@ +name: Build, sign and push PHP base Image on Shared Core ECR +run-name: Test, sign and push PHP base Image on Shared Core ECR + +on: + pull_request: + branches: + - main + +jobs: + + # notation_setup: + # uses: ./.github/workflows/notation-setup-action.yaml + + php-base-image-push: + + runs-on: ubuntu-latest + + env: + AWS_REGION : ${{ vars.DVSA_AWS_REGION }} #Change to reflect your Region + AWS_ACCOUNT_ID: ${{ vars.AWS_ACCOUNT_ID_SHAREDCOREECR }} + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + + permissions: + id-token: write # This is required for requesting the JWT + contents: read # This is required for actions/checkout + + steps: + - uses: actions/checkout@v3 + + + - name: setup Notation CLI + uses: notaryproject/notation-action/setup@v1 + with: + version: "1.0.0" + + # download the required plugin for notary # llok into the ways to do it via action + - name: Set up Notation CLI + run: | + wget https://d2hvyiie56hcat.cloudfront.net/linux/amd64/installer/deb/latest/aws-signer-notation-cli_amd64.deb + sudo dpkg -i aws-signer-notation-cli_amd64.deb + notation version + notation plugin ls + + - name: Configure AWS credentials Shared core ECR + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.DEV_AWS_ROLE }} + aws-region: ${{ vars.DVSA_AWS_REGION }} + role-session-name: GitHub_to_AWS_via_FederatedOIDC + + - name: Login to Shared Core ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 + with: + mask-password: 'true' + + + - name: Build the Docker image + run: | + SHA=$(git rev-parse --short HEAD) + + # Iterate over JSON objects in build.json + jq -c '.[]' build.json | while read -r results; do + + repoName=$(echo "$results" | jq -r '.repoName') + dockerFile=$(echo "$results" | jq -r '.dockerFile') + t \ No newline at end of file diff --git a/build/php-base/docker-php-ext-xdebug.ini b/build/php-base/docker-php-ext-xdebug.ini deleted file mode 100644 index d4623f6..0000000 --- a/build/php-base/docker-php-ext-xdebug.ini +++ /dev/null @@ -1,7 +0,0 @@ -[xdebug] -zend_extension=xdebug.so -xdebug.log =/tmp/xdebug.log -xdebug.remote_log =/tmp/xdebug.log -xdebug.mode=debug -xdebug.client_host=host.docker.internal -xdebug.start_with_request=yes diff --git a/build/php-base/dockerfile_archive b/build/php-base/dockerfile_archive new file mode 100644 index 0000000..97e4b4c --- /dev/null +++ b/build/php-base/dockerfile_archive @@ -0,0 +1,62 @@ +# Add metadata to the image + + + +FROM php:7.4.33-fpm-alpine as production + +#php:7.4.0-fpm-alpine +# php:8.0-fpm-alpine + +LABEL maintainer="shaun.hare@dvsa.gov.uk" +LABEL description="PHP Alpine base image with dependency packages" +LABEL Name="vol-php-fpm:7.4.33-alpine-fpm" +LABEL Version="0.1" + +RUN apk add --no-cache \ + bash \ + autoconf \ + g++ \ + make \ + git \ + icu-dev \ + libmcrypt-dev \ + libpng-dev \ + libzip-dev \ + zlib-dev \ + python3 \ + py3-pip && \ + pip3 install --upgrade awscli && rm -rf '/var/cache/apk/*' \ + && docker-php-ext-install \ + bcmath \ + gd \ + intl \ + opcache \ + pdo_mysql \ + zip \ + pdo_mysql \ + intl + + +RUN pecl install apcu apcu_bc igbinary mcrypt stats-2.0.3 +RUN docker-php-ext-enable apcu igbinary mcrypt stats + +RUN pecl install -D 'enable-redis-igbinary="yes" enable-redis-lzf="no" enable-redis-zstd="no"' redis +RUN docker-php-ext-enable redis + +# Tweak apcu extension settings\ +RUN echo 'extension=apc' >> /usr/local/etc/php/conf.d/docker-php-ext-apcu.ini && \ + echo 'apc.enabled = 1' >> /usr/local/etc/php/conf.d/docker-php-ext-apcu.ini && \ + echo 'apc.mmap_file_mask = /tmp/apc.XXXXXX' >> /usr/local/etc/php/conf.d/docker-php-ext-apcu.ini && \ + # Tweak date settings + sed -i 's/;date.timezone =/date.timezone = "Europe\/London"/g' /usr/local/etc/php/php.ini-production && \ + # Tweak igbinary extension settings + echo 'session.serialize_handler = igbinary' >> /usr/local/etc/php/conf.d/docker-php-ext-igbinary.ini && \ + echo 'session.save_handler = redis' >> /usr/local/etc/php/php.ini-production && \ + # Set session.save_path for default \ + sed -i "s#.*session.save_path = .*#session.save_path = \"tcp://redis:6379\"#" /usr/local/etc/php/php.ini-production && \ + echo 'php_value[session.save_handler] = redis' >> /usr/local/etc/php-fpm.d/www.conf && \ + echo 'php_value[session.save_path] = "tcp://redis:6379"' >> /usr/local/etc/php-fpm.d/www.conf && \ + echo 'upload_tmp_dir = /var/tmp/nginx' >> /usr/local/etc/php/conf.d/docker-php-ext-upload.ini && \ + echo 'upload_max_filesize = 5M' >> /usr/local/etc/php/conf.d/docker-php-ext-upload.ini + + diff --git a/build/php-base/php-fpm/php-fpm.d/php-fpm.conf b/build/php-base/php-fpm/php-fpm.d/php-fpm.conf index 9e15743..71292b6 100644 --- a/build/php-base/php-fpm/php-fpm.d/php-fpm.conf +++ b/build/php-base/php-fpm/php-fpm.d/php-fpm.conf @@ -3,13 +3,23 @@ listen = /run/php-fpm.socket user = www-data group = www-data +request_terminate_timeout =0 +ping.path = /ping + +;config for process manager to control number of child process pm = dynamic pm.max_children = 125 pm.max_requests = 0 -request_terminate_timeout =0 -php_value[memory_limit] = 128M pm.start_servers = 16 pm.min_spare_servers = 16 pm.max_spare_servers = 32 pm.status_path = /status -ping.path = /ping \ No newline at end of file + + +;performance optimization +php_value[memory_limit] = 128M ;This is the default value and may need adjustment based on script + + +;Logging +php_admin_value[error_log] = /var/log/php-fpm/www-error.log +php_admin_flag[log_errors] = on \ No newline at end of file diff --git a/build/php-base/supervisord.conf b/build/php-base/supervisord.conf index 46b6417..d16f295 100644 --- a/build/php-base/supervisord.conf +++ b/build/php-base/supervisord.conf @@ -1,7 +1,12 @@ [unix_http_server] file=/tmp/supervisor.sock ; (the path to the socket file) -username=nobody -password=nobody +chmod=0700 +chown=nobody:nogroup +username=admin +password=p@ssword ;this will be overridden by new config + +;Running the supervisord in foreground will stop the container if an issue occurs with it. +;otherwise we have to depend on the monitoring tool to capture failure [supervisord] logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log) @@ -9,7 +14,7 @@ logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB) logfile_backups=10 ; (num of main logfile rotation backups;default 10) loglevel=info ; (log level;default info; others: debug,warn,trace) pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid) -nodaemon=false ; (start in foreground if true;default false) +nodaemon=true ; (start in foreground if true;default false) minfds=1024 ; (min. avail startup file descriptors;default 1024) minprocs=200 ; (min. avail process descriptors;default 200) user=root ; (default is current user, required if root)