เขียน Dockerfiles และ CI ไปป์ไลน์ใน TypeScript
Trellis เป็นเครื่องมือ CI/CD แบบพกพา ด้วย Trellis คุณสามารถกำหนดไปป์ไลน์ Dockerfiles และ CI/CD ใน TypeScript และเรียกใช้ได้ทุกที่ (ในเครื่องหรือบนแพลตฟอร์มที่โฮสต์)
ขั้นแรก ติดตั้ง Deno ด้วย brew install 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
ส่งออก Image
ใดๆ เพื่อเปิดใช้งานการสร้าง Dockerfile และการสร้างอิมเมจด้วย Trellis
ตัวอย่างเช่น หากต้องการกำหนดอิมเมจ 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)
เราสามารถแสดงตัวอย่าง Dockerfile ที่สร้างขึ้นด้วย 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
เราสามารถสร้างภาพด้วย 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 สามารถกำหนดค่าได้ผ่านไฟล์ trellis.config.ts
ซึ่งความหมายพื้นฐานได้รับการจำลองตาม Vite
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 ขนาดใหญ่ที่มีคอนเทนเนอร์
Dockerfiles นั้นยากต่อ การบำรุงรักษา เมื่อเวลาผ่านไป ระบบขนาดใหญ่มีแนวโน้มที่จะสะสมคอลเลกชันของ Dockerfiles ที่มีส่วนย่อยที่คล้ายกัน แต่ไม่มีนามธรรมร่วมกัน
Dockerfiles ที่มีประสิทธิภาพ นั้น เขียน ได้ยาก การเขียน 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 คุณจะกำหนดไปป์ไลน์ Dockerfiles และ CI/CD ใน TypeScript สิ่งนี้จะทำให้คุณมีพลังของภาษาการเขียนโปรแกรม "เต็มรูปแบบ" ในขณะที่ยังคงรักษา API ที่เปิดเผยไว้ ด้วย TypeScript เราได้รับประโยชน์ดังต่อไปนี้:
apt-get install
ที่ซับซ้อนด้วยมือdeno.land
ประการที่สอง: Trellis ทำให้การดำเนินการเฉพาะที่เป็นสิ่งดั้งเดิมระดับเฟิร์สคลาส CI/CD ไม่ควรรู้สึกเหมือนเป็นระบบที่แยกจากกันโดยสิ้นเชิง มันควรจะรู้สึกเหมือนกำลังรันโค้ด Trellis สร้างขึ้นบน Deno และพกพาสะดวกมาก คุณสามารถรัน trellis build
ช่องภายในเครื่องได้เช่นเดียวกับที่คุณทำบน GitHub Actions หรือที่อื่นๆ ด้วยวิธีนี้ Trellis ได้รับแรงบันดาลใจจากเครื่องมืออย่าง Earthly และ Dagger
Trellis มีเป้าหมายอันทะเยอทะยานบางประการที่ยังไม่บรรลุผล:
Trellis เป็นทั้งไลบรารีและอินเทอร์เฟซบรรทัดคำสั่ง ด้วย Trellis คุณจะส่งออกคำจำกัดความ Image
และฟังก์ชันที่รันได้ (เรียกว่า "งาน") จากโมดูล TypeScript ของคุณ จากนั้นดำเนินการผ่าน trellis
CLI
trellis preview
สร้าง Dockerfile ที่กำหนดไว้ในโมดูล 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
สร้างรูปภาพที่กำหนดในโมดูล 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 มีความยืดหยุ่นและสามารถใช้เพื่อสร้าง Dockerfiles สำหรับระบบอื่นๆ หรือเพื่อกำหนดไปป์ไลน์ CI/CD ทั้งหมดเท่านั้น
rocket
: เว็บเซิร์ฟเวอร์ Rust บนเฟรมเวิร์ก Rocket สาธิตการสร้างและการปรับใช้แบบหลายขั้นตอนผ่าน Fly.io โดยใช้ประโยชน์จากการแสดง trellis preview
ruff
: เครื่องมือบรรทัดคำสั่ง Rust สาธิตการสร้างที่มีประสิทธิภาพและการตรวจสอบ CIrunc
: คอนเทนเนอร์การพัฒนา Linux สาธิตการสร้างอาร์ติแฟกต์ด้วย Trellis และคัดลอกกลับไปยังเครื่องโฮสต์turborepo
: ตัวอย่าง Docker ของ Turborepo ได้รับการแก้ไขเพื่อสร้าง Dockerfiles ด้วย Trellistypescript
: monorepo ของ TypeScript สาธิตการสร้างที่มีประสิทธิภาพและการตรวจสอบ CI พร้อมกับการรวมค่าคงที่ (เช่น รายการพื้นที่ทำงาน TypeScript)wasm
: A "สวัสดีชาวโลก!" ไบนารีสนิมที่คอมไพล์เป็น Wasm และทดสอบบน Wasmtime Trellis สร้างขึ้นบน Deno ซึ่งกระจายเป็นไฟล์ปฏิบัติการไบนารีเดียวโดยไม่ต้องพึ่งพาภายนอก การใช้ Deno หมายความว่าการติดตั้ง Trellis ทุกที่ ) นั้นง่ายพอ ๆ กับ deno install ...
— ไม่มี package.json
ไม่มี npm install
และไม่มีขั้นตอนการถ่ายโอน TypeScript
เช่นเดียวกับ Nixpacks Trellis สร้าง Dockerfiles สิ่งนี้ทำให้การใช้งาน Trellis ง่ายขึ้น แต่ยังช่วยให้ผู้ใช้สามารถใช้ประโยชน์จาก Trellis สำหรับการสร้าง Dockerfile เพียงอย่างเดียว แทนที่จะเป็นโซลูชัน CI/CD ที่สมบูรณ์
trellis build
และ trellis run
ขึ้นอยู่กับ Docker และถือว่า Docker daemon สามารถเข้าถึงได้จากภายในเครื่อง
เอ็มไอที