Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ MANTICORE_PORT=9312
APP_ENV=dev
# Set secret in .env.local
APP_SECRET=7dfa1f3adbe7f25c8c085ee1f74f816a
#TRUSTED_PROXIES=127.0.0.1,127.0.0.2
TRUSTED_PROXIES=REMOTE_ADDR
#TRUSTED_HOSTS=localhost,example.com
###< symfony/framework-bundle ###

Expand Down
267 changes: 267 additions & 0 deletions .github/workflows/build-image-beta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
name: Build and publish beta image

# Builds the production images for the feature/docker-beta branch (PHP-FPM + Nginx
# architecture, master-based) and pushes them to GHCR. Dispatches to sysadmins-infra
# on success so the beta stack can be manually redeployed.
#
# Does NOT auto-deploy — the deploy-bewelcome-beta.yml workflow on sysadmins-infra
# is triggered manually or via the repository_dispatch.
#
# Two images are published:
# ghcr.io/bewelcome/rox:docker-beta — PHP-FPM (bewelcome_php target)
# ghcr.io/bewelcome/rox:docker-beta-web — Nginx (bewelcome_nginx target)

on:
push:
branches: [feature/docker-beta]
paths:
- 'Dockerfile'
- '.dockerignore'
- 'docker/**'
- 'composer.json'
- 'composer.lock'
- 'symfony.lock'
- 'package.json'
- 'yarn.lock'
- 'webpack.config.js'
- 'src/**'
- 'assets/**'
- 'config/**'
- 'templates/**'
- 'public/**'
- 'bin/**'
- 'migrations/**'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed (old migrations all already applied on production DB).

- '.trivyignore'
- '.github/workflows/build-image-beta.yml'
workflow_dispatch: {}

permissions:
contents: read
packages: write
actions: read

env:
IMAGE: ghcr.io/bewelcome/rox

concurrency:
group: build-image-beta-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Build ${{ matrix.prefix }} ${{ matrix.arch }}
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- {arch: amd64, platform: linux/amd64, runner: ubuntu-latest, target: bewelcome_php, prefix: php}
- {arch: arm64, platform: linux/arm64, runner: ubuntu-24.04-arm, target: bewelcome_php, prefix: php}
- {arch: amd64, platform: linux/amd64, runner: ubuntu-latest, target: bewelcome_nginx, prefix: nginx}
- {arch: arm64, platform: linux/arm64, runner: ubuntu-24.04-arm, target: bewelcome_nginx, prefix: nginx}
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # tag=v4.2.2

- name: Compute version metadata
id: version
run: |
echo "revision=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
echo "timestamp=$(git log -n 1 --format=%ct)" >> "$GITHUB_OUTPUT"

- name: Log in to GitHub Container Registry
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # tag=v3.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract image metadata
id: meta
uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # tag=v5.6.1
with:
images: ${{ env.IMAGE }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # tag=v3.8.0

- name: Build and push by digest
id: build
uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # tag=v6.9.0
with:
context: .
target: ${{ matrix.target }}
platforms: ${{ matrix.platform }}
build-args: |
APP_VERSION=${{ steps.version.outputs.revision }}
APP_VERSION_TIMESTAMP=${{ steps.version.outputs.timestamp }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=beta-${{ matrix.prefix }}-${{ matrix.arch }}
cache-to: type=gha,mode=max,scope=beta-${{ matrix.prefix }}-${{ matrix.arch }}
outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=true

- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"

- name: Upload digest
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # tag=v4.6.2
with:
name: digests-${{ matrix.prefix }}-${{ matrix.arch }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1

merge-php:
name: Push PHP manifest
runs-on: ubuntu-latest
needs: [build]
outputs:
short_sha: ${{ steps.vars.outputs.short_sha }}
digest: ${{ steps.manifest.outputs.digest }}
steps:
- name: Download PHP digests
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # tag=v4.1.8
with:
path: /tmp/digests
pattern: digests-php-*
merge-multiple: true

- name: Log in to GitHub Container Registry
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # tag=v3.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # tag=v3.8.0

- name: Extract image metadata
id: meta
uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # tag=v5.6.1
with:
images: ${{ env.IMAGE }}
tags: |
type=sha,prefix=sha-
type=raw,value=docker-beta

- name: Create and push multi-arch manifest
working-directory: /tmp/digests
run: |
docker buildx imagetools create \
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.IMAGE }}@sha256:%s ' *)

- name: Compute short sha
id: vars
run: echo "short_sha=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"

- name: Capture manifest digest
id: manifest
run: |
digest=$(docker buildx imagetools inspect "${{ env.IMAGE }}:sha-${{ steps.vars.outputs.short_sha }}" --format '{{json .Manifest.Digest}}' | tr -d '"')
echo "digest=$digest" >> "$GITHUB_OUTPUT"

merge-nginx:
name: Push Nginx manifest
runs-on: ubuntu-latest
needs: [build]
steps:
- name: Download Nginx digests
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # tag=v4.1.8
with:
path: /tmp/digests
pattern: digests-nginx-*
merge-multiple: true

- name: Log in to GitHub Container Registry
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # tag=v3.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # tag=v3.8.0

- name: Extract image metadata
id: meta
uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # tag=v5.6.1
with:
images: ${{ env.IMAGE }}
tags: |
type=sha,prefix=sha-,suffix=-web
type=raw,value=docker-beta-web

- name: Create and push multi-arch manifest
working-directory: /tmp/digests
run: |
docker buildx imagetools create \
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.IMAGE }}@sha256:%s ' *)

scan:
name: Scan image
runs-on: ubuntu-latest
needs: [merge-php]
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # tag=v4.1.7

- name: Log in to GitHub Container Registry
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # tag=v3.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # tag=v0.36.0
env:
TRIVY_DISABLE_VEX_NOTICE: '1'
with:
image-ref: ${{ env.IMAGE }}:sha-${{ needs.merge-php.outputs.short_sha }}
format: table
severity: CRITICAL,HIGH,MEDIUM
exit-code: '1'
ignore-unfixed: true
trivyignores: .trivyignore
version: v0.74.0

notify:
name: Notify sysadmins-infra
runs-on: ubuntu-latest
needs: [merge-php, merge-nginx, scan]
if: >
github.event_name == 'push' &&
github.ref == 'refs/heads/feature/docker-beta' &&
needs.merge-php.result == 'success' &&
needs.merge-nginx.result == 'success' &&
needs.scan.result == 'success'
steps:
- name: Mint cross-repo token
id: app-token
uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # tag=v1.11.0
with:
app-id: ${{ secrets.DEPLOY_APP_ID }}
private-key: ${{ secrets.DEPLOY_APP_PRIVATE_KEY }}
owner: BeWelcome
repositories: sysadmins-infra

- name: Notify sysadmins-infra of new beta image
uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # tag=v3.0.0
with:
token: ${{ steps.app-token.outputs.token }}
repository: BeWelcome/sysadmins-infra
event-type: rox-beta-image-pushed
client-payload: |
{
"image": "${{ env.IMAGE }}:sha-${{ needs.merge-php.outputs.short_sha }}@${{ needs.merge-php.outputs.digest }}",
"web_image": "${{ env.IMAGE }}:sha-${{ needs.merge-php.outputs.short_sha }}-web",
"tag": "sha-${{ needs.merge-php.outputs.short_sha }}",
"sha": "${{ github.sha }}",
"ref": "${{ github.ref }}"
}
15 changes: 0 additions & 15 deletions .github/workflows/gitlab-mirror.yml

This file was deleted.

11 changes: 11 additions & 0 deletions .trivyignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# CVE-2026-58055: nghttp2-libs 1.69.0-r0 — fix is 1.70.0-r0, not yet backported to Alpine 3.24.
# Track: https://pkgs.alpinelinux.org/packages?name=nghttp2&branch=v3.24
# Remove once Alpine 3.24 ships nghttp2-libs >= 1.70.0-r0.
CVE-2026-58055

# api-platform/core v2.7.18 — CVEs fixed in v3.4.17+ / v4.x only.
# Upgrading from v2 is a breaking change requiring code migration.
# Track: https://github.com/api-platform/core/security/advisories
CVE-2025-31481
CVE-2025-31485
CVE-2026-49858
22 changes: 17 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@


# https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact
ARG PHP_VERSION=8.2.33
ARG PHP_VERSION=8.3.33
ARG NGINX_VERSION=1.30.4


# "php" stage
FROM php:${PHP_VERSION}-fpm-alpine3.23 AS bewelcome_php
FROM php:${PHP_VERSION}-fpm-alpine3.24 AS bewelcome_php

# persistent / runtime deps
# Upgrade all base packages to pick up security patches (CVE fixes in OS packages)
RUN apk update && apk upgrade --no-cache

RUN apk add --no-cache \
acl \
freetype \
Expand All @@ -25,7 +28,7 @@ RUN apk add --no-cache \
python3 \
;

ARG APCU_VERSION=5.1.28
ARG APCU_VERSION=5.1.18

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the downgrade? This leads to loads of deprecation messages.

RUN set -eux; \
apk add --no-cache --virtual .build-deps \
$PHPIZE_DEPS \
Expand Down Expand Up @@ -79,6 +82,7 @@ RUN export PATH="/usr/local/bin:$PATH"

RUN ln -s $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini
COPY docker/php/conf.d/bewelcome.prod.ini $PHP_INI_DIR/conf.d/bewelcome.ini
COPY docker/php/fpm/z-workers.conf /usr/local/etc/php-fpm.d/z-workers.conf

RUN set -eux; \
{ \
Expand All @@ -99,6 +103,8 @@ WORKDIR /srv/bewelcome

# build for production
ARG APP_ENV=prod
ARG APP_VERSION=unknown
ARG APP_VERSION_TIMESTAMP=

# copy only specifically what we need for production
COPY assets assets/
Expand All @@ -112,7 +118,7 @@ COPY pthacks pthacks/
COPY public public/
COPY roxlauncher roxlauncher/
COPY src src/
COPY Migrations Migrations/
COPY migrations migrations/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never used, can be removed.

COPY templates templates/
COPY tools tools/
COPY translations translations/
Expand All @@ -129,7 +135,9 @@ RUN set -eux; \
COPY package.json yarn.lock webpack.config.js postcss.config.js tailwind.config.js tsconfig.json ./
RUN set -eux; \
yarn install --frozen-lock; \
yarn encore production --mode=production
yarn encore production --mode=production; \
rm -rf node_modules; \
yarn cache clean --force

# do not use .env files in production
COPY .env ./
Expand All @@ -140,6 +148,10 @@ RUN set -eux; \
mkdir -p var/cache var/log; \
composer dump-autoload --classmap-authoritative --no-dev; \
chmod +x bin/console; sync

RUN set -eux; \
printf '%s\n' "$APP_VERSION" > VERSION; \
if [ -n "$APP_VERSION_TIMESTAMP" ]; then php -r 'touch("VERSION", (int) $argv[1]);' "$APP_VERSION_TIMESTAMP"; fi
VOLUME /srv/bewelcome/var
VOLUME /srv/bewelcome/data

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@
"config": {
"sort-packages": true,
"platform": {
"php": "8.2"
"php": "8.3"
},
"allow-plugins": {
"infection/extension-installer": true,
Expand Down
Loading
Loading