├── .github └── workflows │ ├── docker-build.yml │ ├── docker.yml │ └── weekly_patch.yml ├── .gitignore ├── .kaniko-project-gitlab-ci.yml ├── .project-gitlab-ci.yml ├── CODE_OF_CONDUCT.md ├── Dockerfile ├── Dockerfile-blackfire ├── Dockerfile-debug ├── Dockerfile-nginx ├── Dockerfile-supervisord ├── LICENSE ├── README.md ├── blackfire └── blackfire.ini ├── fpm ├── php-config.conf ├── php-pool-config.conf └── php.ini ├── nginx └── pimcore-default.conf ├── php ├── docker-entrypoint.sh ├── docker-healthcheck.sh ├── docker-install.sh ├── docker-migrate.sh ├── docker-readiness.sh ├── docker-status.sh ├── docker-wait-db.sh ├── docker-wait-pimcore.sh ├── docker-wait.sh └── docker-xdebug-entrypoint.sh └── supervisord ├── coreshop._conf ├── pimcore.conf └── supervisord.conf /.github/workflows/docker-build.yml: -------------------------------------------------------------------------------- 1 | name: Reusable Build Workflow 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | component: 7 | required: true 8 | type: string 9 | matrix: 10 | required: true 11 | type: string 12 | matrix_manifest: 13 | required: true 14 | type: string 15 | release_tag: 16 | required: false 17 | type: string # Optional input for specifying a release tag. 18 | 19 | permissions: 20 | contents: read 21 | packages: write 22 | attestations: write 23 | id-token: write 24 | 25 | jobs: 26 | build: 27 | name: > 28 | Build ${{ inputs.component }} 29 | ${{ matrix.arch }}/${{ matrix.php_version || matrix.nginx_version }}${{ matrix.php_type && '/' }}${{ matrix.php_type || '' }}${{ matrix.alpine && '/' }}${{ matrix.alpine || '' }} 30 | runs-on: ${{ matrix.arch == 'amd' && 'ubuntu-22.04' || 'ubuntu-22.04-arm' }} 31 | strategy: 32 | matrix: ${{ fromJSON(inputs.matrix) }} 33 | steps: 34 | - name: Checkout code 35 | uses: actions/checkout@v3 36 | 37 | - name: Login to GitHub Container Registry 38 | run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin 39 | 40 | - name: Set Image Name and Tag 41 | id: image_name 42 | run: | 43 | FROM_IMAGE="" 44 | RELEASE_TAG="${{ inputs.release_tag || env.GITHUB_REF_NAME }}" 45 | 46 | if [ "${{ inputs.component }}" == "php" ]; then 47 | IMAGE_NAME=${{ matrix.arch }}-php-${{ matrix.php_type }} 48 | IMAGE_TAG=${{ matrix.php_version }}-alpine${{ matrix.alpine }}-${RELEASE_TAG} 49 | elif [ "${{ inputs.component }}" == "php_debug" ]; then 50 | IMAGE_NAME=${{ matrix.arch }}-php-${{ matrix.php_type }}-debug 51 | FROM_IMAGE=ghcr.io/${{ github.repository }}/${{ matrix.arch }}-php-${{ matrix.php_type }}:${{ matrix.php_version }}-alpine${{ matrix.alpine }}-${RELEASE_TAG} 52 | IMAGE_TAG=${{ matrix.php_version }}-alpine${{ matrix.alpine }}-${RELEASE_TAG} 53 | elif [ "${{ inputs.component }}" == "php_blackfire" ]; then 54 | IMAGE_NAME=${{ matrix.arch }}-php-fpm-blackfire 55 | FROM_IMAGE=ghcr.io/${{ github.repository }}/${{ matrix.arch }}-php-fpm:${{ matrix.php_version }}-alpine${{ matrix.alpine }}-${RELEASE_TAG} 56 | IMAGE_TAG=${{ matrix.php_version }}-alpine${{ matrix.alpine }}-${RELEASE_TAG} 57 | elif [ "${{ inputs.component }}" == "supervisord" ]; then 58 | IMAGE_NAME=${{ matrix.arch }}-php-supervisord 59 | FROM_IMAGE=ghcr.io/${{ github.repository }}/${{ matrix.arch }}-php-cli:${{ matrix.php_version }}-alpine${{ matrix.alpine }}-${RELEASE_TAG} 60 | IMAGE_TAG=${{ matrix.php_version }}-alpine${{ matrix.alpine }}-${RELEASE_TAG} 61 | elif [ "${{ inputs.component }}" == "nginx" ]; then 62 | IMAGE_NAME=${{ matrix.arch }}-nginx 63 | IMAGE_TAG=${{ matrix.nginx_version }}-${RELEASE_TAG} 64 | fi 65 | 66 | echo "IMAGE_NAME=$IMAGE_NAME" >> $GITHUB_ENV 67 | echo "FROM_IMAGE=$FROM_IMAGE" >> $GITHUB_ENV 68 | echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV 69 | 70 | - name: Pull Latest Image for Cache 71 | run: | 72 | REGISTRY=ghcr.io/${{ github.repository }} 73 | docker pull $REGISTRY/$IMAGE_NAME:${{ env.IMAGE_TAG }} || echo "No cache available" 74 | 75 | - name: Build Docker Image 76 | id: build 77 | run: | 78 | DOCKERFILE=Dockerfile 79 | 80 | if [ "${{ inputs.component }}" == "php_debug" ]; then 81 | DOCKERFILE=Dockerfile-debug 82 | elif [ "${{ inputs.component }}" == "php_blackfire" ]; then 83 | DOCKERFILE=Dockerfile-blackfire 84 | elif [ "${{ inputs.component }}" == "supervisord" ]; then 85 | DOCKERFILE=Dockerfile-supervisord 86 | elif [ "${{ inputs.component }}" == "nginx" ]; then 87 | DOCKERFILE=Dockerfile-nginx 88 | fi 89 | 90 | REGISTRY=ghcr.io/${{ github.repository }} 91 | 92 | docker build \ 93 | -f $DOCKERFILE \ 94 | --cache-from $REGISTRY/$IMAGE_NAME:${{ env.IMAGE_TAG }} \ 95 | --tag $REGISTRY/$IMAGE_NAME:${{ env.IMAGE_TAG }} \ 96 | --build-arg PHP_VERSION=${{ matrix.php_version || '' }} \ 97 | $(if [ -n "${{ env.FROM_IMAGE }}" ]; then echo "--build-arg FROM=${{ env.FROM_IMAGE }}"; fi) \ 98 | --build-arg PHP_TYPE=${{ matrix.php_type || '' }} \ 99 | --build-arg ALPINE_VERSION=${{ matrix.alpine || '' }} \ 100 | --build-arg NGINX_VERSION=${{ matrix.nginx_version || '' }} . 101 | 102 | - name: Push Docker Image 103 | id: push 104 | run: | 105 | docker push ghcr.io/${{ github.repository }}/$IMAGE_NAME:${{ env.IMAGE_TAG }} 106 | 107 | - name: Get Image Digest 108 | id: get_digest 109 | run: | 110 | REGISTRY=ghcr.io/${{ github.repository }} 111 | DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' $REGISTRY/$IMAGE_NAME:${{ env.IMAGE_TAG }} | cut -d '@' -f 2) 112 | echo "IMAGE_DIGEST=$DIGEST" >> $GITHUB_ENV 113 | echo "IMAGE_DIGEST=$DIGEST" # Output to logs for debugging 114 | 115 | - name: Generate Artifact Attestation 116 | uses: actions/attest-build-provenance@v2 117 | with: 118 | subject-name: ghcr.io/${{ github.repository }}/${{ env.IMAGE_NAME }} 119 | subject-digest: ${{ env.IMAGE_DIGEST }} 120 | push-to-registry: true 121 | 122 | manifest: 123 | name: 124 | Manifest 125 | ${{ inputs.component }} 126 | ${{ matrix.php_version || matrix.nginx_version }}${{ matrix.php_type && '/' }}${{ matrix.php_type || '' }}${{ matrix.alpine && '/' }}${{ matrix.alpine || '' }} 127 | needs: build 128 | runs-on: ubuntu-22.04 129 | strategy: 130 | matrix: ${{ fromJSON(inputs.matrix_manifest) }} 131 | steps: 132 | - name: Login to GitHub Container Registry 133 | run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin 134 | 135 | - name: Create and Push Multi-Arch Manifest 136 | run: | 137 | REGISTRY=ghcr.io/${{ github.repository }} 138 | 139 | RELEASE_TAG="${{ inputs.release_tag || env.GITHUB_REF_NAME }}" 140 | 141 | if [ "${{ inputs.component }}" == "php" ]; then 142 | IMAGE_NAME=php-${{ matrix.php_type }} 143 | IMAGE_TAG=${{ matrix.php_version }}-alpine${{ matrix.alpine }}-${RELEASE_TAG} 144 | elif [ "${{ inputs.component }}" == "php_debug" ]; then 145 | IMAGE_NAME=php-${{ matrix.php_type }}-debug 146 | IMAGE_TAG=${{ matrix.php_version }}-alpine${{ matrix.alpine }}-${RELEASE_TAG} 147 | elif [ "${{ inputs.component }}" == "php_blackfire" ]; then 148 | IMAGE_NAME=php-fpm-blackfire 149 | IMAGE_TAG=${{ matrix.php_version }}-alpine${{ matrix.alpine }}-${RELEASE_TAG} 150 | elif [ "${{ inputs.component }}" == "supervisord" ]; then 151 | IMAGE_NAME=php-supervisord 152 | IMAGE_TAG=${{ matrix.php_version }}-alpine${{ matrix.alpine }}-${RELEASE_TAG} 153 | elif [ "${{ inputs.component }}" == "nginx" ]; then 154 | IMAGE_NAME=nginx 155 | IMAGE_TAG=${{ matrix.nginx_version }}-${RELEASE_TAG} 156 | fi 157 | 158 | docker manifest create \ 159 | $REGISTRY/$IMAGE_NAME:$IMAGE_TAG \ 160 | --amend $REGISTRY/amd-$IMAGE_NAME:$IMAGE_TAG \ 161 | --amend $REGISTRY/arm-$IMAGE_NAME:$IMAGE_TAG 162 | 163 | docker manifest push $REGISTRY/$IMAGE_NAME:$IMAGE_TAG -------------------------------------------------------------------------------- /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: CORS Pimcore Docker Build 2 | 3 | on: 4 | push: 5 | branches: 6 | - "7.0" 7 | tags: 8 | - "*" 9 | workflow_dispatch: ~ 10 | schedule: 11 | - cron: "0 2 * * *" 12 | 13 | env: 14 | ARCHITECTURES: 'amd arm' 15 | PHP_VERSIONS: '8.1 8.2 8.3 8.4' 16 | PHP_TYPES: 'fpm cli' 17 | ALPINE_VERSIONS: '3.20 3.21 3.22' 18 | NGINX_VERSIONS: '1.25 1.26 1.27 1.28' 19 | INCOMPATIBLE_MATRIX: > 20 | [ 21 | { "php_version": "8.1", "alpine": "3.22" }, 22 | { "php_version": "8.2", "alpine": "3.22" } 23 | ] 24 | 25 | jobs: 26 | matrix: 27 | runs-on: ubuntu-latest 28 | outputs: 29 | php_matrix: ${{ steps.matrix.outputs.php_matrix }} 30 | php_manifest: ${{ steps.matrix.outputs.php_manifest }} 31 | php_debug_matrix: ${{ steps.matrix.outputs.php_debug_matrix }} 32 | php_debug_manifest: ${{ steps.matrix.outputs.php_debug_manifest }} 33 | php_blackfire_matrix: ${{ steps.matrix.outputs.php_blackfire_matrix }} 34 | php_blackfire_manifest: ${{ steps.matrix.outputs.php_blackfire_manifest }} 35 | supervisord_matrix: ${{ steps.matrix.outputs.supervisord_matrix }} 36 | supervisord_manifest: ${{ steps.matrix.outputs.supervisord_manifest }} 37 | nginx_matrix: ${{ steps.matrix.outputs.nginx_matrix }} 38 | nginx_manifest: ${{ steps.matrix.outputs.nginx_manifest }} 39 | steps: 40 | - name: Generate all matrices 41 | id: matrix 42 | run: | 43 | set -e 44 | 45 | ######################## 46 | ## Parse env variables into arrays 47 | ######################## 48 | 49 | IFS=' ' read -r -a ARCH <<< "$ARCHITECTURES" 50 | IFS=' ' read -r -a PHP <<< "$PHP_VERSIONS" 51 | IFS=' ' read -r -a TYPES <<< "$PHP_TYPES" 52 | IFS=' ' read -r -a ALPINE <<< "$ALPINE_VERSIONS" 53 | IFS=' ' read -r -a NGINX <<< "$NGINX_VERSIONS" 54 | 55 | ######################## 56 | ## Incompatibility Check Function 57 | ######################## 58 | 59 | is_incompatible_combination() { 60 | declare -A combination 61 | while [[ "$#" -gt 1 ]]; do 62 | key="$1" 63 | value="$2" 64 | combination["$key"]="$value" 65 | shift 2 66 | done 67 | 68 | for row in $(echo "$INCOMPATIBLE_MATRIX" | jq -c '.[]'); do 69 | local skip=false 70 | for key in $(echo "$row" | jq -r 'keys[]'); do 71 | expected_value=$(echo "$row" | jq -r --arg key "$key" '.[$key]') 72 | if [[ "${combination[$key]}" != "$expected_value" ]]; then 73 | skip=true 74 | break 75 | fi 76 | done 77 | if [[ "$skip" == "false" ]]; then 78 | return 0 79 | fi 80 | done 81 | return 1 82 | } 83 | 84 | ######################## 85 | ## Matrix Generator Function 86 | ######################## 87 | 88 | generate_matrix() { 89 | local component="$1" 90 | local output_var="$2" 91 | local build_axes="$3" 92 | 93 | local matrix='{"include":[' 94 | 95 | if [[ "$component" == "php" || "$component" == "php_debug" ]]; then 96 | for php_version in "${PHP[@]}"; do 97 | for php_type in "${TYPES[@]}"; do 98 | for alpine in "${ALPINE[@]}"; do 99 | if [[ "$component" == "php_debug" && "$php_type" != "fpm" ]]; then continue; fi 100 | if [[ "$build_axes" == "build" ]]; then 101 | for arch in "${ARCH[@]}"; do 102 | if is_incompatible_combination php_version "$php_version" php_type "$php_type" alpine "$alpine" arch "$arch"; then continue; fi 103 | matrix+="{\"arch\":\"$arch\",\"php_version\":\"$php_version\",\"php_type\":\"$php_type\",\"alpine\":\"$alpine\"}," 104 | done 105 | else 106 | if is_incompatible_combination php_version "$php_version" php_type "$php_type" alpine "$alpine"; then continue; fi 107 | matrix+="{\"php_version\":\"$php_version\",\"php_type\":\"$php_type\",\"alpine\":\"$alpine\"}," 108 | fi 109 | done 110 | done 111 | done 112 | 113 | elif [[ "$component" == "php_blackfire" || "$component" == "supervisord" ]]; then 114 | for php_version in "${PHP[@]}"; do 115 | for alpine in "${ALPINE[@]}"; do 116 | if [[ "$build_axes" == "build" ]]; then 117 | for arch in "${ARCH[@]}"; do 118 | if is_incompatible_combination php_version "$php_version" alpine "$alpine" arch "$arch"; then continue; fi 119 | matrix+="{\"arch\":\"$arch\",\"php_version\":\"$php_version\",\"alpine\":\"$alpine\"}," 120 | done 121 | else 122 | if is_incompatible_combination php_version "$php_version" alpine "$alpine"; then continue; fi 123 | matrix+="{\"php_version\":\"$php_version\",\"alpine\":\"$alpine\"}," 124 | fi 125 | done 126 | done 127 | 128 | elif [[ "$component" == "nginx" ]]; then 129 | for nginx_version in "${NGINX[@]}"; do 130 | if [[ "$build_axes" == "build" ]]; then 131 | for arch in "${ARCH[@]}"; do 132 | if is_incompatible_combination nginx_version "$nginx_version" arch "$arch"; then continue; fi 133 | matrix+="{\"arch\":\"$arch\",\"nginx_version\":\"$nginx_version\"}," 134 | done 135 | else 136 | if is_incompatible_combination nginx_version "$nginx_version"; then continue; fi 137 | matrix+="{\"nginx_version\":\"$nginx_version\"}," 138 | fi 139 | done 140 | fi 141 | 142 | matrix="${matrix%,}]}" 143 | echo "$output_var=$matrix" >> $GITHUB_OUTPUT 144 | 145 | echo "::group::Generated matrix for $component ($output_var)" 146 | echo "$matrix" | jq . 147 | echo "::endgroup::" 148 | } 149 | 150 | ######################## 151 | ## Build for all components 152 | ######################## 153 | 154 | for component in php php_debug php_blackfire supervisord nginx; do 155 | generate_matrix "$component" "${component//-/_}_matrix" "build" 156 | generate_matrix "$component" "${component//-/_}_manifest" "manifest" 157 | done 158 | 159 | build_php: 160 | needs: matrix 161 | uses: ./.github/workflows/docker-build.yml 162 | with: 163 | component: php 164 | matrix: ${{ needs.matrix.outputs.php_matrix }} 165 | matrix_manifest: ${{ needs.matrix.outputs.php_manifest }} 166 | release_tag: ${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || format('{0}-LATEST', github.ref_name) }} 167 | 168 | build_php_debug: 169 | needs: [ build_php, matrix ] 170 | uses: ./.github/workflows/docker-build.yml 171 | with: 172 | component: php_debug 173 | matrix: ${{ needs.matrix.outputs.php_debug_matrix }} 174 | matrix_manifest: ${{ needs.matrix.outputs.php_debug_manifest }} 175 | release_tag: ${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || format('{0}-LATEST', github.ref_name) }} 176 | 177 | build_php_blackfire: 178 | needs: [ build_php, matrix ] 179 | uses: ./.github/workflows/docker-build.yml 180 | with: 181 | component: php_blackfire 182 | matrix: ${{ needs.matrix.outputs.php_blackfire_matrix }} 183 | matrix_manifest: ${{ needs.matrix.outputs.php_blackfire_manifest }} 184 | release_tag: ${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || format('{0}-LATEST', github.ref_name) }} 185 | 186 | build_supervisord: 187 | needs: [ build_php, matrix ] 188 | uses: ./.github/workflows/docker-build.yml 189 | with: 190 | component: supervisord 191 | matrix: ${{ needs.matrix.outputs.supervisord_matrix }} 192 | matrix_manifest: ${{ needs.matrix.outputs.supervisord_manifest }} 193 | release_tag: ${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || format('{0}-LATEST', github.ref_name) }} 194 | 195 | build_nginx: 196 | needs: matrix 197 | uses: ./.github/workflows/docker-build.yml 198 | with: 199 | component: nginx 200 | matrix: ${{ needs.matrix.outputs.nginx_matrix }} 201 | matrix_manifest: ${{ needs.matrix.outputs.nginx_manifest }} 202 | release_tag: ${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || format('{0}-LATEST', github.ref_name) }} -------------------------------------------------------------------------------- /.github/workflows/weekly_patch.yml: -------------------------------------------------------------------------------- 1 | name: Weekly Patch Release 2 | 3 | on: 4 | schedule: 5 | - cron: "0 3 * * 1" 6 | workflow_dispatch: ~ 7 | 8 | jobs: 9 | create_patch_release: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout Repository 14 | uses: actions/checkout@v3 15 | 16 | - name: Fetch Tags 17 | run: git fetch --tags 18 | 19 | - name: Get Latest Tag 20 | id: get_latest_tag 21 | run: | 22 | latest_tag=$(git tag --sort=-v:refname | head -n 1) 23 | echo "Latest tag: $latest_tag" 24 | echo "latest_tag=$latest_tag" >> $GITHUB_ENV 25 | 26 | - name: Calculate Next Patch Version 27 | id: calculate_next_patch 28 | run: | 29 | latest_tag=${{ env.latest_tag }} 30 | 31 | # Extrahiere die Major-, Minor- und Patch-Versionen 32 | major=$(echo $latest_tag | cut -d '.' -f1) 33 | minor=$(echo $latest_tag | cut -d '.' -f2) 34 | patch=$(echo $latest_tag | cut -d '.' -f3) 35 | 36 | next_patch=$((patch + 1)) 37 | new_tag="${major}.${minor}.${next_patch}" 38 | 39 | echo "Next patch version: $new_tag" 40 | echo "new_tag=$new_tag" >> $GITHUB_ENV 41 | 42 | - name: Configure Git 43 | run: | 44 | git config --global user.name "github-actions" 45 | git config --global user.email "github-actions@github.com" 46 | 47 | - name: Create New Tag 48 | run: | 49 | if git rev-parse ${{ env.new_tag }} >/dev/null 2>&1; then 50 | echo "Tag already exists. Skipping." 51 | else 52 | git tag ${{ env.new_tag }} 53 | git push origin refs/tags/${{ env.new_tag }} 54 | fi 55 | 56 | - name: Create GitHub Release 57 | env: 58 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 59 | run: | 60 | gh release create ${{ env.new_tag }} \ 61 | --title "Release ${{ env.new_tag }}" \ 62 | --notes "Automated weekly patch release." 63 | gh workflow run docker.yml --ref ${{ env.new_tag }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .libs/ 3 | imagemagick_src/ 4 | php_src/ 5 | 6 | # Object files 7 | *.o 8 | *.lo 9 | 10 | # Libraries 11 | *.lib 12 | *.a 13 | *.la 14 | 15 | # Shared objects (inc. Windows DLLs) 16 | *.dll 17 | *.so 18 | *.so.* 19 | *.dylib 20 | 21 | # Executables 22 | *.exe 23 | *.out 24 | *.app 25 | 26 | # archives 27 | imagick-*.tgz 28 | 29 | # autotools 30 | .deps 31 | .libs 32 | config.cache 33 | config.guess 34 | config.h 35 | config.h.in 36 | config.h.in~ 37 | config.log 38 | config.nice 39 | config.status 40 | config.sub 41 | configure 42 | configure.in 43 | configure.ac 44 | conftest 45 | conftest.c 46 | Makefile 47 | Makefile.fragments 48 | Makefile.global 49 | Makefile.objects 50 | acinclude.m4 51 | aclocal.m4 52 | autom4te.cache 53 | build 54 | install-sh 55 | libtool 56 | ltmain.sh 57 | ltmain.sh.backup 58 | missing 59 | mkinstalldirs 60 | modules 61 | run-tests.php 62 | run-tests.log 63 | tmp-php.ini 64 | 65 | # Failed Test results 66 | tests/*.diff 67 | tests/*.exp 68 | tests/*.log 69 | tests/*.php 70 | tests/*.sh 71 | bugReports 72 | data 73 | *.dep 74 | -------------------------------------------------------------------------------- /.kaniko-project-gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | stages: 2 | - test 3 | - build 4 | - manifest 5 | # - scan 6 | 7 | variables: 8 | TAG: $CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA 9 | APP_ENV: staging 10 | PROD_BRANCH: master 11 | STAGING_BRANCH: staging 12 | DOCKER_BASE_VERSION: "4.0.0" 13 | PHP_VERSION: "8.2" 14 | NGINX_VERSION: "1.21" 15 | ALPINE_VERSION: "3.20" 16 | VARNISH: "false" 17 | TEST_PHPSTAN: "false" 18 | TEST_LINT_TWIG: "true" 19 | TEST_LINT_YAML: "true" 20 | TEST_LINT_CONTAINER: "true" 21 | GCP_URL: europe-west3-docker.pkg.dev 22 | TEST_IMAGE: git.e-conomix.at:5050/cors/docker/php-alpine-cli 23 | REGISTRY_URL: $GCP_URL/cors-wolke/cors/docker 24 | ADDITIONAL_BRANCH: any-additional-branch-to-build 25 | 26 | test: 27 | stage: test 28 | image: $TEST_IMAGE:$PHP_VERSION-$DOCKER_BASE_VERSION 29 | variables: 30 | DATABASE_HOST: "" 31 | DATABASE_PORT: "" 32 | DATABASE_USER: "" 33 | DATABASE_PASSWORD: "" 34 | DATABASE_NAME: "" 35 | DATABASE_VERSION: "8.0.26" 36 | cache: 37 | paths: 38 | - vendor/ 39 | before_script: 40 | - composer install 41 | script: 42 | - vendor/bin/ecs check src 43 | - if [ "$TEST_LINT_TWIG" = "true" ] ; then bin/console lint:twig templates; fi 44 | - if [ "$TEST_LINT_TWIG" = "true" ] ; then bin/console lint:twig themes; fi 45 | - if [ "$TEST_LINT_YAML" = "true" ] ; then bin/console lint:yaml config; fi 46 | - if [ "$TEST_LINT_CONTAINER" = "true" ] ; then bin/console lint:container; fi 47 | - if [ "$TEST_PHPSTAN" = "true" ] ; then vendor/bin/phpstan analyse src; fi 48 | tags: 49 | - cors 50 | 51 | build_and_push: 52 | stage: build 53 | image: 54 | name: gcr.io/kaniko-project/executor:v1.12.1-debug 55 | entrypoint: [ "" ] 56 | rules: 57 | - if: $CI_PIPELINE_SOURCE == "merge_request_event" 58 | when: never 59 | - if: $CI_COMMIT_REF_NAME == $PROD_BRANCH 60 | variables: 61 | APP_ENV: prod 62 | - if: $CI_COMMIT_REF_NAME == $STAGING_BRANCH 63 | variables: 64 | APP_ENV: staging 65 | - if: $CI_COMMIT_REF_NAME == $ADDITIONAL_BRANCH 66 | variables: 67 | APP_ENV: $ADDITIONAL_BRANCH 68 | - if: $CI_COMMIT_REF_NAME == $PROD_BRANCH || $CI_COMMIT_REF_NAME == $STAGING_BRANCH || $CI_COMMIT_REF_NAME == $ADDITIONAL_BRANCH 69 | when: on_success 70 | before_script: 71 | - echo "{\"auths\":{\"$CI_REGISTRY\":{\"auth\":\"$(echo -n ${CI_REGISTRY_USER}:${CI_REGISTRY_PASSWORD} | base64 | tr -d '\n')\"}, \"https://$GCP_URL\":{\"auth\":\"$(echo -n "_json_key":$(base64 -d $GOOGLE_ARTIFACT_REGISTRY) | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json 72 | - export GCP_REGISTRY_IMAGE=$(echo "$GCP_URL/cors-wolke/$CI_PROJECT_PATH" | tr '[:upper:]' '[:lower:]') 73 | script: 74 | - /kaniko/warmer --image $GCP_REGISTRY_IMAGE/php-alpine-fpm:LATEST-$CI_COMMIT_REF_NAME 75 | - /kaniko/warmer --image $GCP_REGISTRY_IMAGE/php-alpine-fpm-blackfire:LATEST-$CI_COMMIT_REF_NAME 76 | - /kaniko/warmer --image $GCP_REGISTRY_IMAGE/php-alpine-supervisord:LATEST-$CI_COMMIT_REF_NAME 77 | - /kaniko/warmer --image $GCP_REGISTRY_IMAGE/php-alpine-cli:LATEST-$CI_COMMIT_REF_NAME 78 | - /kaniko/warmer --image $GCP_REGISTRY_IMAGE/nginx:LATEST-$CI_COMMIT_REF_NAME 79 | 80 | - /kaniko/executor 81 | --context $CI_PROJECT_DIR 82 | --use-new-run 83 | --snapshot-mode=redo 84 | --cache=true 85 | --dockerfile "Dockerfile" 86 | --target=cors_php 87 | --build-arg COMPOSER_AUTH="$COMPOSER_AUTH" 88 | --build-arg DOCKER_BASE_VERSION="$DOCKER_BASE_VERSION" 89 | --build-arg APP_ENV="$APP_ENV" 90 | --build-arg PHP_VERSION="$PHP_VERSION" 91 | --build-arg NGINX_VERSION="$NGINX_VERSION" 92 | --build-arg ALPINE_VERSION="$ALPINE_VERSION" 93 | --build-arg REGISTRY_URL="$REGISTRY_URL" 94 | --cache-repo $GCP_REGISTRY_IMAGE/php-alpine-fpm/cache 95 | --destination $GCP_REGISTRY_IMAGE/php-alpine-fpm:$TAG 96 | --destination $GCP_REGISTRY_IMAGE/php-alpine-fpm:LATEST-$CI_COMMIT_REF_NAME 97 | 98 | - /kaniko/executor 99 | --context $CI_PROJECT_DIR 100 | --use-new-run 101 | --snapshot-mode=redo 102 | --cache=true 103 | --dockerfile "Dockerfile" 104 | --target=cors_php_blackfire 105 | --build-arg COMPOSER_AUTH="$COMPOSER_AUTH" 106 | --build-arg DOCKER_BASE_VERSION="$DOCKER_BASE_VERSION" 107 | --build-arg APP_ENV="$APP_ENV" 108 | --build-arg PHP_VERSION="$PHP_VERSION" 109 | --build-arg NGINX_VERSION="$NGINX_VERSION" 110 | --build-arg ALPINE_VERSION="$ALPINE_VERSION" 111 | --build-arg REGISTRY_URL="$REGISTRY_URL" 112 | --cache-repo $GCP_REGISTRY_IMAGE/php-alpine-fpm/cache 113 | --destination $GCP_REGISTRY_IMAGE/php-alpine-fpm-blackfire:$TAG 114 | --destination $GCP_REGISTRY_IMAGE/php-alpine-fpm-blackfire:LATEST-$CI_COMMIT_REF_NAME 115 | 116 | - /kaniko/executor 117 | --context $CI_PROJECT_DIR 118 | --use-new-run 119 | --snapshot-mode=redo 120 | --cache=true 121 | --dockerfile "Dockerfile" 122 | --target=cors_php_supervisord 123 | --build-arg COMPOSER_AUTH="$COMPOSER_AUTH" 124 | --build-arg DOCKER_BASE_VERSION="$DOCKER_BASE_VERSION" 125 | --build-arg APP_ENV="$APP_ENV" 126 | --build-arg PHP_VERSION="$PHP_VERSION" 127 | --build-arg NGINX_VERSION="$NGINX_VERSION" 128 | --build-arg ALPINE_VERSION="$ALPINE_VERSION" 129 | --build-arg REGISTRY_URL="$REGISTRY_URL" 130 | --cache-repo $GCP_REGISTRY_IMAGE/php-alpine-fpm/cache 131 | --destination $GCP_REGISTRY_IMAGE/php-alpine-supervisord:$TAG 132 | --destination $GCP_REGISTRY_IMAGE/php-alpine-supervisord:LATEST-$CI_COMMIT_REF_NAME 133 | 134 | - /kaniko/executor 135 | --context $CI_PROJECT_DIR 136 | --use-new-run 137 | --snapshot-mode=redo 138 | --cache=true 139 | --dockerfile "Dockerfile" 140 | --target=cors_php_cli 141 | --build-arg COMPOSER_AUTH="$COMPOSER_AUTH" 142 | --build-arg DOCKER_BASE_VERSION="$DOCKER_BASE_VERSION" 143 | --build-arg APP_ENV="$APP_ENV" 144 | --build-arg PHP_VERSION="$PHP_VERSION" 145 | --build-arg NGINX_VERSION="$NGINX_VERSION" 146 | --build-arg ALPINE_VERSION="$ALPINE_VERSION" 147 | --build-arg REGISTRY_URL="$REGISTRY_URL" 148 | --cache-repo $GCP_REGISTRY_IMAGE/php-alpine-fpm/cache 149 | --destination $GCP_REGISTRY_IMAGE/php-alpine-cli:$TAG 150 | --destination $GCP_REGISTRY_IMAGE/php-alpine-cli:LATEST-$CI_COMMIT_REF_NAME 151 | 152 | - /kaniko/executor 153 | --context $CI_PROJECT_DIR 154 | --use-new-run 155 | --snapshot-mode=redo 156 | --cache=true 157 | --dockerfile "Dockerfile" 158 | --target=cors_nginx 159 | --build-arg COMPOSER_AUTH="$COMPOSER_AUTH" 160 | --build-arg DOCKER_BASE_VERSION="$DOCKER_BASE_VERSION" 161 | --build-arg APP_ENV="$APP_ENV" 162 | --build-arg PHP_VERSION="$PHP_VERSION" 163 | --build-arg NGINX_VERSION="$NGINX_VERSION" 164 | --build-arg ALPINE_VERSION="$ALPINE_VERSION" 165 | --build-arg REGISTRY_URL="$REGISTRY_URL" 166 | --cache-repo $GCP_REGISTRY_IMAGE/php-alpine-fpm/cache 167 | --destination $GCP_REGISTRY_IMAGE/nginx:$TAG 168 | --destination $GCP_REGISTRY_IMAGE/nginx:LATEST-$CI_COMMIT_REF_NAME 169 | 170 | - if [ "$VARNISH" = "true" ] ; then 171 | /kaniko/executor 172 | --context $CI_PROJECT_DIR 173 | --use-new-run 174 | --snapshot-mode=redo 175 | --cache=true 176 | --dockerfile "Dockerfile" 177 | --target=cors_varnish 178 | --build-arg DOCKER_BASE_VERSION="$DOCKER_BASE_VERSION" 179 | --build-arg COMPOSER_AUTH="$COMPOSER_AUTH" 180 | --build-arg APP_ENV="$APP_ENV" 181 | --build-arg PHP_VERSION="$PHP_VERSION" 182 | --build-arg NGINX_VERSION="$NGINX_VERSION" 183 | --build-arg ALPINE_VERSION="$ALPINE_VERSION" 184 | --build-arg REGISTRY_URL="$REGISTRY_URL" 185 | --destination $GCP_REGISTRY_IMAGE/varnish:$TAG 186 | --destination $GCP_REGISTRY_IMAGE/varnish:LATEST-$CI_COMMIT_REF_NAME; 187 | fi 188 | tags: 189 | - cors 190 | 191 | update_manifest: 192 | stage: manifest 193 | image: docker:latest 194 | needs: 195 | - job: build_and_push 196 | rules: 197 | - if: $CI_PIPELINE_SOURCE == "merge_request_event" 198 | when: never 199 | - if: $CI_COMMIT_REF_NAME == $PROD_BRANCH || $CI_COMMIT_REF_NAME == $STAGING_BRANCH || $CI_COMMIT_REF_NAME == $ADDITIONAL_BRANCH 200 | when: on_success 201 | variables: 202 | CD_GIT_REPOSITORY: git.e-conomix.at/cors/$CD_CHART_REPO.git 203 | CD_GIT_REPOSITORY_PATH: $CD_CHART_REPO 204 | CD_MANIFEST_VALUES_FILE: values-$CI_COMMIT_REF_NAME.yaml 205 | script: 206 | - apk add --no-cache git yq 207 | - git config --global user.name $CI_PROJECT_NAME 208 | - git config --global user.email $CI_PROJECT_NAME"-manifest@cors.gmbh" 209 | - git clone https://gitlab-ci-token:${CD_PUSH_TOKEN}@${CD_GIT_REPOSITORY} repo 210 | - cd repo 211 | - git checkout $CI_COMMIT_REF_NAME 2>/dev/null || $CI_COMMIT_REF_NAME checkout -b foo 212 | 213 | - yq -i eval ".pimcore.pimcore.image.tag = \"$TAG\"" $CD_MANIFEST_VALUES_FILE 214 | - yq -i eval ".pimcore.nginx.image.tag = \"$TAG\"" $CD_MANIFEST_VALUES_FILE 215 | - yq -i eval ".pimcore.supervisord.image.tag = \"$TAG\"" $CD_MANIFEST_VALUES_FILE 216 | - yq -i eval ".pimcore.pimcore.cli.image.tag = \"$TAG\"" $CD_MANIFEST_VALUES_FILE 217 | 218 | - if [ "$VARNISH" = "true" ]; then yq -i eval ".pimcore.varnish.image.tag = \"$TAG\"" $CD_MANIFEST_VALUES_FILE; fi 219 | 220 | - git commit -am "[$CI_COMMIT_REF_NAME] update $CD_MANIFEST_VALUES_FILE to \"$TAG\"" 221 | - git push origin $CI_COMMIT_REF_NAME 222 | tags: 223 | - cors -------------------------------------------------------------------------------- /.project-gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | stages: 2 | - test 3 | - build 4 | - manifest 5 | # - scan 6 | 7 | variables: 8 | TAG: $CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA 9 | APP_ENV: staging 10 | PROD_BRANCH: master 11 | STAGING_BRANCH: staging 12 | DOCKER_BASE_VERSION: "2.2.0" 13 | PHP_VERSION: "8.0" 14 | NGINX_VERSION: "1.21" 15 | ALPINE_VERSION: "3.16" 16 | VARNISH: "false" 17 | TEST_PHPSTAN: "false" 18 | TEST_PSALM: "false" 19 | TEST_LINT_TWIG: "true" 20 | TEST_LINT_YAML: "true" 21 | TEST_LINT_CONTAINER: "true" 22 | GCP_URL: europe-west3-docker.pkg.dev 23 | REGISTRY_URL: $GCP_URL/cors-wolke/cors/docker 24 | ADDITIONAL_BRANCH: any-additional-branch-to-build 25 | 26 | test: 27 | stage: test 28 | image: ghcr.io/cors-gmbh/pimcore-docker/php-cli:$PHP_VERSION-alpine$ALPINE_VERSION-$DOCKER_BASE_VERSION 29 | variables: 30 | DATABASE_HOST: "" 31 | DATABASE_PORT: "" 32 | DATABASE_USER: "" 33 | DATABASE_PASSWORD: "" 34 | DATABASE_NAME: "" 35 | DATABASE_VERSION: "8.0.26" 36 | APP_ENV: dev 37 | cache: 38 | paths: 39 | - vendor/ 40 | before_script: 41 | - composer install 42 | - PIMCORE_DISABLE_CACHE=1 bin/console pimcore:build:classes --env=dev 43 | - bin/console cache:clear --env=dev 44 | script: 45 | - vendor/bin/ecs check src 46 | - if [ "$TEST_LINT_TWIG" = "true" ] ; then bin/console lint:twig templates; fi 47 | - if [ "$TEST_LINT_TWIG" = "true" ] ; then bin/console lint:twig themes; fi 48 | - if [ "$TEST_LINT_YAML" = "true" ] ; then bin/console lint:yaml config; fi 49 | - if [ "$TEST_LINT_CONTAINER" = "true" ] ; then bin/console lint:container; fi 50 | - if [ "$TEST_PHPSTAN" = "true" ] ; then vendor/bin/phpstan analyse; fi 51 | - if [ "$TEST_PSALM" = "true" ] ; then vendor/bin/psalm src; fi 52 | tags: 53 | - cors 54 | 55 | build_and_push: 56 | stage: build 57 | image: docker:stable 58 | rules: 59 | - if: $CI_PIPELINE_SOURCE == "merge_request_event" 60 | when: never 61 | - if: $CI_COMMIT_REF_NAME == $PROD_BRANCH 62 | variables: 63 | APP_ENV: prod 64 | - if: $CI_COMMIT_REF_NAME == $STAGING_BRANCH 65 | variables: 66 | APP_ENV: staging 67 | - if: $CI_COMMIT_REF_NAME == $ADDITIONAL_BRANCH 68 | variables: 69 | APP_ENV: $ADDITIONAL_BRANCH 70 | - if: $CI_COMMIT_REF_NAME == $PROD_BRANCH || $CI_COMMIT_REF_NAME == $STAGING_BRANCH || $CI_COMMIT_REF_NAME == $ADDITIONAL_BRANCH 71 | when: on_success 72 | before_script: 73 | - base64 -d $GOOGLE_ARTIFACT_REGISTRY | docker login -u _json_key --password-stdin https://$GCP_URL 74 | - export GCP_REGISTRY_IMAGE=$(echo "$GCP_URL/cors-wolke/$CI_PROJECT_PATH" | tr '[:upper:]' '[:lower:]') 75 | script: 76 | - docker build . --tag $GCP_REGISTRY_IMAGE/php-alpine-fpm:$TAG --tag $GCP_REGISTRY_IMAGE/php-alpine-fpm:$CI_COMMIT_REF_NAME-latest --target=cors_php --build-arg COMPOSER_AUTH="$COMPOSER_AUTH" --build-arg DOCKER_BASE_VERSION="$DOCKER_BASE_VERSION" --build-arg APP_ENV="$APP_ENV" --build-arg PHP_VERSION="$PHP_VERSION" --build-arg NGINX_VERSION="$NGINX_VERSION" --build-arg ALPINE_VERSION="$ALPINE_VERSION" --build-arg REGISTRY_URL="$REGISTRY_URL" 77 | - docker build . --tag $GCP_REGISTRY_IMAGE/php-alpine-fpm-blackfire:$TAG --tag $GCP_REGISTRY_IMAGE/php-alpine-fpm-blackfire:$CI_COMMIT_REF_NAME-latest --target=cors_php_blackfire --build-arg COMPOSER_AUTH="$COMPOSER_AUTH" --build-arg DOCKER_BASE_VERSION="$DOCKER_BASE_VERSION" --build-arg APP_ENV="$APP_ENV" --build-arg PHP_VERSION="$PHP_VERSION" --build-arg NGINX_VERSION="$NGINX_VERSION" --build-arg ALPINE_VERSION="$ALPINE_VERSION" --build-arg REGISTRY_URL="$REGISTRY_URL" 78 | - docker build . --tag $GCP_REGISTRY_IMAGE/php-alpine-supervisord:$TAG --tag $GCP_REGISTRY_IMAGE/php-alpine-supervisord:$CI_COMMIT_REF_NAME-latest --target=cors_php_supervisord --build-arg COMPOSER_AUTH="$COMPOSER_AUTH" --build-arg DOCKER_BASE_VERSION="$DOCKER_BASE_VERSION" --build-arg APP_ENV="$APP_ENV" --build-arg PHP_VERSION="$PHP_VERSION" --build-arg NGINX_VERSION="$NGINX_VERSION" --build-arg ALPINE_VERSION="$ALPINE_VERSION" --build-arg REGISTRY_URL="$REGISTRY_URL" 79 | - docker build . --tag $GCP_REGISTRY_IMAGE/php-alpine-cli:$TAG --tag $GCP_REGISTRY_IMAGE/php-alpine-cli:$CI_COMMIT_REF_NAME-latest --target=cors_php_cli --build-arg COMPOSER_AUTH="$COMPOSER_AUTH" --build-arg DOCKER_BASE_VERSION="$DOCKER_BASE_VERSION" --build-arg APP_ENV="$APP_ENV" --build-arg PHP_VERSION="$PHP_VERSION" --build-arg NGINX_VERSION="$NGINX_VERSION" --build-arg ALPINE_VERSION="$ALPINE_VERSION" --build-arg REGISTRY_URL="$REGISTRY_URL" 80 | - docker build . --tag $GCP_REGISTRY_IMAGE/nginx:$TAG --tag $GCP_REGISTRY_IMAGE/nginx:$CI_COMMIT_REF_NAME-latest --target=cors_nginx --build-arg COMPOSER_AUTH="$COMPOSER_AUTH" --build-arg DOCKER_BASE_VERSION="$DOCKER_BASE_VERSION" --build-arg APP_ENV="$APP_ENV" --build-arg PHP_VERSION="$PHP_VERSION" --build-arg NGINX_VERSION="$NGINX_VERSION" --build-arg ALPINE_VERSION="$ALPINE_VERSION" --build-arg REGISTRY_URL="$REGISTRY_URL" 81 | - if [ "$VARNISH" = "true" ] ; then docker build . --tag $GCP_REGISTRY_IMAGE/varnish:$TAG --tag $GCP_REGISTRY_IMAGE/varnish:$CI_COMMIT_REF_NAME-latest --target=cors_varnish --build-arg DOCKER_BASE_VERSION="$DOCKER_BASE_VERSION" --build-arg COMPOSER_AUTH="$COMPOSER_AUTH" --build-arg APP_ENV="$APP_ENV" --build-arg PHP_VERSION="$PHP_VERSION" --build-arg NGINX_VERSION="$NGINX_VERSION" --build-arg ALPINE_VERSION="$ALPINE_VERSION" --build-arg REGISTRY_URL="$REGISTRY_URL"; fi 82 | 83 | - docker push $GCP_REGISTRY_IMAGE/php-alpine-fpm:$TAG 84 | - docker push $GCP_REGISTRY_IMAGE/php-alpine-fpm:$CI_COMMIT_REF_NAME-latest 85 | - docker push $GCP_REGISTRY_IMAGE/php-alpine-fpm-blackfire:$TAG 86 | - docker push $GCP_REGISTRY_IMAGE/php-alpine-fpm-blackfire:$CI_COMMIT_REF_NAME-latest 87 | - docker push $GCP_REGISTRY_IMAGE/php-alpine-supervisord:$TAG 88 | - docker push $GCP_REGISTRY_IMAGE/php-alpine-supervisord:$CI_COMMIT_REF_NAME-latest 89 | - docker push $GCP_REGISTRY_IMAGE/php-alpine-cli:$TAG 90 | - docker push $GCP_REGISTRY_IMAGE/php-alpine-cli:$CI_COMMIT_REF_NAME-latest 91 | - docker push $GCP_REGISTRY_IMAGE/nginx:$TAG 92 | - docker push $GCP_REGISTRY_IMAGE/nginx:$CI_COMMIT_REF_NAME-latest 93 | - if [ "$VARNISH" = "true" ] ; then docker push $GCP_REGISTRY_IMAGE/varnish:$TAG; fi 94 | - if [ "$VARNISH" = "true" ] ; then docker push $GCP_REGISTRY_IMAGE/varnish:$CI_COMMIT_REF_NAME-latest; fi 95 | tags: 96 | - cors 97 | 98 | update_manifest: 99 | stage: manifest 100 | image: docker:latest 101 | needs: 102 | - job: build_and_push 103 | rules: 104 | - if: $CI_PIPELINE_SOURCE == "merge_request_event" 105 | when: never 106 | - if: $CI_COMMIT_REF_NAME == $PROD_BRANCH || $CI_COMMIT_REF_NAME == $STAGING_BRANCH || $CI_COMMIT_REF_NAME == $ADDITIONAL_BRANCH 107 | when: on_success 108 | variables: 109 | CD_GIT_REPOSITORY: git.e-conomix.at/cors/$CD_CHART_REPO.git 110 | CD_GIT_REPOSITORY_PATH: $CD_CHART_REPO 111 | CD_MANIFEST_VALUES_FILE: values-$CI_COMMIT_REF_NAME.yaml 112 | script: 113 | - apk add --no-cache git yq 114 | - git config --global user.name $CI_PROJECT_NAME 115 | - git config --global user.email $CI_PROJECT_NAME"-manifest@cors.gmbh" 116 | - git clone https://gitlab-ci-token:${CD_PUSH_TOKEN}@${CD_GIT_REPOSITORY} repo 117 | - cd repo 118 | - git checkout $CI_COMMIT_REF_NAME 2>/dev/null || $CI_COMMIT_REF_NAME checkout -b foo 119 | 120 | - yq -i eval ".pimcore.pimcore.image.tag = \"$TAG\"" $CD_MANIFEST_VALUES_FILE 121 | - yq -i eval ".pimcore.nginx.image.tag = \"$TAG\"" $CD_MANIFEST_VALUES_FILE 122 | - yq -i eval ".pimcore.supervisord.image.tag = \"$TAG\"" $CD_MANIFEST_VALUES_FILE 123 | - yq -i eval ".pimcore.pimcore.cli.image.tag = \"$TAG\"" $CD_MANIFEST_VALUES_FILE 124 | 125 | - if [ "$VARNISH" = "true" ]; then yq -i eval ".pimcore.varnish.image.tag = \"$TAG\"" $CD_MANIFEST_VALUES_FILE; fi 126 | 127 | - git commit -am "[$CI_COMMIT_REF_NAME] update $CD_MANIFEST_VALUES_FILE to \"$TAG\"" 128 | - git push origin $CI_COMMIT_REF_NAME 129 | tags: 130 | - cors -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | email. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ARG PHP_VERSION="8.3" 2 | ARG PHP_TYPE="fpm" 3 | ARG ALPINE_VERSION=3.20 4 | 5 | FROM php:${PHP_VERSION}-${PHP_TYPE}-alpine${ALPINE_VERSION} AS cors_php 6 | 7 | ARG PHP_VERSION 8 | ARG PHP_TYPE 9 | ARG ALPINE_VERSION 10 | 11 | SHELL ["/bin/sh", "-eo", "pipefail", "-c"] 12 | 13 | ENV TIMEZONE=Europe/Vienna 14 | 15 | RUN set -eux; \ 16 | apk update && apk upgrade && apk add --no-cache \ 17 | apk-tools autoconf gcc make g++ automake nasm cmake clang clang-dev tar \ 18 | curl tzdata freetype libbsd graphviz openssl openblas openblas-dev \ 19 | ffmpeg pngcrush jpegoptim exiftool poppler-utils wget icu-dev oniguruma-dev \ 20 | libwebp libwebp-tools cmake unzip libxml2-dev libxslt-dev \ 21 | xvfb ttf-dejavu ttf-droid ttf-freefont ttf-liberation \ 22 | libwmf-dev libxext-dev libxt-dev librsvg-dev libzip-dev fcgi \ 23 | libpng-dev libjpeg libxpm libjpeg-turbo-dev imap-dev krb5-dev openssl-dev libavif libavif-dev libheif libheif-dev zopfli \ 24 | musl-locales icu-data-full lcms2-dev ghostscript libreoffice imagemagick imagemagick-dev; \ 25 | pecl install imagick; \ 26 | docker-php-ext-enable imagick; \ 27 | docker-php-ext-install intl mbstring mysqli bcmath bz2 soap xsl pdo pdo_mysql fileinfo exif zip opcache; \ 28 | docker-php-ext-configure gd -enable-gd --with-freetype --with-jpeg --with-webp; \ 29 | docker-php-ext-install gd; \ 30 | docker-php-ext-configure pcntl --enable-pcntl; \ 31 | docker-php-ext-install pcntl; \ 32 | pecl install apcu redis; \ 33 | docker-php-ext-enable redis apcu; \ 34 | cp /usr/share/zoneinfo/${TIMEZONE} /etc/localtime; \ 35 | echo "${TIMEZONE}" > /etc/timezone; \ 36 | apk del tzdata autoconf gcc make g++ automake nasm cmake clang clang-dev openblas-dev tar; \ 37 | rm -rf /var/cache/apk/*; 38 | 39 | ENV COMPOSER_ALLOW_SUPERUSER=1 40 | ENV COMPOSER_MEMORY_LIMIT=-1 41 | COPY --from=composer:latest /usr/bin/composer /usr/bin/composer 42 | 43 | RUN mkdir -p /usr/local/var/log/php7/ 44 | RUN mkdir -p /usr/local/var/run/ 45 | 46 | WORKDIR /var/www/html 47 | 48 | COPY php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint 49 | COPY php/docker-migrate.sh /usr/local/bin/docker-migrate 50 | COPY php/docker-install.sh /usr/local/bin/install 51 | COPY php/docker-wait.sh /usr/local/bin/wait 52 | COPY php/docker-wait-db.sh /usr/local/bin/wait_db 53 | COPY php/docker-wait-pimcore.sh /usr/local/bin/wait_pimcore 54 | COPY php/docker-healthcheck.sh /usr/local/bin/health 55 | COPY php/docker-readiness.sh /usr/local/bin/readiness 56 | COPY php/docker-status.sh /usr/local/bin/status 57 | 58 | COPY fpm/php.ini /usr/local/etc/php/php.ini 59 | 60 | RUN chmod +x /usr/local/bin/docker-entrypoint 61 | RUN chmod +x /usr/local/bin/docker-migrate 62 | RUN chmod +x /usr/local/bin/install 63 | RUN chmod +x /usr/local/bin/wait 64 | RUN chmod +x /usr/local/bin/wait_db 65 | RUN chmod +x /usr/local/bin/wait_pimcore 66 | RUN chmod +x /usr/local/bin/health 67 | RUN chmod +x /usr/local/bin/status 68 | 69 | FROM cors_php AS cors_php_cli 70 | 71 | ENTRYPOINT ["docker-entrypoint"] 72 | CMD ["/bin/sh", "-c"] 73 | 74 | FROM cors_php AS cors_php_fpm 75 | 76 | COPY fpm/php-config.conf /usr/local/etc/php-fpm.conf 77 | COPY fpm/php-pool-config.conf /usr/local/etc/php-fpm.d/www.conf 78 | 79 | ENTRYPOINT ["docker-entrypoint"] 80 | CMD ["php-fpm"] -------------------------------------------------------------------------------- /Dockerfile-blackfire: -------------------------------------------------------------------------------- 1 | ARG FROM 2 | 3 | FROM ${FROM} 4 | 5 | USER root 6 | 7 | RUN version=$(php -r "echo PHP_MAJOR_VERSION.PHP_MINOR_VERSION;") \ 8 | && architecture=$(uname -m) \ 9 | && curl -A "Docker" -o /tmp/blackfire-probe.tar.gz -D - -L -s https://blackfire.io/api/v1/releases/probe/php/alpine/$architecture/$version \ 10 | && mkdir -p /tmp/blackfire \ 11 | && tar zxpf /tmp/blackfire-probe.tar.gz -C /tmp/blackfire \ 12 | && mv /tmp/blackfire/blackfire-*.so $(php -r "echo ini_get ('extension_dir');")/blackfire.so \ 13 | && printf "extension=blackfire.so\nblackfire.agent_socket=tcp://blackfire:8307\n" > $PHP_INI_DIR/conf.d/blackfire.ini \ 14 | && rm -rf /tmp/blackfire /tmp/blackfire-probe.tar.gz \ 15 | && mkdir -p /tmp/blackfire \ 16 | && curl -A "Docker" -L https://blackfire.io/api/v1/releases/cli/linux/$architecture | tar zxp -C /tmp/blackfire \ 17 | && mv /tmp/blackfire/blackfire /usr/bin/blackfire \ 18 | && rm -Rf /tmp/blackfire; 19 | 20 | COPY blackfire/blackfire.ini /usr/local/etc/php/conf.d/blackfire.ini 21 | 22 | USER www-data -------------------------------------------------------------------------------- /Dockerfile-debug: -------------------------------------------------------------------------------- 1 | ARG FROM 2 | 3 | FROM ${FROM} 4 | 5 | ARG PHP_VERSION 6 | 7 | RUN apk add --no-cache \ 8 | apk-tools autoconf gcc make g++ automake nasm ninja cmake clang clang-dev; \ 9 | if [ "$PHP_VERSION" = "8.3" ] || [ "$PHP_VERSION" = "8.4" ]; then \ 10 | pecl install xdebug; \ 11 | else \ 12 | pecl install xdebug-3.2.2; \ 13 | fi; \ 14 | docker-php-ext-enable xdebug; \ 15 | apk del autoconf gcc make g++ automake nasm ninja cmake clang clang-dev; \ 16 | rm -rf /var/cache/apk/*; 17 | 18 | COPY php/docker-xdebug-entrypoint.sh /usr/local/bin/xdebug-entrypoint 19 | 20 | RUN chmod +x /usr/local/bin/xdebug-entrypoint 21 | 22 | ENTRYPOINT ["xdebug-entrypoint"] 23 | CMD ["php-fpm"] 24 | -------------------------------------------------------------------------------- /Dockerfile-nginx: -------------------------------------------------------------------------------- 1 | ARG NGINX_VERSION=1.21 2 | 3 | FROM nginx:${NGINX_VERSION}-alpine AS cors_nginx 4 | 5 | COPY nginx/pimcore-default.conf /etc/nginx/conf.d/default.conf 6 | 7 | WORKDIR /var/www/html -------------------------------------------------------------------------------- /Dockerfile-supervisord: -------------------------------------------------------------------------------- 1 | ARG FROM 2 | 3 | FROM ${FROM} 4 | 5 | RUN apk update && apk add --no-cache supervisor 6 | 7 | COPY supervisord/supervisord.conf /etc/supervisor/supervisord.conf 8 | COPY supervisord/pimcore.conf /etc/supervisor/conf.d/pimcore.conf 9 | COPY supervisord/coreshop._conf /etc/supervisor/conf.d/coreshop._conf 10 | 11 | CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"] 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2004-present Dominik Pfaffenbauer 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![CORS](https://github.com/cors-gmbh/.github/blob/dc0f9620a08711cfdcdbed7ec274b1675a29ef50/cors-we-want-you-3.jpg?raw=true)](https://cors.gmbh/jobs) 2 | 3 | 4 | # CORS Pimcore Docker Images 5 | 6 | This repository provides a Docker-based environment for running and managing [Pimcore](https://pimcore.com), a leading 7 | open-source digital experience platform (DXP). It enables developers to quickly set up, develop, and test Pimcore 8 | projects using a preconfigured Docker setup. 9 | 10 | These optimized Docker images, based on Alpine Linux, are designed to run Pimcore in production environments, 11 | specifically on Google Kubernetes Engine. This is also a Multi-Arch Build for ARM (Mainly Apple Silicon) and x86-64 12 | (AMD) Systems. 13 | 14 | As part of our journey to Kubernetes, we’ve been running this setup since 2021, and it has proven reliable. We share 15 | this knowledge for free because we believe in open source, Pimcore, and the power of collaboration. 16 | 17 | Cheers Dominik :) 18 | 19 | ## Table of Contents 20 | 21 | - [Features](#features) 22 | - [Versioning](#versioning) 23 | - [Available Images](#available-images) 24 | - [Getting Started](#getting-started) 25 | - [Contributing](#contributing) 26 | - [License](#license) 27 | 28 | ## Features 29 | 30 | - ***Alpine Linux Base***: Lightweight and secure foundation for the Docker images. 31 | - ***Optimized for Pimcore***: Tailored configurations to ensure optimal performance with Pimcore applications. 32 | - ***Production-Ready***: Suitable for deployment in production environments with best practices incorporated. 33 | - ***Development-Ready***: Use the same image in development as for production 34 | 35 | ## Versioning 36 | 37 | We currently build the images for following Versions: 38 | 39 | - ***Alpine***: 3.20, 3.21, 3.22 40 | - ***PHP***: 8.2, 8.3, 8.4 41 | - ***Variants***: CLI, FPM, FPM-Debug, Supervisord, FPM-Blackfire 42 | - ***Nginx***: 1.25, 1.26, 1.27, 1.28 43 | 44 | ## Available Images 45 | 46 | - ***PHP-FPM***: Configured with necessary extensions and settings for running Pimcore. 47 | - ***PHP-FPM Debug***: Configured with xdebug to also step-by-step debug. 48 | - ***Nginx***: Optimized web server configuration to serve Pimcore applications efficiently. 49 | - ***Supervisord***: Process control system to manage and monitor processes like PHP-FPM and Nginx. 50 | - ***Blackfire***: Integrated for performance profiling and monitoring. 51 | 52 | Images are named like: 53 | 54 | - ***FPM***: ghcr.io/cors-gmbh/pimcore-docker/php-fpm:8.2-alpine3.21-7.0-LATEST 55 | - ***FPM-Debug***: ghcr.io/cors-gmbh/pimcore-docker/php-fpm-debug:8.2-alpine3.21-7.0-LATEST 56 | - ***Supervisord***: ghcr.io/cors-gmbh/pimcore-docker/php-supervisord:8.2-alpine3.21-7.0-LATEST 57 | - ***Blackfire***: ghcr.io/cors-gmbh/pimcore-docker/php-fpm-blackfire:8.2-alpine3.21-7.0-LATEST 58 | - ***Nginx***: ghcr.io/cors-gmbh/pimcore-docker/nginx:1.26-7.0-LATEST 59 | 60 | ## Getting Started 61 | 62 | We use this image as our base layer for our Projects. We then use a custom Dockerfile and docker-compose.yaml per 63 | Project. 64 | 65 | ### docker-compose.yaml 66 | 67 | This is our example docker-compose.yaml that we use for Development. We further abstract this into a much more complex 68 | setup. But for the gist of it, here is the simple version :) 69 | 70 | ```yaml 71 | name: pimcore 72 | 73 | services: 74 | db: 75 | image: mysql:8.4 76 | working_dir: /application 77 | volumes: 78 | - pimcore-database:/var/lib/mysql 79 | - .:/application:cached 80 | environment: 81 | - MYSQL_ROOT_PASSWORD=ROOT 82 | - MYSQL_DATABASE=pimcore 83 | - MYSQL_USER=pimcore 84 | - MYSQL_PASSWORD=pimcore 85 | 86 | nginx: 87 | image: nginx:stable-alpine 88 | ports: 80:80 89 | volumes: 90 | - ./:/var/www/html:ro 91 | - ./.docker/nginx.conf:/etc/nginx/conf.d/default.conf:ro 92 | depends_on: 93 | - php 94 | - php-debug 95 | 96 | php: 97 | image: ghcr.io/cors-gmbh/pimcore-docker/php-fpm:8.2-alpine3.21-7.0-LATEST 98 | command: 'php-fpm' 99 | entrypoint: docker-php-entrypoint 100 | depends_on: 101 | - db 102 | volumes: 103 | - ./:/var/www/html:cached 104 | 105 | php-debug: 106 | image: ghcr.io/cors-gmbh/pimcore-docker/php-fpm-debug:8.2-alpine3.21-7.0-LATEST 107 | command: 'php-fpm' 108 | entrypoint: xdebug-entrypoint 109 | depends_on: 110 | - db 111 | volumes: 112 | - ./:/var/www/html:cached 113 | networks: 114 | - kwizda 115 | - cors_dev 116 | environment: 117 | - PHP_IDE_CONFIG=serverName=localhost 118 | 119 | supervisord: 120 | image: ghcr.io/cors-gmbh/pimcore-docker/php-supervisord:8.2-alpine3.21-7.0-LATEST 121 | depends_on: 122 | - db 123 | volumes: 124 | - ./:/var/www/html:cached 125 | 126 | volumes: 127 | pimcore-database: 128 | ``` 129 | 130 | ### Dockerfile 131 | 132 | For Production and Stage Build, we then have our gitlab-ci pipeline [.project-gitlab-ci.yml](.project-gitlab-ci.yml) 133 | which builds our project, pushes it to Google Artifact Registry and we update a separate project where the Kubernetes 134 | Manifest lives. For now, we only have this setup for Gitlab. 135 | 136 | This is the dockerfile we use in the Projects. It is a multi-stage build that builds several images for several 137 | purposes: 138 | 139 | - ***FPM***: FPM Server with the application code 140 | - ***CLI***: CLI Image mainly to be slimmer and to run migrations and pre-hook jobs 141 | - ***Supervisor***: To run queue workers 142 | - ***NGINX***: Frontend HTTP Server 143 | - ***Blackfire***: For Production Profiling, which is our default deployment anyway 144 | - ***Node***: To build webpack encore and copy it to the PHP Containers and NGINX. 145 | 146 | ```Dockerfile 147 | ARG PHP_VERSION 148 | ARG NGINX_VERSION 149 | ARG NODE_VERSION=22 150 | ARG DOCKER_BASE_VERSION 151 | ARG ALPINE_VERSION 152 | 153 | FROM node:${NODE_VERSION}-alpine AS cors_node 154 | 155 | RUN apk add --update python3 py3-setuptools make g++\ 156 | && rm -rf /var/cache/apk/* 157 | 158 | WORKDIR /var/www/html 159 | COPY package.json package-lock.json postcss.config.js webpack.config.js tsconfig.json ./ 160 | RUN set -eux; \ 161 | npm install; 162 | 163 | COPY themes /var/www/html/themes 164 | 165 | RUN set -eux; \ 166 | npm run build; 167 | 168 | FROM ghcr.io/cors-gmbh/pimcore-docker/php-fpm:${PHP_VERSION}-alpine${ALPINE_VERSION}-${DOCKER_BASE_VERSION} AS cors_php 169 | 170 | WORKDIR /var/www/html 171 | 172 | ARG APP_ENV=prod 173 | ENV APP_ENV=$APP_ENV 174 | ENV APP_DEBUG=0 175 | 176 | ARG COMPOSER_AUTH 177 | 178 | USER www-data 179 | 180 | COPY --chown=www-data:www-data composer.* ./ 181 | COPY --chown=www-data:www-data bin bin/ 182 | 183 | RUN set -eux; \ 184 | COMPOSER_MEMORY_LIMIT=-1 composer install --prefer-dist --no-scripts --no-progress --no-dev; \ 185 | mkdir -p var/cache var/log public/bundles; \ 186 | chmod +x bin/console; \ 187 | sync; 188 | 189 | COPY --chown=www-data:www-data public/index.php public/index.php 190 | COPY --chown=www-data:www-data config config/ 191 | COPY --chown=www-data:www-data src src/ 192 | COPY --chown=www-data:www-data templates templates/ 193 | COPY --chown=www-data:www-data themes themes/ 194 | COPY --chown=www-data:www-data translations translations/ 195 | COPY --chown=www-data:www-data var var/ 196 | COPY --chown=www-data:www-data .env .env 197 | 198 | RUN set -eux; \ 199 | bin/console cache:clear --env=$APP_ENV; \ 200 | bin/console assets:install; \ 201 | PIMCORE_DISABLE_CACHE=1 bin/console pimcore:build:classes; \ 202 | COMPOSER_MEMORY_LIMIT=-1 composer dump-autoload --classmap-authoritative; \ 203 | sync; 204 | 205 | COPY --chown=www-data:www-data --from=cors_node /var/www/html/public public/ 206 | 207 | FROM ghcr.io/cors-gmbh/pimcore-docker/php-supervisord:${PHP_VERSION}-alpine${ALPINE_VERSION}-${DOCKER_BASE_VERSION} AS cors_php_supervisord 208 | 209 | COPY .docker/supervisord/project.conf /etc/supervisor/conf.d/project.conf 210 | COPY .docker/supervisord/coreshop.conf /etc/supervisor/conf.d/coreshop.conf 211 | COPY .docker/supervisord/pimcore.conf /etc/supervisor/conf.d/pimcore.conf 212 | 213 | ARG APP_ENV=prod 214 | ENV APP_ENV=$APP_ENV 215 | ENV APP_DEBUG=0 216 | 217 | USER www-data 218 | 219 | COPY --from=cors_php /var/www/html /var/www/html 220 | 221 | FROM ghcr.io/cors-gmbh/pimcore-docker/php-cli:${PHP_VERSION}-alpine${ALPINE_VERSION}-${DOCKER_BASE_VERSION} AS cors_php_cli 222 | 223 | ARG APP_ENV=prod 224 | ENV APP_ENV=$APP_ENV 225 | ENV APP_DEBUG=0 226 | 227 | USER www-data 228 | 229 | COPY --from=cors_php /var/www/html /var/www/html 230 | 231 | FROM ghcr.io/cors-gmbh/pimcore-docker/php-fpm-blackfire:${PHP_VERSION}-alpine${ALPINE_VERSION}-${DOCKER_BASE_VERSION} AS cors_php_blackfire 232 | 233 | ARG APP_ENV=prod 234 | ENV APP_ENV=$APP_ENV 235 | ENV APP_DEBUG=0 236 | 237 | USER www-data 238 | 239 | COPY --from=cors_php /var/www/html /var/www/html 240 | 241 | FROM ghcr.io/cors-gmbh/pimcore-docker/nginx:${NGINX_VERSION}-${DOCKER_BASE_VERSION} AS cors_nginx 242 | 243 | COPY --from=cors_php /var/www/html/public public/ 244 | COPY --from=cors_node /var/www/html/public public/ 245 | ``` 246 | 247 | ## Contributing 248 | 249 | We welcome contributions to improve this project! If you encounter issues or have suggestions, please: 250 | 251 | 1. Fork the repository. 252 | 2. Create a new branch for your feature or bug fix. 253 | 3. Submit a pull request for review. 254 | 255 | ## License 256 | 257 | This repository is licensed under the MIT [License](LICENSE). The docker images are not licensed since we didn't do any 258 | due diligence on any included software and their licenses. Only the Sourcecode is MIT Licensed! 259 | 260 | Happy Kubernetesing! 🎉 261 | -------------------------------------------------------------------------------- /blackfire/blackfire.ini: -------------------------------------------------------------------------------- 1 | ; priority=90 2 | ; ?priority=90 3 | [blackfire] 4 | extension=blackfire.so 5 | ; Default port is 8707. 6 | ; You can check the actual configuration by running (see "socket" setting): 7 | ; docker-compose exec blackfire_agent blackfire-agent -d 8 | blackfire.agent_socket = tcp://127.0.0.1:8307 9 | blackfire.agent_timeout = 0.25 10 | 11 | ;Sets fine-grained configuration for Probe. 12 | ;This should be left blank in most cases. For most installs, 13 | ;the server credentials should only be set in the agent. 14 | ;blackfire.server_id = 15 | 16 | ;Sets fine-grained configuration for Probe. 17 | ;This should be left blank in most cases. For most installs, 18 | ;the server credentials should only be set in the agent. 19 | ;blackfire.server_token = 20 | ;blackfire.log_level = 3 21 | ;blackfire.log_file = /tmp/blackfire.log -------------------------------------------------------------------------------- /fpm/php-config.conf: -------------------------------------------------------------------------------- 1 | [global] 2 | include=etc/php-fpm.d/*.conf -------------------------------------------------------------------------------- /fpm/php-pool-config.conf: -------------------------------------------------------------------------------- 1 | [www] 2 | user = www-data 3 | group = www-data 4 | listen = 0.0.0.0:9000 5 | pm = dynamic 6 | pm.max_children = 10 7 | pm.start_servers = 2 8 | pm.min_spare_servers = 2 9 | pm.max_spare_servers = 5 10 | pm.process_idle_timeout = 90 11 | pm.max_requests = 150 12 | ping.path = /ping 13 | 14 | ; Status 15 | pm.status_path = /fpm-status 16 | pm.status_listen = 127.0.0.1:9001 -------------------------------------------------------------------------------- /fpm/php.ini: -------------------------------------------------------------------------------- 1 | [PHP] 2 | engine = On 3 | short_open_tag = Off 4 | precision = 14 5 | output_buffering = 4096 6 | zlib.output_compression = Off 7 | implicit_flush = Off 8 | unserialize_callback_func = 9 | serialize_precision = -1 10 | disable_functions = 11 | disable_classes = 12 | zend.enable_gc = On 13 | expose_php = Off 14 | request_terminate_timeout = 1200 15 | max_execution_time = 1200 16 | max_input_time = 1200 17 | memory_limit = 512M 18 | error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT 19 | display_errors = Off 20 | display_startup_errors = Off 21 | log_errors = On 22 | log_errors_max_len = 1024 23 | error_log = /var/www/var/logs/php_error.log 24 | ignore_repeated_errors = Off 25 | ignore_repeated_source = Off 26 | report_memleaks = On 27 | track_errors = Off 28 | html_errors = On 29 | variables_order = "EGPCS" 30 | request_order = "GP" 31 | register_argc_argv = Off 32 | auto_globals_jit = On 33 | post_max_size = 512M 34 | auto_prepend_file = 35 | auto_append_file = 36 | default_mimetype = "text/html" 37 | default_charset = "UTF-8" 38 | doc_root = 39 | user_dir = 40 | enable_dl = Off 41 | cgi.fix_pathinfo=0 42 | file_uploads = On 43 | upload_max_filesize = 512M 44 | max_file_uploads = 20 45 | allow_url_fopen = On 46 | allow_url_include = Off 47 | default_socket_timeout = 60 48 | realpath_cache_size = 4096k 49 | realpath_cache_ttl = 7200 50 | [CLI Server] 51 | cli_server.color = On 52 | [Date] 53 | date.timezone = Europe/Berlin 54 | [filter] 55 | [iconv] 56 | [intl] 57 | [sqlite3] 58 | [Pcre] 59 | [Pdo] 60 | [Pdo_mysql] 61 | pdo_mysql.cache_size = 2000 62 | pdo_mysql.default_socket= 63 | [Phar] 64 | [mail function] 65 | SMTP = localhost 66 | smtp_port = 25 67 | mail.add_x_header = On 68 | [SQL] 69 | sql.safe_mode = Off 70 | [ODBC] 71 | odbc.allow_persistent = On 72 | odbc.check_persistent = On 73 | odbc.max_persistent = -1 74 | odbc.max_links = -1 75 | odbc.defaultlrl = 4096 76 | odbc.defaultbinmode = 1 77 | [Interbase] 78 | ibase.allow_persistent = 1 79 | ibase.max_persistent = -1 80 | ibase.max_links = -1 81 | ibase.timestampformat = "%Y-%m-%d %H:%M:%S" 82 | ibase.dateformat = "%Y-%m-%d" 83 | ibase.timeformat = "%H:%M:%S" 84 | [MySQLi] 85 | mysqli.max_persistent = -1 86 | mysqli.allow_persistent = On 87 | mysqli.max_links = -1 88 | mysqli.cache_size = 2000 89 | mysqli.default_port = 3306 90 | mysqli.default_socket = 91 | mysqli.default_host = 92 | mysqli.default_user = 93 | mysqli.default_pw = 94 | mysqli.reconnect = Off 95 | [mysqlnd] 96 | mysqlnd.collect_statistics = On 97 | mysqlnd.collect_memory_statistics = Off 98 | [OCI8] 99 | [PostgreSQL] 100 | pgsql.allow_persistent = On 101 | pgsql.auto_reset_persistent = Off 102 | pgsql.max_persistent = -1 103 | pgsql.max_links = -1 104 | pgsql.ignore_notice = 0 105 | pgsql.log_notice = 0 106 | [bcmath] 107 | bcmath.scale = 0 108 | [browscap] 109 | [Session] 110 | session.use_strict_mode = 0 111 | session.use_cookies = 1 112 | session.use_only_cookies = 1 113 | session.name = PHPSESSID 114 | session.auto_start = 0 115 | session.cookie_lifetime = 0 116 | session.cookie_path = / 117 | session.serialize_handler = php 118 | session.gc_probability = 1 119 | session.gc_divisor = 1000 120 | session.gc_maxlifetime = 1440 121 | session.cache_limiter = nocache 122 | session.cache_expire = 180 123 | session.use_trans_sid = 0 124 | session.sid_length = 26 125 | session.trans_sid_tags = "a=href,area=href,frame=src,form=" 126 | session.sid_bits_per_character = 5 127 | [Assertion] 128 | zend.assertions = -1 129 | [COM] 130 | [mbstring] 131 | [gd] 132 | [exif] 133 | [Tidy] 134 | tidy.clean_output = Off 135 | [soap] 136 | soap.wsdl_cache_enabled=1 137 | soap.wsdl_cache_dir="/tmp" 138 | soap.wsdl_cache_ttl=86400 139 | soap.wsdl_cache_limit = 5 140 | [sysvshm] 141 | [ldap] 142 | ldap.max_links = -1 143 | [mcrypt] 144 | [dba] 145 | [opcache] 146 | opcache.enable=1 147 | opcache.memory_consumption=256 148 | opcache.interned_strings_buffer=8 149 | opcache.max_accelerated_files=11000 150 | opcache.fast_shutdown=1 151 | opcache.preload=/var/www/html/config/preload.php 152 | opcache.preload_user=www-data 153 | [curl] 154 | [openssl] -------------------------------------------------------------------------------- /nginx/pimcore-default.conf: -------------------------------------------------------------------------------- 1 | upstream php-pimcore { 2 | server 127.0.0.1:9000; 3 | } 4 | 5 | server { 6 | listen 80; 7 | server_name _; 8 | root /var/www/html/public; 9 | index index.php; 10 | 11 | access_log off; 12 | error_log /dev/stderr error; 13 | 14 | client_max_body_size 500m; 15 | 16 | rewrite ^/cache-buster-(?:\d+)/(.*) /$1 last; 17 | 18 | add_header Content-Security-Policy upgrade-insecure-requests; 19 | 20 | location ~* /var/assets/.*\.php(/|$) { 21 | return 404; 22 | } 23 | 24 | location ~* /\.(?!well-known/) { 25 | deny all; 26 | log_not_found off; 27 | access_log off; 28 | } 29 | 30 | location ~* (?:\.(?:bak|conf(ig)?|dist|fla|in[ci]|log|psd|sh|sql|sw[op])|~)$ { 31 | deny all; 32 | } 33 | 34 | location ~* ^/admin/(adminer|external) { 35 | rewrite .* /index.php$is_args$args last; 36 | } 37 | 38 | location ~* .*/(image|video)-thumb__\d+__.* { 39 | try_files /var/tmp/thumbnails$uri /index.php; 40 | expires 2w; 41 | access_log off; 42 | add_header Cache-Control "public"; 43 | } 44 | 45 | #Since we store assets offsite in Google Cloud Storage, this can never resolve any asset anyway 46 | #location ~* ^(?!/admin)(.+?)\.((?:css|js)(?:\.map)?|jpe?g|gif|webp|avif|png|svgz?|webmanifest|woff2|eps|exe|gz|zip|mp\d|ogg|ogv|webm|pdf|docx?|xlsx?|pptx?)$ { 47 | # try_files /var/assets$uri $uri =404; 48 | # expires 2w; 49 | # access_log off; 50 | # log_not_found off; 51 | # add_header Cache-Control "public"; 52 | #} 53 | 54 | location / { 55 | error_page 404 /meta/404; 56 | try_files $uri /index.php$is_args$args; 57 | } 58 | 59 | location /api/graphql { 60 | auth_basic off; 61 | error_page 404 /meta/404; 62 | try_files $uri /app.php$is_args$args; 63 | } 64 | 65 | location /api/graphql/explorer { 66 | auth_basic off; 67 | error_page 404 /meta/404; 68 | try_files $uri /app.php$is_args$args; 69 | } 70 | 71 | location ~ ^/index\.php(/|$) { 72 | send_timeout 1800; 73 | fastcgi_read_timeout 1800; 74 | fastcgi_send_timeout 1800; 75 | fastcgi_split_path_info ^(.+\.php)(/.+)$; 76 | try_files $fastcgi_script_name =404; 77 | include fastcgi.conf; 78 | set $path_info $fastcgi_path_info; 79 | fastcgi_param PATH_INFO $path_info; 80 | fastcgi_pass php-pimcore; 81 | fastcgi_param TRUSTED_PROXIES 10.0.0.0/16; 82 | fastcgi_param HTTP_X_FORWARDED_FOR $http_x_real_ip; 83 | internal; 84 | } 85 | } -------------------------------------------------------------------------------- /php/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # first arg is `-f` or `--some-option` 5 | if [ "${1#-}" != "$1" ]; then 6 | set -- php-fpm "$@" 7 | fi 8 | 9 | if [ "$1" = 'php-fpm' ] || [ "$1" = 'bin/console' ]; then 10 | mkdir -p var/cache var/log public/var 11 | # bin/console pimcore:deployment:classes-rebuild --no-interaction || true 12 | # composer dump-autoload #required to load pimcore classes after they have been installed 13 | fi 14 | 15 | exec docker-php-entrypoint "$@" 16 | -------------------------------------------------------------------------------- /php/docker-healthcheck.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | export SCRIPT_NAME=/fpm-status 5 | export SCRIPT_FILENAME=/fpm-status 6 | export REQUEST_METHOD=GET 7 | 8 | if cgi-fcgi -bind -connect 127.0.0.1:9001; then 9 | exit 0 10 | fi 11 | 12 | exit 1 13 | -------------------------------------------------------------------------------- /php/docker-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "Install Pimcore" 5 | vendor/bin/pimcore-install --skip-database-config --ignore-existing-config --no-interaction 6 | 7 | rm -rf var/config/system.yml 8 | rm -rf var/cache 9 | 10 | touch /var/www/html/var/tmp/.pimcore_installed 11 | -------------------------------------------------------------------------------- /php/docker-migrate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "Generating Classes"; 5 | bin/console pimcore:deployment:classes-rebuild --create-classes --no-interaction; 6 | echo "Composer dump-autoload"; 7 | composer dump-autoload; 8 | echo "Running Migrations"; 9 | bin/console doctrine:migrations:migrate --no-interaction -------------------------------------------------------------------------------- /php/docker-readiness.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | export SCRIPT_NAME=/fpm-status 5 | export SCRIPT_FILENAME=/fpm-status 6 | export REQUEST_METHOD=GET 7 | 8 | bin/console doctrine:migrations:up-to-date 9 | 10 | if cgi-fcgi -bind -connect 127.0.0.1:9001; then 11 | exit 0 12 | fi 13 | 14 | exit 1 15 | -------------------------------------------------------------------------------- /php/docker-status.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | export SCRIPT_NAME=/fpm-status 5 | export SCRIPT_FILENAME=/fpm-status 6 | export REQUEST_METHOD=GET 7 | 8 | cgi-fcgi -bind -connect 127.0.0.1:9001 -------------------------------------------------------------------------------- /php/docker-wait-db.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | until bin/console doctrine:query:sql "SELECT 1" > /dev/null 2>&1; do 5 | (>&2 echo "Waiting for MySQL to be ready...") 6 | sleep 1 7 | done 8 | -------------------------------------------------------------------------------- /php/docker-wait-pimcore.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | until bin/console doctrine:query:sql "SELECT * FROM classes" > /dev/null 2>&1; do 5 | (>&2 echo "Waiting for Pimcore to be installed...") 6 | sleep 1 7 | done 8 | -------------------------------------------------------------------------------- /php/docker-wait.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | /usr/local/bin/wait_db 5 | /usr/local/bin/wait_pimcore 6 | -------------------------------------------------------------------------------- /php/docker-xdebug-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Override default configuration for xdebug v3.x. 4 | # See: https://xdebug.org/docs/all_settings 5 | cat << EOF > /usr/local/etc/php/conf.d/20-xdebug.ini 6 | xdebug.idekey = PHPSTORM 7 | xdebug.mode = debug 8 | xdebug.start_with_request = 1 9 | EOF 10 | 11 | # if XDEBUG_HOST is manually set 12 | HOST="$XDEBUG_HOST" 13 | 14 | #OrbStack 15 | if [ -z "$HOST" ]; then 16 | HOST=`getent ahostsv4 host.internal | awk 'NR==1{ print $1 }'` 17 | fi 18 | 19 | # Docker for Mac 20 | if [ -z "$HOST" ]; then 21 | HOST=`getent hosts docker.for.mac.localhost | awk '{ print $1 }'` 22 | fi 23 | 24 | # else get host ip 25 | if [ -z "$HOST" ]; then 26 | HOST=`/sbin/ip route|awk '/default/ { print $3 }'` 27 | fi 28 | 29 | # if we managed to determine HOST add it to the xdebug config. Otherwise use xdebug's 30 | # default config. 31 | if [ -n "$HOST" ]; then 32 | echo "xdebug.client_host = $HOST" >> /usr/local/etc/php/conf.d/20-xdebug.ini 33 | fi 34 | 35 | 36 | exec docker-php-entrypoint "$@" 37 | -------------------------------------------------------------------------------- /supervisord/coreshop._conf: -------------------------------------------------------------------------------- 1 | [program:coreshop] 2 | command=php /var/www/html/bin/console messenger:consume coreshop_notification coreshop_index --memory-limit=250M --time-limit=300 3 | numprocs=1 4 | startsecs=0 5 | autostart=true 6 | autorestart=true 7 | process_name=%(program_name)s_%(process_num)02d 8 | stdout_logfile=/dev/fd/1 9 | stdout_logfile_maxbytes=0 10 | redirect_stderr=true 11 | -------------------------------------------------------------------------------- /supervisord/pimcore.conf: -------------------------------------------------------------------------------- 1 | [program:messenger-consume] 2 | command=php /var/www/html/bin/console messenger:consume pimcore_core pimcore_image_optimize --memory-limit=250M --time-limit=300 3 | numprocs=1 4 | startsecs=0 5 | autostart=true 6 | autorestart=true 7 | process_name=%(program_name)s_%(process_num)02d 8 | stdout_logfile=/dev/fd/1 9 | stdout_logfile_maxbytes=0 10 | redirect_stderr=true 11 | 12 | [program:messenger-maintenance] 13 | command=php /var/www/html/bin/console messenger:consume pimcore_maintenance --memory-limit=100M --limit=5 14 | numprocs=1 15 | startsecs=0 16 | autostart=true 17 | autorestart=true 18 | process_name=%(program_name)s_%(process_num)02d 19 | stdout_logfile=/dev/fd/1 20 | stdout_logfile_maxbytes=0 21 | redirect_stderr=true 22 | 23 | [program:maintenance] 24 | command=sh -c 'sleep 300 && exec php /var/www/html/bin/console pimcore:maintenance --async' 25 | autostart=true 26 | autorestart=true 27 | stdout_logfile=/dev/fd/1 28 | stdout_logfile_maxbytes=0 29 | redirect_stderr=true 30 | -------------------------------------------------------------------------------- /supervisord/supervisord.conf: -------------------------------------------------------------------------------- 1 | ; supervisor config file 2 | 3 | [supervisord] 4 | nodaemon=true 5 | logfile=/dev/null 6 | logfile_maxbytes=0 7 | 8 | [include] 9 | files = /etc/supervisor/conf.d/*.conf 10 | --------------------------------------------------------------------------------