Esta página empaqueta un servidor de TypeScript como imagen de contenedor basada en elide.dev/elide.
Escribir la app
// server.ts
import { Hono } from "hono";
const app = new Hono();
app.use(async (c, next) => {
await next();
console.log(JSON.stringify({ method: c.req.method, path: c.req.path, status: c.res.status }));
});
app.get("/healthz", (c) => c.text("ok"));
app.get("/", (c) => c.json({ greeting: process.env.GREETING ?? "hello" }));
export default app;// healthcheck.mjs
const res = await fetch("http://127.0.0.1:8080/healthz");
process.exit(res.ok ? 0 : 1);{
"name": "deploy-app",
"type": "module",
"dependencies": {
"hono": "^4.7.0"
}
}Ejecute elide install --ecosystems=npm una vez para escribir aube-lock.yaml.
Escribir el Dockerfile
FROM elide.dev/elide:1.6.0
WORKDIR /app
COPY package.json aube-lock.yaml ./
RUN elide install --ecosystems=npm
COPY . .
EXPOSE 8080
HEALTHCHECK --interval=10s --timeout=3s CMD ["elide", "healthcheck.mjs"]
CMD ["--allow-read=/app,/root/.cache/aube", "--allow-net=api.example.com", "serve", "--no-tui", "--host", "0.0.0.0", "--port", "8080", "server.ts"]# .dockerignore
node_modules
.env| Línea | Motivo |
|---|---|
FROM elide. | El punto de entrada de la imagen es elide, así que CMD contiene solo sus argumentos. Etiquetas: Imágenes de contenedor. |
RUN elide install --ecosystems= | Instala dentro de la imagen. node_modules enlaza a /root/.cache/aube, así que un node_modules del host no funcionaría. |
--host 0.0.0.0 | Un manejador exportado por defecto escucha en 127.0.0.1, que no es accesible desde fuera del contenedor. |
--no-tui | Sin ella, docker run -t inicia la interfaz de terminal y la salida de la app nunca llega a docker logs. |
HEALTHCHECK | La imagen no tiene curl ni wget; un script corto de Elide hace la comprobación. |
docker build -t my-app .
docker run -d --name my-app -p 8080:8080 -e GREETING=hi my-app
curl http://127.0.0.1:8080/{"greeting":"hi"}docker inspect --format '{{.State.Health.Status}}' my-app imprime healthy en cuanto pasa la primera comprobación.
docker stop detiene el servidor en menos de un segundo, con el código de salida 143.
Pasar variables de entorno
process.env contiene las variables del contenedor; páselas con docker run -e NAME=value o --env-file .env. Elide
no lee archivos .env ni define NODE_ENV. Para ejecuciones locales, cargue el archivo en el código:
import { existsSync } from "node:fs";
if (existsSync(".env")) process.loadEnvFile();Sin la comprobación, process.loadEnvFile() lanza ENOENT: no such file or directory, open '.env' cuando falta el
archivo. Consulte Variables de entorno.
Restringir el servidor
Los programas se ejecutan sin restricciones hasta que se indica una opción de sandbox. Conceda al servidor lo que necesita y nada más:
| Opción | En el Dockerfile anterior |
|---|---|
--allow-read=PATHS | /app y el almacén de npm /root/.cache/aube. |
--allow-net=HOSTS | Hosts de salida. Escuchar en un puerto no necesita permiso. |
--allow-run=CMDS | No se indica: los subprocesos siguen permitidos. Indique una lista para restringirlos. |
--deny-net=HOSTS | Hosts bloqueados aunque estén permitidos, p. ej. --deny-net=. |
--max-mem=SIZE, --timeout=DURATION | Tamaño del heap y tiempo total de ejecución. |
Las opciones globales van antes del comando (serve, run). --deny-net y --deny-run necesitan la forma con =.
Si el almacén de npm no está en --allow-read, el servidor se detiene al arrancar:
Error: Filesystem read denied by policy: /app/node_modules/honoUna llamada de salida bloqueada nombra la opción:
fetch to '169.254.169.254:80' denied by --deny-netTodas las opciones: Sandbox y límites.
Leer los registros
console.log escribe en stdout y console.error en stderr; docker logs muestra ambos:
{"method":"GET","path":"/healthz","status":200}
{"method":"GET","path":"/","status":200}elide serve --no-tui no imprime registro de accesos, y un manejador que lanza una excepción responde 500 sin
imprimir el error. Registre las peticiones y los errores en la app, o exporte spans de peticiones, métricas y errores
con OpenTelemetry.
Desplegar una app de la JVM
- Cree una imagen JVM a partir de
elide.pklcon un artefactoContainerImage: Contenedores JVM. - Compile un ejecutable nativo: Native Image.