commit e749d9838d75ca644acb4b75bbb3ff5028ad7485 Author: Alex Maldonado Date: Fri Jun 26 14:41:51 2026 -0400 feat: initial commit diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..cbbad0d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,10 @@ +FROM node:26-trixie-slim@sha256:a1d9d671994fc2d26e297ac56b4b1522a8bc7fa71c43b14cd1b1fe6c5116f7dc + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + git rsync curl ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +ENV PIXI_VERSION=0.71.1 +RUN curl -fsSL https://pixi.sh/install.sh | bash +ENV PATH="/root/.pixi/bin:${PATH}" diff --git a/README.md b/README.md new file mode 100644 index 0000000..a18efee --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +# quarto-deploy + +The container image our Gitea Actions runners use to build and publish Quarto sites. + +## What it is + +A push to a site repository triggers a runner to render the site and then copy the result to the web server. +This image is the environment in which that job runs. +It is deliberately small: rendering uses Quarto's frozen output, so executed R and Python results are committed to each site repository instead of being recomputed here. +The image carries no language kernels; only what it takes to check out a repository, resolve Quarto, render, and sync files. + +Node runs the JavaScript actions Gitea uses to bootstrap a job, such as `actions/checkout`. `git` performs the checkout, `rsync` copies the rendered site into place, and `curl` fetches Pixi baked into the image, so each run neither downloads the tool nor pipes a script into a shell. + + +The image stays generic on purpose: it ships the Pixi tool, but no project dependencies, so one image can render every site regardless of which Quarto version that site pins. +Each repository resolves its own dependencies at build time with `pixi install`. + +## Build + +Build the image on your own machine and push it to Gitea's container registry. +The runners only ever pull it. + +You will need an access token with `package:write` access. +Go to your Gitea settings and under “Applications,” you will find “Generate New Token.” +Give the token a name like `quarto-deploy-package`, select “Read and Write” for package permissions. +Next, we will authenticate Docker for pushing packages by running `docker login` and using the newly generated token as the password. + +```bash +docker login git.scient.ing +``` + +Now we can build the package for our servers, which are `linux/amd64`. +Note that Apple Silicon defaults to `arm64`, and an `arm64` image may push but then fail to start on the runner with an exec-format error. + +`buildx` cross-compiles for the platform you specify, `--push` sends the result straight to the registry, so the build and upload are one step, and the trailing `.` is the build context—the directory containing this `Dockerfile`. + +```bash +docker buildx build --platform linux/amd64 \ + -t git.scient.ing/infra/quarto-deploy:1 --push . +``` + +Bump the tag (`:2`, `:3`) whenever the `Dockerfile` is changed. +The image is always pulled by an explicit version, never `latest`, so a runner's behavior stays tied to a named artifact you can roll back to. + + +## Use + +A runner advertises a label that maps to this image, and a workflow selects it with `runs-on`. + +```yaml +# in a runner's config.yaml +runner: + labels: + - "quarto-deploy:docker://git.scient.ing/infra/quarto-deploy:1" +``` + +```yaml +# in a site repository's .gitea/workflows/deploy.yml +jobs: + deploy: + runs-on: quarto-deploy +``` + +Changing the image for each runner involves pointing the label at a new tag and restarting the runner. +The workflows never change.