Files
test-quarkus/scripts/README.md
T
darroyo b65730c45f El nombre de la imagen sale de la carpeta del servicio y el Dockerfile depende de si es java o web.
Así se puede desplegar sin pom.xml y ubicar el Dockerfile en la raíz cuando el servicio es web.
2026-09-25 12:55:43 -03:00

227 lines
8.1 KiB
Markdown

# Scripts de despliegue
Guía de uso de los scripts de este directorio.
## `build-and-push.sh`
Construye la imagen nativa de Quarkus y la envía al daemon Docker de un host remoto por SSH, sin usar un registry externo ([unregistry](https://github.com/psviderski/unregistry) / `docker pussh`). Solo se transfieren las capas que el remoto aún no tiene.
### Qué hace el flujo
1. Toma el nombre de la imagen de la última carpeta de la ubicación del servicio y lee `version` de [`pom.xml`](../pom.xml) para el tag, salvo que uses `--name` o `--tag`. Si no hay `pom.xml`, el tag es `1.0.0-SNAPSHOT`.
2. Ejecuta `docker build` para la plataforma fija `linux/amd64` (útil si construyes desde un Mac arm64). Con `--type java` (el valor por defecto) usa [`src/main/docker/Dockerfile`](../src/main/docker/Dockerfile). Con `--type web` usa `Dockerfile` en la raíz del servicio.
3. Ejecuta `docker pussh` hacia el destino SSH indicado.
4. Comprueba por SSH que la imagen existe en el remoto (salvo `--no-verify`).
5. Muestra un comando `docker run` sugerido para arrancar el contenedor en el remoto.
### Requisitos
| Requisito | Descripción |
|-----------|-------------|
| Docker local | Daemon en marcha (`docker info` debe responder). |
| SSH | Acceso al host remoto; en el remoto debe estar instalado y usable Docker. |
| Plugin `docker pussh` | CLI plugin de unregistry. |
Si el plugin no está instalado, el script indica cómo añadirlo:
```shell
mkdir -p ~/.docker/cli-plugins
curl -fsSL https://raw.githubusercontent.com/psviderski/unregistry/main/docker-pussh \
-o ~/.docker/cli-plugins/docker-pussh
chmod +x ~/.docker/cli-plugins/docker-pussh
```
`xmllint` es opcional: si no está en el PATH y existe `pom.xml`, el script obtiene `version` del POM con `grep`/`sed`.
### Invocación
Puedes ejecutar el script desde cualquier directorio. Por defecto usa como raíz del proyecto el directorio padre de `scripts/` (donde está `pom.xml`).
```shell
./scripts/build-and-push.sh --remote USER@HOST
```
Alternativas para la raíz del proyecto:
- `--project-dir /ruta/al/proyecto`
- variable de entorno `PROJECT_DIR`
Ayuda integrada (en inglés):
```shell
./scripts/build-and-push.sh --help
```
### Opciones
**Destino (obligatorio)**
| Opción | Descripción |
|--------|-------------|
| `--remote TARGET` | Destino SSH: `usuario@host[:puerto]` o un alias definido en `~/.ssh/config` (sin `@`). |
**Identidad de la imagen** (el nombre es la última carpeta del servicio; el tag sale de `pom.xml` si existe)
| Opción | Descripción |
|--------|-------------|
| `--name NAME` | Nombre del repositorio de la imagen. |
| `--tag TAG` | Tag de la imagen. |
**Directorio de trabajo**
| Opción | Descripción |
|--------|-------------|
| `--project-dir PATH` | Raíz del servicio. El nombre de la imagen es su última carpeta. |
| `PROJECT_DIR` | Misma función vía entorno. |
**Build**
| Opción | Descripción |
|--------|-------------|
| `--type` | Dónde está el Dockerfile. `java` (por defecto): `src/main/docker/Dockerfile`. `web`: `Dockerfile` en la raíz del servicio. |
| `--skip-build` | No construye; solo hace `pussh` de una imagen que ya exista en local. La plataforma de build sigue siendo `linux/amd64` cuando no se omite el build. |
**SSH** (se reenvían a `docker pussh` y, en la verificación, a `ssh`)
| Opción | Descripción |
|--------|-------------|
| `--ssh-key PATH` | Clave privada; tiene prioridad sobre `IdentityFile` del config SSH. |
| `--ssh-config PATH` | Archivo de configuración SSH (por defecto `~/.ssh/config`). |
**Post-push**
| Opción | Descripción |
|--------|-------------|
| `--no-verify` | Omite la comprobación `docker images` en el remoto. |
**Otros**
| Opción | Descripción |
|--------|-------------|
| `-h`, `--help` | Muestra la ayuda del script. |
### Alias en `~/.ssh/config`
Si `--remote` es un alias sin `@`, el script resuelve `HostName`, `User`, `Port` e `IdentityFile` del bloque `Host` correspondiente. `--ssh-key` siempre anula `IdentityFile`.
Ejemplo de configuración:
```text
# ~/.ssh/config
Host prod
HostName prod.example.com
User deploy
Port 22
IdentityFile ~/.ssh/deploy_ed25519
```
Uso:
```shell
./scripts/build-and-push.sh --remote prod
# Equivale a deploy@prod.example.com:22 con la clave del bloque Host prod
```
### Ejemplos
Destino explícito:
```shell
./scripts/build-and-push.sh --remote deploy@prod.example.com
```
Alias SSH:
```shell
./scripts/build-and-push.sh --remote prod
```
Clave explícita:
```shell
./scripts/build-and-push.sh --remote ubuntu@1.2.3.4 --ssh-key ~/.ssh/deploy_ed25519
```
Solo push (imagen ya construida) con otro tag:
```shell
./scripts/build-and-push.sh --remote deploy@prod --skip-build --tag 2.0.0
```
Ruta absoluta al script:
```shell
/absolute/path/to/test-quarkus/scripts/build-and-push.sh --remote deploy@prod
```
Proyecto en otra ruta:
```shell
PROJECT_DIR=/srv/proj ./scripts/build-and-push.sh --remote deploy@prod --skip-build
```
### Después del push
Al terminar con éxito, el script sugiere algo equivalente a:
```shell
ssh deploy@prod.example.com \
"docker run -d --name <carpeta> --restart unless-stopped -p 8080:8080 <carpeta>:<version>"
```
Sustituye `<carpeta>` por la última carpeta de la ubicación del servicio (o el valor de `--name`) y `<version>` por el tag del build (el de `pom.xml`, `1.0.0-SNAPSHOT` si no hay POM, o el de `--tag`).
### Solución de problemas
#### `invalid reference format` con saltos de línea en el tag
Si `docker build` falla con un tag parecido a `test-quarkus\n1.0.0-SNAPSHOT:test-quarkus\n1.0.0-SNAPSHOT`, el checkout del script es anterior al commit `57af30f`. En hosts sin `xmllint` (por ejemplo vm-compilador), el fallback antiguo de `read_pom` mezclaba `artifactId` y `version` en una sola cadena.
En la máquina donde compilas (`~/repo` u otra ruta del proyecto):
```shell
git rev-parse --short HEAD
grep -n 'head -2' scripts/build-and-push.sh || echo "script actualizado"
git pull
git rev-parse --short HEAD # debe ser 57af30f o posterior
./scripts/build-and-push.sh --remote TU_DESTINO
```
Comprueba que la primera línea del log sea `Image: test-quarkus:1.0.0-SNAPSHOT` (sin saltos de línea).
**Atajo** si aún no puedes actualizar el repo: fija nombre y tag explícitos (no usa el fallback roto):
```shell
./scripts/build-and-push.sh --remote TU_DESTINO \
--name test-quarkus --tag 1.0.0-SNAPSHOT
```
Opcional: instala `xmllint` para que el script lea el POM con XPath (`libxml2-utils` en Debian/Ubuntu).
## `deploy-services.sh`
Script independiente, en el mismo directorio que `build-and-push.sh`. No lo modifica: lo ejecuta una vez por cada servicio de un archivo de lista. Si un servicio falla, sigue con el resto y al terminar indica cuáles fallaron. El código de salida es `1` si alguno falló.
Al terminar el lote, ese resumen queda también en `deploy-YYYYMMDD-HHMMSS.log` en el directorio desde el que se lanzó el script (hora local de inicio). Si ese nombre ya existe, se añade el PID. Si no se puede escribir el archivo, el script avisa y conserva el código de salida del lote.
No hay lista por defecto. `--services` es obligatorio, así cada proyecto puede tener su propio archivo.
```shell
./scripts/deploy-services.sh --remote prod --services /srv/proyecto-a/services.txt
./scripts/deploy-services.sh --remote prod --services /srv/proyecto-b/services.txt --skip-build
```
Formato del archivo: una ruta por línea y, si hace falta, un segundo campo `java` o `web`. Si el tipo falta, es `java`. Se ignoran las líneas vacías y las que empiezan por `#`. Una ruta relativa se resuelve desde el directorio del archivo de lista, no desde el directorio donde lanzas el script.
```text
# /srv/proyecto-a/services.txt
./api
./portal web
```
`java` usa `src/main/docker/Dockerfile`. `web` usa `Dockerfile` en la raíz del servicio. El nombre de la imagen es la última carpeta de esa ruta. El tag sale de `pom.xml` si existe; si no, es `1.0.0-SNAPSHOT`.
Se reenvían a cada servicio: `--ssh-key`, `--ssh-config`, `--skip-build`, `--no-verify` y `--cleanup`, más el `--type` de esa línea. No se aceptan `--name`, `--tag`, `--project-dir` ni `--type`.
Ctrl+C interrumpe el lote. Ayuda: `./scripts/deploy-services.sh --help`.