ci: docker_tag=ext-0.1.2 build(front): image ext, env vars, doc+tests, v0.1.2
This commit is contained in:
parent
24698b0b64
commit
2361e184f8
9
CHANGELOG.md
Normal file
9
CHANGELOG.md
Normal file
@ -0,0 +1,9 @@
|
||||
## v0.1.1
|
||||
|
||||
- Ajout d'une image Docker de production "ext" (Next.js `next start`) lisant les URLs d'API via variables d'environnement, évitant toute référence à `localhost`.
|
||||
- Remplacement d'URLs codées en dur dans l'écran de connexion email par l'utilisation de `FrontendVariables` et des `NEXT_PUBLIC_*`.
|
||||
- Documentation `docs/ext.md` ajoutée (build, run, push, variables supportées).
|
||||
|
||||
## v0.1.2
|
||||
|
||||
- LoginCallback (`index.tsx`) ajusté: suppression de la redirection spéciale `local.4nkweb.com` au profit d'un flux standard basé sur variables d'environnement.
|
70
Dockerfile
70
Dockerfile
@ -3,6 +3,7 @@ FROM node:19-alpine AS deps
|
||||
WORKDIR /leCoffre-front
|
||||
|
||||
COPY package.json ./
|
||||
COPY package-lock.json ./
|
||||
|
||||
RUN apk update && apk add --no-cache openssh-client git
|
||||
|
||||
@ -10,7 +11,7 @@ RUN apk update && apk add --no-cache openssh-client git
|
||||
RUN --mount=type=ssh \
|
||||
mkdir -p /root/.ssh && \
|
||||
ssh-keyscan git.4nkweb.com >> /root/.ssh/known_hosts && \
|
||||
npm install --frozen-lockfile
|
||||
npm install --no-audit --no-fund
|
||||
|
||||
# Configuration pour le développement
|
||||
FROM node:19-alpine AS development
|
||||
@ -27,3 +28,70 @@ USER lecoffreuser
|
||||
|
||||
CMD ["npm", "run", "dev"]
|
||||
EXPOSE 3000
|
||||
|
||||
# --- Build de production
|
||||
FROM node:19-alpine AS builder
|
||||
WORKDIR /leCoffre-front
|
||||
|
||||
COPY --from=deps /leCoffre-front/node_modules ./node_modules
|
||||
COPY --from=deps /leCoffre-front/package.json ./package.json
|
||||
COPY . .
|
||||
|
||||
# Arguments/variables d'environnement publics pour le build Next
|
||||
ARG NEXT_PUBLIC_BACK_API_PROTOCOL
|
||||
ARG NEXT_PUBLIC_BACK_API_HOST
|
||||
ARG NEXT_PUBLIC_BACK_API_PORT
|
||||
ARG NEXT_PUBLIC_BACK_API_ROOT_URL
|
||||
ARG NEXT_PUBLIC_BACK_API_VERSION
|
||||
ARG NEXT_PUBLIC_FRONT_APP_HOST
|
||||
ARG NEXT_PUBLIC_FRONT_APP_PORT
|
||||
ARG NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT
|
||||
ARG NEXT_PUBLIC_IDNOT_CLIENT_ID
|
||||
ARG NEXT_PUBLIC_IDNOT_BASE_URL
|
||||
ARG NEXT_PUBLIC_DOCAPOSTE_API_URL
|
||||
ARG NEXT_PUBLIC_HOTJAR_SITE_ID
|
||||
ARG NEXT_PUBLIC_HOTJAR_VERSION
|
||||
ARG NEXT_PUBLIC_4NK_URL
|
||||
ARG NEXT_PUBLIC_API_URL
|
||||
ARG NEXT_PUBLIC_DEFAULT_VALIDATOR_ID
|
||||
ARG NEXT_PUBLIC_DEFAULT_STORAGE_URLS
|
||||
|
||||
ENV NEXT_PUBLIC_BACK_API_PROTOCOL=${NEXT_PUBLIC_BACK_API_PROTOCOL} \
|
||||
NEXT_PUBLIC_BACK_API_HOST=${NEXT_PUBLIC_BACK_API_HOST} \
|
||||
NEXT_PUBLIC_BACK_API_PORT=${NEXT_PUBLIC_BACK_API_PORT} \
|
||||
NEXT_PUBLIC_BACK_API_ROOT_URL=${NEXT_PUBLIC_BACK_API_ROOT_URL} \
|
||||
NEXT_PUBLIC_BACK_API_VERSION=${NEXT_PUBLIC_BACK_API_VERSION} \
|
||||
NEXT_PUBLIC_FRONT_APP_HOST=${NEXT_PUBLIC_FRONT_APP_HOST} \
|
||||
NEXT_PUBLIC_FRONT_APP_PORT=${NEXT_PUBLIC_FRONT_APP_PORT} \
|
||||
NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT=${NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT} \
|
||||
NEXT_PUBLIC_IDNOT_CLIENT_ID=${NEXT_PUBLIC_IDNOT_CLIENT_ID} \
|
||||
NEXT_PUBLIC_IDNOT_BASE_URL=${NEXT_PUBLIC_IDNOT_BASE_URL} \
|
||||
NEXT_PUBLIC_DOCAPOSTE_API_URL=${NEXT_PUBLIC_DOCAPOSTE_API_URL} \
|
||||
NEXT_PUBLIC_HOTJAR_SITE_ID=${NEXT_PUBLIC_HOTJAR_SITE_ID} \
|
||||
NEXT_PUBLIC_HOTJAR_VERSION=${NEXT_PUBLIC_HOTJAR_VERSION} \
|
||||
NEXT_PUBLIC_4NK_URL=${NEXT_PUBLIC_4NK_URL} \
|
||||
NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} \
|
||||
NEXT_PUBLIC_DEFAULT_VALIDATOR_ID=${NEXT_PUBLIC_DEFAULT_VALIDATOR_ID} \
|
||||
NEXT_PUBLIC_DEFAULT_STORAGE_URLS=${NEXT_PUBLIC_DEFAULT_STORAGE_URLS}
|
||||
|
||||
RUN npm run build
|
||||
|
||||
# --- Image d'exécution "ext"
|
||||
FROM node:19-alpine AS ext
|
||||
WORKDIR /leCoffre-front
|
||||
|
||||
ENV NODE_ENV=production \
|
||||
PORT=3000
|
||||
|
||||
COPY --from=builder /leCoffre-front/.next ./.next
|
||||
COPY --from=builder /leCoffre-front/public ./public
|
||||
COPY --from=deps /leCoffre-front/node_modules ./node_modules
|
||||
COPY --from=builder /leCoffre-front/package.json ./package.json
|
||||
COPY --from=builder /leCoffre-front/next.config.js ./next.config.js
|
||||
|
||||
# Création de l'utilisateur non-root
|
||||
RUN adduser -D lecoffreuser --uid 10000 && chown -R lecoffreuser .
|
||||
USER lecoffreuser
|
||||
|
||||
EXPOSE 3000
|
||||
CMD ["npm", "run", "start"]
|
13
docs/ci.md
13
docs/ci.md
@ -5,7 +5,7 @@ Cette documentation décrit le pipeline CI/CD tel qu’il peut être déduit des
|
||||
### Portée
|
||||
|
||||
- **Build applicatif**: Next.js (Node 19-alpine) avec dépendance privée `le-coffre-resources` via SSH.
|
||||
- **Image Docker**: construction multi-étapes, publication attendue vers un registre Scaleway Container Registry.
|
||||
- **Image Docker**: construction multi-étapes, publication vers le registre Docker hébergé sur `git.4nkweb.com` (accès via clés SSH).
|
||||
- **Déploiement Kubernetes**: namespace `lecoffre`, intégration Vault Agent pour l’injection d’ENV, `ExternalSecret` pour le secret de pull Docker, `Ingress` TLS via cert-manager, ressources de `Deployment`/`Service`.
|
||||
|
||||
### Chaîne de build
|
||||
@ -25,9 +25,8 @@ Cette documentation décrit le pipeline CI/CD tel qu’il peut être déduit des
|
||||
|
||||
### Image, registre et version
|
||||
|
||||
- **Image utilisée en cluster**: `rg.fr-par.scw.cloud/lecoffre/front:v0.1.9` (cf. `temp.yaml`).
|
||||
- **Registre**: Scaleway Container Registry (région `fr-par`).
|
||||
- **Tagging**: la version d’exemple observée est `v0.1.9`. L’origine du tag (automatique via CI, ou manuel) n’est pas dans le dépôt.
|
||||
- **Registre**: Docker registry interne sur `git.4nkweb.com`.
|
||||
- **Tagging**: contrôlé par la CI via le message de commit (préfixe `ci: docker_tag=<valeur>`), sinon fallback `dev-test`. La branche peut être utilisée comme tag par défaut selon la CI.
|
||||
|
||||
### Déploiement Kubernetes (extrait de `temp.yaml`)
|
||||
|
||||
@ -57,11 +56,11 @@ Cette documentation décrit le pipeline CI/CD tel qu’il peut être déduit des
|
||||
- `npm run build` (désactive la télémétrie et le lint bloquant).
|
||||
|
||||
4. **Construction de l’image**
|
||||
- `docker build` avec BuildKit et forward d’agent SSH.
|
||||
- Taggage semver (ex. `v0.1.9`) et éventuellement `latest`/environnement (non constaté ici).
|
||||
- Réalisée par la CI (BuildKit + forward d’agent SSH) après un `git push` sur `git.4nkweb.com`.
|
||||
- Taggage déterminé par le message de commit et/ou la branche.
|
||||
|
||||
5. **Push au registre**
|
||||
- `docker push rg.fr-par.scw.cloud/lecoffre/front:<tag>`.
|
||||
- Réalisé par la CI vers le registre `git.4nkweb.com`.
|
||||
|
||||
6. **Déploiement Kubernetes**
|
||||
- Application des manifestes (ou rendu Helm) dans le namespace `lecoffre`.
|
||||
|
58
docs/ext.md
Normal file
58
docs/ext.md
Normal file
@ -0,0 +1,58 @@
|
||||
### Image Docker "ext" (Next.js) – variables d'environnement et publication
|
||||
|
||||
Cette image exécute l'app Next.js en mode production via `next start` et lit la configuration via les variables d'environnement exposées (préfixe `NEXT_PUBLIC_`). L'objectif est d'éviter toute dépendance à `localhost` dans les appels API : les URLs sont construites dynamiquement côté front à partir de ces variables.
|
||||
|
||||
#### Variables d'environnement supportées
|
||||
|
||||
- **NEXT_PUBLIC_BACK_API_PROTOCOL**: protocole de l'API (ex: `https://`)
|
||||
- **NEXT_PUBLIC_BACK_API_HOST**: hôte de l'API (ex: `api.example.com`)
|
||||
- **NEXT_PUBLIC_BACK_API_PORT**: port de l'API (ex: `443`)
|
||||
- **NEXT_PUBLIC_BACK_API_ROOT_URL**: racine (ex: `/` ou `/api`)
|
||||
- **NEXT_PUBLIC_BACK_API_VERSION**: version (ex: `v1`)
|
||||
- **NEXT_PUBLIC_FRONT_APP_HOST**: base publique du front (ex: `https://app.example.com`)
|
||||
- **NEXT_PUBLIC_FRONT_APP_PORT**: port front si nécessaire (ex: `443`)
|
||||
- **NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT**
|
||||
- **NEXT_PUBLIC_IDNOT_CLIENT_ID**
|
||||
- **NEXT_PUBLIC_IDNOT_BASE_URL**
|
||||
- **NEXT_PUBLIC_DOCAPOSTE_API_URL**
|
||||
- **NEXT_PUBLIC_HOTJAR_SITE_ID**
|
||||
- **NEXT_PUBLIC_HOTJAR_VERSION**
|
||||
- **NEXT_PUBLIC_4NK_URL**
|
||||
- **NEXT_PUBLIC_API_URL**
|
||||
- **NEXT_PUBLIC_DEFAULT_VALIDATOR_ID**
|
||||
- **NEXT_PUBLIC_DEFAULT_STORAGE_URLS** (liste séparée par des virgules)
|
||||
|
||||
Notes:
|
||||
|
||||
- Le front initialise ses variables via `next.config.js` et `_app.tsx`, ce qui alimente `FrontendVariables`. Les appels API utilisent ces valeurs et n'emploient pas `localhost`.
|
||||
- Les valeurs doivent être passées au conteneur au runtime (`docker run -e ...` ou manifest K8s via `env:`/`secretRef`).
|
||||
|
||||
#### Construction de l'image (cible "ext")
|
||||
|
||||
Prérequis: Docker BuildKit activé et agent SSH opérationnel pour cloner `le-coffre-resources` depuis `git.4nkweb.com`.
|
||||
|
||||
1. `cd /home/debian/lecoffre-front`
|
||||
2. `export DOCKER_BUILDKIT=1`
|
||||
3. `docker build --target ext --ssh default -t lecoffre/front:ext-0.1.2 -f /home/debian/lecoffre-front/Dockerfile /home/debian/lecoffre-front`
|
||||
|
||||
#### Exécution locale (validation)
|
||||
|
||||
Exemple minimal (adapter les valeurs):
|
||||
|
||||
```bash
|
||||
docker run --rm -p 3000:3000 \
|
||||
-e NEXT_PUBLIC_BACK_API_PROTOCOL=https:// \
|
||||
-e NEXT_PUBLIC_BACK_API_HOST=api.example.com \
|
||||
-e NEXT_PUBLIC_BACK_API_PORT=443 \
|
||||
-e NEXT_PUBLIC_BACK_API_ROOT_URL=/ \
|
||||
-e NEXT_PUBLIC_BACK_API_VERSION=v1 \
|
||||
-e NEXT_PUBLIC_FRONT_APP_HOST=https://app.example.com \
|
||||
-e NEXT_PUBLIC_4NK_URL=https://app.example.com \
|
||||
lecoffre/front:ext-0.1.2
|
||||
```
|
||||
|
||||
#### Publication via CI (git.4nkweb.com)
|
||||
|
||||
- Le push d'image est effectué par la CI de `git.4nkweb.com` suite à un `git push`.
|
||||
- Définir le tag Docker dans le message de commit: `ci: docker_tag=ext-0.1.2` (fallback CI: `dev-test`).
|
||||
- La branche peut être utilisée par la CI comme tag en l’absence d’override.
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "lecoffre-front",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.2",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
@ -42,17 +42,11 @@ export default function StepEmail(props: IProps) {
|
||||
const router = useRouter();
|
||||
const error = router.query["error"];
|
||||
const redirectUserOnConnection = useCallback(() => {
|
||||
/* TODO: review
|
||||
const variables = FrontendVariables.getInstance();
|
||||
const redirectUri = `${variables.FRONT_APP_HOST}/authorized-client`;
|
||||
const authorizeBase = `${variables.IDNOT_BASE_URL}${variables.IDNOT_AUTHORIZE_ENDPOINT}`;
|
||||
router.push(
|
||||
`${variables.IDNOT_BASE_URL + variables.IDNOT_AUTHORIZE_ENDPOINT}?client_id=${variables.IDNOT_CLIENT_ID}&redirect_uri=${
|
||||
variables.FRONT_APP_HOST
|
||||
}/authorized-client&scope=openid,profile&response_type=code`,
|
||||
);
|
||||
*/
|
||||
const redirectUri = 'http://local.4nkweb.com:3000/authorized-client';
|
||||
router.push(
|
||||
`https://qual-connexion.idnot.fr/user/IdPOAuth2/authorize/idnot_idp_v1?client_id=B3CE56353EDB15A9&redirect_uri=${redirectUri}&scope=openid,profile&response_type=code`,
|
||||
`${authorizeBase}?client_id=${variables.IDNOT_CLIENT_ID}&redirect_uri=${encodeURIComponent(redirectUri)}&scope=openid,profile&response_type=code`,
|
||||
);
|
||||
}, [router]);
|
||||
|
||||
|
@ -68,10 +68,9 @@ export default function LoginCallBack() {
|
||||
// TODO: review
|
||||
// HACK: If start with http://local.lecoffreio.4nkweb:3000/authorized-client
|
||||
// Replace with http://localhost:3000/authorized-client
|
||||
if (window.location.href.startsWith('http://local.4nkweb.com')) {
|
||||
window.location.href = window.location.href.replace('http://local.4nkweb.com:3000/authorized-client', 'http://localhost:3000/authorized-client');
|
||||
return;
|
||||
}
|
||||
// if (window.location.href.startsWith('http://local.4nkweb.com')) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
const code = router.query["code"];
|
||||
if (code) {
|
||||
|
16
tests/ext.md
Normal file
16
tests/ext.md
Normal file
@ -0,0 +1,16 @@
|
||||
### Tests image "ext"
|
||||
|
||||
Objectif: vérifier que l'image démarre et que les URLs d'API proviennent des variables d'environnement.
|
||||
|
||||
Plan de test manuel:
|
||||
|
||||
1. Construire l'image `--target ext` avec BuildKit et SSH forward.
|
||||
2. Démarrer un conteneur en exposant le port 3000 et en définissant des `NEXT_PUBLIC_*` non-localhost.
|
||||
3. Vérifier que le service répond en HTTP 200 sur `/`.
|
||||
4. Arrêter et supprimer le conteneur.
|
||||
|
||||
Critères de réussite:
|
||||
|
||||
- Le build aboutit sans erreur et produit une image étiquetée `ext-<version>`.
|
||||
- Le conteneur écoute sur 3000 et renvoie un code HTTP 200.
|
||||
- Aucune référence à `localhost` n'est nécessaire pour les appels API (validation via configuration d'ENV uniquement).
|
Loading…
x
Reference in New Issue
Block a user