Add AppJail as an alternative deployment tool#1
Conversation
DtxdF
commented
Mar 13, 2026
- Add AppJail icon.
- Add AppJail and Director to:
- immich
- mariadb
- nginx-base
- openspeedtest
- postgres
- redis
- Add AppJail icon. - Add AppJail and Director to: - immich - mariadb - nginx-base - openspeedtest - postgres - redis
|
This is fantastic work! I’m really excited to see AppJail as a first-class deployment option! I realized I haven’t properly documented our documentation pipeline, and I apologize for that oversight. Because of how it's currently set up, if I merge these manual edits to the .md files right now, the next automated run will unfortunately overwrite them. For context, our deploy workflow automatically regenerates the site by pulling the compose.yaml and README.md files from each individual image repository. Those README.md files are themselves generated via the dbuild templates. To get this merged, we have a couple of options: The Short-Term Fix: I'm happy to temporarily disable the automated docs sync and merge this PR as-is so we can get your work live right away. The Ideal Long-Term Fix: We port your AppJail logic into the central README.j2 template so that every image in the fleet gets these instructions automatically. I'm happy to go with the short-term option for now to get this across the finish line. What are your thoughts? |
|
I went ahead and disabled the docs generation and merging this. |
|
No problem! I'll create a pr for each image I've edited. |
|
Oh, I’ve taken a closer look at the |
I don't think that's possible. After reading the README file for the images I've edited, it seems they differ slightly from daemonless-io and appear to have been automatically generated by dbuild. I think I'll wait until the documentation process is complete to avoid making mistakes. Any other suggestions are welcome. |
|
We actually had two separate templates, which was confusing and caused drift. I’ve just finished consolidating them—we now have a single "Source of Truth" template at dbuild/templates/README.j2. The daemonless-io site generator has been updated to pull directly from there. To make AppJail a permanent part of the project, I’d love to help you get this into the template. Instead of submitting multiple PRs to individual images, we can add a few lines to each image's compose.yaml and let the template do the heavy lifting. Here is an example of what I'm thinking for the metadata in compose.yaml: x-daemonless:
title: "MariaDB"
# ... existing metadata ...
appjail:
makejail:
options:
- "container=boot args:--pull"
director:
options:
- "virtualnet: ':<random> default'"
- "nat:"The template would then use this to auto-generate the tabs like this: appjail-director.yml: options:
{%- for opt in appjail.director.options %}
- {{ opt }}
{%- endfor %}
services:
{{ name }}:
# ... auto-mapped from compose service definition ...This way, AppJail support becomes a core feature for the entire fleet. If you're open to it, I can handle the template logic if you help me define the best default fields for the appjail section. What do you think? |
|
should dbuild output appjail-director.yml .env , etc like it does for README.md? what do you think? |
|
I’ve been prototyping some updates to the init and template logic to automate more of the boilerplate. Here’s a look at where this is heading: Init + generate example[ahze@saturn ~/src/apache]$ dbuild init --freebsd-port www/apache24 --github --variants=pkg,pkg-latest --port 80 --title Apache
[info] querying port metadata for www/apache24...
[info] querying runtime deps for apache24...
=== Port metadata ===
[ok] name: apache24 (pkg: apache24)
[ok] description: The Apache HTTP Server Project is an effort to develop and maintain an open-sour...
[ok] license: Apache-2.0
[ok] web: https://httpd.apache.org/
[ok] category: Network
[ok] run_deps: perl5 pcre2 libxml2 libnghttp2 jansson gdbm expat curl apr
=== created /home/ahze/src/apache/.daemonless/config.yaml ===
=== created /home/ahze/src/apache/compose.yaml ===
=== created /home/ahze/src/apache/Containerfile.pkg.j2 ===
=== created /home/ahze/src/apache/root/etc/services.d/apache24/run ===
=== created /home/ahze/src/apache/root/healthz ===
=== created /home/ahze/src/apache/.github/workflows/build.yaml ===
=== scaffolded 6 file(s) (created) ===This pulls metadata directly from the local ports tree — description from [ahze@saturn ~/src/apache]$ dbuild generate
=== Generated README.md ===
=== Generated Containerfile.pkg ===The AppJail section in the generated README shows exactly what users need to deploy via AppJail Director -- no manual work required: [ahze@saturn ~/src/apache]$ grep -A30 appjail README.md
=== ":appjail-appjail: AppJail Director"
**.env**:
```
DIRECTOR_PROJECT=apache
PUID=@PUID@
PGID=@PGID@
TZ=@TZ@
```
**appjail-director.yml**:
```yaml
options:
- virtualnet: ':<random> default'
- nat:
services:
apache:
name: apache
options:
- from: @REGISTRY@/apache:latest
oci:
environment:
- PUID: '@PUID@'
- PGID: '@PGID@'
- TZ: '@TZ@'
volumes:
- apache_config: /config
volumes:
apache_config:
device: '@CONTAINER_CONFIG_ROOT@/@APACHE_CONFIG_PATH@'
```
**Makejail**:
```
OPTION container=boot args:--pull
```And in [ahze@saturn ~/src/apache]$ grep -A5 -B5 appjail compose.yaml
compose.yaml- web_url: "https://httpd.apache.org/"
compose.yaml- freshports_url: "https://www.freshports.org/www/apache24/"
compose.yaml- user: "bsd"
compose.yaml- mlock: false
compose.yaml-
compose.yaml: appjail:
compose.yaml-
compose.yaml- docs:
compose.yaml- env:
compose.yaml- PUID: "User ID for the application process"
compose.yaml- PGID: "Group ID for the application process"No boilerplate, no commented-out examples. If you want to override the defaults (custom virtualnet, multi-service Complex example: ImmichFor multi-service stacks, the full appjail:
director:
options:
- "alias:"
- "ip4_inherit:"
depends_on:
- name: database
image: ghcr.io/daemonless/immich-postgres:latest
template: "immich-postgres-template.conf"
env:
POSTGRES_PASSWORD: "!ENV '${DB_PASSWORD}'"
POSTGRES_USER: "!ENV '${DB_USERNAME}'"
POSTGRES_DB: "!ENV '${DB_DATABASE_NAME}'"
volumes:
db-data: "/var/lib/postgresql/data"
- name: redis
image: ghcr.io/daemonless/redis:latest
env:
LANG: "C.UTF-8"
TZ: "!ENV '${TZ}'"
volumes:
redis-data: "/config"
- name: immich-machine-learning
image: ghcr.io/daemonless/immich-ml:latest
env:
HF_HOME: "/cache/huggingface"
MPLCONFIGDIR: "/tmp"
TZ: "!ENV '${TZ}'"
volumes:
model-cache: "/cache"That metadata drives the full generated I'm still learning the ropes with AppJail, so I'd love your thoughts on this schema. Does this approach look solid to you before I commit more time to this path? |
|
Yeah, as I said, I have no problem adding logic to your template, but right now I don’t think I can do it because I’m not entirely sure how the process works. For example, let’s say I just want to edit nginx-base to fix a typo: what steps do I need to perform? Maybe I’m a bit confused right now, and the process is actually simpler. But if you want to simplify this process, take a look at how I do it in Makejails:
Basically, if I or any other user wants to fix a typo, all we have to do is edit If you prefer the dbuild template, Director has a man page called |
|
I completely agree that the old process was confusing -- part of the problem was that I’ve just finished a major overhaul of our documentation engine to strip all that away and make the workflow simple as possible, while keeping compose.yaml as the single source of truth. I’ve added a Contributing Guide that explains the new workflow. To answer your "fix a typo" question, the process is now just as straightforward as your README.template -> update.sh example: Typos/Metadata: Edit the compose.yaml in the image repo. Structural changes (like AppJail): Edit the master template in the dbuild repo. Sync: Run dbuild generate (our new equivalent to your update.sh) to automatically update the repo's README.md. I've also already ported your AppJail patterns into our central template. It now auto-generates the .env with defaults and uses the !ENV syntax in appjail-director.yml exactly as you suggested to pass those variables to oci.environment. I tested the automated output for Redis on one of my FreeBSD nodes and it worked perfectly, I also tested home-assistant and it worked. |
|
Thanks for this! I'll try it all out later. btw I've updated the dbuild port to the latest version, so I'll make changes later with the most recent code. |
|
Following up on the Redis test, I've just added AppJail support to both Plex and Home Assistant. Everything deployed smoothly using the instructions in the READMEs. Let me know what you think when you have a chance to take a look. |