Contributing Quickstart
Welcome to Daemonless! Whether you're fixing a bug in an existing image or bringing a completely new service to the FreeBSD container ecosystem, this guide will get you set up and submitting your first Pull Request in under 10 minutes.
1. Environment Setup
Before you start building, you need to prepare your FreeBSD host.
Prerequisites
- FreeBSD Host (physical machine or VM).
- A GitHub account.
Installation
Install the required tools, the dbuild engine, and optionally the testing dependencies.
pkg install dbuild podman-suite ocijail jq security/trivy devel/py-pyyaml devel/git
# Optional: for screenshot-based visual regression testing
pkg install chromium www/py-selenium graphics/py-scikit-image # (1)!
- Optional: Only required if you intend to run screenshot-based visual regression tests locally.
Clone the Repositories
The Daemonless project is organized into multiple repositories under the @daemonless organization. You'll need the main repository for scripts and documentation.
Clone the entire fleet
To clone all daemonless image repositories at once, you must first install the GitHub CLI (pkg install gh), then run:
Verify Setup
Ensure everything is configured correctly:
2. Your First Contribution
Daemonless uses a standardized toolchain. Choose your path below:
- Scaffold the project: Use
dbuild initto generate the boilerplate. - Configure Metadata: Edit
compose.yamlto define thex-daemonlessmetadata (title, category, ports, volumes, etc.). - Edit the Containerfiles: Define how your app installs and runs in
ContainerfileandContainerfile.pkg. See Containerfile Patterns. - Fetch Assets & Generate Docs: Run
dbuild logo(used in the app grid),dbuild screenshot(used on the website to showcase the app), anddbuild baseline(used for CIT visual regression tests) to pull down the app's visual assets. Then, rundbuild generateto auto-generate theREADME.mdand inject labels into the Containerfiles. - Configure testing: Edit
.daemonless/config.yamlto define how the image should be tested.
- Find the repository: Each image has its own repository (e.g.,
@daemonless/radarr). - Fork and clone: Fork the repository on GitHub, then clone it locally.
- Make your changes: Edit
compose.yaml(if modifying metadata), theContainerfile, or service scripts underroot/etc/services.d/. Always rundbuild generateafter modifyingcompose.yaml.
3. Build & Test Loop
We use CIT (Container Integration Testing) to ensure every image works natively on FreeBSD.
Build your image locally:
Run the automated tests:
Test Modes
Tests are defined in .daemonless/config.yaml. Most web apps should use mode: health. For apps with complex UIs, use mode: screenshot to catch visual regressions. See Quality Gates (CIT) for details.
To manually verify your image, run it with Podman:
4. Submitting Your PR
Before you open a Pull Request, run through this checklist to ensure a smooth review process:
Pre-Flight Checklist
- License Check: Upstream license verified using the SPDX identifier. Never guess a license; if none exists, use
NOASSERTION. - Metadata Sync:
dbuild generatehas been run to synccompose.yamlmetadata intoContainerfile,Containerfile.pkg, andREADME.md. - Permissions: Run scripts (
root/etc/services.d/<app>/run) uses6-setuidgid bsdso the app doesn't run as root. - Testing:
.daemonless/config.yamlis configured anddbuild testpasses locally. - CI Pipeline:
.github/workflows/is present and configured (Woodpecker is maintained as a fallback Plan B).
How to Submit
For existing images: Push your branch to your fork and open a Pull Request against the main branch of the respective repository. Our CI will automatically run the CIT suite against your changes.
For new images: You cannot open a PR until a repository exists in the Daemonless organization! Please hop on our Discord and ask us to create a new repository for your image. Once created, you can push your scaffolded project there.
5. Golden Rules & Conventions
To keep the fleet consistent, adhere to these core rules:
- Use
fetch: FreeBSD providesfetchin the base system. Do not install or usecurl/wgetunless absolutely necessary. - Clean Caches: Always clean up after installing packages:
pkg clean -ay && rm -rf /var/cache/pkg/*. - Permissions: Use
chown -R bsd:bsd /config /appin your Containerfile. - Configuration: Always use
/configas the persistent volume mount point.
For the complete list of rules, labels, and architectural details, read the full Development Guide.
Need Help?
Stuck on a build error or have questions about ocijail? Join us on Discord — it's the fastest way to get help from the Daemonless community.