diff --git a/.github/workflows/docker_build_develop.yml b/.github/workflows/docker_build_develop.yml index 612d81b8..d75ee7e2 100644 --- a/.github/workflows/docker_build_develop.yml +++ b/.github/workflows/docker_build_develop.yml @@ -10,6 +10,7 @@ jobs: runs-on: ubuntu-latest env: APP_VERSION: develop + COMPOSER_ALLOW_SUPERUSER: 1 steps: - name: Checkout uses: actions/checkout@v3 @@ -25,7 +26,7 @@ jobs: id: meta-api uses: docker/metadata-action@v4 with: - images: itkdev/os2display-api-service + images: os2display/display-api-service - name: Build and push (API) uses: docker/build-push-action@v4 @@ -43,7 +44,7 @@ jobs: id: meta-nginx uses: docker/metadata-action@v4 with: - images: itkdev/os2display-api-service-nginx + images: os2display/display-api-service-nginx - name: Build and push (Nginx) uses: docker/build-push-action@v4 diff --git a/.github/workflows/docker_build_tag.yml b/.github/workflows/docker_build_tag.yml index cf4f3d13..5b809013 100644 --- a/.github/workflows/docker_build_tag.yml +++ b/.github/workflows/docker_build_tag.yml @@ -8,6 +8,8 @@ name: Build docker image (tag) jobs: docker: runs-on: ubuntu-latest + env: + COMPOSER_ALLOW_SUPERUSER: 1 steps: - name: Checkout uses: actions/checkout@v3 @@ -23,7 +25,7 @@ jobs: id: meta-api uses: docker/metadata-action@v4 with: - images: itkdev/os2display-api-service + images: os2display/display-api-service - name: Build and push (API) uses: docker/build-push-action@v4 @@ -41,7 +43,7 @@ jobs: id: meta-nginx uses: docker/metadata-action@v4 with: - images: itkdev/os2display-api-service-nginx + images: os2display/display-api-service-nginx - name: Get the tag id: get_tag diff --git a/.github/workflows/github_build_release.yml b/.github/workflows/github_build_release.yml new file mode 100644 index 00000000..c2080f95 --- /dev/null +++ b/.github/workflows/github_build_release.yml @@ -0,0 +1,45 @@ +on: + push: + tags: + - '*.*.*' + +name: Create Github Release + +permissions: + contents: write + +jobs: + create-release: + runs-on: ubuntu-latest + env: + COMPOSER_ALLOW_SUPERUSER: 1 + APP_ENV: prod + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Composer install + run: | + docker network create frontend + docker compose run --rm phpfpm composer install --no-dev -o --classmap-authoritative + docker compose run --rm phpfpm composer clear-cache + rm -rf infrastructure + + - name: Make artefacts dir + run: | + mkdir -p ../assets + + - name: Create archive + run: | + tar \ + -zcf ../assets/${{ github.event.repository.name }}-${{ github.ref_name }}.tar.gz ./* + + - name: Create checksum + run: sha256sum ../assets/${{ github.event.repository.name }}-${{ github.ref_name }}.tar.gz > ../assets/checksum.txt + + - name: Create a release in GitHub and uploads assets + run: | + gh release create ${{ github.ref_name }} --verify-tag --generate-notes ../assets/*.* + env: + GITHUB_TOKEN: ${{ github.TOKEN }} + shell: bash diff --git a/.github/workflows/php_upgrade.yaml b/.github/workflows/php_upgrade.yaml index f6f67055..a4f99ff9 100644 --- a/.github/workflows/php_upgrade.yaml +++ b/.github/workflows/php_upgrade.yaml @@ -1,8 +1,10 @@ on: pull_request -name: Upgrade +name: PHP Upgrade Check jobs: test-composer-install: runs-on: ubuntu-latest + env: + COMPOSER_ALLOW_SUPERUSER: 1 strategy: fail-fast: false matrix: @@ -91,7 +93,7 @@ jobs: runs-on: ubuntu-latest services: mariadb: - image: mariadb:latest + image: mariadb:lts ports: - 3306 env: diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 07028a75..bd907ce2 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -1,8 +1,10 @@ on: pull_request -name: Review +name: Pull Request Review jobs: test-composer-install: runs-on: ubuntu-latest + env: + COMPOSER_ALLOW_SUPERUSER: 1 strategy: fail-fast: false matrix: @@ -141,7 +143,7 @@ jobs: runs-on: ubuntu-latest services: mariadb: - image: mariadb:latest + image: mariadb:lts ports: - 3306 env: diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f46561a..b3e0d3eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +- Update docker build to publish to "os2display" org on docker hup. Update github workflow to latest actions. ## [1.2.8] - 2023-05-25 - [#145](https://github.com/os2display/display-api-service/pull/145) diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml deleted file mode 100644 index 0e734f29..00000000 --- a/docker-compose.dev.yml +++ /dev/null @@ -1,28 +0,0 @@ -# itk-version: 3.0.0 -version: "3" - -services: - phpfpm: - environment: - - PHP_SENDMAIL_PATH='/usr/local/bin/mhsendmail --smtp-addr="mailhog:1025"' - - nginx: - labels: - - "traefik.http.routers.${COMPOSE_PROJECT_NAME}.middlewares=ITKBasicAuth@file" - - mailhog: - image: itkdev/mailhog - networks: - - app - - frontend - labels: - - "traefik.enable=true" - - "traefik.docker.network=frontend" - - "traefik.http.routers.mailhog_${COMPOSE_PROJECT_NAME}-http.rule=Host(`mailhog.${COMPOSE_SERVER_DOMAIN}`)" - - "traefik.http.routers.mailhog_${COMPOSE_PROJECT_NAME}-http.entrypoints=web" - - "traefik.http.routers.mailhog_${COMPOSE_PROJECT_NAME}-http.middlewares=redirect-to-https" - - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" - - "traefik.http.routers.mailhog_${COMPOSE_PROJECT_NAME}.rule=Host(`mailhog.${COMPOSE_SERVER_DOMAIN}`)" - - "traefik.http.routers.mailhog_${COMPOSE_PROJECT_NAME}.entrypoints=websecure" - - "traefik.http.services.mailhog_${COMPOSE_PROJECT_NAME}.loadbalancer.server.port=8025" - - "traefik.http.routers.mailhog_${COMPOSE_PROJECT_NAME}.middlewares=ITKMailhogAuth@file" diff --git a/docker-compose.redirect.yml b/docker-compose.redirect.yml deleted file mode 100644 index 9c1d2af1..00000000 --- a/docker-compose.redirect.yml +++ /dev/null @@ -1,17 +0,0 @@ -# itk-version: 3.0.0 -version: "3" - -services: - nginx: - labels: - # Add www before domain and set redirect to non-www - - "traefik.http.routers.www_${COMPOSE_PROJECT_NAME}-http.rule=Host(`www.${COMPOSE_SERVER_DOMAIN}`)" - - "traefik.http.routers.www_${COMPOSE_PROJECT_NAME}-http.entrypoints=web" - - "traefik.http.routers.www_${COMPOSE_PROJECT_NAME}-http.middlewares=redirect-to-https,non_www" - - "traefik.http.routers.www_${COMPOSE_PROJECT_NAME}.rule=Host(`www.${COMPOSE_SERVER_DOMAIN}`)" - - "traefik.http.routers.www_${COMPOSE_PROJECT_NAME}.entrypoints=websecure" - - "traefik.http.routers.www_${COMPOSE_PROJECT_NAME}.middlewares=non_www" - - - traefik.http.middlewares.non_www.redirectregex.regex=^(http|https)?://(?:www\.)?(.+) - - traefik.http.middlewares.non_www.redirectregex.replacement=https://$${2} - - traefik.http.middlewares.non_www.redirectregex.permanent=true diff --git a/docker-compose.server.yml b/docker-compose.server.yml deleted file mode 100644 index 47797eb6..00000000 --- a/docker-compose.server.yml +++ /dev/null @@ -1,48 +0,0 @@ -# itk-version: 3.0.0 -version: "3" - -networks: - frontend: - external: true - app: - driver: bridge - internal: false - -services: - phpfpm: - image: itkdev/php8.1-fpm:alpine - restart: unless-stopped - networks: - - app - extra_hosts: - - "host.docker.internal:host-gateway" - environment: - - PHP_MAX_EXECUTION_TIME=30 - - PHP_MEMORY_LIMIT=128M - - COMPOSER_VERSION=2 - volumes: - - .:/app - - nginx: - image: nginxinc/nginx-unprivileged:alpine - restart: unless-stopped - networks: - - app - - frontend - depends_on: - - phpfpm - ports: - - '8080' - volumes: - - ./.docker/vhost.conf:/etc/nginx/conf.d/default.conf:ro - - ./.docker/nginx.conf:/etc/nginx/nginx.conf:ro - - ./:/app:rw - labels: - - "traefik.enable=true" - - "traefik.docker.network=frontend" - - "traefik.http.routers.${COMPOSE_PROJECT_NAME}-http.rule=Host(`${COMPOSE_SERVER_DOMAIN}`)" - - "traefik.http.routers.${COMPOSE_PROJECT_NAME}-http.entrypoints=web" - - "traefik.http.routers.${COMPOSE_PROJECT_NAME}-http.middlewares=redirect-to-https" - - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" - - "traefik.http.routers.${COMPOSE_PROJECT_NAME}.rule=Host(`${COMPOSE_SERVER_DOMAIN}`)" - - "traefik.http.routers.${COMPOSE_PROJECT_NAME}.entrypoints=websecure" diff --git a/infrastructure/display-api-service/Dockerfile b/infrastructure/display-api-service/Dockerfile index f8ec6fe8..ee17f0ba 100644 --- a/infrastructure/display-api-service/Dockerfile +++ b/infrastructure/display-api-service/Dockerfile @@ -1,47 +1,140 @@ -FROM itkdev/php8.1-fpm:alpine AS APP_BUILDER +FROM php:8.1-fpm-alpine LABEL maintainer="ITK Dev " -ARG APP_VERSION="develop" -ENV APP_PATH=/var/www/html +############# SETUP CONTAINER ############# USER root +ARG APP_VERSION="develop" + +ENV APP_PATH=/var/www/html \ + # PHP + TZ="Europe/Copenhagen" \ + PHP_TIMEZONE="Europe/Copenhagen" \ + PHP_MAX_EXECUTION_TIME="30" \ + PHP_MEMORY_LIMIT="128M" \ + PHP_POST_MAX_SIZE="8M" \ + PHP_UPLOAD_MAX_FILESIZE="2M" \ + PHP_USER="www-data" \ + PHP_GROUP="www-data" \ + PHP_SENDMAIL_PATH='/usr/sbin/sendmail -S host.docker.internal -t -i' \ + # OpCache + PHP_OPCACHE_ENABLED="1" \ + PHP_OPCACHE_JIT="off" \ + PHP_OPCACHE_REVALIDATE_FREQ=0 \ + PHP_OPCACHE_VALIDATE_TIMESTAMPS="1" \ + PHP_OPCACHE_MAX_ACCELERATED_FILES="20000" \ + PHP_OPCACHE_MEMORY_CONSUMPTION="64" \ + PHP_OPCACHE_MAX_WASTED_PERCENTAGE="10" \ + # APCU + PHP_APCU_ENABLED=0 \ + PHP_APCU_ENABLED_CLI=0 \ + PHP_APCU_MEMORY_SIZE="16M" \ + PHP_APCU_SEGMENTS=1 \ + PHP_APCU_PRELOAD_PATH='' \ + # FPM pool + PHP_PM_TYPE="static" \ + PHP_PM_MAX_CHILDREN="8" \ + PHP_PM_MAX_REQUESTS="0" \ + PHP_PM_START_SERVERS="5" \ + PHP_PM_MIN_SPARE_SERVERS="5" \ + PHP_PM_MAX_SPARE_SERVERS="8" \ + # Other + PHP_REQUEST_SLOWLOG_TIMEOUT="0" \ + PHP_SLOWLOG="/dev/stderr" \ + COMPOSER_ALLOW_SUPERUSER=1 + +RUN apk upgrade --no-cache --ignore curl +RUN apk --update add --no-cache \ + libxslt-dev \ + libzip-dev \ + libpng-dev \ + gettext-dev \ + git \ + unzip \ + icu-dev \ + icu-data-full \ + openldap-dev \ + libmcrypt-dev \ + mysql-client \ + libmemcached-libs \ + zlib \ + patch \ + tzdata \ + freetype-dev \ + libjpeg-turbo-dev \ + libjpeg-turbo \ + libwebp-dev \ + && docker-php-ext-configure gd --with-freetype --with-webp --with-jpeg \ + && docker-php-ext-install -j$(nproc) \ + bcmath \ + calendar \ + gd \ + gettext \ + intl \ + ldap \ + mysqli \ + opcache \ + pdo_mysql \ + sysvsem \ + soap \ + xsl \ + zip + +# Extension that are not available via ext- +RUN apk --update add --no-cache --virtual .build-deps autoconf g++ make zlib-dev libmemcached-dev cyrus-sasl-dev \ + && pecl channel-update pecl.php.net \ + && pecl install redis memcached apcu \ + && docker-php-ext-enable apcu redis memcached \ + && apk del .build-deps + +# Install AMQP support +RUN apk --update add --no-cache rabbitmq-c +RUN apk --update add --no-cache --virtual .build-deps autoconf g++ make rabbitmq-c-dev \ + && pecl install amqp \ + && docker-php-ext-enable amqp memcached \ + && apk del .build-deps + +# Install composer +COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer + +# Use default PHP production configuration. +RUN mv ${PHP_INI_DIR}/php.ini-production ${PHP_INI_DIR}/php.ini + +# # Copy custom PHP configuration. +COPY php/opcache.ini ${PHP_INI_DIR}/conf.d/docker-php-ext-opcache.ini +COPY php/php.ini ${PHP_INI_DIR}/conf.d/zz-php.ini +COPY php/apcu.ini ${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini + +# Custom FPM configuration. +COPY php/fpm.ini ${PHP_INI_DIR}/../php-fpm.d/zz-fpm-docker.conf + +# Add mhsendmail for mailhog +ADD https://github.com/mailhog/mhsendmail/releases/download/v0.2.0/mhsendmail_linux_amd64 /usr/local/bin/mhsendmail +RUN chmod +x /usr/local/bin/mhsendmail + +# Added FPM health check script (https://github.com/renatomefi/php-fpm-healthcheck) +ADD https://raw.githubusercontent.com/renatomefi/php-fpm-healthcheck/master/php-fpm-healthcheck /usr/local/bin/php-fpm-healthcheck +RUN chmod +x /usr/local/bin/php-fpm-healthcheck + +# Add git global config +COPY gitconfig /root/.gitconfig + +############# SETUP APPLICATION ############# + # Move site into the container. ADD https://github.com/os2display/display-api-service/archive/${APP_VERSION}.tar.gz /tmp/app.tar RUN tar -zxf /tmp/app.tar --strip-components=1 -C ${APP_PATH} \ && rm /tmp/app.tar -# Add composer in from the official composer image (also alpine). -COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer - -WORKDIR ${APP_PATH} - ## Install assets, which requires a HACK as redis is not available (should be removed later on). RUN APP_ENV=prod composer install --no-dev -o --classmap-authoritative \ && rm -rf infrastructure \ && APP_ENV=prod composer clear-cache -#### -## Build main application image. -#### -FROM itkdev/php8.1-fpm:alpine -LABEL maintainer="ITK Dev " - -ENV APP_PATH=/var/www/html \ - COMPOSER_VERSION=2 - -USER root - -# Add composer needed to run optimizations after config is loaded. -COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer - # Install the application. -COPY --from=APP_BUILDER ${APP_PATH} ${APP_PATH} RUN mkdir -p ${APP_PATH}/config/secrets \ - && chown -R deploy:deploy ${APP_PATH} - -# Download Prometheus php-fpm export. -COPY --from=hipages/php-fpm_exporter:1.1.1 /php-fpm_exporter /usr/local/bin/php-fpm_exporter + && chown -R www-data:www-data ${APP_PATH} # Copy configuration. COPY etc/ /etc/ @@ -56,8 +149,6 @@ COPY etc/ /etc/ COPY docker-entrypoint.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/docker-entrypoint.sh -USER deploy - WORKDIR ${APP_PATH} CMD [ "docker-entrypoint.sh" ] diff --git a/infrastructure/display-api-service/docker-entrypoint.sh b/infrastructure/display-api-service/docker-entrypoint.sh index 306e9f13..0ed90848 100644 --- a/infrastructure/display-api-service/docker-entrypoint.sh +++ b/infrastructure/display-api-service/docker-entrypoint.sh @@ -11,15 +11,12 @@ composer dump-env prod ## Warm-up Symfony cache (with the current configuration). /var/www/html/bin/console --env=prod cache:warmup -## Set selected composer version. Default version 2. -if [ ! -z "${COMPOSER_VERSION}" ]; then - if [ "${COMPOSER_VERSION}" = "1" ]; then - ln -fs /usr/bin/composer1 /home/deploy/bin/composer - else - ln -fs /usr/bin/composer2 /home/deploy/bin/composer - fi -else - ln -fs /usr/bin/composer2 /home/deploy/bin/composer +# first arg is `-f` or `--some-option` +if [ "${1#-}" != "$1" ]; then + set -- php-fpm "$@" fi +## Start the PHP FPM process. +echo "Starting PHP 8.1 FPM" + exec php-fpm "$@" diff --git a/infrastructure/display-api-service/gitconfig b/infrastructure/display-api-service/gitconfig new file mode 100644 index 00000000..60a3b020 --- /dev/null +++ b/infrastructure/display-api-service/gitconfig @@ -0,0 +1,9 @@ +[color] + ui = true + +[alias] + branch-name = !git for-each-ref --format='%(refname:short)' `git symbolic-ref HEAD` + lg = log --graph --pretty=format:'%Cred%h%Creset %Cgreen(%cr) -%C(yellow)%d%Creset %s %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative + +[safe] + directory = * \ No newline at end of file diff --git a/infrastructure/display-api-service/php/apcu.ini b/infrastructure/display-api-service/php/apcu.ini new file mode 100644 index 00000000..86164be8 --- /dev/null +++ b/infrastructure/display-api-service/php/apcu.ini @@ -0,0 +1,7 @@ +extension=apcu +apc.enabled=${PHP_APCU_ENABLED} +apc.shm_segments=${PHP_APCU_SEGMENTS} +apc.shm_size=${PHP_APCU_MEMORY_SIZE} + +apc.enable_cli=${PHP_APCU_ENABLED_CLI} +apc.preload_path=${PHP_APCU_PRELOAD_PATH} \ No newline at end of file diff --git a/infrastructure/display-api-service/php/fpm.ini b/infrastructure/display-api-service/php/fpm.ini new file mode 100644 index 00000000..49e0aeb4 --- /dev/null +++ b/infrastructure/display-api-service/php/fpm.ini @@ -0,0 +1,17 @@ +[www] +pm = ${PHP_PM_TYPE} +pm.max_children = ${PHP_PM_MAX_CHILDREN} +pm.start_servers = ${PHP_PM_START_SERVERS} +pm.min_spare_servers = ${PHP_PM_MIN_SPARE_SERVERS} +pm.max_spare_servers = ${PHP_PM_MAX_SPARE_SERVERS} +pm.max_requests = ${PHP_PM_MAX_REQUESTS} + +request_slowlog_timeout = ${PHP_REQUEST_SLOWLOG_TIMEOUT} +slowlog = ${PHP_SLOWLOG} + +; Enable the FPM status page +pm.status_path = /status + +user = ${PHP_USER} +group = ${PHP_GROUP} + diff --git a/infrastructure/display-api-service/php/opcache.ini b/infrastructure/display-api-service/php/opcache.ini new file mode 100644 index 00000000..8ff17863 --- /dev/null +++ b/infrastructure/display-api-service/php/opcache.ini @@ -0,0 +1,15 @@ +zend_extension=opcache.so + +[opcache] +opcache.jit=${PHP_OPCACHE_JIT} + +opcache.enable=${PHP_OPCACHE_ENABLED} +opcache.revalidate_freq=${PHP_OPCACHE_REVALIDATE_FREQ} +opcache.validate_timestamps=${PHP_OPCACHE_VALIDATE_TIMESTAMPS} +opcache.max_accelerated_files=${PHP_OPCACHE_MAX_ACCELERATED_FILES} +opcache.memory_consumption=${PHP_OPCACHE_MEMORY_CONSUMPTION} +opcache.max_wasted_percentage=${PHP_OPCACHE_MAX_WASTED_PERCENTAGE} +opcache.interned_strings_buffer=16 +opcache.fast_shutdown=1 + +opcache.optimization_level=0xFFFFFFEF diff --git a/infrastructure/display-api-service/php/php.ini b/infrastructure/display-api-service/php/php.ini new file mode 100644 index 00000000..2bfde2b4 --- /dev/null +++ b/infrastructure/display-api-service/php/php.ini @@ -0,0 +1,13 @@ +realpath_cache_size = 4096k +realpath_cache_ttl = 600 + +expose_php = Off +max_execution_time = ${PHP_MAX_EXECUTION_TIME} +memory_limit = ${PHP_MEMORY_LIMIT} + +post_max_size = ${PHP_POST_MAX_SIZE} +upload_max_filesize = ${PHP_UPLOAD_MAX_FILESIZE} + +date.timezone = ${PHP_TIMEZONE} + +sendmail_path = ${PHP_SENDMAIL_PATH} diff --git a/infrastructure/nginx/Dockerfile b/infrastructure/nginx/Dockerfile index 7a0334dd..f6b93c74 100644 --- a/infrastructure/nginx/Dockerfile +++ b/infrastructure/nginx/Dockerfile @@ -1,5 +1,5 @@ ARG APP_VERSION="develop" -FROM itkdev/os2display-api-service:${APP_VERSION} as APPLICATION +FROM os2display/display-api-service:${APP_VERSION} as APPLICATION FROM nginxinc/nginx-unprivileged:alpine LABEL maintainer="ITK Dev " diff --git a/infrastructure/run.sh b/infrastructure/run.sh index b028f5cd..ae23d67b 100755 --- a/infrastructure/run.sh +++ b/infrastructure/run.sh @@ -6,8 +6,8 @@ APP_VERSION=develop docker pull nginxinc/nginx-unprivileged:alpine -docker build --pull --no-cache --build-arg APP_VERSION=${APP_VERSION} --tag=itkdev/os2display-api-service:${APP_VERSION} --file="display-api-service/Dockerfile" display-api-service -docker build --no-cache --build-arg VERSION=${APP_VERSION} --tag=itkdev/os2display-api-service-nginx:${APP_VERSION} --file="nginx/Dockerfile" nginx +docker build --pull --no-cache --build-arg APP_VERSION=${APP_VERSION} --tag=os2display/display-api-service:${APP_VERSION} --file="display-api-service/Dockerfile" display-api-service +docker build --no-cache --build-arg VERSION=${APP_VERSION} --tag=os2display/display-api-service-nginx:${APP_VERSION} --file="nginx/Dockerfile" nginx -# docker push itkdev/os2display-api-service:${APP_VERSION} -# docker push itkdev/os2display-api-service-nginx:${APP_VERSION} +# docker push os2display/display-api-service:${APP_VERSION} +# docker push os2display/display-api-service-nginx:${APP_VERSION}