Skip to content

Commit 12b88e3

Browse files
committed
Refactor Dockerfile and Makefile for improved build process and testing
- Transitioned to a multi-stage Dockerfile using Alpine for a more efficient build. - Added build arguments for versioning and Git metadata. - Updated Makefile to include a dedicated test image and streamline build commands. - Enhanced Playwright configuration to utilize system Chromium in tests. - Revised GitHub Actions workflows for better dependency management and testing flow. These changes optimize the development and testing workflow, ensuring a cleaner and more efficient build process.
1 parent a6a7468 commit 12b88e3

10 files changed

Lines changed: 234 additions & 54 deletions

File tree

.dockerignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.git
2+
.github
3+
node_modules
4+
.nuxt
5+
.output
6+
test-results
7+
playwright-report
8+
*.md
9+
.env
10+
.env.*
11+
!.env.exemple
12+
certificates

.github/workflows/docker-image.yml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Image GHCR sur push main (chemins applicatifs + Docker), sur le modèle de sesame-orchestrator/.github/workflows/docker-image.yml.
2+
name: Docker image
3+
4+
on:
5+
push:
6+
branches:
7+
- main
8+
paths:
9+
- "Dockerfile"
10+
- "Dockerfile.test"
11+
- ".github/workflows/docker-image.yml"
12+
- "package.json"
13+
- "yarn.lock"
14+
- "tsconfig.json"
15+
- "nuxt.config.ts"
16+
- "start.mjs"
17+
- "src/**"
18+
- "tests/**"
19+
- "playwright.config.ts"
20+
- "vitest.config.ts"
21+
22+
env:
23+
REGISTRY: ghcr.io
24+
IMAGE_NAME: ${{ github.repository }}
25+
26+
jobs:
27+
build-and-push-image:
28+
runs-on: ubuntu-latest
29+
permissions:
30+
contents: read
31+
packages: write
32+
33+
steps:
34+
- name: Checkout repository
35+
uses: actions/checkout@v4
36+
37+
- name: Setup Node.js
38+
uses: actions/setup-node@v4
39+
with:
40+
node-version: 22
41+
cache: yarn
42+
43+
- name: Install dependencies
44+
run: yarn install --frozen-lockfile
45+
46+
- name: Lint and unit tests
47+
run: yarn lint && yarn test:unit
48+
49+
- name: Log in to the Container registry
50+
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
51+
with:
52+
registry: ${{ env.REGISTRY }}
53+
username: ${{ github.actor }}
54+
password: ${{ secrets.GITHUB_TOKEN }}
55+
56+
- name: Extract metadata (tags, labels) for Docker
57+
id: meta
58+
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
59+
with:
60+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
61+
62+
- name: Extract version and commit info
63+
id: version
64+
run: |
65+
echo "version=$(jq -r .version package.json)" >> "$GITHUB_OUTPUT"
66+
echo "build_id=${{ github.sha }}" >> "$GITHUB_OUTPUT"
67+
68+
- name: Build and push Docker image
69+
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
70+
with:
71+
context: .
72+
push: true
73+
tags: ${{ steps.meta.outputs.tags }}
74+
labels: ${{ steps.meta.outputs.labels }}
75+
platforms: linux/amd64
76+
build-args: |
77+
BUILD_VERSION=${{ steps.version.outputs.version }}-${{ steps.version.outputs.build_id }}
78+
GIT_BRANCH=${{ github.ref_name }}
79+
GIT_COMMIT=${{ github.sha }}
80+
DOCKER_TAG=${{ steps.version.outputs.version }}-${{ steps.version.outputs.build_id }}

.github/workflows/lint.yml

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ on:
66
- '*'
77

88
env:
9-
CI_IMG: ghcr.io/libertech-fr/sesame-gestion-mdp
9+
APP_CI_IMG: sesame-gestion-mdp:ci
10+
TEST_CI_IMG: sesame-gestion-mdp:ci-test
1011
NODE_MODULES_VOL: sesame-gestion-mdp-node-modules
11-
PLAYWRIGHT_CACHE_VOL: sesame-gestion-mdp-playwright-cache
1212

1313
jobs:
1414
lint-app:
@@ -21,37 +21,41 @@ jobs:
2121
- name: Réseau Docker dev
2222
run: docker network create dev || true
2323

24-
- name: Dépendances + Chromium Playwright (dans Docker)
24+
- name: Images Docker (app Alpine + test avec Chromium)
25+
run: |
26+
docker build -t "${APP_CI_IMG}" .
27+
docker build -f Dockerfile.test --build-arg BASE_IMAGE="${APP_CI_IMG}" -t "${TEST_CI_IMG}" .
28+
29+
- name: Dépendances (yarn install dans l’image de test)
2530
run: |
2631
docker run --rm \
2732
-u 0 \
2833
-e NODE_ENV=development \
2934
-e NODE_TLS_REJECT_UNAUTHORIZED=0 \
30-
-e DEBIAN_FRONTEND=noninteractive \
3135
--add-host host.docker.internal:host-gateway \
3236
--platform linux/amd64 \
3337
--network dev \
3438
-v "${GITHUB_WORKSPACE}:/data" \
3539
-v "${NODE_MODULES_VOL}:/data/node_modules" \
36-
-v "${PLAYWRIGHT_CACHE_VOL}:/root/.cache/ms-playwright" \
3740
-w /data \
38-
"${CI_IMG}" sh -lc 'yarn install --prefer-offline --non-interactive && yarn playwright:install-chromium'
41+
"${TEST_CI_IMG}" \
42+
sh -lc 'yarn install --prefer-offline --non-interactive'
3943
40-
- name: Tests + build (yarn ci dans Docker)
44+
- name: Tests + build (yarn ci)
4145
run: |
4246
docker run --rm \
4347
-u 0 \
4448
-e CI=1 \
4549
-e NODE_ENV=development \
4650
-e NODE_TLS_REJECT_UNAUTHORIZED=0 \
47-
-e DEBIAN_FRONTEND=noninteractive \
4851
-e SESAME_HTTPS_ENABLED=false \
4952
-e BROWSERSLIST_IGNORE_OLD_DATA=1 \
5053
-e PLAYWRIGHT_BASE_URL=http://127.0.0.1:3000 \
54+
-e PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/chromium \
5155
--platform linux/amd64 \
5256
--network dev \
5357
-v "${GITHUB_WORKSPACE}:/data" \
5458
-v "${NODE_MODULES_VOL}:/data/node_modules" \
55-
-v "${PLAYWRIGHT_CACHE_VOL}:/root/.cache/ms-playwright" \
5659
-w /data \
57-
"${CI_IMG}" sh -lc 'yarn playwright:install-deps && yarn ci'
60+
"${TEST_CI_IMG}" \
61+
sh -lc 'yarn ci'

.github/workflows/release.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,21 @@ jobs:
3131
packages: write
3232

3333
steps:
34+
- name: Checkout repository
35+
uses: actions/checkout@v4
36+
37+
- name: Setup Node.js
38+
uses: actions/setup-node@v4
39+
with:
40+
node-version: 22
41+
cache: yarn
42+
43+
- name: Install dependencies
44+
run: yarn install --frozen-lockfile
45+
46+
- name: Lint and unit tests
47+
run: yarn lint && yarn test:unit
48+
3449
- name: Build docker
3550
uses: Libertech-FR/lt-actions/release@main
3651
with:
@@ -42,3 +57,8 @@ jobs:
4257
password: ${{ secrets.GITHUB_TOKEN }}
4358
access_token: ${{ secrets.GITHUB_TOKEN }}
4459
github_token: ${{ secrets.GITHUB_TOKEN }}
60+
args: |
61+
BUILD_VERSION={{NEW_VERSION}}
62+
GIT_BRANCH=${{ github.ref_name }}
63+
GIT_COMMIT=${{ github.sha }}
64+
DOCKER_TAG={{NEW_VERSION}}

Dockerfile

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,64 @@
1-
FROM node:22-bookworm-slim
1+
# Multi-stage Alpine (même esprit que sesame-orchestrator) : build isolé, runtime avec node_modules complet pour `start.mjs` (rebuild si `.env` change).
2+
FROM node:22-alpine AS builder
3+
4+
WORKDIR /data
5+
6+
RUN apk add --no-cache git
7+
8+
COPY package.json yarn.lock ./
9+
10+
RUN yarn install \
11+
--prefer-offline \
12+
--frozen-lockfile \
13+
--non-interactive \
14+
--production=false
15+
16+
COPY . .
17+
18+
RUN yarn build
19+
20+
FROM node:22-alpine AS production
221

322
ARG NODE_ENV=production
23+
ARG BUILD_VERSION=dev
24+
ARG GIT_BRANCH=unknown
25+
ARG GIT_COMMIT=unknown
26+
ARG DOCKER_TAG=unknown
27+
428
ENV NODE_ENV=${NODE_ENV}
5-
ENV NODE_OPTIONS=--openssl-legacy-provider
29+
ENV BUILD_VERSION=${BUILD_VERSION}
30+
ENV GIT_BRANCH=${GIT_BRANCH}
31+
ENV GIT_COMMIT=${GIT_COMMIT}
32+
ENV DOCKER_TAG=${DOCKER_TAG}
33+
ENV DO_NOT_TRACK=1
34+
ENV TZ=Europe/Paris
635

736
WORKDIR /data
837

9-
# Install dependencies. Note that the package names and the package manager are different for Debian-based images.
10-
RUN apt-get update && apt-get -y --no-install-recommends upgrade && apt-get install -y --no-install-recommends \
38+
RUN apk add --no-cache \
1139
git \
40+
openssl \
1241
jq \
13-
nano \
14-
vim \
1542
bash \
16-
bash-completion \
17-
iputils-ping \
18-
telnet \
19-
dnsutils \
20-
net-tools \
21-
tcpdump \
22-
&& apt-get clean \
23-
&& rm -rf /var/lib/apt/lists/*
43+
tzdata \
44+
&& cp "/usr/share/zoneinfo/${TZ}" /etc/localtime \
45+
&& echo "${TZ}" > /etc/timezone
2446

25-
COPY . .
47+
COPY package.json yarn.lock ./
2648

27-
# Pas de --frozen-lockfile : le yarn.lock est synchronisé depuis le dépôt après « make exec » puis « yarn install » (bind-mount).
28-
RUN yarn install \
29-
--prefer-offline \
30-
--non-interactive \
31-
--production=false
32-
# && yarn cache clean \
33-
# && yarn autoclean --init \
34-
# && yarn autoclean --force
49+
# Même jeu de fichiers que le builder : `start.mjs` peut relancer `yarn build` si le hash `.env` change.
50+
COPY --from=builder /data/node_modules ./node_modules
51+
COPY --from=builder /data/.output ./.output
52+
COPY --from=builder /data/start.mjs ./start.mjs
53+
COPY --from=builder /data/nuxt.config.ts ./nuxt.config.ts
54+
COPY --from=builder /data/tsconfig.json ./tsconfig.json
55+
COPY --from=builder /data/src ./src
56+
COPY --from=builder /data/playwright.config.ts ./playwright.config.ts
57+
COPY --from=builder /data/vitest.config.ts ./vitest.config.ts
58+
COPY --from=builder /data/tests ./tests
3559

36-
RUN yarn build
60+
RUN yarn cache clean \
61+
&& rm -rf /tmp/* /var/cache/apk/* /root/.npm /root/.node-gyp
3762

3863
EXPOSE 3000
3964

Dockerfile.test

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Image de test : image app Alpine + Chromium (apk) + devDependencies pour Playwright.
2+
ARG BASE_IMAGE=ghcr.io/libertech-fr/sesame-gestion-mdp
3+
FROM ${BASE_IMAGE}
4+
5+
USER root
6+
7+
RUN apk add --no-cache chromium
8+
9+
WORKDIR /data
10+
11+
COPY playwright.config.ts /data/playwright.config.ts
12+
13+
RUN yarn install --frozen-lockfile --production=false --non-interactive
14+
15+
ENV NODE_ENV=development
16+
ENV PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/chromium

Makefile

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ APP_WEB_PORT_SECURE = 3443
55
APP_WEB_DEBUG_PORT = 24678
66

77
IMG_NAME = ghcr.io/libertech-fr/sesame-gestion-mdp
8+
TEST_IMG_NAME = sesame-gestion-mdp-test-local
89
BASE_NAME = sesame
910
APP_NAME = sesame-gestion-mdp
1011
# Volume dédié : évite de monter les node_modules du mac dans le conteneur Linux.
1112
# Réseau Docker « dev » : créer une fois (make network-dev ou docker network create dev).
12-
# Flux : pas de yarn sur le Mac — make exec puis yarn install ; e2e / CI : docker dans .github/workflows/lint.yml.
13-
# Chaque « make test » / « verify » : nouveau conteneur → yarn playwright:install-deps puis tests (prérequis : node_modules + cache Playwright remplis, ex. étapes du workflow ou exec).
13+
# Flux : pas de yarn sur le Mac — make exec puis yarn install ; PR : .github/workflows/lint.yml ; push main (chemins filtrés) : docker-image.yml ; tests e2e locaux : make build && make test (image test basée sur $(IMG_NAME)).
1414
NODE_MODULES_VOLUME = sesame-gestion-mdp-node-modules
15-
# Cache Chromium Playwright (Linux) entre les « make exec » — pas sur le Mac.
15+
# Cache Playwright (binaires téléchargés) pour « make exec » ; make test / verify utilisent Chromium système Alpine (pas ce volume).
1616
PLAYWRIGHT_CACHE_VOLUME = sesame-gestion-mdp-playwright-cache
1717

1818
-include .env
@@ -45,14 +45,19 @@ help:
4545
@grep -h -E '^[-a-zA-Z0-9_\.\/]+:.*?## .*$$' $(MAKEFILE_LIST) \
4646
| sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[32m%-18s\033[0m %s\n", $$1, $$2}'
4747

48-
build: ## Image Docker (yarn build dans l’image ; pas de Playwright dans l’image — voir workflow GitHub)
48+
build: ## Image Docker (Alpine multi-stage ; pas de Playwright — voir Dockerfile.test et workflows)
4949
@docker build --platform $(PLATFORM) -t $(IMG_NAME) --no-cache --progress=plain \
5050
--build-arg BUILD_VERSION=$(DOCKER_TAG) \
5151
--build-arg GIT_BRANCH=$(GIT_BRANCH) \
5252
--build-arg GIT_COMMIT=$(GIT_COMMIT) \
5353
--build-arg DOCKER_TAG=$(DOCKER_TAG) \
5454
.
5555

56+
build-test-image: ## Image locale dédiée aux tests (FROM $(IMG_NAME) + Chromium + devDependencies)
57+
@docker build --platform $(PLATFORM) -f Dockerfile.test \
58+
--build-arg BASE_IMAGE=$(IMG_NAME) \
59+
-t $(TEST_IMG_NAME) .
60+
5661
# Mode « simulation » : image déjà buildée, env + certificats montés (sans écraser tout le code par le bind-mount complet)
5762
simulation: ## Lancer en NODE_ENV=production avec montages ciblés (.env, certificats, hash)
5863
@touch $(CURDIR)/.env.hash
@@ -151,41 +156,39 @@ stop-all: ## Arrêter le conteneur applicatif (équivalent ici, pas de stack BDD
151156
run-lint: ## Rejouer le job GitHub Actions « lint-app » avec act (nécessite nektos/act)
152157
act --container-architecture=linux/amd64 -j lint-app
153158

154-
test: ## Tests : paquets système Chromium puis prepare + Vitest + E2E (yarn install + Chromium : voir lint.yml)
159+
test: build-test-image ## Vitest + Playwright dans l’image test (prérequis : make build pour taguer $(IMG_NAME) en local)
155160
@docker run --rm \
156161
-u 0 \
157162
-e CI=1 \
158163
-e NODE_ENV=development \
159164
-e NODE_TLS_REJECT_UNAUTHORIZED=0 \
160-
-e DEBIAN_FRONTEND=noninteractive \
161165
-e SESAME_HTTPS_ENABLED=false \
162166
-e BROWSERSLIST_IGNORE_OLD_DATA=1 \
163167
-e PLAYWRIGHT_BASE_URL=http://127.0.0.1:3000 \
168+
-e PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/chromium \
164169
--platform $(PLATFORM) \
165170
--network dev \
166-
-v $(CURDIR):/data \
167-
-v $(NODE_MODULES_VOLUME):/data/node_modules \
168-
-v $(PLAYWRIGHT_CACHE_VOLUME):/root/.cache/ms-playwright \
171+
-v $(CURDIR)/playwright.config.ts:/data/playwright.config.ts \
172+
-v $(CURDIR)/tests:/data/tests \
169173
-w /data \
170-
$(IMG_NAME) yarn test
174+
$(TEST_IMG_NAME) sh -lc 'yarn test'
171175

172-
verify: ## CI locale : paquets système Chromium puis yarn ci (même prérequis que test)
176+
verify: build-test-image ## CI locale : yarn ci dans l’image test (lint + unit + e2e + build)
173177
@docker run --rm \
174178
-u 0 \
175179
-e CI=1 \
176180
-e NODE_ENV=development \
177181
-e NODE_TLS_REJECT_UNAUTHORIZED=0 \
178-
-e DEBIAN_FRONTEND=noninteractive \
179182
-e SESAME_HTTPS_ENABLED=false \
180183
-e BROWSERSLIST_IGNORE_OLD_DATA=1 \
181184
-e PLAYWRIGHT_BASE_URL=http://127.0.0.1:3000 \
185+
-e PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/chromium \
182186
--platform $(PLATFORM) \
183187
--network dev \
184-
-v $(CURDIR):/data \
185-
-v $(NODE_MODULES_VOLUME):/data/node_modules \
186-
-v $(PLAYWRIGHT_CACHE_VOLUME):/root/.cache/ms-playwright \
188+
-v $(CURDIR)/playwright.config.ts:/data/playwright.config.ts \
189+
-v $(CURDIR)/tests:/data/tests \
187190
-w /data \
188-
$(IMG_NAME) yarn ci
191+
$(TEST_IMG_NAME) sh -lc 'yarn ci'
189192

190193
ncu: ## Vérifier les mises à jour des dépendances
191194
@npx npm-check-updates

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# sesame-gestion-mdp
22
Gestion des mot de passe sesame
33

4-
Les commandes **yarn** (install, test, build, etc.) se font dans **Docker** : `make build` puis `make exec`, puis par exemple `yarn install` et `yarn playwright:install` dans le shell du conteneur. Sur la CI, **`make ci-github`** enchaîne tout sans yarn sur le runner.
4+
Les commandes **yarn** (install, build, etc.) se font dans **Docker** : `make build` puis `make exec`, puis par exemple `yarn install`. Les **e2e** passent par **`make test`** (image `Dockerfile.test`, Chromium système Alpine, sans `apt-get`). Sur GitHub, le workflow **`.github/workflows/lint.yml`** construit l’image app + image de test puis exécute `yarn ci` dans l’image de test.
55

66
## build release
77
Construire une release :

0 commit comments

Comments
 (0)