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
|
WORKDIR /leCoffre-front
|
||||||
|
|
||||||
COPY package.json ./
|
COPY package.json ./
|
||||||
|
COPY package-lock.json ./
|
||||||
|
|
||||||
RUN apk update && apk add --no-cache openssh-client git
|
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 \
|
RUN --mount=type=ssh \
|
||||||
mkdir -p /root/.ssh && \
|
mkdir -p /root/.ssh && \
|
||||||
ssh-keyscan git.4nkweb.com >> /root/.ssh/known_hosts && \
|
ssh-keyscan git.4nkweb.com >> /root/.ssh/known_hosts && \
|
||||||
npm install --frozen-lockfile
|
npm install --no-audit --no-fund
|
||||||
|
|
||||||
# Configuration pour le développement
|
# Configuration pour le développement
|
||||||
FROM node:19-alpine AS development
|
FROM node:19-alpine AS development
|
||||||
@ -27,3 +28,70 @@ USER lecoffreuser
|
|||||||
|
|
||||||
CMD ["npm", "run", "dev"]
|
CMD ["npm", "run", "dev"]
|
||||||
EXPOSE 3000
|
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
|
### Portée
|
||||||
|
|
||||||
- **Build applicatif**: Next.js (Node 19-alpine) avec dépendance privée `le-coffre-resources` via SSH.
|
- **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`.
|
- **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
|
### 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, registre et version
|
||||||
|
|
||||||
- **Image utilisée en cluster**: `rg.fr-par.scw.cloud/lecoffre/front:v0.1.9` (cf. `temp.yaml`).
|
- **Registre**: Docker registry interne sur `git.4nkweb.com`.
|
||||||
- **Registre**: Scaleway Container Registry (région `fr-par`).
|
- **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.
|
||||||
- **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.
|
|
||||||
|
|
||||||
### Déploiement Kubernetes (extrait de `temp.yaml`)
|
### 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).
|
- `npm run build` (désactive la télémétrie et le lint bloquant).
|
||||||
|
|
||||||
4. **Construction de l’image**
|
4. **Construction de l’image**
|
||||||
- `docker build` avec BuildKit et forward d’agent SSH.
|
- Réalisée par la CI (BuildKit + forward d’agent SSH) après un `git push` sur `git.4nkweb.com`.
|
||||||
- Taggage semver (ex. `v0.1.9`) et éventuellement `latest`/environnement (non constaté ici).
|
- Taggage déterminé par le message de commit et/ou la branche.
|
||||||
|
|
||||||
5. **Push au registre**
|
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**
|
6. **Déploiement Kubernetes**
|
||||||
- Application des manifestes (ou rendu Helm) dans le namespace `lecoffre`.
|
- 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",
|
"name": "lecoffre-front",
|
||||||
"version": "0.1.0",
|
"version": "0.1.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
|
@ -42,17 +42,11 @@ export default function StepEmail(props: IProps) {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const error = router.query["error"];
|
const error = router.query["error"];
|
||||||
const redirectUserOnConnection = useCallback(() => {
|
const redirectUserOnConnection = useCallback(() => {
|
||||||
/* TODO: review
|
|
||||||
const variables = FrontendVariables.getInstance();
|
const variables = FrontendVariables.getInstance();
|
||||||
|
const redirectUri = `${variables.FRONT_APP_HOST}/authorized-client`;
|
||||||
|
const authorizeBase = `${variables.IDNOT_BASE_URL}${variables.IDNOT_AUTHORIZE_ENDPOINT}`;
|
||||||
router.push(
|
router.push(
|
||||||
`${variables.IDNOT_BASE_URL + variables.IDNOT_AUTHORIZE_ENDPOINT}?client_id=${variables.IDNOT_CLIENT_ID}&redirect_uri=${
|
`${authorizeBase}?client_id=${variables.IDNOT_CLIENT_ID}&redirect_uri=${encodeURIComponent(redirectUri)}&scope=openid,profile&response_type=code`,
|
||||||
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`,
|
|
||||||
);
|
);
|
||||||
}, [router]);
|
}, [router]);
|
||||||
|
|
||||||
|
@ -68,10 +68,9 @@ export default function LoginCallBack() {
|
|||||||
// TODO: review
|
// TODO: review
|
||||||
// HACK: If start with http://local.lecoffreio.4nkweb:3000/authorized-client
|
// HACK: If start with http://local.lecoffreio.4nkweb:3000/authorized-client
|
||||||
// Replace with http://localhost:3000/authorized-client
|
// Replace with http://localhost:3000/authorized-client
|
||||||
if (window.location.href.startsWith('http://local.4nkweb.com')) {
|
// 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;
|
||||||
return;
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
const code = router.query["code"];
|
const code = router.query["code"];
|
||||||
if (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