diff --git a/.caddy/config-cache/.gitkeep b/.caddy/config-cache/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/.caddy/data/.gitkeep b/.caddy/data/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/.caddy/php-socket/.gitkeep b/.caddy/php-socket/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/.github/workflows/reusable-build-and-push.yml b/.github/workflows/reusable-build-and-push.yml index a5044a4342..13dccefef6 100644 --- a/.github/workflows/reusable-build-and-push.yml +++ b/.github/workflows/reusable-build-and-push.yml @@ -58,26 +58,13 @@ jobs: push: true file: api/Dockerfile tags: | - ${{ ((inputs.tag != '') && format('{0}/ecamp3-api-php:{1}', vars.DOCKER_HUB_USERNAME, inputs.tag) || '') }} - ${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-api-php:${{ inputs.sha }} + ${{ ((inputs.tag != '') && format('{0}/ecamp3-api:{1}', vars.DOCKER_HUB_USERNAME, inputs.tag) || '') }} + ${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-api:${{ inputs.sha }} context: './api' - target: api_platform_php + target: frankenphp_prod cache-from: type=gha,scope=api cache-to: type=gha,scope=api,mode=max - - name: Build and push caddy docker image - uses: docker/build-push-action@v5 - with: - push: true - file: api/Dockerfile - tags: | - ${{ ((inputs.tag != '') && format('{0}/ecamp3-api-caddy:{1}', vars.DOCKER_HUB_USERNAME, inputs.tag) || '') }} - ${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-api-caddy:${{ inputs.sha }} - context: './api' - target: api_platform_caddy_prod - cache-from: type=gha,scope=caddy - cache-to: type=gha,scope=caddy,mode=max - - name: Build and push print docker image uses: docker/build-push-action@v5 with: diff --git a/.github/workflows/reusable-dev-deployment.yml b/.github/workflows/reusable-dev-deployment.yml index a971cba1ac..bb56e8ecd8 100644 --- a/.github/workflows/reusable-dev-deployment.yml +++ b/.github/workflows/reusable-dev-deployment.yml @@ -83,8 +83,7 @@ jobs: --set imageTag=${{ inputs.sha }} \ --set frontend.image.repository='docker.io/${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-frontend' \ --set print.image.repository='docker.io/${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-print' \ - --set php.image.repository='docker.io/${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-api-php' \ - --set caddy.image.repository='docker.io/${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-api-caddy' \ + --set api.image.repository='docker.io/${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-api' \ --set apiCache.image.repository='docker.io/${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-varnish' \ --set postgresql.dbBackupRestoreImage.repository='docker.io/${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-db-backup-restore' \ --set termsOfServiceLinkTemplate='https://ecamp3.ch/{lang}/tos' \ @@ -112,12 +111,12 @@ jobs: --set postgresql.restore.s3.accessKeyId='${{ secrets.RESTORE_S3_ACCESS_KEY_ID }}' \ --set postgresql.restore.s3.accessKey='${{ secrets.RESTORE_S3_ACCESS_KEY }}' \ --set postgresql.restore.encryptionKey=${{ secrets.RESTORE_ENCRYPTION_KEY != null && format('''{0}''', secrets.RESTORE_ENCRYPTION_KEY) || null }} \ - --set php.dataMigrationsDir='${{ vars.DATA_MIGRATIONS_DIR }}' \ - --set php.appSecret='${{ secrets.API_APP_SECRET }}' \ - --set php.sentryDsn='${{ secrets.API_SENTRY_DSN }}' \ - --set php.jwt.passphrase='${{ secrets.JWT_PASSPHRASE }}' \ - --set php.jwt.publicKey='${{ secrets.JWT_PUBLIC_KEY }}' \ - --set php.jwt.privateKey='${{ secrets.JWT_PRIVATE_KEY }}' \ + --set api.dataMigrationsDir='${{ vars.DATA_MIGRATIONS_DIR }}' \ + --set api.appSecret='${{ secrets.API_APP_SECRET }}' \ + --set api.sentryDsn='${{ secrets.API_SENTRY_DSN }}' \ + --set api.jwt.passphrase='${{ secrets.JWT_PASSPHRASE }}' \ + --set api.jwt.publicKey='${{ secrets.JWT_PUBLIC_KEY }}' \ + --set api.jwt.privateKey='${{ secrets.JWT_PRIVATE_KEY }}' \ --set frontend.sentryDsn='${{ secrets.FRONTEND_SENTRY_DSN }}' \ --set print.sentryDsn='${{ secrets.PRINT_SENTRY_DSN }}' \ --set print.browserWsEndpoint='${{ secrets.BROWSER_WS_ENDPOINT }}' \ diff --git a/.github/workflows/reusable-e2e-tests-build.yml b/.github/workflows/reusable-e2e-tests-build.yml index be4b20da6c..1cf2ee6463 100644 --- a/.github/workflows/reusable-e2e-tests-build.yml +++ b/.github/workflows/reusable-e2e-tests-build.yml @@ -23,27 +23,12 @@ jobs: context: './api' push: false load: true - target: api_platform_php_dev + target: frankenphp_dev builder: ${{ steps.buildx.outputs.name }} - tags: ecamp/ecamp3-dev-api-php + tags: ecamp/ecamp3-dev-api cache-from: type=gha,scope=api cache-to: type=gha,scope=api,mode=max - outputs: type=docker,dest=/tmp/ecamp3-dev-api-php.tar - - # build caddy (using cache; provide image to docker compose) - - name: Build docker image (Caddy) - uses: docker/build-push-action@v5 - with: - file: api/Dockerfile - context: './api' - push: false - load: true - target: api_platform_caddy - builder: ${{ steps.buildx.outputs.name }} - tags: ecamp/ecamp3-dev-api-caddy - cache-from: type=gha,scope=caddy - cache-to: type=gha,scope=caddy,mode=max - outputs: type=docker,dest=/tmp/ecamp3-dev-api-caddy.tar + outputs: type=docker,dest=/tmp/ecamp3-dev-api.tar - uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/reusable-e2e-tests-run.yml b/.github/workflows/reusable-e2e-tests-run.yml index 3ccfb2f35d..40855c272c 100644 --- a/.github/workflows/reusable-e2e-tests-run.yml +++ b/.github/workflows/reusable-e2e-tests-run.yml @@ -36,8 +36,7 @@ jobs: - name: Load images run: | - docker load --input /tmp/ecamp3-dev-api-php.tar - docker load --input /tmp/ecamp3-dev-api-caddy.tar + docker load --input /tmp/ecamp3-dev-api.tar docker image ls -a --digests - name: Restore cache volumes (npm, composer) @@ -49,7 +48,7 @@ jobs: docker-compose- # start necessary containers - - run: docker compose up -d php caddy frontend pdf print browserless database docker-host http-cache mail + - run: docker compose up -d api frontend pdf print browserless database docker-host http-cache mail - uses: cypress-io/github-action@v6.7.0 with: diff --git a/.github/workflows/reusable-stage-prod-deployment.yml b/.github/workflows/reusable-stage-prod-deployment.yml index a7faec4c39..450f71f404 100644 --- a/.github/workflows/reusable-stage-prod-deployment.yml +++ b/.github/workflows/reusable-stage-prod-deployment.yml @@ -42,8 +42,7 @@ jobs: --set imageTag=${{ github.sha }} \ --set frontend.image.repository='docker.io/${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-frontend' \ --set print.image.repository='docker.io/${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-print' \ - --set php.image.repository='docker.io/${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-api-php' \ - --set caddy.image.repository='docker.io/${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-api-caddy' \ + --set api.image.repository='docker.io/${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-api' \ --set apiCache.image.repository='docker.io/${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-varnish' \ --set postgresql.dbBackupRestoreImage.repository='docker.io/${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-db-backup-restore' \ --set termsOfServiceLinkTemplate='https://ecamp3.ch/{lang}/tos' \ @@ -71,23 +70,23 @@ jobs: --set postgresql.restore.s3.accessKey='${{ secrets.RESTORE_S3_ACCESS_KEY }}' \ --set postgresql.restore.encryptionKey=${{ secrets.RESTORE_ENCRYPTION_KEY != null && format('''{0}''', secrets.RESTORE_ENCRYPTION_KEY) || null }} \ --set postgresql.restore.inviteSupportAccountToInterestingCamps=${{ vars.RESTORE_INVITE_TO_INTERESTING_CAMPS != null && format('''{0}''', vars.RESTORE_INVITE_TO_INTERESTING_CAMPS) || false }} \ - --set php.dataMigrationsDir='${{ vars.DATA_MIGRATIONS_DIR }}' \ - --set php.appSecret='${{ secrets.API_APP_SECRET }}' \ - --set php.sentryDsn='${{ secrets.API_SENTRY_DSN }}' \ - --set php.jwt.passphrase='${{ secrets.JWT_PASSPHRASE }}' \ - --set php.jwt.publicKey='${{ secrets.JWT_PUBLIC_KEY }}' \ - --set php.jwt.privateKey='${{ secrets.JWT_PRIVATE_KEY }}' \ - --set php.oauth.google.clientId='${{ secrets.OAUTH_GOOGLE_CLIENT_ID }}' \ - --set php.oauth.google.clientSecret='${{ secrets.OAUTH_GOOGLE_CLIENT_SECRET }}' \ - --set php.oauth.pbsmidata.clientId='${{ secrets.OAUTH_PBSMIDATA_CLIENT_ID }}' \ - --set php.oauth.pbsmidata.clientSecret='${{ secrets.OAUTH_PBSMIDATA_CLIENT_SECRET }}' \ - --set php.oauth.pbsmidata.baseUrl='${{ secrets.OAUTH_PBSMIDATA_BASE_URL }}' \ - --set php.oauth.cevidb.clientId='${{ secrets.OAUTH_CEVIDB_CLIENT_ID }}' \ - --set php.oauth.cevidb.clientSecret='${{ secrets.OAUTH_CEVIDB_CLIENT_SECRET }}' \ - --set php.oauth.cevidb.baseUrl='${{ secrets.OAUTH_CEVIDB_BASE_URL }}' \ - --set php.oauth.jubladb.clientId='${{ secrets.OAUTH_JUBLADB_CLIENT_ID }}' \ - --set php.oauth.jubladb.clientSecret='${{ secrets.OAUTH_JUBLADB_CLIENT_SECRET }}' \ - --set php.oauth.jubladb.baseUrl='${{ secrets.OAUTH_JUBLADB_BASE_URL }}' \ + --set api.dataMigrationsDir='${{ vars.DATA_MIGRATIONS_DIR }}' \ + --set api.appSecret='${{ secrets.API_APP_SECRET }}' \ + --set api.sentryDsn='${{ secrets.API_SENTRY_DSN }}' \ + --set api.jwt.passphrase='${{ secrets.JWT_PASSPHRASE }}' \ + --set api.jwt.publicKey='${{ secrets.JWT_PUBLIC_KEY }}' \ + --set api.jwt.privateKey='${{ secrets.JWT_PRIVATE_KEY }}' \ + --set api.oauth.google.clientId='${{ secrets.OAUTH_GOOGLE_CLIENT_ID }}' \ + --set api.oauth.google.clientSecret='${{ secrets.OAUTH_GOOGLE_CLIENT_SECRET }}' \ + --set api.oauth.pbsmidata.clientId='${{ secrets.OAUTH_PBSMIDATA_CLIENT_ID }}' \ + --set api.oauth.pbsmidata.clientSecret='${{ secrets.OAUTH_PBSMIDATA_CLIENT_SECRET }}' \ + --set api.oauth.pbsmidata.baseUrl='${{ secrets.OAUTH_PBSMIDATA_BASE_URL }}' \ + --set api.oauth.cevidb.clientId='${{ secrets.OAUTH_CEVIDB_CLIENT_ID }}' \ + --set api.oauth.cevidb.clientSecret='${{ secrets.OAUTH_CEVIDB_CLIENT_SECRET }}' \ + --set api.oauth.cevidb.baseUrl='${{ secrets.OAUTH_CEVIDB_BASE_URL }}' \ + --set api.oauth.jubladb.clientId='${{ secrets.OAUTH_JUBLADB_CLIENT_ID }}' \ + --set api.oauth.jubladb.clientSecret='${{ secrets.OAUTH_JUBLADB_CLIENT_SECRET }}' \ + --set api.oauth.jubladb.baseUrl='${{ secrets.OAUTH_JUBLADB_BASE_URL }}' \ --set frontend.sentryDsn='${{ secrets.FRONTEND_SENTRY_DSN }}' \ --set print.sentryDsn='${{ secrets.PRINT_SENTRY_DSN }}' \ --set print.ingress.readTimeoutSeconds='${{ vars.PRINT_INGRESS_READ_TIMEOUT_SECONDS }}' \ @@ -103,11 +102,9 @@ jobs: --set browserless.connectionTimeout=${{ vars.BROWSERLESS_CONNECTION_TIMEOUT_MS || '30000' }} \ --set browserless.resources.requests.cpu=${{ vars.BROWSERLESS_CPU || '500m' }} \ --set browserless.resources.requests.memory=${{ vars.BROWSERLESS_MEMORY || '800Mi' }} \ - --set caddy.resources.requests.cpu=50m \ - --set caddy.resources.limits.cpu=500m \ - --set php.resources.requests.cpu=${{ vars.PHP_CPU || '1000m' }} \ - --set php.resources.requests.memory=${{ vars.PHP_MEMORY || '500Mi' }} \ - --set php.resources.limits.cpu=${{ vars.PHP_CPULIMIT || '1900m' }} \ + --set api.resources.requests.cpu=${{ vars.PHP_CPU || '1000m' }} \ + --set api.resources.requests.memory=${{ vars.PHP_MEMORY || '500Mi' }} \ + --set api.resources.limits.cpu=${{ vars.PHP_CPULIMIT || '1900m' }} \ --set frontend.resources.requests.cpu=50m \ --set print.resources.requests.cpu=${{ vars.PRINT_CPU || '300m' }} \ --set print.resources.requests.memory=${{ vars.PRINT_MEMORY || '150Mi' }} \ diff --git a/.helm/build-images.sh b/.helm/build-images.sh index 9ba604edd0..acad4b3fcc 100755 --- a/.helm/build-images.sh +++ b/.helm/build-images.sh @@ -25,14 +25,10 @@ frontend_image_tag="${docker_hub_account}/ecamp3-frontend:${version}" docker build "$REPO_DIR" -f "$REPO_DIR"/.docker-hub/frontend/Dockerfile $frontend_sentry_build_args -t "$frontend_image_tag" docker push "$frontend_image_tag" -api_image_tag="${docker_hub_account}/ecamp3-api-php:${version}" -docker build "$REPO_DIR"/api -f "$REPO_DIR"/api/Dockerfile -t "$api_image_tag" --target api_platform_php $sentry_build_args +api_image_tag="${docker_hub_account}/ecamp3-api:${version}" +docker build "$REPO_DIR"/api -f "$REPO_DIR"/api/Dockerfile -t "$api_image_tag" --target frankenphp_prod $sentry_build_args docker push "$api_image_tag" -caddy_image_tag="${docker_hub_account}/ecamp3-api-caddy:${version}" -docker build "$REPO_DIR"/api -f "$REPO_DIR"/api/Dockerfile -t "$caddy_image_tag" --target api_platform_caddy_prod -docker push "$caddy_image_tag" - print_sentry_build_args="$sentry_build_args --build-arg SENTRY_PRINT_PROJECT=$SENTRY_PRINT_PROJECT" print_image_tag="${docker_hub_account}/ecamp3-print:${version}" diff --git a/.helm/deploy-to-cluster.sh b/.helm/deploy-to-cluster.sh index 241d202e58..fcf7c17def 100755 --- a/.helm/deploy-to-cluster.sh +++ b/.helm/deploy-to-cluster.sh @@ -47,10 +47,10 @@ for i in 1; do values="$values --set postgresql.url=$POSTGRES_URL/ecamp3$instance_name-"$i"?sslmode=require" values="$values --set postgresql.adminUrl=$POSTGRES_ADMIN_URL/ecamp3$instance_name-"$i"?sslmode=require" values="$values --set postgresql.dropDBOnUninstall=true" - values="$values --set php.dataMigrationsDir=$migrations_dir" - values="$values --set php.appSecret=$app_secret" + values="$values --set api.dataMigrationsDir=$migrations_dir" + values="$values --set api.appSecret=$app_secret" if [ -n "$API_SENTRY_DSN" ]; then - values="$values --set php.sentryDsn=$API_SENTRY_DSN" + values="$values --set api.sentryDsn=$API_SENTRY_DSN" fi if [ -n "$FRONTEND_SENTRY_DSN" ]; then values="$values --set frontend.sentryDsn=$FRONTEND_SENTRY_DSN" @@ -58,9 +58,9 @@ for i in 1; do if [ -n "$PRINT_SENTRY_DSN" ]; then values="$values --set print.sentryDsn=$PRINT_SENTRY_DSN" fi - values="$values --set php.jwt.passphrase=$app_jwt_passphrase" - values="$values --set-file php.jwt.publicKey=$SCRIPT_DIR/public.pem" - values="$values --set-file php.jwt.privateKey=$SCRIPT_DIR/private.pem" + values="$values --set api.jwt.passphrase=$app_jwt_passphrase" + values="$values --set-file api.jwt.publicKey=$SCRIPT_DIR/public.pem" + values="$values --set-file api.jwt.privateKey=$SCRIPT_DIR/private.pem" values="$values --set deploymentTime=$(date -u +%s)" values="$values --set deployedVersion=\"$(git rev-parse --short HEAD)\"" values="$values --set featureToggle.developer=true" @@ -89,16 +89,11 @@ for i in 1; do values="$values --set postgresql.restore.inviteSupportAccountToInterestingCamps=$RESTORE_INVITE_TO_INTERESTING_CAMPS" fi - for imagespec in "frontend" "print"; do + for imagespec in "frontend" "print" "api"; do values="$values --set $imagespec.image.pullPolicy=$pull_policy" values="$values --set $imagespec.image.repository=docker.io/${docker_hub_account}/ecamp3-$imagespec" done - for imagespec in "php" "caddy"; do - values="$values --set $imagespec.image.pullPolicy=$pull_policy" - values="$values --set $imagespec.image.repository=docker.io/${docker_hub_account}/ecamp3-api-$imagespec" - done - values="$values --set apiCache.image.repository=docker.io/${docker_hub_account}/ecamp3-varnish" values="$values --set postgresql.dbBackupRestoreImage.pullPolicy=$pull_policy" diff --git a/.helm/ecamp3/templates/api_configmap.yaml b/.helm/ecamp3/templates/api_configmap.yaml index ef96a5d5c3..f8bcb88ec1 100644 --- a/.helm/ecamp3/templates/api_configmap.yaml +++ b/.helm/ecamp3/templates/api_configmap.yaml @@ -8,20 +8,21 @@ metadata: data: ADDITIONAL_TRUSTED_HOSTS: {{ .Values.domain | quote }} COOKIE_PREFIX: {{ include "api.cookiePrefix" . | quote }} - APP_ENV: {{ .Values.php.appEnv | quote }} - APP_DEBUG: {{ .Values.php.appDebug | quote }} - {{- if .Values.php.dataMigrationsDir }} - DATA_MIGRATIONS_DIR: {{ .Values.php.dataMigrationsDir | quote }} + APP_ENV: {{ .Values.api.appEnv | quote }} + APP_DEBUG: {{ .Values.api.appDebug | quote }} + {{- if .Values.api.dataMigrationsDir }} + DATA_MIGRATIONS_DIR: {{ .Values.api.dataMigrationsDir | quote }} {{- end }} CORS_ALLOW_ORIGIN: {{ include "frontend.url" . | quote }} - TRUSTED_PROXIES: "{{ join "," .Values.php.trustedProxies }}" - {{- if .Values.php.sentryDsn }} - SENTRY_API_DSN: {{ .Values.php.sentryDsn | quote }} + TRUSTED_PROXIES: "{{ join "," .Values.api.trustedProxies }}" + {{- if .Values.api.sentryDsn }} + SENTRY_API_DSN: {{ .Values.api.sentryDsn | quote }} SENTRY_ENVIRONMENT: {{ .Values.domain | quote }} {{- else }} SENTRY_API_DSN: {{ "" | quote }} {{- end }} FRONTEND_BASE_URL: {{ include "frontend.url" . | quote }} + CADDY_GLOBAL_OPTIONS: {{ .Values.api.caddyGlobalOptions | quote }} API_CACHE_ENABLED: {{ .Values.apiCache.enabled | quote }} {{- if .Values.apiCache.enabled }} VARNISH_API_URL: {{ printf "%s:%d" (include "apiCache.name" .) (.Values.apiCache.service.ports.purge | int) | quote }} diff --git a/.helm/ecamp3/templates/api_deployment.yaml b/.helm/ecamp3/templates/api_deployment.yaml index 58e74baa9a..f51ead4c90 100644 --- a/.helm/ecamp3/templates/api_deployment.yaml +++ b/.helm/ecamp3/templates/api_deployment.yaml @@ -31,53 +31,26 @@ spec: {{- toYaml .Values.podSecurityContext | nindent 8 }} enableServiceLinks: false containers: - - name: caddy + - name: {{ .Chart.Name }}-api + {{/* Define the api container as a template, so it can be reused in other places */}} + {{- define "api.container" }} securityContext: {{- toYaml .Values.securityContext | nindent 12 }} - image: "{{ .Values.caddy.image.repository }}:{{ .Values.caddy.image.tag | default .Values.imageTag }}" - imagePullPolicy: {{ .Values.caddy.image.pullPolicy }} - env: - - name: SERVER_NAME - value: :3001 + image: "{{ .Values.api.image.repository }}:{{ .Values.api.image.tag | default .Values.imageTag }}" + imagePullPolicy: {{ .Values.api.image.pullPolicy }} ports: - name: api-http containerPort: {{ .Values.api.service.port }} protocol: TCP - name: api-metrics containerPort: {{ .Values.api.metrics.port }} - protocol: TCP - volumeMounts: - - mountPath: /var/run/php - name: php-socket - lifecycle: - preStop: - exec: - command: ["curl", "-XPOST", "http://localhost:2019/stop"] - readinessProbe: - tcpSocket: - port: 3001 - initialDelaySeconds: 3 - periodSeconds: 10 - timeoutSeconds: 5 - livenessProbe: - tcpSocket: - port: 3001 - initialDelaySeconds: 3 - periodSeconds: 10 - timeoutSeconds: 5 - resources: - {{- toYaml .Values.caddy.resources | nindent 12 }} - - name: php - {{/* Define the php container as a template, so it can be reused in other places */}} - {{- define "api.phpContainer" }} - securityContext: - {{- toYaml .Values.securityContext | nindent 12 }} - image: "{{ .Values.php.image.repository }}:{{ .Values.php.image.tag | default .Values.imageTag }}" - imagePullPolicy: {{ .Values.php.image.pullPolicy }} + protocol: TCP envFrom: - configMapRef: name: {{ include "api.name" . }}-configmap env: + - name: SERVER_NAME + value: :3001 - name: APP_SECRET valueFrom: secretKeyRef: @@ -103,7 +76,7 @@ spec: secretKeyRef: name: {{ include "api.name" . }} key: recaptcha-secret - {{- if .Values.php.oauth.google.clientId }} + {{- if .Values.api.oauth.google.clientId }} - name: OAUTH_GOOGLE_CLIENT_ID valueFrom: secretKeyRef: @@ -115,7 +88,7 @@ spec: name: {{ include "api.name" . }} key: oauth-google-client-secret {{- end }} - {{- if .Values.php.oauth.pbsmidata.clientId }} + {{- if .Values.api.oauth.pbsmidata.clientId }} - name: OAUTH_PBSMIDATA_CLIENT_ID valueFrom: secretKeyRef: @@ -132,7 +105,7 @@ spec: name: {{ include "api.name" . }} key: oauth-pbsmidata-base-url {{- end }} - {{- if .Values.php.oauth.cevidb.clientId }} + {{- if .Values.api.oauth.cevidb.clientId }} - name: OAUTH_CEVIDB_CLIENT_ID valueFrom: secretKeyRef: @@ -149,7 +122,7 @@ spec: name: {{ include "api.name" . }} key: oauth-cevidb-base-url {{- end }} - {{- if .Values.php.oauth.jubladb.clientId }} + {{- if .Values.api.oauth.jubladb.clientId }} - name: OAUTH_JUBLADB_CLIENT_ID valueFrom: secretKeyRef: @@ -167,12 +140,10 @@ spec: key: oauth-jubladb-base-url {{- end }} volumeMounts: - - mountPath: /var/run/php - name: php-socket - - mountPath: /srv/api/config/jwt/public.pem + - mountPath: /app/config/jwt/public.pem name: jwt-keypair subPath: public.pem - - mountPath: /srv/api/config/jwt/private.pem + - mountPath: /app/config/jwt/private.pem name: jwt-keypair subPath: private.pem lifecycle: @@ -180,27 +151,25 @@ spec: exec: command: ["/bin/sh", "-c", "/bin/sleep 1; kill -QUIT 1"] {{- end }} - {{- template "api.phpContainer" . }} + {{- template "api.container" . }} resources: - {{- toYaml .Values.php.resources | nindent 12 }} + {{- toYaml .Values.api.resources | nindent 12 }} readinessProbe: - exec: - command: - - docker-healthcheck + tcpSocket: + port: 3001 periodSeconds: 10 timeoutSeconds: 5 livenessProbe: - exec: - command: - - docker-healthcheck + tcpSocket: + port: 3001 periodSeconds: 10 timeoutSeconds: 5 startupProbe: - exec: - command: - - docker-healthcheck - failureThreshold: 40 - periodSeconds: 3 + tcpSocket: + port: 3001 + failureThreshold: 10 + periodSeconds: 15 + timeoutSeconds: 10 volumes: - name: php-socket diff --git a/.helm/ecamp3/templates/api_secrets.yaml b/.helm/ecamp3/templates/api_secrets.yaml index 2bf2d9b0e9..2d7615d10f 100644 --- a/.helm/ecamp3/templates/api_secrets.yaml +++ b/.helm/ecamp3/templates/api_secrets.yaml @@ -10,28 +10,28 @@ metadata: type: Opaque data: database-url: {{ $databaseUrl | b64enc | quote }} - php-app-secret: {{ .Values.php.appSecret | default (randAlphaNum 40) | b64enc | quote }} - php-jwt-passphrase: {{ .Values.php.jwt.passphrase | default (randAlphaNum 40) | b64enc | quote }} - jwt-public-key: {{ .Values.php.jwt.publicKey | default "" | b64enc | quote }} - jwt-private-key: {{ .Values.php.jwt.privateKey | default "" | b64enc | quote }} - {{- if .Values.php.oauth.google.clientId }} - oauth-google-client-id: {{ .Values.php.oauth.google.clientId | default "" | b64enc | quote }} - oauth-google-client-secret: {{ .Values.php.oauth.google.clientSecret | default "" | b64enc | quote }} + php-app-secret: {{ .Values.api.appSecret | default (randAlphaNum 40) | b64enc | quote }} + php-jwt-passphrase: {{ .Values.api.jwt.passphrase | default (randAlphaNum 40) | b64enc | quote }} + jwt-public-key: {{ .Values.api.jwt.publicKey | default "" | b64enc | quote }} + jwt-private-key: {{ .Values.api.jwt.privateKey | default "" | b64enc | quote }} + {{- if .Values.api.oauth.google.clientId }} + oauth-google-client-id: {{ .Values.api.oauth.google.clientId | default "" | b64enc | quote }} + oauth-google-client-secret: {{ .Values.api.oauth.google.clientSecret | default "" | b64enc | quote }} {{- end }} - {{- if .Values.php.oauth.pbsmidata.clientId }} - oauth-pbsmidata-client-id: {{ .Values.php.oauth.pbsmidata.clientId | default "" | b64enc | quote }} - oauth-pbsmidata-client-secret: {{ .Values.php.oauth.pbsmidata.clientSecret | default "" | b64enc | quote }} - oauth-pbsmidata-base-url: {{ .Values.php.oauth.pbsmidata.baseUrl | default "" | b64enc | quote }} + {{- if .Values.api.oauth.pbsmidata.clientId }} + oauth-pbsmidata-client-id: {{ .Values.api.oauth.pbsmidata.clientId | default "" | b64enc | quote }} + oauth-pbsmidata-client-secret: {{ .Values.api.oauth.pbsmidata.clientSecret | default "" | b64enc | quote }} + oauth-pbsmidata-base-url: {{ .Values.api.oauth.pbsmidata.baseUrl | default "" | b64enc | quote }} {{- end }} - {{- if .Values.php.oauth.cevidb.clientId }} - oauth-cevidb-client-id: {{ .Values.php.oauth.cevidb.clientId | default "" | b64enc | quote }} - oauth-cevidb-client-secret: {{ .Values.php.oauth.cevidb.clientSecret | default "" | b64enc | quote }} - oauth-cevidb-base-url: {{ .Values.php.oauth.cevidb.baseUrl | default "" | b64enc | quote }} + {{- if .Values.api.oauth.cevidb.clientId }} + oauth-cevidb-client-id: {{ .Values.api.oauth.cevidb.clientId | default "" | b64enc | quote }} + oauth-cevidb-client-secret: {{ .Values.api.oauth.cevidb.clientSecret | default "" | b64enc | quote }} + oauth-cevidb-base-url: {{ .Values.api.oauth.cevidb.baseUrl | default "" | b64enc | quote }} {{- end }} - {{- if .Values.php.oauth.jubladb.clientId }} - oauth-jubladb-client-id: {{ .Values.php.oauth.jubladb.clientId | default "" | b64enc | quote }} - oauth-jubladb-client-secret: {{ .Values.php.oauth.jubladb.clientSecret | default "" | b64enc | quote }} - oauth-jubladb-base-url: {{ .Values.php.oauth.jubladb.baseUrl | default "" | b64enc | quote }} + {{- if .Values.api.oauth.jubladb.clientId }} + oauth-jubladb-client-id: {{ .Values.api.oauth.jubladb.clientId | default "" | b64enc | quote }} + oauth-jubladb-client-secret: {{ .Values.api.oauth.jubladb.clientSecret | default "" | b64enc | quote }} + oauth-jubladb-base-url: {{ .Values.api.oauth.jubladb.baseUrl | default "" | b64enc | quote }} {{- end }} {{- if .Values.mail.dummyEnabled }} mailer-dsn: {{ .Values.mail.dsn | default (printf "smtp://%s:1025" (include "mail.name" .)) | b64enc | quote }} diff --git a/.helm/ecamp3/templates/hook_db_create.yaml b/.helm/ecamp3/templates/hook_db_create.yaml index 2476163fde..21ee0df1ff 100644 --- a/.helm/ecamp3/templates/hook_db_create.yaml +++ b/.helm/ecamp3/templates/hook_db_create.yaml @@ -23,7 +23,7 @@ spec: restartPolicy: Never containers: - name: db-create-job - image: "{{ .Values.php.image.repository }}:{{ .Values.php.image.tag | default .Values.imageTag }}" + image: "{{ .Values.api.image.repository }}:{{ .Values.api.image.tag | default .Values.imageTag }}" command: ["php", "bin/console", "doctrine:database:create", "--if-not-exists"] env: - name: DATABASE_URL diff --git a/.helm/ecamp3/templates/hook_db_drop.yaml b/.helm/ecamp3/templates/hook_db_drop.yaml index 61fe66531b..d7cb659a88 100644 --- a/.helm/ecamp3/templates/hook_db_drop.yaml +++ b/.helm/ecamp3/templates/hook_db_drop.yaml @@ -23,7 +23,7 @@ spec: restartPolicy: Never containers: - name: db-drop-job - image: "{{ .Values.php.image.repository }}:{{ .Values.php.image.tag | default .Values.imageTag }}" + image: "{{ .Values.api.image.repository }}:{{ .Values.api.image.tag | default .Values.imageTag }}" command: ["php", "bin/console", "doctrine:database:drop", "--if-exists", "-f"] env: - name: DATABASE_URL diff --git a/.helm/ecamp3/templates/hook_db_migrate.yaml b/.helm/ecamp3/templates/hook_db_migrate.yaml index 685ea6b10b..23e8696815 100644 --- a/.helm/ecamp3/templates/hook_db_migrate.yaml +++ b/.helm/ecamp3/templates/hook_db_migrate.yaml @@ -21,7 +21,7 @@ spec: restartPolicy: Never containers: - name: db-migrate-job - {{ template "api.phpContainer" . }} + {{ template "api.container" . }} command: ["migrate-database"] volumes: - name: php-socket diff --git a/.helm/ecamp3/values.yaml b/.helm/ecamp3/values.yaml index 72031c27d8..e60ab9fcb2 100644 --- a/.helm/ecamp3/values.yaml +++ b/.helm/ecamp3/values.yaml @@ -18,19 +18,17 @@ featureToggle: api: subpath: "/api" + image: + repository: "docker.io/ecamp/ecamp3-api" + pullPolicy: IfNotPresent + # Overrides the image tag whose shared default is .Values.imageTag + tag: service: type: ClusterIP port: 3001 metrics: port: 2019 replicaCount: 1 - -php: - image: - repository: "docker.io/ecamp/ecamp3-api-php" - pullPolicy: IfNotPresent - # Overrides the image tag whose shared default is .Values.imageTag - tag: appEnv: prod appDebug: "0" appSecret: "" @@ -41,6 +39,7 @@ php: - "10.0.0.0/8" - "172.16.0.0/12" - "192.168.0.0/16" + caddyGlobalOptions: "" sentryDsn: jwt: passphrase: @@ -67,17 +66,6 @@ php: cpu: 10m memory: 120Mi -caddy: - image: - repository: "docker.io/ecamp/ecamp3-api-caddy" - pullPolicy: IfNotPresent - # Overrides the image tag whose shared default is .Values.imageTag - tag: - resources: - requests: - cpu: 10m - memory: 20Mi - frontend: image: repository: "docker.io/ecamp/ecamp3-frontend" diff --git a/.vscode/launch.json b/.vscode/launch.json index 59a1fa179e..d41e061217 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,7 +12,7 @@ "port": 9003, "log": true, "pathMappings": { - "/srv/api": "${workspaceRoot}/api" + "/app": "${workspaceRoot}/api" } }, { diff --git a/api/.dockerignore b/api/.dockerignore index 40128c8bb1..942ffc005f 100644 --- a/api/.dockerignore +++ b/api/.dockerignore @@ -11,6 +11,10 @@ **/.gitattributes **/.gitignore **/.gitmodules +**/compose.*.yaml +**/compose.*.yml +**/compose.yaml +**/compose.yml **/docker-compose.*.yaml **/docker-compose.*.yml **/docker-compose.yaml diff --git a/api/.vscode/launch.json b/api/.vscode/launch.json index 2e00728428..ee03f1c99b 100644 --- a/api/.vscode/launch.json +++ b/api/.vscode/launch.json @@ -12,7 +12,7 @@ "port": 9003, "log": true, "pathMappings": { - "/srv/api": "${workspaceRoot}" + "/app": "${workspaceRoot}" } }, { diff --git a/api/Dockerfile b/api/Dockerfile index 0de11c3df1..5c53f84667 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -1,49 +1,42 @@ #syntax=docker/dockerfile:1.7 -# the different stages of this Dockerfile are meant to be built into separate images -# https://docs.docker.com/develop/develop-images/multistage-build/#stop-at-a-specific-build-stage -# https://docs.docker.com/compose/compose-file/#target - - -# https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact +# Adapted from https://github.com/api-platform/api-platform/blob/fa1c5808305d7cadbf7b8392e0fddb6e80fb2092/api/Dockerfile # renovate: datasource=docker depName=php ARG PHP_VERSION=8.3.7 -# renovate: datasource=docker depName=alpine -ARG ALPINE_VERSION=3.18 - -# renovate: datasource=docker depName=caddy -ARG CADDY_VERSION=2.7.6 +# Versions +FROM dunglas/frankenphp:1.1.4-php${PHP_VERSION} AS frankenphp_upstream -# "php" stage -FROM php:${PHP_VERSION}-fpm-alpine${ALPINE_VERSION} AS api_platform_php - -# build for production -ARG APP_ENV=prod +# the different stages of this Dockerfile are meant to be built into separate images +# https://docs.docker.com/develop/develop-images/multistage-build/#stop-at-a-specific-build-stage +# https://docs.docker.com/compose/compose-file/#target -WORKDIR /srv/api +# Base FrankenPHP image +FROM frankenphp_upstream AS frankenphp_base -# php extensions installer: https://github.com/mlocati/docker-php-extension-installer -COPY --from=mlocati/php-extension-installer --link /usr/bin/install-php-extensions /usr/local/bin/ +WORKDIR /app # persistent / runtime deps -RUN apk add --no-cache \ +# hadolint ignore=DL3008 +RUN apt-get update && apt-get install --no-install-recommends -y \ acl \ - fcgi \ file \ gettext \ git \ - gnu-libiconv \ patch \ - ; + && rm -rf /var/lib/apt/lists/* -# install gnu-libiconv and set LD_PRELOAD env to make iconv work fully on Alpine image. -# see https://github.com/docker-library/php/issues/240#issuecomment-763112749 -ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so +# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser +ENV COMPOSER_ALLOW_SUPERUSER=1 +ENV COMPOSER_HOME=/tmp/composer +ENV COMPOSER_CACHE_DIR=/tmp/composer/cache +RUN mkdir -p /tmp/composer/cache +RUN chmod ugo+w /tmp/composer/cache RUN set -eux; \ install-php-extensions \ + @composer \ intl \ zip \ apcu \ @@ -57,46 +50,51 @@ RUN set -eux; \ ###< doctrine/doctrine-bundle ### ###< recipes ### -# Copy development php.ini -RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" COPY --link docker/php/conf.d/api-platform.ini $PHP_INI_DIR/conf.d/ -COPY --link docker/php/conf.d/api-platform.prod.ini $PHP_INI_DIR/conf.d/ +COPY --link --chmod=755 docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint +COPY --link --chmod=755 docker/php/migrate-database.sh /usr/local/bin/migrate-database -COPY --link docker/php/php-fpm.d/zz-docker.conf /usr/local/etc/php-fpm.d/zz-docker.conf -COPY --link docker/php/php-fpm.d/www.conf /usr/local/etc/php-fpm.d/www.conf +ENTRYPOINT ["docker-entrypoint"] -RUN mkdir -p /var/run/php +HEALTHCHECK --start-period=60s CMD curl -f http://localhost:2019/metrics || exit 1 +CMD [ "frankenphp", "run", "--config", "/etc/caddy/Caddyfile" ] -COPY --link docker/php/docker-healthcheck.sh /usr/local/bin/docker-healthcheck -RUN chmod +x /usr/local/bin/docker-healthcheck +# Dev FrankenPHP image +FROM frankenphp_base AS frankenphp_dev +ENV APP_ENV=dev XDEBUG_MODE=off -HEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD ["docker-healthcheck"] +RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" -COPY --link docker/php/migrate-database.sh /usr/local/bin/migrate-database -RUN chmod +x /usr/local/bin/migrate-database +COPY --link docker/php/conf.d/api-platform.dev.ini $PHP_INI_DIR/conf.d/ +COPY --link docker/caddy/Caddyfile /etc/caddy/Caddyfile -COPY docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint -RUN chmod +x /usr/local/bin/docker-entrypoint +# renovate: datasource=github-tags depName=xdebug/xdebug +ARG XDEBUG_VERSION=3.3.2 +RUN set -eux; \ + install-php-extensions \ + xdebug-$XDEBUG_VERSION \ + pcov \ + ; -ENTRYPOINT ["docker-entrypoint"] -CMD ["php-fpm"] +CMD [ "frankenphp", "run", "--config", "/etc/caddy/Caddyfile", "--watch" ] -# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser -ENV COMPOSER_ALLOW_SUPERUSER=1 -ENV PATH="${PATH}:/root/.composer/vendor/bin" -ENV COMPOSER_HOME=/tmp/composer -ENV COMPOSER_CACHE_DIR=/tmp/composer/cache -RUN mkdir -p /tmp/composer/cache -RUN chmod ugo+w /tmp/composer/cache +# Prod FrankenPHP image +FROM frankenphp_base AS frankenphp_prod -COPY --from=composer:2.7 /usr/bin/composer /usr/bin/composer +ENV APP_ENV=prod +#ENV FRANKENPHP_CONFIG="import worker.Caddyfile" + +RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" + +COPY --link docker/php/conf.d/api-platform.prod.ini $PHP_INI_DIR/conf.d/ +COPY --link docker/caddy/Caddyfile.prod /etc/caddy/Caddyfile +#COPY --link docker/caddy/worker.Caddyfile /etc/caddy/worker.Caddyfile # prevent the reinstallation of vendors at every changes in the source code -COPY composer.json composer.lock symfony.lock ./ +COPY --link composer.* symfony.* ./ COPY --link patch patch/ RUN set -eux; \ - composer install --prefer-dist --no-dev --no-autoloader --no-scripts --no-progress; \ - composer clear-cache + composer install --no-cache --prefer-dist --no-dev --no-autoloader --no-scripts --no-progress # copy only specifically what we need COPY --link .env ./ @@ -114,36 +112,6 @@ RUN set -eux; \ composer dump-autoload --classmap-authoritative --no-dev; \ composer dump-env prod; \ composer run-script --no-dev post-install-cmd; \ - chmod +x bin/console; sync - - -# Debug stage, for using XDebug -FROM api_platform_php as api_platform_php_dev -ENV APP_ENV=dev XDEBUG_MODE=off - -RUN rm $PHP_INI_DIR/conf.d/api-platform.prod.ini; \ - mv "$PHP_INI_DIR/php.ini" "$PHP_INI_DIR/php.ini-production"; \ - mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" -COPY --link docker/php/conf.d/api-platform.dev.ini $PHP_INI_DIR/conf.d/ - -# renovate: datasource=github-tags depName=xdebug/xdebug -ARG XDEBUG_VERSION=3.3.2 -RUN set -eux; \ - install-php-extensions \ - xdebug-$XDEBUG_VERSION \ - pcov \ - ; - -# "caddy" stage -# depends on the "php" stage above -FROM caddy:${CADDY_VERSION} AS api_platform_caddy - -WORKDIR /srv/api - -COPY --from=api_platform_php --link /srv/api/public public/ -COPY --link docker/caddy/Caddyfile /etc/caddy/Caddyfile - -FROM api_platform_caddy AS api_platform_caddy_prod -COPY --link docker/caddy/Caddyfile.prod /etc/caddy/Caddyfile + chmod +x bin/console; sync; diff --git a/api/bin/console b/api/bin/console index c933dc535d..d8d530e2c3 100755 --- a/api/bin/console +++ b/api/bin/console @@ -4,6 +4,10 @@ use App\Kernel; use Symfony\Bundle\FrameworkBundle\Console\Application; +if (!is_dir(dirname(__DIR__).'/vendor')) { + throw new LogicException('Dependencies are missing. Try running "composer install".'); +} + if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) { throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".'); } diff --git a/api/composer.json b/api/composer.json index aeec50b886..506e148259 100644 --- a/api/composer.json +++ b/api/composer.json @@ -77,7 +77,6 @@ }, "sort-packages": true, "allow-plugins": { - "composer/package-versions-deprecated": true, "cweagans/composer-patches": true, "php-http/discovery": false, "symfony/flex": true, @@ -157,4 +156,4 @@ } } } -} +} \ No newline at end of file diff --git a/api/config/packages/api_platform.yaml b/api/config/packages/api_platform.yaml index c63e72f3e8..a40cf7c6ba 100644 --- a/api/config/packages/api_platform.yaml +++ b/api/config/packages/api_platform.yaml @@ -29,6 +29,9 @@ api_platform: versions: [3] defaults: stateless: true + extra_properties: + standard_put: true + rfc_7807_compliant_errors: false pagination_enabled: false itemOperations: [ 'get', 'patch', 'delete' ] collection_operations: @@ -39,3 +42,4 @@ api_platform: skip_null_values: false order: createTime: DESC + keep_legacy_inflector: false diff --git a/api/config/packages/doctrine.yaml b/api/config/packages/doctrine.yaml index 1f948e1541..fb25b29cac 100644 --- a/api/config/packages/doctrine.yaml +++ b/api/config/packages/doctrine.yaml @@ -18,12 +18,16 @@ doctrine: naming_strategy: App\Util\CamelPascalNamingStrategy auto_mapping: true report_fields_where_declared: true + validate_xml_mapping: false mappings: App: + type: attribute is_bundle: false dir: '%kernel.project_dir%/src/Entity' prefix: 'App\Entity' alias: App + controller_resolver: + auto_mapping: true schema_ignore_classes: - App\Entity\CampRootContentNode diff --git a/api/config/packages/framework.yaml b/api/config/packages/framework.yaml index 321c4496e3..e3ef193849 100644 --- a/api/config/packages/framework.yaml +++ b/api/config/packages/framework.yaml @@ -2,12 +2,12 @@ framework: secret: '%env(APP_SECRET)%' #csrf_protection: true + annotations: false http_method_override: false handle_all_throwables: true trusted_proxies: '%env(TRUSTED_PROXIES)%' trusted_hosts: - localhost - - caddy - '%env(ADDITIONAL_TRUSTED_HOSTS)%' # See https://caddyserver.com/docs/caddyfile/directives/reverse_proxy#headers trusted_headers: diff --git a/api/config/packages/twig.yaml b/api/config/packages/twig.yaml index f9f4cc539b..3f795d921e 100644 --- a/api/config/packages/twig.yaml +++ b/api/config/packages/twig.yaml @@ -1,5 +1,5 @@ twig: - default_path: '%kernel.project_dir%/templates' + file_name_pattern: '*.twig' when@test: twig: diff --git a/api/docker/caddy/Caddyfile b/api/docker/caddy/Caddyfile index 2a080206d7..bf5924d1f5 100644 --- a/api/docker/caddy/Caddyfile +++ b/api/docker/caddy/Caddyfile @@ -1,6 +1,12 @@ { - # Debug - {$CADDY_DEBUG} + {$CADDY_GLOBAL_OPTIONS} + + frankenphp { + {$FRANKENPHP_CONFIG} + } + + # https://caddyserver.com/docs/caddyfile/directives#sorting-algorithm + order php_server before file_server auto_https disable_redirects # make it possible to connect from remote host to admin endpoint @@ -14,6 +20,8 @@ } } +{$CADDY_EXTRA_CONFIG} + :3000 { log { level DEBUG @@ -44,15 +52,32 @@ :3001 { route { - root * /srv/api/public + root * /app/public + + encode { + zstd + br + gzip + + match { + header Content-Type text/* + header Content-Type application/json* + header Content-Type application/javascript* + header Content-Type application/xhtml+xml* + header Content-Type application/atom+xml* + header Content-Type application/rss+xml* + header Content-Type image/svg+xml* + # Custom formats supported + header Content-Type application/ld+json* + } + } # Add links to the API docs if not set explicitly (e.g. the PWA) header ?Link `; rel="www.w3.org/ns/hydra/core#apiDocumentation"` - php_fastcgi unix//var/run/php/php-fpm.sock { - env HTTP_X_FORWARDED_PREFIX {header.X-Forwarded-Prefix} - } - encode zstd gzip - file_server + # Disable Topics tracking if not enabled explicitly: https://github.com/jkarlin/topics + header ?Permissions-Policy "browsing-topics=()" + + php_server } } diff --git a/api/docker/caddy/Caddyfile.prod b/api/docker/caddy/Caddyfile.prod index e8ed39a389..4311891b43 100644 --- a/api/docker/caddy/Caddyfile.prod +++ b/api/docker/caddy/Caddyfile.prod @@ -1,6 +1,12 @@ { - # Debug - {$CADDY_DEBUG} + {$CADDY_GLOBAL_OPTIONS} + + frankenphp { + {$FRANKENPHP_CONFIG} + } + + # https://caddyserver.com/docs/caddyfile/directives#sorting-algorithm + order php_server before file_server http_port 3001 https_port 3443 @@ -16,19 +22,38 @@ } } -{$SERVER_NAME} +{$CADDY_EXTRA_CONFIG} + + +{$SERVER_NAME:localhost} { + log -log + root * /app/public -route { - root * /srv/api/public + encode { + zstd + br + gzip + + match { + header Content-Type text/* + header Content-Type application/json* + header Content-Type application/javascript* + header Content-Type application/xhtml+xml* + header Content-Type application/atom+xml* + header Content-Type application/rss+xml* + header Content-Type image/svg+xml* + # Custom formats supported + header Content-Type application/ld+json* + header Content-Type application/hal+json* + } + } # Add links to the API docs if not set explicitly (e.g. the PWA) header ?Link `; rel="http://www.w3.org/ns/hydra/core#apiDocumentation"` - php_fastcgi unix//var/run/php/php-fpm.sock { - env HTTP_X_FORWARDED_PREFIX {header.X-Forwarded-Prefix} - } - encode zstd gzip - file_server + # Disable Topics tracking if not enabled explicitly: https://github.com/jkarlin/topics + header ?Permissions-Policy "browsing-topics=()" + + php_server } diff --git a/api/docker/php/conf.d/api-platform.dev.ini b/api/docker/php/conf.d/api-platform.dev.ini index 91eb01519c..ea217ae806 100644 --- a/api/docker/php/conf.d/api-platform.dev.ini +++ b/api/docker/php/conf.d/api-platform.dev.ini @@ -2,4 +2,4 @@ ; See https://github.com/docker/for-linux/issues/264 ; The `client_host` below may optionally be replaced with `discover_client_host=yes` ; Add `start_with_request=yes` to start debug session on each request -xdebug.client_host = 'host.docker.internal' \ No newline at end of file +xdebug.client_host = host.docker.internal \ No newline at end of file diff --git a/api/docker/php/conf.d/api-platform.prod.ini b/api/docker/php/conf.d/api-platform.prod.ini index 85ba89ea05..1986286e80 100644 --- a/api/docker/php/conf.d/api-platform.prod.ini +++ b/api/docker/php/conf.d/api-platform.prod.ini @@ -1,2 +1,2 @@ -opcache.preload_user=www-data -opcache.preload=/srv/api/config/preload.php +opcache.preload_user=root +opcache.preload=/app/config/preload.php diff --git a/api/docker/php/docker-entrypoint.sh b/api/docker/php/docker-entrypoint.sh index 2f245f6aa5..6fd12c7659 100755 --- a/api/docker/php/docker-entrypoint.sh +++ b/api/docker/php/docker-entrypoint.sh @@ -1,12 +1,7 @@ #!/bin/sh set -e -# first arg is `-f` or `--some-option` -if [ "${1#-}" != "$1" ]; then - set -- php-fpm "$@" -fi - -if [ "$1" = 'php-fpm' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ] || [ "$1" = 'composer' ] || [ "$1" = 'bin/phpunit' ]; then +if [ "$1" = 'frankenphp' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ] || [ "$1" = 'composer' ] || [ "$1" = 'bin/phpunit' ]; then if [ "$APP_ENV" = 'prod' ]; then setfacl -R -m u:www-data:rwX -m u:"$(whoami)":rwX var @@ -28,7 +23,7 @@ if [ "$1" = 'php-fpm' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ] || [ "$1 composer install --prefer-dist --no-progress --no-interaction - if grep -q DATABASE_URL= .env; then + if grep -q ^DATABASE_URL= .env; then migrate-database || exit 1 migrate-database -e test || exit 1 fi diff --git a/api/docker/php/docker-healthcheck.sh b/api/docker/php/docker-healthcheck.sh deleted file mode 100755 index f322de5b47..0000000000 --- a/api/docker/php/docker-healthcheck.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -set -e - -if env -i REQUEST_METHOD=GET SCRIPT_NAME=/ping SCRIPT_FILENAME=/ping cgi-fcgi -bind -connect /var/run/php/php-fpm.sock; then - exit 0 -fi - -exit 1 diff --git a/api/docker/php/migrate-database.sh b/api/docker/php/migrate-database.sh index 7de3d4df3f..1c19591556 100755 --- a/api/docker/php/migrate-database.sh +++ b/api/docker/php/migrate-database.sh @@ -23,5 +23,5 @@ else fi if [ "$( find ./migrations -iname '*.php' -print -quit )" ]; then - php bin/console doctrine:migrations:migrate --no-interaction "$@" + php bin/console doctrine:migrations:migrate --no-interaction --all-or-nothing "$@" fi diff --git a/api/docker/php/php-fpm.d/www.conf b/api/docker/php/php-fpm.d/www.conf deleted file mode 100644 index d183a34938..0000000000 --- a/api/docker/php/php-fpm.d/www.conf +++ /dev/null @@ -1,463 +0,0 @@ -; Start a new pool named 'www'. -; the variable $pool can be used in any directive and will be replaced by the -; pool name ('www' here) -[www] - -; Per pool prefix -; It only applies on the following directives: -; - 'access.log' -; - 'slowlog' -; - 'listen' (unixsocket) -; - 'chroot' -; - 'chdir' -; - 'php_values' -; - 'php_admin_values' -; When not set, the global prefix (or NONE) applies instead. -; Note: This directive can also be relative to the global prefix. -; Default Value: none -;prefix = /path/to/pools/$pool - -; Unix user/group of processes -; Note: The user is mandatory. If the group is not set, the default user's group -; will be used. -user = www-data -group = www-data - -; The address on which to accept FastCGI requests. -; Valid syntaxes are: -; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on -; a specific port; -; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on -; a specific port; -; 'port' - to listen on a TCP socket to all addresses -; (IPv6 and IPv4-mapped) on a specific port; -; '/path/to/unix/socket' - to listen on a unix socket. -; Note: This value is mandatory. -listen = 127.0.0.1:9000 - -; Set listen(2) backlog. -; Default Value: 511 (-1 on FreeBSD and OpenBSD) -;listen.backlog = 511 - -; Set permissions for unix socket, if one is used. In Linux, read/write -; permissions must be set in order to allow connections from a web server. Many -; BSD-derived systems allow connections regardless of permissions. The owner -; and group can be specified either by name or by their numeric IDs. -; Default Values: user and group are set as the running user -; mode is set to 0660 -;listen.owner = www-data -;listen.group = www-data -;listen.mode = 0660 -; When POSIX Access Control Lists are supported you can set them using -; these options, value is a comma separated list of user/group names. -; When set, listen.owner and listen.group are ignored -;listen.acl_users = -;listen.acl_groups = - -; List of addresses (IPv4/IPv6) of FastCGI clients which are allowed to connect. -; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original -; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address -; must be separated by a comma. If this value is left blank, connections will be -; accepted from any ip address. -; Default Value: any -;listen.allowed_clients = 127.0.0.1 - -; Specify the nice(2) priority to apply to the pool processes (only if set) -; The value can vary from -19 (highest priority) to 20 (lower priority) -; Note: - It will only work if the FPM master process is launched as root -; - The pool processes will inherit the master process priority -; unless it specified otherwise -; Default Value: no set -; process.priority = -19 - -; Set the process dumpable flag (PR_SET_DUMPABLE prctl) even if the process user -; or group is different than the master process user. It allows to create process -; core dump and ptrace the process for the pool user. -; Default Value: no -; process.dumpable = yes - -; Choose how the process manager will control the number of child processes. -; Possible Values: -; static - a fixed number (pm.max_children) of child processes; -; dynamic - the number of child processes are set dynamically based on the -; following directives. With this process management, there will be -; always at least 1 children. -; pm.max_children - the maximum number of children that can -; be alive at the same time. -; pm.start_servers - the number of children created on startup. -; pm.min_spare_servers - the minimum number of children in 'idle' -; state (waiting to process). If the number -; of 'idle' processes is less than this -; number then some children will be created. -; pm.max_spare_servers - the maximum number of children in 'idle' -; state (waiting to process). If the number -; of 'idle' processes is greater than this -; number then some children will be killed. -; pm.max_spawn_rate - the maximum number of rate to spawn child -; processes at once. -; ondemand - no children are created at startup. Children will be forked when -; new requests will connect. The following parameter are used: -; pm.max_children - the maximum number of children that -; can be alive at the same time. -; pm.process_idle_timeout - The number of seconds after which -; an idle process will be killed. -; Note: This value is mandatory. -pm = static - -; The number of child processes to be created when pm is set to 'static' and the -; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'. -; This value sets the limit on the number of simultaneous requests that will be -; served. Equivalent to the ApacheMaxClients directive with mpm_prefork. -; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP -; CGI. The below defaults are based on a server without much resources. Don't -; forget to tweak pm.* to fit your needs. -; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand' -; Note: This value is mandatory. -pm.max_children = 6 - -; The number of child processes created on startup. -; Note: Used only when pm is set to 'dynamic' -; Default Value: (min_spare_servers + max_spare_servers) / 2 -;pm.start_servers = 2 - -; The desired minimum number of idle server processes. -; Note: Used only when pm is set to 'dynamic' -; Note: Mandatory when pm is set to 'dynamic' -;pm.min_spare_servers = 1 - -; The desired maximum number of idle server processes. -; Note: Used only when pm is set to 'dynamic' -; Note: Mandatory when pm is set to 'dynamic' -;pm.max_spare_servers = 3 - -; The number of rate to spawn child processes at once. -; Note: Used only when pm is set to 'dynamic' -; Note: Mandatory when pm is set to 'dynamic' -; Default Value: 32 -;pm.max_spawn_rate = 32 - -; The number of seconds after which an idle process will be killed. -; Note: Used only when pm is set to 'ondemand' -; Default Value: 10s -;pm.process_idle_timeout = 10s; - -; The number of requests each child process should execute before respawning. -; This can be useful to work around memory leaks in 3rd party libraries. For -; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS. -; Default Value: 0 -pm.max_requests = 1000 - -; The URI to view the FPM status page. If this value is not set, no URI will be -; recognized as a status page. It shows the following information: -; pool - the name of the pool; -; process manager - static, dynamic or ondemand; -; start time - the date and time FPM has started; -; start since - number of seconds since FPM has started; -; accepted conn - the number of request accepted by the pool; -; listen queue - the number of request in the queue of pending -; connections (see backlog in listen(2)); -; max listen queue - the maximum number of requests in the queue -; of pending connections since FPM has started; -; listen queue len - the size of the socket queue of pending connections; -; idle processes - the number of idle processes; -; active processes - the number of active processes; -; total processes - the number of idle + active processes; -; max active processes - the maximum number of active processes since FPM -; has started; -; max children reached - number of times, the process limit has been reached, -; when pm tries to start more children (works only for -; pm 'dynamic' and 'ondemand'); -; Value are updated in real time. -; Example output: -; pool: www -; process manager: static -; start time: 01/Jul/2011:17:53:49 +0200 -; start since: 62636 -; accepted conn: 190460 -; listen queue: 0 -; max listen queue: 1 -; listen queue len: 42 -; idle processes: 4 -; active processes: 11 -; total processes: 15 -; max active processes: 12 -; max children reached: 0 -; -; By default the status page output is formatted as text/plain. Passing either -; 'html', 'xml' or 'json' in the query string will return the corresponding -; output syntax. Example: -; http://www.foo.bar/status -; http://www.foo.bar/status?json -; http://www.foo.bar/status?html -; http://www.foo.bar/status?xml -; -; By default the status page only outputs short status. Passing 'full' in the -; query string will also return status for each pool process. -; Example: -; http://www.foo.bar/status?full -; http://www.foo.bar/status?json&full -; http://www.foo.bar/status?html&full -; http://www.foo.bar/status?xml&full -; The Full status returns for each process: -; pid - the PID of the process; -; state - the state of the process (Idle, Running, ...); -; start time - the date and time the process has started; -; start since - the number of seconds since the process has started; -; requests - the number of requests the process has served; -; request duration - the duration in µs of the requests; -; request method - the request method (GET, POST, ...); -; request URI - the request URI with the query string; -; content length - the content length of the request (only with POST); -; user - the user (PHP_AUTH_USER) (or '-' if not set); -; script - the main script called (or '-' if not set); -; last request cpu - the %cpu the last request consumed -; it's always 0 if the process is not in Idle state -; because CPU calculation is done when the request -; processing has terminated; -; last request memory - the max amount of memory the last request consumed -; it's always 0 if the process is not in Idle state -; because memory calculation is done when the request -; processing has terminated; -; If the process is in Idle state, then informations are related to the -; last request the process has served. Otherwise informations are related to -; the current request being served. -; Example output: -; ************************ -; pid: 31330 -; state: Running -; start time: 01/Jul/2011:17:53:49 +0200 -; start since: 63087 -; requests: 12808 -; request duration: 1250261 -; request method: GET -; request URI: /test_mem.php?N=10000 -; content length: 0 -; user: - -; script: /home/fat/web/docs/php/test_mem.php -; last request cpu: 0.00 -; last request memory: 0 -; -; Note: There is a real-time FPM status monitoring sample web page available -; It's available in: /usr/local/share/php/fpm/status.html -; -; Note: The value must start with a leading slash (/). The value can be -; anything, but it may not be a good idea to use the .php extension or it -; may conflict with a real PHP file. -; Default Value: not set -;pm.status_path = /status - -; The address on which to accept FastCGI status request. This creates a new -; invisible pool that can handle requests independently. This is useful -; if the main pool is busy with long running requests because it is still possible -; to get the status before finishing the long running requests. -; -; Valid syntaxes are: -; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on -; a specific port; -; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on -; a specific port; -; 'port' - to listen on a TCP socket to all addresses -; (IPv6 and IPv4-mapped) on a specific port; -; '/path/to/unix/socket' - to listen on a unix socket. -; Default Value: value of the listen option -;pm.status_listen = 127.0.0.1:9001 - -; The ping URI to call the monitoring page of FPM. If this value is not set, no -; URI will be recognized as a ping page. This could be used to test from outside -; that FPM is alive and responding, or to -; - create a graph of FPM availability (rrd or such); -; - remove a server from a group if it is not responding (load balancing); -; - trigger alerts for the operating team (24/7). -; Note: The value must start with a leading slash (/). The value can be -; anything, but it may not be a good idea to use the .php extension or it -; may conflict with a real PHP file. -; Default Value: not set -;ping.path = /ping - -; This directive may be used to customize the response of a ping request. The -; response is formatted as text/plain with a 200 response code. -; Default Value: pong -;ping.response = pong - -; The access log file -; Default: not set -;access.log = log/$pool.access.log - -; The access log format. -; The following syntax is allowed -; %%: the '%' character -; %C: %CPU used by the request -; it can accept the following format: -; - %{user}C for user CPU only -; - %{system}C for system CPU only -; - %{total}C for user + system CPU (default) -; %d: time taken to serve the request -; it can accept the following format: -; - %{seconds}d (default) -; - %{milliseconds}d -; - %{milli}d -; - %{microseconds}d -; - %{micro}d -; %e: an environment variable (same as $_ENV or $_SERVER) -; it must be associated with embraces to specify the name of the env -; variable. Some examples: -; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e -; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e -; %f: script filename -; %l: content-length of the request (for POST request only) -; %m: request method -; %M: peak of memory allocated by PHP -; it can accept the following format: -; - %{bytes}M (default) -; - %{kilobytes}M -; - %{kilo}M -; - %{megabytes}M -; - %{mega}M -; %n: pool name -; %o: output header -; it must be associated with embraces to specify the name of the header: -; - %{Content-Type}o -; - %{X-Powered-By}o -; - %{Transfert-Encoding}o -; - .... -; %p: PID of the child that serviced the request -; %P: PID of the parent of the child that serviced the request -; %q: the query string -; %Q: the '?' character if query string exists -; %r: the request URI (without the query string, see %q and %Q) -; %R: remote IP address -; %s: status (response code) -; %t: server time the request was received -; it can accept a strftime(3) format: -; %d/%b/%Y:%H:%M:%S %z (default) -; The strftime(3) format must be encapsulated in a %{}t tag -; e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t -; %T: time the log has been written (the request has finished) -; it can accept a strftime(3) format: -; %d/%b/%Y:%H:%M:%S %z (default) -; The strftime(3) format must be encapsulated in a %{}t tag -; e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t -; %u: remote user -; -; Default: "%R - %u %t \"%m %r\" %s" -;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{milli}d %{kilo}M %C%%" - -; The log file for slow requests -; Default Value: not set -; Note: slowlog is mandatory if request_slowlog_timeout is set -;slowlog = log/$pool.log.slow - -; The timeout for serving a single request after which a PHP backtrace will be -; dumped to the 'slowlog' file. A value of '0s' means 'off'. -; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) -; Default Value: 0 -;request_slowlog_timeout = 0 - -; Depth of slow log stack trace. -; Default Value: 20 -;request_slowlog_trace_depth = 20 - -; The timeout for serving a single request after which the worker process will -; be killed. This option should be used when the 'max_execution_time' ini option -; does not stop script execution for some reason. A value of '0' means 'off'. -; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) -; Default Value: 0 -;request_terminate_timeout = 0 - -; The timeout set by 'request_terminate_timeout' ini option is not engaged after -; application calls 'fastcgi_finish_request' or when application has finished and -; shutdown functions are being called (registered via register_shutdown_function). -; This option will enable timeout limit to be applied unconditionally -; even in such cases. -; Default Value: no -;request_terminate_timeout_track_finished = no - -; Set open file descriptor rlimit. -; Default Value: system defined value -;rlimit_files = 1024 - -; Set max core size rlimit. -; Possible Values: 'unlimited' or an integer greater or equal to 0 -; Default Value: system defined value -;rlimit_core = 0 - -; Chroot to this directory at the start. This value must be defined as an -; absolute path. When this value is not set, chroot is not used. -; Note: you can prefix with '$prefix' to chroot to the pool prefix or one -; of its subdirectories. If the pool prefix is not set, the global prefix -; will be used instead. -; Note: chrooting is a great security feature and should be used whenever -; possible. However, all PHP paths will be relative to the chroot -; (error_log, sessions.save_path, ...). -; Default Value: not set -;chroot = - -; Chdir to this directory at the start. -; Note: relative path can be used. -; Default Value: current directory or / when chroot -;chdir = /var/www - -; Redirect worker stdout and stderr into main error log. If not set, stdout and -; stderr will be redirected to /dev/null according to FastCGI specs. -; Note: on highloaded environment, this can cause some delay in the page -; process time (several ms). -; Default Value: no -;catch_workers_output = yes - -; Decorate worker output with prefix and suffix containing information about -; the child that writes to the log and if stdout or stderr is used as well as -; log level and time. This options is used only if catch_workers_output is yes. -; Settings to "no" will output data as written to the stdout or stderr. -; Default value: yes -;decorate_workers_output = no - -; Clear environment in FPM workers -; Prevents arbitrary environment variables from reaching FPM worker processes -; by clearing the environment in workers before env vars specified in this -; pool configuration are added. -; Setting to "no" will make all environment variables available to PHP code -; via getenv(), $_ENV and $_SERVER. -; Default Value: yes -;clear_env = no - -; Limits the extensions of the main script FPM will allow to parse. This can -; prevent configuration mistakes on the web server side. You should only limit -; FPM to .php extensions to prevent malicious users to use other extensions to -; execute php code. -; Note: set an empty value to allow all extensions. -; Default Value: .php -;security.limit_extensions = .php .php3 .php4 .php5 .php7 - -; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from -; the current environment. -; Default Value: clean env -;env[HOSTNAME] = $HOSTNAME -;env[PATH] = /usr/local/bin:/usr/bin:/bin -;env[TMP] = /tmp -;env[TMPDIR] = /tmp -;env[TEMP] = /tmp - -; Additional php.ini defines, specific to this pool of workers. These settings -; overwrite the values previously defined in the php.ini. The directives are the -; same as the PHP SAPI: -; php_value/php_flag - you can set classic ini defines which can -; be overwritten from PHP call 'ini_set'. -; php_admin_value/php_admin_flag - these directives won't be overwritten by -; PHP call 'ini_set' -; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no. - -; Defining 'extension' will load the corresponding shared extension from -; extension_dir. Defining 'disable_functions' or 'disable_classes' will not -; overwrite previously defined php.ini values, but will append the new value -; instead. - -; Note: path INI options can be relative and will be expanded with the prefix -; (pool, global or /usr/local) - -; Default Value: nothing is defined by default except the values in php.ini and -; specified at startup with the -d argument -;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com -;php_flag[display_errors] = off -;php_admin_value[error_log] = /var/log/fpm-php.www.log -;php_admin_flag[log_errors] = on -;php_admin_value[memory_limit] = 32M \ No newline at end of file diff --git a/api/docker/php/php-fpm.d/zz-docker.conf b/api/docker/php/php-fpm.d/zz-docker.conf deleted file mode 100644 index 9f454cdadd..0000000000 --- a/api/docker/php/php-fpm.d/zz-docker.conf +++ /dev/null @@ -1,8 +0,0 @@ -[global] -daemonize = no -process_control_timeout = 20 - -[www] -listen = /var/run/php/php-fpm.sock -listen.mode = 0666 -ping.path = /ping diff --git a/api/docker/varnish/vcl/_config.vcl b/api/docker/varnish/vcl/_config.vcl index 1f81b8bdab..980a1cac54 100644 --- a/api/docker/varnish/vcl/_config.vcl +++ b/api/docker/varnish/vcl/_config.vcl @@ -1,4 +1,4 @@ backend default { - .host = "caddy"; + .host = "api"; .port = "3000"; } \ No newline at end of file diff --git a/api/phpunit.xml.dist b/api/phpunit.xml.dist index ddab476963..33057b2e7c 100644 --- a/api/phpunit.xml.dist +++ b/api/phpunit.xml.dist @@ -32,12 +32,7 @@ - - + src diff --git a/api/symfony.lock b/api/symfony.lock index b2e17ac9f2..af5c74d665 100644 --- a/api/symfony.lock +++ b/api/symfony.lock @@ -342,9 +342,6 @@ "phpmyadmin/sql-parser": { "version": "5.5.0" }, - "phpspec/prophecy": { - "version": "1.14.0" - }, "phpstan/phpstan": { "version": "1.1.2" }, diff --git a/api/tests/bootstrap.php b/api/tests/bootstrap.php index 3181151d9a..47a58557dc 100644 --- a/api/tests/bootstrap.php +++ b/api/tests/bootstrap.php @@ -4,9 +4,7 @@ require dirname(__DIR__).'/vendor/autoload.php'; -if (file_exists(dirname(__DIR__).'/config/bootstrap.php')) { - require dirname(__DIR__).'/config/bootstrap.php'; -} elseif (method_exists(Dotenv::class, 'bootEnv')) { +if (method_exists(Dotenv::class, 'bootEnv')) { (new Dotenv())->bootEnv(dirname(__DIR__).'/.env'); } diff --git a/api/var/.gitignore b/api/var/.gitignore deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docker-compose.yml b/docker-compose.yml index 28d786a5b6..50fc864518 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -24,21 +24,29 @@ services: depends_on: - pdf - php: - image: ecamp/ecamp3-dev-api-php + api: + image: ecamp/ecamp3-dev-api build: context: ./api - target: api_platform_php_dev + target: frankenphp_dev cache_from: - - ecamp/ecamp3-dev-api-php - container_name: 'ecamp3-api-php' + - ecamp/ecamp3-dev-api + container_name: 'ecamp3-api' depends_on: - database - docker-host - restart: unless-stopped + ports: + - target: 3000 + published: 3000 + protocol: tcp + - target: 2019 + published: 2019 + protocol: tcp volumes: - - ./.caddy/php-socket:/var/run/php - - ./api:/srv/api:rw,delegated + - ./api:/app:rw,delegated + - caddy_data:/data + - caddy_config:/config + - ./api/docker/caddy/Caddyfile:/etc/caddy/Caddyfile:ro - ./api/docker/php/conf.d/api-platform.dev.ini:/usr/local/etc/php/conf.d/api-platform.ini:delegated - ./api/docker/php/docker-entrypoint.sh:/usr/local/bin/docker-entrypoint:delegated - ./.cache/composer:/tmp/composer/cache:delegated @@ -65,37 +73,11 @@ services: extra_hosts: - 'host.docker.internal:host-gateway' - caddy: - image: ecamp/ecamp3-dev-api-caddy - build: - context: ./api - target: api_platform_caddy - cache_from: - - ecamp/ecamp3-dev-api-caddy - container_name: 'ecamp3-api-caddy' - depends_on: - - php - ports: - - target: 3000 - published: 3000 - protocol: tcp - - target: 2019 - published: 2019 - protocol: tcp - restart: unless-stopped - user: ${USER_ID:-1000} - volumes: - - ./.caddy/php-socket:/var/run/php - - ./.caddy/data:/data:delegated - - ./.caddy/config-cache:/config:delegated - - ./api/docker/caddy/Caddyfile:/etc/caddy/Caddyfile:ro - - ./api/public:/srv/api/public:ro - http-cache: image: varnish:7.5.0 container_name: 'ecamp3-http-cache' depends_on: - - caddy + - api volumes: - ./api/docker/varnish/vcl/:/etc/varnish/:ro ports: @@ -219,3 +201,5 @@ services: volumes: db-data-postgres: null + caddy_data: + caddy_config: diff --git a/pre-commit.sh b/pre-commit.sh index 37dc2ee5ce..ccccd62fed 100644 --- a/pre-commit.sh +++ b/pre-commit.sh @@ -30,7 +30,7 @@ execute_or_run() { execute_or_run "frontend" "ecamp3-frontend" "frontend" "npm run lint" & # API/PHP -execute_or_run "api" "ecamp3-api-php" "php" "composer cs-fix" & +execute_or_run "api" "ecamp3-api" "php" "composer cs-fix" & # Print execute_or_run "print" "ecamp3-print" "print" "npm run lint" & diff --git a/print/nuxt.config.js b/print/nuxt.config.js index 8bcf2c6d63..1e6b7fac32 100644 --- a/print/nuxt.config.js +++ b/print/nuxt.config.js @@ -63,7 +63,7 @@ export default defineNuxtConfig({ basicAuthToken: null, browserWsEndpoint: 'ws://browserless:3000', printUrl: 'http://print:3003/print', - internalApiRootUrl: 'http://caddy:3000/api', + internalApiRootUrl: 'http://api:3000/api', cookiePrefix: 'localhost_', renderHtmlTimeoutMs: null, renderPdfTimeoutMs: null,