TypeScript로 Dockerfile 및 CI 파이프라인을 작성합니다.
Trellis는 이식 가능한 CI/CD 도구입니다. Trellis를 사용하면 TypeScript에서 Dockerfile 및 CI/CD 파이프라인을 정의하고 어디에서나(로컬 또는 호스팅 플랫폼에서) 실행할 수 있습니다.
먼저, brew install deno
(또는 이와 유사한)를 사용하여 Deno를 설치합니다.
둘째, 다음을 사용하여 Trellis CLI를 설치합니다.
deno install
--allow-run=docker
--allow-net
--allow-write
--allow-env
--allow-read
https://deno.land/x/[email protected]/cli.ts
trellis --help
실행하여 설치를 확인합니다.
>>> 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
Trellis를 사용하여 Dockerfile 생성 및 이미지 구축을 활성화하려면 Image
내보냅니다.
예를 들어, 몇 가지 유용한 유틸리티가 설치된 Ubuntu 이미지를 정의하려면 다음 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" ,
] ) ;
trellis ls mod.ts
실행하면 빌드 가능한 이미지가 나열됩니다.
>>> trellis ls mod.ts
Images:
- buildStage (trellis build --target buildStage)
trellis preview mod.ts --target buildStage
사용하여 생성된 Dockerfile을 미리 볼 수 있습니다.
>>> 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
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
TypeScript 모듈에서 함수를 내보내 Trellis로 작업 실행을 활성화합니다.
예를 들어 명령줄 유틸리티가 성공적으로 설치되었는지 확인하기 위해 CI 파이프라인을 정의하려면 다음 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 ) ,
] ) ;
}
trellis ls tasks.ts
실행하면 실행 가능한 작업이 나열됩니다.
>>> trellis ls tasks.ts
Tasks:
- default (trellis run tasks.ts)
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는 Vite를 모델로 한 기본 의미인 trellis.config.ts
파일을 통해 구성할 수 있습니다.
trellis.config.ts
다음과 같이 defineConfig
호출로 구성된 단일 기본 내보내기가 포함되어야 합니다.
import { defineConfig } from "https://deno.land/x/[email protected]/mod.ts" ;
export default defineConfig ( {
engine : "docker" ,
} ) ;
Trellis는 가장 가까운 trellis.config.ts
사용하여 현재 작업 디렉터리를 먼저 찾은 다음 각 후속 상위 디렉터리를 찾습니다.
Trellis는 구성 없이 클라우드 가속 빌드를 활성화하는 데 사용할 수 있는 depot.dev와 호환됩니다. Depot 설치( brew install depot/tap/depot
또는 이와 유사한 것, depot login
)를 실행한 후 다음과 같이 trellis.config.ts
를 정의합니다.
import { defineConfig } from "https://deno.land/x/[email protected]/mod.ts" ;
export default defineConfig ( {
engine : {
type : "depot" ,
project : "${YOUR_PROJECT_ID}" ,
} ,
} ) ;
거기에서 모든 Trellis 빌드는 Depot을 통해 실행됩니다.
Trellis는 Deno에서 실행되므로 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는 대규모 컨테이너형 CI/CD 시스템을 유지 관리한 경험에서 얻은 다음 관찰에서 영감을 얻었습니다.
Dockerfile은 유지 관리 가 어렵습니다. 시간이 지남에 따라 대규모 시스템은 유사한 하위 섹션이 있지만 공유 추상화는 없는 Dockerfile 컬렉션을 축적하는 경향이 있습니다.
효율적인 Dockerfile은 작성 하기 어렵습니다. 최소한의 설치 공간으로 최대한 캐시 가능한 Dockerfile을 작성하려면 상당한 전문 지식이 필요합니다. 예를 들어 apt-get install
의 경우 Docker 설명서에서는 다음을 권장합니다.
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/ *
CI/CD 반복 루프가 너무 느립니다 . 새로운 GitHub Actions 파이프라인, Jenkinsfile 등을 작성하기 위한 일반적인 워크플로는 커밋하고 푸시하고 시스템이 변경 사항을 인식할 때까지 기다린 다음 작업이 연속해서 수십 번 또는 수백 번 실패할 때까지 기다리는 것입니다. 기존 CI 솔루션을 사용하면 최고 수준의 개발 워크플로 없이 제어할 수 없는 익숙하지 않은 시스템에서 실행되는 코드를 작성하게 됩니다.
CI/CD 시스템은 상당한 종속성을 야기합니다. Jenkinsfiles 또는 YAML 파일을 GitHub Actions로 이식하거나 그 반대로 이식하려면 플랫폼별 추상화 문제를 해결해야 합니다.
Trellis는 몇 가지 중요한 설계 결정을 통해 이러한 문제를 해결합니다.
첫째: Trellis를 사용하면 TypeScript에서 Dockerfile과 CI/CD 파이프라인을 정의합니다. 이는 선언적 API를 유지하면서 "완전한" 프로그래밍 언어의 성능을 제공합니다. TypeScript를 사용하면 다음과 같은 이점을 얻을 수 있습니다.
apt-get install
단계를 직접 작성하지 않도록 공통 빌드 단계와 상위 수준 기본 요소를 정의합니다.deno.land
에서 Slack 클라이언트를 가져오는 것만큼 간단합니다. 둘째: Trellis는 로컬 실행을 일류 기본 요소로 만듭니다. CI/CD는 완전히 별개의 시스템처럼 느껴져서는 안 됩니다. 코드를 실행하는 것처럼 느껴져야 합니다. Trellis는 Deno를 기반으로 구축되었으며 휴대성이 뛰어납니다. GitHub Actions 또는 다른 곳에서와 마찬가지로 trellis build
로컬로 실행할 수 있습니다. 이러한 방식으로 Trellis는 Earthly 및 Dagger와 같은 도구에서 영감을 얻습니다.
Trellis에는 아직 실현되지 않은 몇 가지 야심 찬 목표가 있습니다.
Trellis는 라이브러리이자 명령줄 인터페이스입니다. Trellis를 사용하면 TypeScript 모듈에서 Image
정의와 실행 가능한 함수("작업"이라고 함)를 내보낸 다음 trellis
CLI를 통해 실행합니다.
trellis preview
TypeScript 모듈에 정의된 Dockerfile을 생성합니다.
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
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
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
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
./examples
디렉토리는 Trellis의 다양한 사용 사례를 보여줍니다. Trellis는 유연하며 다른 시스템에 대한 Dockerfile을 생성하거나 전체 CI/CD 파이프라인을 정의하는 데에만 사용할 수 있습니다.
rocket
: Rocket 프레임워크 위에 있는 Rust 웹서버입니다. trellis preview
를 활용하여 Fly.io를 통한 다단계 빌드 및 배포를 보여줍니다.ruff
: Rust 명령줄 도구입니다. 효율적인 빌드 및 CI 검사를 보여줍니다.runc
: Linux 개발 컨테이너입니다. Trellis를 사용하여 아티팩트를 생성하고 이를 호스트 시스템에 다시 복사하는 방법을 보여줍니다.turborepo
: Trellis를 사용하여 Dockerfile을 생성하도록 수정된 Turborepo의 자체 Docker 예제입니다.typescript
: TypeScript 모노레포입니다. 상수 통합(예: TypeScript 작업 영역 목록)과 함께 효율적인 빌드 및 CI 검사를 보여줍니다.wasm
: "Hello, world!" Wasm으로 컴파일되고 Wasmtime에서 테스트된 Rust 바이너리입니다. Trellis는 외부 종속성 없이 단일 바이너리 실행 파일로 배포되는 Deno를 기반으로 구축되었습니다. Deno를 사용한다는 것은 어디든 Trellis를 설치하는 것이 deno install ...
— package.json
, npm install
및 TypeScript 변환 단계가 없습니다.
Nixpacks와 유사하게 Trellis는 Dockerfile을 생성합니다. 이는 Trellis의 구현을 단순화할 뿐만 아니라 사용자가 완전한 CI/CD 솔루션이 아닌 Dockerfile 생성에만 Trellis를 활용할 수 있게 해줍니다.
trellis build
및 trellis run
Docker에 따라 달라지며 Docker 데몬에 로컬로 액세스할 수 있다고 가정합니다.
MIT