Compare commits

..
Author SHA1 Message Date
devops 27a1e75a4c fix(devsecops): timeout de 15m en Trivy imagen para docs-portal
Preventivo: mismo comando que en commerce-backend, donde se vio en
vivo que el timeout default de Trivy (5m) no alcanza en este host bajo
carga ("context deadline exceeded" a los 4m52s, run 136). Ver
fix/devsecops-trivy-timeout para el fix real en commerce-backend.
2026-08-15 13:08:24 -05:00
devops 1bcae76102 feat(devsecops): replicar pipeline de seguridad a docs-portal
Agrega a deploy-docs.yaml las mismas 6 etapas ya validadas en
build.yaml (run 134, frontend): Gitleaks, Trivy IaC, Semgrep (SAST),
Trivy imagen, Syft (SBOM) y Cosign (firma + verificación).

Adaptaciones de stack:
- Trivy IaC escanea todo workloads/docs-portal/ (varios manifiestos
  K8s separados: deployment/service/ingress), no un MANIFEST_FILE
  único como el frontend.
- Semgrep usa p/python + p/security-audit (no hay TypeScript/React
  acá) -- docs-portal no tiene código de aplicación propio hoy (solo
  Markdown + config de MkDocs), así que 0 hallazgos es el resultado
  esperado; el stage queda listo para el día que se agregue un
  hook/plugin en Python.

Mismos umbrales que el resto: Trivy bloquea en CRITICAL, Semgrep en
modo auditoría. Reutiliza el mismo par de llaves Cosign (secrets ya
existentes a nivel de repo); se agrega workloads/docs-portal/cosign.pub.
2026-08-15 12:47:43 -05:00
devops c25877c700 chore: release v1.0.104 [skip ci] 2026-08-15 06:23:20 +00:00
devops 941c009c9c Merge pull request 'chore: retrigger real del pipeline (take 4)' (#25) from chore/retrigger-pipeline-take4 into main
Build and Push Frontend / Escaneo de Secretos (Gitleaks) (push) Successful in 21s
Build and Push Frontend / Construir y Subir Imagen (push) Successful in 7m26s
2026-08-15 06:15:09 +00:00
devops 5d3d578d36 chore: retrigger real del pipeline (comentario en build.yaml, path filtrado)
Build and Push Frontend / Escaneo de Secretos (Gitleaks) (pull_request) Successful in 29s
Build and Push Frontend / Construir y Subir Imagen (pull_request) Skipped
2026-08-15 01:14:59 -05:00
devops ff1f1358a7 Merge pull request 'chore: reintentar disparo del pipeline (take 3)' (#24) from chore/retrigger-pipeline-take3 into main 2026-08-15 06:10:55 +00:00
devops f9a4b0a4ea chore: reintentar disparo del pipeline (take 3, runner reiniciado) 2026-08-15 01:10:42 -05:00
devops 69db467edd Merge pull request 'chore: reintentar disparo del pipeline (take 2)' (#23) from chore/retrigger-pipeline-take2 into main 2026-08-15 06:09:07 +00:00
devops 63de0b4ed3 chore: reintentar disparo del pipeline (la corrida anterior coincidió con inestabilidad transitoria del túnel) 2026-08-15 01:08:56 -05:00
devops 9418fb4d1a Merge pull request 'chore: re-disparar pipeline tras fix del tunel Cloudflare' (#22) from chore/retrigger-pipeline-cosign-fix into main 2026-08-15 06:03:47 +00:00
devops c492269740 chore: re-disparar pipeline tras arreglar el realm https del túnel Cloudflare→NPM
El fix fue en infraestructura (regla de ingress de cloudflared para
gitea.cruzcloud.net -> HTTPS con Origin Server Name correcto), no en
este repo -- este commit vacío es solo para generar un push nuevo y
validar el pipeline completo (incluida la firma de Cosign) de punta
a punta con las credenciales reales.
2026-08-15 01:03:33 -05:00
devops 1f467f2b8f Merge pull request 'fix(ci): correr Semgrep nativo (venv) en vez de docker run anidado' (#21) from fix/build-yaml-anchor-not-supported into main
Build and Push Frontend / Escaneo de Secretos (Gitleaks) (push) Successful in 17s
Build and Push Frontend / Construir y Subir Imagen (push) Failing after 11m59s
2026-08-15 04:50:41 +00:00
devops e3ab3f7fc0 fix(ci): correr Semgrep nativo (venv) en vez de docker run anidado
Build and Push Frontend / Escaneo de Secretos (Gitleaks) (pull_request) Successful in 22s
Build and Push Frontend / Construir y Subir Imagen (pull_request) Skipped
El runner de Gitea ejecuta cada job dentro de un contenedor propio que
habla con el daemon Docker del host (sibling containers) -- un
`docker run -v "\${{ github.workspace }}:/src"` desde ahí intenta
montar una ruta que solo existe DENTRO del contenedor del job, no en
el host real: "mkdir /workspace: read-only file system". Confirmado en
el run real (job 128, task_id 128) tras el fix del anchor.

Se valida localmente contra docker.gitea.com/runner-images:ubuntu-latest
(la misma imagen del runner real) que python3/pip3 están disponibles.
pip3 install directo falla por paquetes de apt sin metadata compatible
(PyJWT, "RECORD file not found") -- se usa un venv aislado en su lugar,
validado end-to-end con los dos steps extraídos del YAML real.
2026-08-14 23:50:23 -05:00
devops 1df1c3a3c1 Merge pull request 'fix(ci): quitar anchors/aliases YAML de build.yaml' (#20) from fix/build-yaml-anchor-not-supported into main
Build and Push Frontend / Escaneo de Secretos (Gitleaks) (push) Successful in 25s
Build and Push Frontend / Construir y Subir Imagen (push) Failing after 42s
2026-08-15 04:25:51 +00:00
devops 6773a8085d fix(ci): quitar anchors/aliases YAML de build.yaml, no soportados por Gitea Actions
Build and Push Frontend / Escaneo de Secretos (Gitleaks) (pull_request) Successful in 39s
Build and Push Frontend / Construir y Subir Imagen (pull_request) Skipped
Gitea descartaba el workflow completo en TODOS los eventos (push y
pull_request), desde el primer commit de gitleaks: "unknown on type:
&yaml.Node{...Value:"frontend_paths"...}". El YAML era válido (pyyaml
lo parsea sin problema, resolviendo el alias como cualquier parser
estándar) pero el parser propio de Gitea Actions para el bloque "on:"
no resuelve &anchor/*alias antes de inspeccionar el tipo de nodo.

Confirmado en vivo: tras mergear #19 a main, deploy-docs.yaml corrió
normal (sin anchors) pero build.yaml no generó ningún action_run.

Fix: paths duplicados literalmente entre push: y pull_request:, sin
anchor. Válido con parser YAML + bash -n en los 20 steps.
2026-08-14 23:24:31 -05:00
gitea-actions ea7d5e7f47 chore(gitops): deploy Docs Portal v1.0.98 [skip ci] 2026-08-15 04:15:42 +00:00
devops 98096ab69f Merge pull request 'feat(devsecops): Gitleaks + Trivy + Semgrep + Syft + Cosign en el frontend' (#19) from fix/frontend-gitleaks-ci into main
Build and Push Docs Portal / Construir y publicar Docs Portal (push) Successful in 1m36s
2026-08-15 04:14:08 +00:00
5 changed files with 333 additions and 29 deletions
+54 -14
View File
@@ -1,10 +1,18 @@
name: Build and Push Frontend name: Build and Push Frontend
# Retrigger real (take 4): los 3 intentos anteriores fueron commits vacíos
# (--allow-empty) que no tocaban ningún path filtrado -- por diseño, nunca
# iban a disparar build.yaml. Este comentario sí cuenta como cambio real
# en .gitea/workflows/build.yaml, que está en la lista de paths.
on: on:
# NOTA: sin anchors/aliases de YAML (&x / *x) a propósito -- el parser
# de workflows de Gitea Actions no los resuelve en el bloque "on:" y
# descarta el archivo completo con "unknown on type" (visto en vivo el
# 2026-08-15). Las dos listas de paths quedan duplicadas literalmente.
push: push:
branches: branches:
- main - main
paths: &frontend_paths paths:
# Código y configuración real del frontend. # Código y configuración real del frontend.
# Los cambios exclusivos de GitOps (frontend.yaml, ingress, patches, etc.) # Los cambios exclusivos de GitOps (frontend.yaml, ingress, patches, etc.)
# no vuelven a construir la imagen. # no vuelven a construir la imagen.
@@ -32,7 +40,28 @@ on:
pull_request: pull_request:
branches: branches:
- main - main
paths: *frontend_paths paths:
- 'workloads/ecommerce/Dockerfile'
- 'workloads/ecommerce/.dockerignore'
- 'workloads/ecommerce/.npmrc'
- 'workloads/ecommerce/package.json'
- 'workloads/ecommerce/package-lock.json'
- 'workloads/ecommerce/next.config.*'
- 'workloads/ecommerce/tsconfig.json'
- 'workloads/ecommerce/tailwind.config.*'
- 'workloads/ecommerce/postcss.config.*'
- 'workloads/ecommerce/eslint.config.*'
- 'workloads/ecommerce/*.js'
- 'workloads/ecommerce/*.mjs'
- 'workloads/ecommerce/*.ts'
- 'workloads/ecommerce/*.tsx'
- 'workloads/ecommerce/app/**'
- 'workloads/ecommerce/src/**'
- 'workloads/ecommerce/components/**'
- 'workloads/ecommerce/lib/**'
- 'workloads/ecommerce/public/**'
- 'workloads/ecommerce/styles/**'
- '.gitea/workflows/build.yaml'
permissions: permissions:
contents: write contents: write
@@ -260,6 +289,27 @@ jobs:
--exit-code 0 \ --exit-code 0 \
"${MANIFEST_FILE}" "${MANIFEST_FILE}"
# Instalado directo con pip (no como container aparte): el runner de
# Gitea ejecuta cada job ya dentro de un contenedor propio que habla
# con el daemon Docker del host (sibling containers) -- un
# `docker run -v "${{ github.workspace }}:/src"` desde acá intenta
# montar una ruta que solo existe DENTRO del contenedor del job, no
# en el host real, y falla con "read-only file system". Evitamos por
# completo el problema corriendo Semgrep nativo, igual que
# gitleaks/trivy/syft/cosign.
# venv en vez de "pip3 install --break-system-packages": la imagen del
# runner ya trae paquetes de Python instalados por apt (ej. PyJWT)
# sin metadata compatible con pip, y pip aborta al intentar
# reemplazarlos ("RECORD file not found"). Un venv aislado evita
# tocar los paquetes del sistema por completo.
- name: Instalar Semgrep
shell: bash
run: |
set -euo pipefail
python3 -m venv /tmp/semgrep-venv
/tmp/semgrep-venv/bin/pip install --quiet "semgrep==1.173.0"
/tmp/semgrep-venv/bin/semgrep --version
# Modo auditoría: sin --error a propósito, Semgrep siempre termina # Modo auditoría: sin --error a propósito, Semgrep siempre termina
# con exit 0 aunque reporte hallazgos. Es la primera vuelta — se # con exit 0 aunque reporte hallazgos. Es la primera vuelta — se
# revisan los resultados en conjunto antes de decidir qué reglas # revisan los resultados en conjunto antes de decidir qué reglas
@@ -268,13 +318,7 @@ jobs:
shell: bash shell: bash
run: | run: |
set -euo pipefail set -euo pipefail
SEMGREP_IMAGE="semgrep/semgrep:1.173.0" /tmp/semgrep-venv/bin/semgrep scan \
docker run --rm \
-v "${{ github.workspace }}:/src" \
-w /src \
"${SEMGREP_IMAGE}" \
semgrep scan \
--config=p/typescript \ --config=p/typescript \
--config=p/react \ --config=p/react \
--config=p/nextjs \ --config=p/nextjs \
@@ -284,11 +328,7 @@ jobs:
"${APP_DIR}" "${APP_DIR}"
echo "=== Resumen Semgrep ===" echo "=== Resumen Semgrep ==="
docker run --rm \ /tmp/semgrep-venv/bin/python -c "
-v "${{ github.workspace }}:/src" \
-w /src \
"${SEMGREP_IMAGE}" \
python3 -c "
import json import json
data = json.load(open('semgrep-report.json')) data = json.load(open('semgrep-report.json'))
results = data.get('results', []) results = data.get('results', [])
+266 -6
View File
@@ -1,5 +1,9 @@
name: Build and Push Docs Portal name: Build and Push Docs Portal
# Sin anchors/aliases de YAML (&x / *x) a propósito -- el parser de
# workflows de Gitea Actions no los resuelve en el bloque "on:" y
# descarta el archivo completo con "unknown on type". Las dos listas de
# paths quedan duplicadas literalmente (mismo criterio que build.yaml).
on: on:
push: push:
branches: branches:
@@ -10,14 +14,71 @@ on:
- 'workloads/docs-portal/requirements.txt' - 'workloads/docs-portal/requirements.txt'
- 'workloads/docs-portal/Dockerfile' - 'workloads/docs-portal/Dockerfile'
- '.gitea/workflows/deploy-docs.yaml' - '.gitea/workflows/deploy-docs.yaml'
pull_request:
branches:
- main
paths:
- 'workloads/docs-portal/docs/**'
- 'workloads/docs-portal/mkdocs.yml'
- 'workloads/docs-portal/requirements.txt'
- 'workloads/docs-portal/Dockerfile'
- '.gitea/workflows/deploy-docs.yaml'
permissions: permissions:
contents: write contents: write
packages: write packages: write
jobs: jobs:
# Corre en push y en pull_request, siempre antes que build. Mismo
# criterio que el frontend: si hay un secreto commiteado, el job build
# nunca arranca (needs: gitleaks).
gitleaks:
name: Escaneo de Secretos (Gitleaks)
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout del código
uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Instalar Gitleaks
shell: bash
run: |
set -euo pipefail
GITLEAKS_VERSION="8.21.2"
curl -sSfL \
"https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \
-o /tmp/gitleaks.tar.gz
tar -xzf /tmp/gitleaks.tar.gz -C /tmp gitleaks
chmod +x /tmp/gitleaks
/tmp/gitleaks version
- name: Escanear secretos en el árbol de archivos
shell: bash
run: |
set -euo pipefail
/tmp/gitleaks detect \
--source=workloads/docs-portal \
--no-git \
--redact \
--report-format=json \
--report-path=gitleaks-report.json \
--exit-code=1
- name: Publicar reporte de Gitleaks
if: always()
uses: actions/upload-artifact@v3
with:
name: gitleaks-report
path: gitleaks-report.json
if-no-files-found: ignore
build: build:
name: Construir y publicar Docs Portal name: Construir y publicar Docs Portal
needs: gitleaks
if: github.event_name == 'push'
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 20 timeout-minutes: 20
@@ -56,6 +117,83 @@ jobs:
exit 1 exit 1
} }
- name: Instalar Trivy
shell: bash
run: |
set -euo pipefail
TRIVY_VERSION="0.74.0"
curl -sSfL \
"https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz" \
-o /tmp/trivy.tar.gz
tar -xzf /tmp/trivy.tar.gz -C /tmp trivy
chmod +x /tmp/trivy
/tmp/trivy version
# Escanea todo el directorio de la app (Deployment, Service,
# Ingress y Dockerfile), no un único MANIFEST_FILE como el
# frontend -- docs-portal tiene varios manifiestos K8s separados
# (deployment.yaml, service.yaml, ingress.yaml) en vez de uno
# solo, así que un único archivo dejaría fuera la mayoría del
# directorio. Informativo por ahora, mismo criterio que el resto.
- name: Escanear manifiestos Kubernetes (Trivy IaC)
shell: bash
run: |
set -euo pipefail
/tmp/trivy config \
--severity CRITICAL,HIGH,MEDIUM \
--exit-code 0 \
"${APP_DIR}"
# Mismo motivo que en build.yaml: sibling containers, no
# Docker-in-Docker -- Semgrep corre nativo en un venv.
- name: Instalar Semgrep
shell: bash
run: |
set -euo pipefail
python3 -m venv /tmp/semgrep-venv
/tmp/semgrep-venv/bin/pip install --quiet "semgrep==1.173.0"
/tmp/semgrep-venv/bin/semgrep --version
# Ruleset adaptado: docs-portal no tiene código de aplicación
# propio (es contenido Markdown + configuración de MkDocs), así
# que ni p/typescript ni p/react/p/nextjs del frontend aplican
# acá. Se usa p/python -- el único código ejecutable real en este
# directorio sería un hook/plugin de Python de MkDocs, si algún
# día se agrega uno. Hoy no hay ningún archivo .py en
# workloads/docs-portal, así que 0 hallazgos es el resultado
# esperado, no un falso negativo -- se deja el stage para que
# detecte código nuevo el día que se agregue, sin tener que
# recordar volver a tocar el pipeline. Modo auditoría, igual que
# el resto: no bloquea.
- name: Escaneo SAST (Semgrep) — modo auditoría, no bloquea
shell: bash
run: |
set -euo pipefail
/tmp/semgrep-venv/bin/semgrep scan \
--config=p/python \
--config=p/security-audit \
--json \
--output=semgrep-report.json \
"${APP_DIR}"
echo "=== Resumen Semgrep ==="
/tmp/semgrep-venv/bin/python -c "
import json
data = json.load(open('semgrep-report.json'))
results = data.get('results', [])
print(f'Hallazgos: {len(results)}')
for r in results:
print(f\" [{r['extra']['severity']}] {r['check_id']} - {r['path']}:{r['start']['line']}\")
"
- name: Publicar reporte de Semgrep
if: always()
uses: actions/upload-artifact@v3
with:
name: semgrep-report
path: semgrep-report.json
if-no-files-found: ignore
- name: Login en Gitea Registry - name: Login en Gitea Registry
uses: docker/login-action@v2 uses: docker/login-action@v2
with: with:
@@ -64,18 +202,129 @@ jobs:
password: ${{ secrets.REGISTRY_PASSWORD }} password: ${{ secrets.REGISTRY_PASSWORD }}
logout: true logout: true
# mkdocs build --strict corre dentro del propio Dockerfile (stage de # mkdocs build --strict corre dentro del propio Dockerfile (stage
# build), así que un nav/link roto rompe este paso antes de publicar. # de build), así que un nav/link roto rompe este paso antes de
- name: Construir y subir imagen # publicar. push: false / load: true -- igual que el frontend, la
# imagen queda cargada localmente para escanearla con Trivy antes
# de subirla.
- name: Construir Imagen
uses: docker/build-push-action@v4 uses: docker/build-push-action@v4
with: with:
context: workloads/docs-portal/ context: ${{ env.APP_DIR }}/
file: workloads/docs-portal/Dockerfile file: ${{ env.APP_DIR }}/Dockerfile
push: true push: false
load: true
tags: | tags: |
${{ env.IMAGE_NAME }}:${{ steps.vars.outputs.VERSION }} ${{ env.IMAGE_NAME }}:${{ steps.vars.outputs.VERSION }}
${{ env.IMAGE_NAME }}:latest ${{ env.IMAGE_NAME }}:latest
# CRITICAL bloquea el pipeline: no se sube una imagen con una CVE
# crítica conocida y con fix disponible.
# --timeout 15m0s: agregado preventivamente. Se vio en vivo, al
# correr este mismo comando sin el flag en commerce-backend, que
# el default de Trivy (5m) no alcanza en este host bajo carga
# ("context deadline exceeded" a los 4m52s) -- la imagen de
# docs-portal es chica, pero no cuesta nada blindar el mismo
# comando en los tres pipelines.
- name: Escanear imagen (Trivy) — CRITICAL bloquea
shell: bash
run: |
set -euo pipefail
/tmp/trivy image \
--severity CRITICAL \
--exit-code 1 \
--ignore-unfixed \
--timeout 15m0s \
"${IMAGE_NAME}:${{ steps.vars.outputs.VERSION }}"
# HIGH solo informa por ahora — mismo criterio que el resto.
- name: Escanear imagen (Trivy) — HIGH informativo
shell: bash
run: |
set -euo pipefail
/tmp/trivy image \
--severity HIGH \
--exit-code 0 \
--ignore-unfixed \
--timeout 15m0s \
"${IMAGE_NAME}:${{ steps.vars.outputs.VERSION }}"
- name: Instalar Syft
shell: bash
run: |
set -euo pipefail
SYFT_VERSION="1.51.0"
curl -sSfL \
"https://github.com/anchore/syft/releases/download/v${SYFT_VERSION}/syft_${SYFT_VERSION}_linux_amd64.tar.gz" \
-o /tmp/syft.tar.gz
tar -xzf /tmp/syft.tar.gz -C /tmp syft
chmod +x /tmp/syft
/tmp/syft version
- name: Generar SBOM (Syft)
shell: bash
run: |
set -euo pipefail
/tmp/syft "${IMAGE_NAME}:${{ steps.vars.outputs.VERSION }}" \
-o cyclonedx-json=sbom.cdx.json \
-o spdx-json=sbom.spdx.json
- name: Publicar SBOM
if: always()
uses: actions/upload-artifact@v3
with:
name: sbom-${{ steps.vars.outputs.VERSION }}
path: |
sbom.cdx.json
sbom.spdx.json
if-no-files-found: ignore
# Login ya se hizo arriba; recién acá se sube, después de que la
# imagen pasó el gate de CRITICAL.
- name: Subir Imagen al Registry
shell: bash
run: |
set -euo pipefail
docker push "${IMAGE_NAME}:${{ steps.vars.outputs.VERSION }}"
docker push "${IMAGE_NAME}:latest"
- name: Instalar Cosign
shell: bash
run: |
set -euo pipefail
COSIGN_VERSION="3.1.3"
curl -sSfL \
"https://github.com/sigstore/cosign/releases/download/v${COSIGN_VERSION}/cosign-linux-amd64" \
-o /tmp/cosign
chmod +x /tmp/cosign
/tmp/cosign version
# Mismo par de llaves que el frontend y commerce-backend (secrets
# ya existentes a nivel de repo). Llave pública commiteada en
# workloads/docs-portal/cosign.pub.
- name: Firmar Imagen (Cosign)
shell: bash
env:
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
run: |
set -euo pipefail
/tmp/cosign sign \
--key env://COSIGN_PRIVATE_KEY \
--use-signing-config=false \
--tlog-upload=false \
--yes \
"${IMAGE_NAME}:${{ steps.vars.outputs.VERSION }}"
- name: Verificar Firma (smoke test)
shell: bash
run: |
set -euo pipefail
/tmp/cosign verify \
--key "${APP_DIR}/cosign.pub" \
--insecure-ignore-tlog=true \
"${IMAGE_NAME}:${{ steps.vars.outputs.VERSION }}"
- name: Verificar promoción segura - name: Verificar promoción segura
id: promotion id: promotion
shell: bash shell: bash
@@ -123,3 +372,14 @@ jobs:
-m "chore(gitops): deploy Docs Portal ${VERSION} [skip ci]" -m "chore(gitops): deploy Docs Portal ${VERSION} [skip ci]"
git push origin HEAD:main git push origin HEAD:main
- name: Resumen del pipeline
if: always()
shell: bash
run: |
echo "========================================"
echo "CruzCloud Lab Docs Portal"
echo "Versión: ${{ steps.vars.outputs.VERSION }}"
echo "Commit: ${{ github.sha }}"
echo "Promoción GitOps: ${{ steps.promotion.outputs.promote }}"
echo "========================================"
+4
View File
@@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhjg9/nC0u+iEANiHkVJY8iN+LZo+
VFMF7XG/oC64W3/SfwrPgt+ZIqF6t+ceyrNuEgugajvUdpigz1PHEqQKLw==
-----END PUBLIC KEY-----
+1 -1
View File
@@ -16,7 +16,7 @@ spec:
- name: gitea-registry-secret - name: gitea-registry-secret
containers: containers:
- name: docs-portal - name: docs-portal
image: gitea.cruzcloud.net/devops/docs-portal:v1.0.97 image: gitea.cruzcloud.net/devops/docs-portal:v1.0.98
ports: ports:
- containerPort: 80 - containerPort: 80
resources: resources:
+1 -1
View File
@@ -16,7 +16,7 @@ spec:
- name: gitea-registry-secret - name: gitea-registry-secret
containers: containers:
- name: web - name: web
image: gitea.cruzcloud.net/devops/ecommerce-frontend:v1.0.91 image: gitea.cruzcloud.net/devops/ecommerce-frontend:v1.0.104
ports: ports:
- containerPort: 80 - containerPort: 80
env: env: