Escriba Dockerfiles y canalizaciones de CI en TypeScript.
Trellis es una herramienta CI/CD portátil. Con Trellis, puede definir sus Dockerfiles y canalizaciones de CI/CD en TypeScript y ejecutarlos en cualquier lugar (localmente o en una plataforma alojada).
Primero, instale Deno con brew install deno
(o similar).
En segundo lugar, instale Trellis CLI con:
deno install
--allow-run=docker
--allow-net
--allow-write
--allow-env
--allow-read
https://deno.land/x/[email protected]/cli.ts
Ejecute trellis --help
para verificar su instalación:
>>> trellis --help
Usage: trellis build mod.ts
Options:
-V, --version output the version number
-h, --help display help for command
Commands:
ls [file] List all Images and Tasks available in a
TypeScript module
preview [options] [file] Generate a Dockerfile defined in a TypeScript
module
build [options] [file] Build an Image defined in a TypeScript module
run [options] [file] Run a Task defined in a TypeScript module
help [command] display help for command
Exporte cualquier Image
para permitir la generación de Dockerfile y la creación de imágenes con Trellis.
Por ejemplo, para definir una imagen de Ubuntu con algunas utilidades útiles instaladas, puedes escribir el siguiente archivo mod.ts
:
import { Image } from "https://deno.land/x/[email protected]/mod.ts" ;
const UBUNTU_VERSION = "20.04" ;
export const buildStage = Image . from ( `ubuntu: ${ UBUNTU_VERSION } ` )
. workDir ( "/root" )
. aptInstall ( [
"curl" ,
"jq" ,
"git" ,
] ) ;
Al ejecutar trellis ls mod.ts
se enumeran las imágenes construibles:
>>> trellis ls mod.ts
Images:
- buildStage (trellis build --target buildStage)
Podemos obtener una vista previa del Dockerfile generado con trellis preview mod.ts --target buildStage
:
>>> trellis preview --target buildStage
# syntax=docker/dockerfile:1.4
FROM ubuntu:20.04 AS stage-0
WORKDIR /root
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,target=/var/lib/apt,sharing=locked apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends curl git jq
Podemos construir la imagen con trellis build --target buildStage
:
>>> trellis build --target buildStage
[+] Building 0.6s (11/11) FINISHED
= > [internal] load build definition from Dockerfile 0.0s
= > = > transferring dockerfile: 335B 0.0s
= > [internal] load .dockerignore 0.0s
= > = > transferring context: 2B 0.0s
= > resolve image config for docker.io/docker/dockerfile:1.4 0.2s
= > CACHED docker-image://docker.io/docker/dockerfile:1.4@sha256:9ba7531bd80fb0a858632727cf7a112fbf 0.0s
= > [internal] load build definition from Dockerfile 0.0s
= > [internal] load .dockerignore 0.0s
= > [internal] load metadata for docker.io/library/ubuntu:20.04 0.2s
= > [stage-0 1/3] FROM docker.io/library/ubuntu:20.04@sha256:35ab2bf57814e9ff49e365efd5a5935b6915ee 0.0s
= > CACHED [stage-0 2/3] WORKDIR /root 0.0s
= > CACHED [stage-0 3/3] RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=c 0.0s
= > exporting to image 0.0s
= > = > exporting layers 0.0s
= > = > writing image sha256:17f750ba9a4becf38ce4d584d0de4793bfd6a8139674c3b332cdcdf6525ea8d9 0.0s
= > = > naming to docker.io/trellis/db112e211de238c035a9fd3bbcbd5c417aafc5ee96a8c24d99d4caf81a759903 0.0s
√ Build: trellis/db112e211de238c035a9fd3bbcbd5c417aafc5ee96a8c24d99d4caf81a759903
Exporte cualquier función desde un módulo TypeScript para habilitar la ejecución de tareas con Trellis.
Por ejemplo, para definir una canalización de CI para verificar que nuestras utilidades de línea de comandos se instalaron correctamente, puede escribir el siguiente archivo tasks.ts
:
import { build , Image , run } from "https://deno.land/x/[email protected]/mod.ts" ;
import { buildStage } from "./mod.ts" ;
export default async function runChecks ( ) {
await build ( buildStage ) ;
const checkCurl = Image . from ( buildStage ) . run (
"curl --help" ,
) ;
const checkJq = Image . from ( buildStage ) . run (
"jq --help" ,
) ;
const checkGit = Image . from ( buildStage ) . run (
"git --help" ,
) ;
await Promise . all ( [
run ( checkCurl ) ,
run ( checkJq ) ,
run ( checkGit ) ,
] ) ;
}
Al ejecutar trellis ls tasks.ts
se enumeran las tareas ejecutables:
>>> trellis ls tasks.ts
Tasks:
- default (trellis run tasks.ts)
Podemos ejecutar la tarea localmente con trellis run tasks.ts
:
>>> trellis run tasks.ts
[+] Building 1.1s (13/13) FINISHED
= > [internal] load build definition from Dockerfile 0.0s
= > = > transferring dockerfile: 335B 0.0s
= > [internal] load .dockerignore 0.0s
= > = > transferring context: 2B 0.0s
= > resolve image config for docker.io/docker/dockerfile:1.4 0.5s
= > [auth] docker/dockerfile:pull token for registry-1.docker.io 0.0s
= > CACHED docker-image://docker.io/docker/dockerfile:1.4@sha256:9ba7531bd80fb0a858632727cf7a112fbf 0.0s
= > [internal] load .dockerignore 0.0s
= > [internal] load build definition from Dockerfile 0.0s
= > [internal] load metadata for docker.io/library/ubuntu:20.04 0.3s
= > [auth] library/ubuntu:pull token for registry-1.docker.io 0.0s
= > [stage-0 1/3] FROM docker.io/library/ubuntu:20.04@sha256:35ab2bf57814e9ff49e365efd5a5935b6915ee 0.0s
= > CACHED [stage-0 2/3] WORKDIR /root 0.0s
= > CACHED [stage-0 3/3] RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=c 0.0s
= > exporting to image 0.0s
= > = > exporting layers 0.0s
= > = > writing image sha256:17f750ba9a4becf38ce4d584d0de4793bfd6a8139674c3b332cdcdf6525ea8d9 0.0s
= > = > naming to docker.io/trellis/adf8a603d1ab539848d89f68491e1b9213c1ca498f3f68d871e1b59c4c7de601 0.0s
√ Build: trellis/adf8a603d1ab539848d89f68491e1b9213c1ca498f3f68d871e1b59c4c7de601
√ Run: git --help
√ Run: jq --help
√ Run: curl --help
Trellis se puede configurar a través de un archivo trellis.config.ts
, cuya semántica básica está modelada a partir de Vite.
trellis.config.ts
debe contener una única exportación predeterminada que consista en una invocación defineConfig
, como esta:
import { defineConfig } from "https://deno.land/x/[email protected]/mod.ts" ;
export default defineConfig ( {
engine : "docker" ,
} ) ;
Trellis utilizará el trellis.config.ts
más cercano, buscando primero en el directorio de trabajo actual y luego en cada directorio principal posterior.
Trellis es compatible con depot.dev, que se puede utilizar para habilitar compilaciones aceleradas en la nube sin configuración. Ejecute la instalación del depósito ( brew install depot/tap/depot
o similar, seguido del depot login
), luego defina un trellis.config.ts
de esta manera:
import { defineConfig } from "https://deno.land/x/[email protected]/mod.ts" ;
export default defineConfig ( {
engine : {
type : "depot" ,
project : "${YOUR_PROJECT_ID}" ,
} ,
} ) ;
A partir de ahí, todas las compilaciones de Trellis pasarán por Depot.
Trellis se ejecuta en Deno, lo que lo convierte en una instalación de un solo paso en GitHub Actions:
name : CI
on :
push :
branches : [ main ]
pull_request :
branches : [ main ]
env :
DOCKER_BUILDKIT : 1
jobs :
build :
name : " Build "
runs-on : ubuntu-latest
steps :
- uses : actions/checkout@v3
- name : " Install Deno "
uses : denoland/setup-deno@v1
with :
deno-version : " 1.25.2 "
- name : " Install Trellis "
working-directory : ./trellis
run : deno install --allow-run=docker --allow-net --allow-write --allow-env --allow-read https://deno.land/x/[email protected]/cli.ts
- name : " Build the image "
working-directory : ./examples/typescript
run : trellis build trellis/mod.ts
Trellis está motivado por las siguientes observaciones, extraídas de la experiencia de mantener grandes sistemas CI/CD en contenedores.
Los Dockerfiles son difíciles de mantener . Con el tiempo, los sistemas grandes tienden a acumular colecciones de Dockerfiles con subsecciones similares, pero sin abstracciones compartidas.
Los Dockerfiles eficientes son difíciles de escribir . Escribir un Dockerfile que se pueda almacenar en caché al máximo, con un espacio mínimo, requiere una experiencia significativa. Por ejemplo, para apt-get install
, la documentación de Docker recomienda lo siguiente:
RUN apt-get update && apt-get install -y
# Be sure to sort dependencies to maximize cacheability.
bzr
cvs
git
mercurial
subversion
# Clear the apt cache to minimize disk size.
&& rm -rf /var/lib/apt/lists/ *
El ciclo de iteración de CI/CD es demasiado lento . El flujo de trabajo común para escribir una nueva canalización de GitHub Actions, Jenkinsfile, etc., es confirmar, enviar, esperar a que el sistema reconozca su cambio y luego esperar a que su tarea falle: decenas o incluso cientos de veces seguidas. Con las soluciones de CI existentes, usted escribe código para ejecutarlo en un sistema desconocido, fuera de su control, sin un flujo de trabajo de desarrollo de primera clase.
Los sistemas CI/CD crean un bloqueo significativo . Portar sus archivos Jenkinsfiles o YAML a GitHub Actions, o viceversa, requiere lidiar con abstracciones específicas de la plataforma.
Trellis resuelve estos problemas mediante algunas decisiones de diseño importantes.
Primero: con Trellis, usted define sus Dockerfiles y canalizaciones de CI/CD en TypeScript. Esto le brinda el poder de un lenguaje de programación "completo" al tiempo que conserva una API declarativa. Con TypeScript, obtenemos los siguientes beneficios:
apt-get install
.deno.land
. Segundo: Trellis hace que la ejecución local sea una primitiva de primera clase. CI/CD no debería parecer un sistema completamente separado; Debería sentirse como si estuviera ejecutando código. Trellis está construido sobre Deno y es altamente portátil. Puede ejecutar trellis build
localmente tal como lo haría en GitHub Actions o en cualquier otro lugar. De esta forma, Trellis se inspira en herramientas como Earthly y Dagger.
Trellis tiene algunas metas a las que aspira que aún no se han cumplido:
Trellis es tanto una biblioteca como una interfaz de línea de comandos. Con Trellis, exporta definiciones Image
y funciones ejecutables (llamadas "Tareas") desde sus módulos TypeScript y luego las ejecuta a través de la CLI trellis
.
trellis preview
Genere un Dockerfile definido en un módulo TypeScript.
Usage: trellis preview [options] [file]
Generate a Dockerfile defined in a TypeScript module
Options:
-t, --target < TARGET > Image to build within the TypeScript module
-h, --help display help for command
trellis build
Cree una imagen definida en un módulo de TypeScript.
Usage: trellis build [options] [file]
Build an Image defined in a TypeScript module
Options:
-t, --target < TARGET > Image to build within the TypeScript module
--push Whether to push the image to a remote registry
-h, --help display help for command
trellis ls
Enumere todas las imágenes y tareas disponibles en un módulo de TypeScript.
Usage: trellis ls [options] [file]
List all Images and Tasks available in a TypeScript module
Options:
-h, --help display help for command
trellis run
Ejecute una tarea definida en un módulo de TypeScript.
Run a Task defined in a TypeScript module
Options:
-t, --target <TARGET> Task to run within the TypeScript module
-h, --help display help for command
El directorio ./examples
muestra una variedad de casos de uso para Trellis. Trellis es flexible y se puede utilizar únicamente para generar Dockerfiles para otros sistemas o para definir canalizaciones completas de CI/CD.
rocket
: un servidor web Rust encima del marco Rocket. Demuestra compilaciones e implementación en varias etapas a través de Fly.io aprovechando trellis preview
.ruff
: una herramienta de línea de comandos de Rust. Demuestra compilaciones eficientes y comprobaciones de CI.runc
: un contenedor de desarrollo de Linux. Demuestra generar artefactos con Trellis y copiarlos nuevamente a la máquina host.turborepo
: ejemplo de Docker propio de Turborepo, modificado para generar Dockerfiles con Trellis.typescript
: un monorepo de TypeScript. Demuestra compilaciones eficientes y comprobaciones de CI, además de consolidar constantes (como la lista de espacios de trabajo de TypeScript).wasm
: Un "¡Hola, mundo!" Binario Rust compilado en Wasm y probado en Wasmtime. Trellis se basa en Deno, que se distribuye como un único ejecutable binario sin dependencias externas. Usar Deno significa que instalar Trellis en cualquier lugar es tan simple como deno install ...
: no hay package.json
, ni npm install
, ni ningún paso de transpilación de TypeScript.
Al igual que Nixpacks, Trellis genera Dockerfiles. Esto simplifica la implementación de Trellis, pero también permite a los usuarios aprovechar Trellis solo para la generación de Dockerfile, en lugar de como una solución CI/CD completa.
trellis build
y trellis run
dependen de Docker y asumen que el demonio de Docker es accesible localmente.
MIT