Development environment
Work from the SecureBuild repository root. For service configuration (YAML, registry, storage), see the Self-hosted docs and the configuration reference.
Before you start
- Docker — a recent Docker Engine with the Compose plugin (
docker compose). Docker Desktop, OrbStack, and typical Linux packages provide this. - Tooling — the repo ships a Nix flake; run
nix develop(or direnv) somake, Go, Node, and related CLIs match CI. - Linux — Bubblewrap — when you run the worker on the host (e.g. after
make dev-worker) withbuild_backend: local, melange needs thebwrapbinary onPATH. Install the OS package: Debian/Ubuntusudo apt-get install bubblewrap, Fedoradnf install bubblewrap, Archpacman -S bubblewrap.
Create securebuild-config.yaml at the repo root for the Go services (worker, apk-proxy, oci-proxy) and securebuild-app/.env.local for the Next.js app before make dev-stack-up. The stack also mounts these paths; the worker and app mount dev-pipelines/ at /var/run/securebuild/pipelines (the directory is gitignored; make dev-stack-up creates it before docker compose up). make build-dev-images reads .env.local for NEXT_PUBLIC_* build arguments.
The examples below are for local development and are intended to work out of the box. They are not a secure production configuration: simple passwords and placeholder secrets are acceptable here. The only values that may require real credentials are container registry login details and S3-compatible storage (R2) keys—when those point at real services you care about.
Example: securebuild-config.yaml
# Repo root: securebuild-config.yaml (Go services — dev defaults; see note above) # Full template: securebuild-config.example.yaml in the SecureBuild repository. # DB_URI is set in docker-compose.yml for the Compose dev stack (omit here unless you need an override). registry_image_prefix: ghcr.io/your-org/securebuild registry_username: your-registry-user registry_password: your-registry-token-or-password apk_repository: http://apk-proxy:8880 # apk-proxy (available on 8880 in docker-compose) apk_public_key_name: dev-signing.rsa.pub apk_public_key_data: "<base64 data>" # replace: base64-encoded public key PEM apk_signing_key_data: "<base64 data>" # replace: base64-encoded private key PEM apk_signing_key_name: dev-signing.rsa.key r2_endpoint: https://s3.example.com r2_access_key: replace-me # replace with your R2 or S3 access key r2_secret_key: replace-me # replace with your R2 or S3 secret key r2_region: us-east-1 # leave blank for Cloudflare R2 r2_bucket_name: securebuild r2_use_path_style: true build_backend: local # Pipeline files: Docker Compose mounts repo dev-pipelines/ here — keep this path. pipeline_dir: /var/run/securebuild/pipelines auth_method: password admin_user_email: admin@example.com # only if SMTP is not configured in the app admin_user_password: clear-text-password # only if SMTP is not configured in the app log_level: info
Add optional static_vms and other fields from the example file as needed. Field meanings: Configuration reference.
Example: securebuild-app/.env.local
# securebuild-app/.env.local (web app — password auth; dev defaults) # DB_URI and PIPELINE_DIR are set in docker-compose.yml for the Compose app container. # For npm run dev on the host, set PIPELINE_DIR to an absolute path to repo dev-pipelines/. HMAC_SECRET=dev-only-secret REGISTRY_IMAGE_PREFIX=ghcr.io/your-org/securebuild AUTH_METHOD=password PIPELINE_DIR=/absolute/path/to/securebuild/dev-pipelines NEXT_PUBLIC_APK_REPOSITORY=http://apk-proxy:8880 # apk-proxy on host
docker-compose.yml sets DB_URI and PIPELINE_DIR for the app, and DB_URI for the worker, in the Compose stack; you do not need those in these files for make dev-stack-up. Use admin_user_email and admin_user_password in the YAML when the app does not have SMTP configured or if you just want to use a single pre-defined user—otherwise omit them and use email-based setup flows.
Start dev environment
make dev-stack-upOpen localhost:3000 in your browser to view the site.
Enter dev shell for a service
Pick the component you want to run from source. Exiting the shell restores the stack.
make dev-workermake dev-appmake dev-apk-proxymake dev-oci-proxyIn that shell, run the service. For example, make run-worker for the worker, or npm run dev from securebuild-app/ for the app.
Open a shell for database migrations
make dev-migrateThen run make migrate in the same shell.
Stop the dev environment
make dev-stack-downWhat each target does
The canonical list of targets and descriptions is printed by:
make helpRelevant sections for day-to-day development:
Development
Development: build-worker - Build worker with embedded builder binaries build-worker-release - Build worker for linux/amd64 and linux/arm64 (release) build-builder - Build builder binaries for Linux x86_64 and aarch64 run-worker - Run the worker service run-oci-proxy - Run the OCI proxy service run-apk-proxy - Run the APK proxy service
Local Dev Stack (Docker Compose)
Local Dev Stack (Docker Compose): dev-stack-up - Build images and start the full dev stack (docker compose) dev-stack-down - Stop and remove the dev stack dev-worker - Stop worker in the stack, open shell with DB_URI set; restores on exit dev-app - Stop app in the stack, open shell in securebuild-app/ with DB_URI set; restores on exit dev-apk-proxy - Stop apk-proxy in the stack, open shell with DB_URI set; restores on exit dev-oci-proxy - Stop oci-proxy in the stack, open shell with DB_URI set; restores on exit dev-migrate - Open shell with DB_URI set; run 'make migrate' inside
Database
Database: migrate - Run database migrations using schemahero
Testing
Testing: test-unit - Run all unit tests (Go + securebuild-app) test-unit-go - Run Go unit tests only test-integration-oci-proxy - Run OCI proxy integration tests test-integration-apk-proxy - Run APK proxy integration tests test-integration-worker - Run worker integration tests
Example: make test-unit. CI runs these on pull requests—use the integration target that matches your change when needed.
