Getting started
This page sets up a Linux workstation to build any Inky Labs project. You need two
things: Nix, which supplies the pinned tools a build runs, and
Bazelisk, which runs the version of Bazel that each repository asks for.
Builds then read the shared cache automatically.
To send changes you also need glab and the
fork workflow; an administrator adds
AWS and Porkbun access.
1. Install Nix
Section titled “1. Install Nix”Use the official multi-user (daemon) installer. It needs sudo and asks a few
questions, so run it in a real terminal:
sh <(curl -L https://nixos.org/nix/install) --daemonOpen a new terminal afterwards so your shell picks up the Nix profile, then check it:
nix --versionBazel uses Nix only to fetch tools from nixpkgs at the versions a repository pins. You don’t need to learn Nix to build a project.
2. Install Bazelisk as bazel
Section titled “2. Install Bazelisk as bazel”Bazelisk is a single binary. It reads .bazelversion in the repository you’re
in, then downloads and runs that Bazel release. Install it on your PATH under
the name bazel:
version=v1.29.0url=https://github.com/bazelbuild/bazelisk/releases/download/$version/bazelisk-linux-amd64mkdir -p ~/.local/bincurl -fsSL -o ~/.local/bin/bazelisk "$url"echo "$(curl -fsSL "$url.sha256") $HOME/.local/bin/bazelisk" | sha256sum -c -chmod +x ~/.local/bin/bazeliskln -sf bazelisk ~/.local/bin/bazelCheck it. Outside a repository this prints the latest Bazel release. Inside
one, it prints the version pinned in .bazelversion:
bazel --version3. Build a project
Section titled “3. Build a project”No Inky Labs repository builds with Bazel yet, so there is nothing to try this on until one is converted. From the root of any converted repository:
bazel build //... # build every cacheable outputbazel test //... # run every test Bazel knows aboutbazel run //:assets # in a repository with generated files: install them, # and run the steps that can't be cachedA repository that needs other tools (usually Node, for npm ci and its
tests) pins them in shell.nix: run nix-shell at its root to get them. Its
AGENTS.md says if anything must come first, such as npm ci. See
Builds and CI.
Build only what you need by naming a target, for example
bazel build //:site. Bazel works out what that target depends on and builds
only that.
On Ubuntu, Bazel reports processwrapper-sandbox instead of
linux-sandbox, because AppArmor restricts the user namespaces the Linux
sandbox needs. That’s expected.
Nothing else needs to be installed. If a build seems to need a program from
your machine’s PATH, that’s a bug in the build. Report it rather than
installing the program.
Bazel reads the shared cache at https://bazel-cache.inkylabs.com (each
repository’s .bazelrc says so), so anything CI has already built comes down
instead of being rebuilt. The summary line shows it: … remote cache hit.
The host exists, but until CI uploads to it a build finds few remote hits.
4. glab and the fork workflow
Section titled “4. glab and the fork workflow”glab is GitLab’s CLI. inkylabs-mr
and the examples in this handbook use it. Install it from nixpkgs and log in
once, choosing gitlab.com and HTTPS as the Git protocol:
nix --extra-experimental-features 'nix-command flakes' profile add nixpkgs#glabglab auth loginglab auth statusThen let Git use it for gitlab.com credentials, so HTTPS clones and pushes need no SSH key or password:
git config --global credential.https://gitlab.com.helper ''git config --global --add credential.https://gitlab.com.helper '!glab auth git-credential'You need to be a member of the
inkylabs group; ask an owner to add
you (Getting access).
Install the shared tools from this handbook’s repository
(Tools), inkylabs-mr among them. Every change is then a
merge request from the project’s fork, never a push to the project
(Source code):
git clone https://gitlab.com/inkylabs/<project>.git # the project, not the forkcd <project>git switch -c <topic> # …commit…git fetch origin && git rebase origin/master # merges are fast-forwardinkylabs-mr # push to inkylabs/forks/<project>, open the merge requestNot yet set up for Inky Labs: the inkylabs/forks group, the review bot and
the handbook’s own project
don’t exist yet, so inkylabs-mr has nowhere to push. Until they do, Inky Labs
projects take changes the way they always have. A few projects’ default
branch is main, not master (edit-server, kid-years, remark-fancyquote);
rebase onto that.
Trusted workstations
Section titled “Trusted workstations”Only for an Inky Labs administrator’s own machine, with full-disk encryption (see Builds and CI for what trusted means). These steps let it upload what it builds to the shared cache. Every other machine stops at step 4.
The inkylabs AWS account exists (created 2026-10-26), but only its
administrator can sign in so far: ask an owner for a user.
5. Install the AWS CLI, from nixpkgs:
nix --extra-experimental-features 'nix-command flakes' profile add nixpkgs#awscli2aws --version6. Point it at the Inky Labs access portal. Add this to ~/.aws/config
(create the file if it doesn’t exist):
[sso-session inkylabs]sso_start_url = https://d-906662109b.awsapps.com/startsso_region = us-east-1sso_registration_scopes = sso:account:access
[profile inkylabs]sso_session = inkylabssso_account_id = 889952605315sso_role_name = AdministratorAccessregion = us-west-2Then sign in. This opens a browser tab to approve, and lasts about a working day:
aws sso login --profile inkylabsaws sts get-caller-identity --profile inkylabs # shows your user name7. Install bazel-cache-sync from this handbook’s repository (see
Tools):
ln -sf ~/projects/developers.inkylabs.com/tools/bazel-cache-sync ~/.local/bin/bazel-cache-sync8. Upload after a build. Build as usual, then:
AWS_PROFILE=inkylabs bazel-cache-sync --dry-run # what would go upAWS_PROFILE=inkylabs bazel-cache-syncinkylabs-mr does this for you before it pushes a merge request, after
building and testing the commit, so its pipeline finds everything already
done; it uploads only that build’s results. By hand, bazel-cache-sync
uploads your whole disk cache, uncommitted experiments included, so prefer
inkylabs-mr. Every other machine trusts what you upload.
Porkbun
Section titled “Porkbun”Only for an administrator who manages Inky Labs’ domains and DNS
(Domains). Inky Labs’ domains, inkylabs.com among them, are in
the default Porkbun account, not a subaccount, so porkbun
reaches them without --profile. Create an API key pair under Account →
API Access in Porkbun’s control panel, turn on API Access for each domain
you’ll manage, and put the keys in ~/.env, never in a repository:
PORKBUN_API_KEY=pk1_…PORKBUN_SECRET_KEY=sk1_…Then check:
porkbun ping # shows the account the keys act asporkbun dns list inkylabs.comThese keys reach more than Inky Labs. The default account also holds personal domains (latilde.org, symbolics.dev, matchingwell.com, biblepod.app and others), and a key pair sees every domain in its account. Keep them to trusted workstations, and think twice before handing them to CI. Porkbun’s per-domain API Access switch may limit what a key can touch; unverified: check that a key is refused for a domain with API access off before relying on it.
- Builds and CI: why the setup looks like this, and the rules every repository follows.
- Source code: forks, owners, the review bot, and who may merge.