fix: include quarto in container
This commit is contained in:
+13
-3
@@ -1,10 +1,20 @@
|
|||||||
FROM node:26-trixie-slim@sha256:a1d9d671994fc2d26e297ac56b4b1522a8bc7fa71c43b14cd1b1fe6c5116f7dc
|
FROM node:26-trixie-slim@sha256:a1d9d671994fc2d26e297ac56b4b1522a8bc7fa71c43b14cd1b1fe6c5116f7dc
|
||||||
|
|
||||||
|
# OS packages used to fetch sources and deploy output
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install -y --no-install-recommends \
|
&& apt-get install -y --no-install-recommends \
|
||||||
git rsync curl ca-certificates \
|
git rsync curl ca-certificates \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
ENV PIXI_VERSION=0.71.1
|
# Quarto setup.
|
||||||
RUN curl -fsSL https://pixi.sh/install.sh | bash
|
ARG QUARTO_VERSION=1.9.38
|
||||||
ENV PATH="/root/.pixi/bin:${PATH}"
|
ARG QUARTO_SHA256=ea8c897368791ad9f200010c087ea3111b2e556b12a960487dd4e216902aa102
|
||||||
|
|
||||||
|
RUN curl -fsSL -o /tmp/quarto.tar.gz \
|
||||||
|
"https://github.com/quarto-dev/quarto-cli/releases/download/v${QUARTO_VERSION}/quarto-${QUARTO_VERSION}-linux-amd64.tar.gz" \
|
||||||
|
&& echo "${QUARTO_SHA256} /tmp/quarto.tar.gz" | sha256sum -c - \
|
||||||
|
&& mkdir -p /opt/quarto/${QUARTO_VERSION} \
|
||||||
|
&& tar -xzf /tmp/quarto.tar.gz -C /opt/quarto/${QUARTO_VERSION} --strip-components=1 \
|
||||||
|
&& ln -s /opt/quarto/${QUARTO_VERSION}/bin/quarto /usr/local/bin/quarto \
|
||||||
|
&& rm /tmp/quarto.tar.gz \
|
||||||
|
&& quarto --version
|
||||||
|
|||||||
@@ -6,14 +6,13 @@ The container image our Gitea Actions runners use to build and publish Quarto si
|
|||||||
|
|
||||||
A push to a site repository triggers a runner to render the site and then copy the result to the web server.
|
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.
|
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.
|
It is deliberately small: rendering uses Quarto's frozen output, so the executed R and Python results are committed to each site repository rather than recomputed here.
|
||||||
The image carries no language kernels; only what it takes to check out a repository, resolve Quarto, render, and sync files.
|
The image carries no language kernels; only what it takes to check out a repository, 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.
|
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 about project dependencies on purpose: it ships Pixi but no packages.
|
||||||
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.
|
The Quarto it fixes, baked in and named by the tag, is the renderer the runner uses, and each site mirrors that version in its own `pixi.toml` so local work matches what the runner produces.
|
||||||
Each repository resolves its own dependencies at build time with `pixi install`.
|
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
@@ -22,7 +21,7 @@ The runners only ever pull it.
|
|||||||
|
|
||||||
You will need an access token with `package:write` access.
|
You will need an access token with `package:write` access.
|
||||||
Go to your Gitea settings and under “Applications,” you will find “Generate New Token.”
|
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.
|
Give the token a name like `quarto-deploy-package` and 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.
|
Next, we will authenticate Docker for pushing packages by running `docker login` and using the newly generated token as the password.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -32,16 +31,52 @@ docker login git.scient.ing
|
|||||||
Now we can build the package for our servers, which are `linux/amd64`.
|
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.
|
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`.
|
`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
|
```bash
|
||||||
docker buildx build --platform linux/amd64 \
|
docker buildx build --platform linux/amd64 \
|
||||||
-t git.scient.ing/infra/quarto-deploy:1 --push .
|
-t git.scient.ing/infra/quarto-deploy:1.9.38 --push .
|
||||||
```
|
```
|
||||||
|
|
||||||
Bump the tag (`:2`, `:3`) whenever the `Dockerfile` is changed.
|
Bump the tag whenever the `Dockerfile` changes: to the new Quarto version on a Quarto bump, or with a revision suffix like `:1.9.38-2` otherwise.
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|
## Quarto versions
|
||||||
|
|
||||||
|
Quarto is pinned in the image, not pulled fresh at render time.
|
||||||
|
The version lives in the `Dockerfile` as the `QUARTO_VERSION` build argument, paired with `QUARTO_SHA256`, the checksum of that release's `linux-amd64` tarball.
|
||||||
|
The image tag carries the same number, so a runner renders against one known Quarto, and that Quarto travels with the artifact you push, pull, and roll back to.
|
||||||
|
|
||||||
|
Each site mirrors this version in its own `pixi.toml` for local work, so a bump happens in two places.
|
||||||
|
To move to a new Quarto, set `QUARTO_VERSION` in the `Dockerfile` to the release you want and `QUARTO_SHA256` to the matching `quarto-<version>-linux-amd64.tar.gz` checksum from the [releases page](https://github.com/quarto-dev/quarto-cli/releases), then change the `quarto` pin in each site's `pixi.toml` to the same number.
|
||||||
|
The build verifies the download against the checksum, so a wrong or stale hash fails the build instead of shipping a Quarto you didn't intend.
|
||||||
|
Then build and push under the new version tag as shown above, point each runner's label at it, and restart the runner.
|
||||||
|
Site workflows stay untouched. They select the runner by its `quarto-deploy` label, never by version.
|
||||||
|
|
||||||
|
## Local development
|
||||||
|
|
||||||
|
You author and test a site in a Pixi environment that pins the same Quarto image renders with, so what you see locally is what the runner publishes.
|
||||||
|
Quarto comes from conda-forge:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[dependencies]
|
||||||
|
quarto = { version = "==1.9.38", channel = "conda-forge" }
|
||||||
|
```
|
||||||
|
|
||||||
|
Keep this equal to `QUARTO_VERSION` in the `Dockerfile`.
|
||||||
|
A few tasks cover the loop:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[tasks]
|
||||||
|
serve = { cmd = ["quarto", "preview", "content"] }
|
||||||
|
build = { cmd = ["quarto", "render", "content", "--output-dir", "../public"] }
|
||||||
|
bump = { cmd = ["bump-my-version", "bump", "patch"] }
|
||||||
|
```
|
||||||
|
|
||||||
|
`pixi run serve` previews `content/` while you write.
|
||||||
|
`pixi run build` renders it into `public/`, the directory the runner publishes.
|
||||||
|
`pixi run bump` advances the site's own version, which is separate from the Quarto pin.
|
||||||
|
If a site executes code, add the kernels it needs (`jupyter`, `r-base`, and so on) to `pixi.toml`, render once, and commit the resulting `_freeze` so the runner reproduces the output without running anything.
|
||||||
|
|
||||||
## Use
|
## Use
|
||||||
|
|
||||||
@@ -51,7 +86,7 @@ A runner advertises a label that maps to this image, and a workflow selects it w
|
|||||||
# in a runner's config.yaml
|
# in a runner's config.yaml
|
||||||
runner:
|
runner:
|
||||||
labels:
|
labels:
|
||||||
- "quarto-deploy:docker://git.scient.ing/infra/quarto-deploy:1"
|
- "quarto-deploy:docker://git.scient.ing/infra/quarto-deploy:1.9.38"
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
|||||||
Reference in New Issue
Block a user