Skip to content

Modernize Docker build infrastructure: multi-arch GitHub Actions + buildkit strategy - #222

Open
b23prodtm with Copilot wants to merge 4 commits into
fix/composefrom
copilot/update-docker-build-infrastructure
Open

Modernize Docker build infrastructure: multi-arch GitHub Actions + buildkit strategy#222
b23prodtm with Copilot wants to merge 4 commits into
fix/composefrom
copilot/update-docker-build-infrastructure

Conversation

Copilot AI commented Jul 11, 2026

Copy link
Copy Markdown

Replaces the outdated single-arch CircleCI + GitHub Actions setup with the proven multi-platform buildkit strategy from balena-photo-cropper. Adds full armhf/aarch64/x86_64 matrix builds, GHA layer caching, buildkit secret mounts, and manifest merging.

CI/CD

  • New .github/workflows/docker-build.yml — replaces build.yml; uses docker/bake-action@v5, full 3-arch matrix, separated "Write buildkit secrets" step, GHA cache injection, manifest merge in deploy job
  • Removed .circleci/config.yml and .github/workflows/build.yml
  • Explicit permissions: contents: read / actions: write on both jobs (least-privilege)

docker-bake.hcl

  • Added REGISTRY, REGISTRY_IMAGE, GITHUB_SHA variables
  • New common target inheriting GHA cache (type=gha) — all service targets inherit it
  • Per-arch groups armhf / aarch64 / x86_64, each building all 4 services with platform-suffixed tags (arm32v7, arm64v8, amd64) plus branch-safe and SHA tags
target "common" {
  cache-from = ["type=gha"]
  cache-to   = ["type=gha,mode=max"]
}

target "php-fpm-x86_64" {
  inherits   = ["php-fpm"]
  platforms  = ["linux/amd64"]
  dockerfile = "Dockerfile.x86_64"
  tags = [
    "${REGISTRY}/${REGISTRY_IMAGE}/php-fpm:amd64",
    BAKE_TAG != "" ? "…:${BAKE_TAG}-amd64" : "",
    GITHUB_SHA != "" ? "…:${GITHUB_SHA}-amd64" : ""
  ]
}

manifest-push.sh (new)

  • Sources common.env for BALENA_PROJECTS, parses REGISTRY/DOCKER_ORG from docker-bake.hcl
  • Merges per-arch images into a single multi-platform manifest; pushes latest on main/development

common.env

  • BALENA_PROJECTS updated from path-based entries to service names: ( php-fpm httpd mysqldb balena-storage )

Dockerfiles

  • PHP base image bumped 7.4.33-fpm-alpine3.168.3-fpm-alpine across all arch variants and template (PHP 8.1+ required for CakePHP 5)
  • Node build stage pinned to node:20-alpine (drops end-of-life alpine 3.16)

Copilot AI changed the title [WIP] Update Docker build infrastructure for multi-platform support Modernize Docker build infrastructure: multi-arch GitHub Actions + buildkit strategy Jul 11, 2026
Copilot AI requested a review from b23prodtm July 11, 2026 14:47
@b23prodtm
b23prodtm marked this pull request as ready for review July 19, 2026 15:55
@b23prodtm
b23prodtm requested a review from Copilot July 19, 2026 16:06

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Modernizes the container build/release pipeline by moving to a multi-architecture Docker Buildx Bake approach on GitHub Actions (with GHA caching and a manifest-merge deploy step), while updating the application’s container base images to support newer CakePHP/PHP requirements.

Changes:

  • Added a new multi-arch GitHub Actions workflow that builds/pushes per-arch images and then merges them into multi-platform manifests.
  • Refactored docker-bake.hcl to introduce a shared GHA cache target, registry variables, and per-arch groups/targets with arch-suffixed tags.
  • Updated Dockerfiles to use newer Node/PHP base images; removed the legacy CircleCI and older GitHub Actions workflow.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
.github/workflows/docker-build.yml New multi-arch Buildx Bake workflow + deploy manifest-merge job.
docker-bake.hcl Adds registry/SHA vars, shared cache target, and per-arch build groups/targets.
manifest-push.sh New script to merge per-arch tags into multi-platform manifests.
common.env Updates BALENA_PROJECTS to service-name list used by manifest merge loop.
Dockerfile.x86_64 Updates Node/PHP base images for amd64 build.
Dockerfile.aarch64 Updates Node/PHP base images for arm64 build.
Dockerfile.armhf Updates Node/PHP base images for arm/v7 build.
Dockerfile.template Updates Node/PHP base images in the template.
.github/workflows/build.yml Removed legacy workflow replaced by docker-build.yml.
.circleci/config.yml Removed legacy CircleCI pipeline replaced by GitHub Actions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +70 to +78
- name: Write buildkit secrets
run: |
mkdir -p .balena/secrets
echo "${{ secrets.MYSQL_ROOT_PASSWORD }}" > .balena/secrets/secret_mysql_root_password
echo "${{ secrets.MYSQL_USER }}" > .balena/secrets/secret_mysql_user
echo "${{ secrets.MYSQL_PASSWORD }}" > .balena/secrets/secret_mysql_password
echo "${{ secrets.MYSQL_DATABASE }}" > .balena/secrets/secret_mysql_database
echo "${{ secrets.MASTER_PASSWORD }}" > .balena/secrets/secret_master_password

Comment thread manifest-push.sh
@@ -0,0 +1,85 @@
#!/usr/bin/env bash
set -eu
Comment thread Dockerfile.x86_64
# BEGIN - Multi-stage Build
# Stage 1: Install NodeJS dependencies
FROM node:20-alpine3.16 AS node-build
FROM node:20-alpine AS node-build
Comment thread Dockerfile.template
# BEGIN - Multi-stage Build
# Stage 1: Install NodeJS dependencies
FROM node:20-alpine3.16 AS node-build
FROM node:20-alpine AS node-build
Comment thread Dockerfile.armhf
# BEGIN - Multi-stage Build
# Stage 1: Install NodeJS dependencies
FROM node:20-alpine3.16 AS node-build
FROM node:20-alpine AS node-build
Comment thread Dockerfile.aarch64
# BEGIN - Multi-stage Build
# Stage 1: Install NodeJS dependencies
FROM node:20-alpine3.16 AS node-build
FROM node:20-alpine AS node-build
Comment on lines +100 to +101
permissions:
contents: read

@b23prodtm b23prodtm left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

docker-bake.hcl needs renaming secret files to id=some_var, target=./balena/secrets/some_var_file

@b23prodtm

Copy link
Copy Markdown
Owner

Mission : Refactoring complet de la PR #222 acake2php

Tu es un agent IA senior spécialisé en :

  • DevOps
  • Docker / Docker Buildx
  • Balena Cloud
  • GitHub Actions
  • PHP-FPM
  • Apache HTTPD
  • CakePHP 5
  • architectures ARM/x86
  • sécurité des secrets et déploiements IoT

Tu travailles sur cette Pull Request :

#222

Objectif : transformer cette PR en une version fusionnable en production, avec tous les GitHub Checks verts, en alignant l’architecture sur les standards déjà validés dans :

  • balena-cloud-apps
  • balena-photo-cropper

Principe général

Ne pas réinventer l’architecture.

Avant toute modification :

  1. analyser la dernière PR de balena-photo-cropper ;
  2. analyser les templates et scripts de balena-cloud-apps ;
  3. identifier les composants réutilisables ;
  4. porter uniquement les améliorations compatibles avec acake2php.

Toute divergence avec ces projets devra être justifiée.

L’objectif est de créer une architecture homogène entre les projets Balena existants.

Architecture cible obligatoire

La référence absolue est :

  • balena-cloud-apps pour l’organisation des plateformes, templates et déploiements ;
  • balena-photo-cropper pour les améliorations récentes (secrets, SSL, CakePHP 5, init-web, sécurité).

Les plateformes supportées sont exclusivement :

  • armhf
  • aarch64
  • x86_64

Correspondance Docker :

  • linux/arm/v7
  • linux/arm64
  • linux/amd64

Aucune autre architecture ne doit être ajoutée.

Docker Buildx / docker-bake.hcl

Créer ou corriger docker-bake.hcl.

Le build doit produire les images pour :

  • amd64
  • arm64
  • armhf

Les plateformes doivent correspondre exactement aux plateformes Balena Cloud.

Utiliser :

  • Docker Buildx
  • cache GitHub Actions
  • stratégie multi-platform propre

Les workflows GitHub Actions doivent utiliser une matrice basée sur :

armhf
aarch64
x86_64

GitHub Actions

Refactoriser les workflows.

Objectifs :

  • éviter les builds complets inutiles ;
  • utiliser les conditions GitHub Actions ;
  • utiliser paths et paths-ignore ;
  • lancer uniquement les jobs nécessaires ;
  • conserver une validation complète avant merge.

Les checks doivent valider :

  • syntaxe YAML ;
  • docker compose ;
  • génération des templates ;
  • build Docker ;
  • multi-architecture ;
  • démarrage des services ;
  • CakePHP ;
  • Apache ;
  • PHP-FPM ;
  • MariaDB ;
  • secrets.

Utilisation des templates Balena

Ne pas créer un nouveau système de génération.

Utiliser le mécanisme existant de balena-cloud-apps.

La génération doit utiliser :

update_templates

Cette commande est la source officielle.

Adapter les templates si nécessaire, mais conserver le mécanisme.

Déploiement Balena

Le flux de déploiement doit suivre :

balena_deploy . ${BALENA_ARCH} 2 0

avec :

BALENA_ARCH=armhf
BALENA_ARCH=aarch64
BALENA_ARCH=x86_64

Le déploiement doit fonctionner sans modification manuelle.

Sélection du docker-compose

Après génération des templates :

Méthode préférée :

ln -sf docker-compose.${BALENA_ARCH} docker-compose.yml

Prévoir également le mode copie :

cp docker-compose.${BALENA_ARCH} docker-compose.yml

afin de fonctionner dans les environnements où les liens symboliques ne sont pas adaptés.

Docker Compose

Compatibilité obligatoire :

Compose version <= 2.1

Ne pas utiliser de fonctionnalités récentes incompatibles.

Supprimer tous les bind mounts.

Utiliser uniquement :

  • volumes Docker nommés ;
  • réseaux Docker ;
  • secrets.

Service init-web

Créer ou adapter un service init-web basé sur celui de balena-photo-cropper.

Responsabilités :

  • initialiser /var/www/html ;
  • copier les sources applicatives ;
  • créer les répertoires nécessaires ;
  • appliquer les permissions ;
  • éviter une réinitialisation d’un volume déjà initialisé.

Les autres services doivent dépendre correctement de cette initialisation.

Architecture applicative

Conserver :

app/

pour CakePHP.

Ne pas déplacer l’application.

Migration CakePHP 5

Mettre à jour l’application vers CakePHP 5.

Corriger :

  • composer ;
  • bootstrap ;
  • webroot ;
  • cache ;
  • logs ;
  • permissions ;
  • configuration PHP.

PHP

Optimiser les builds PHP.

Éviter les compilations complètes inutiles.

Privilégier :

  • images PHP officielles ;
  • extensions précompilées ;
  • mécanismes compatibles multi-architecture.

Vérifier :

  • PHP-FPM ;
  • OPcache ;
  • extensions nécessaires ;
  • configuration production.

Apache HTTPD

Conserver Apache.

Ne pas remplacer par Nginx.

Architecture :

Apache HTTPD
|
|
PHP-FPM

Vérifier :

  • VirtualHost ;
  • SSL ;
  • ProxyPass ;
  • proxy_fcgi ;
  • permissions ;
  • réseau Docker ;
  • healthcheck ;
  • exposition HTTPS.

Le problème actuel :

httpd non accessible sur 8443

doit être identifié et corrigé.

Sécurité / Secrets

Reprendre le modèle de balena-photo-cropper.

Utiliser :

  • .balena/secrets
  • secrets Balena
  • variables sécurisées

Interdiction :

  • mots de passe dans docker-compose ;
  • secrets dans Git ;
  • valeurs sensibles dans les Dockerfiles.

MySQL / MariaDB

Mettre à jour le service MySQL/MariaDB.

Objectifs :

  • secrets sécurisés ;
  • initialisation propre ;
  • compatibilité Balena ;
  • persistance via volumes ;
  • healthcheck.

Dépendances Node.js

Identifier les outils nécessitant Node.js.

Installer automatiquement les dépendances nécessaires.

Mettre à jour :

  • package.json ;
  • scripts npm si nécessaires ;
  • documentation.

Éviter toute dépendance inutile.

Documentation

Mettre à jour :

INSTALL

Ajouter :

  • installation des dépendances ;
  • installation Node.js ;
  • génération templates :

update_templates

  • sélection architecture :

ln -sf docker-compose.${BALENA_ARCH} docker-compose.yml

ou :

cp docker-compose.${BALENA_ARCH} docker-compose.yml

  • tests locaux ;
  • build Docker ;
  • déploiement Balena.

README

Documenter :

  • architectures supportées ;
  • armhf ;
  • aarch64 ;
  • x86_64 ;
  • Docker Buildx ;
  • templates ;
  • secrets ;
  • SSL ;
  • init-web ;
  • CakePHP 5 ;
  • Apache ;
  • PHP-FPM ;
  • commandes de test ;
  • commandes de déploiement.

Méthode de travail

Travailler par itérations.

Pour chaque modification :

  1. analyser ;
  2. modifier ;
  3. lancer les validations ;
  4. corriger la cause racine ;
  5. recommencer jusqu’à succès.

Ne jamais contourner un test.

Produire des commits cohérents.

Validation finale obligatoire

La PR est terminée uniquement lorsque :

✓ GitHub Actions passent
✓ docker-bake.hcl fonctionne
✓ build amd64 OK
✓ build arm64 OK
✓ build armhf OK
✓ Balena deploy OK
✓ Apache répond sur 8443
✓ SSL fonctionne
✓ PHP-FPM fonctionne
✓ CakePHP 5 démarre
✓ MariaDB fonctionne
✓ secrets sécurisés
✓ aucune dépendance inutile
✓ documentation complète

Rapport final attendu

Fournir :

  • résumé des modifications ;
  • fichiers modifiés ;
  • raisons techniques ;
  • différences avec balena-photo-cropper ;
  • différences avec balena-cloud-apps ;
  • temps de build avant/après ;
  • taille des images avant/après ;
  • risques résiduels ;
  • recommandations futures.

Règle finale :

Avant d’écrire une nouvelle implémentation, vérifier systématiquement si elle existe déjà dans balena-cloud-apps ou balena-photo-cropper et la réutiliser. Le but est une convergence d’architecture, pas une nouvelle branche technique.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants