Build Unraid image directly from the Gitea repo

docker-compose.unraid.yml now uses a Git URL as the build context
(https://git.oservr.com/ort/KCal.git#main) instead of requiring a manual
clone onto the array — Docker/BuildKit fetches the source itself at build
time. Requires the repo to allow anonymous HTTP read access in Gitea
(Settings -> Visibility -> Public); this is a read-only clone, nothing
more. Verified with a real docker build/compose run against the public
repo, not just syntax-checked.

UNRAID.md rewritten to match: no deploy key, no NerdTools/git, no source
checkout needed. Kept a token-auth alternative documented for anyone who'd
rather keep the repo private.
This commit is contained in:
ort
2026-08-15 14:50:00 -04:00
parent 5c2fde0c86
commit 9021a7839d
2 changed files with 93 additions and 88 deletions
+85 -87
View File
@@ -2,105 +2,88 @@
This app has no native/compiled dependencies (it uses Node's built-in This app has no native/compiled dependencies (it uses Node's built-in
`node:sqlite`), so it builds and runs on Unraid's stock Docker exactly like `node:sqlite`), so it builds and runs on Unraid's stock Docker exactly like
anywhere else. This file covers the Unraid-specific parts: getting the anywhere else. `docker-compose.unraid.yml` builds straight from the Gitea
code onto the array, where data lives, and how to run it via either the repo — Docker/BuildKit clones it itself as part of the build, so you don't
Compose Manager plugin or the terminal. need to check out the source on the array at all, and there's no deploy
key involved in this path.
## 1. Get the code onto Unraid ## 1. Make the repo readable over HTTP
Pick whichever is easier for you — both end up with the project folder The compose file's `build.context` is a Git URL
somewhere under `/mnt/user/`. (`https://git.oservr.com/ort/KCal.git#main`) — Docker fetches that itself
at build time. This is a read-only clone, same as any anonymous `git
clone`, so the repo needs to allow anonymous HTTP read access:
**Option A — copy via network share (no git needed on Unraid):** In Gitea: **repo → Settings → Visibility → Public** (save).
Unraid shares `/mnt/user/appdata` over SMB by default. From your Mac:
```bash No token, no key, no extra permission grant — public visibility is
mkdir -p /Volumes/appdata/kids-calendar-src # after connecting to \\TOWER\appdata sufficient for a read-only clone.
rsync -av --exclude node_modules --exclude data --exclude .git \
"/Users/ort84/kids calendar/kids-calendar/" /Volumes/appdata/kids-calendar-src/
```
(Connect to the share first via Finder → Go → Connect to Server → ## 2. Create the appdata data folder
`smb://TOWER/appdata`, adjust the mount path/share name to match your
server.)
**Option B — git clone directly on Unraid:**
Unraid's base OS doesn't ship git. Install the **NerdTools** plugin from
Community Applications, enable `git` in it, then from the Unraid terminal
(Tools → Terminal, or SSH in):
```bash
mkdir -p /mnt/user/appdata/kids-calendar-src
cd /mnt/user/appdata/kids-calendar-src
git clone ssh://git@git.oservr.com:23/ort/KCal.git .
```
This needs the deploy key available on Unraid too (copy `GitOServr/` over
via the same SMB share, then `chmod 600` the private key file — SSH will
refuse a world-readable key just like it did on the Mac). Only do this if
you're comfortable having a copy of that key on the server; Option A avoids
that entirely.
## 2. Create the appdata folder
```bash ```bash
mkdir -p /mnt/user/appdata/kids-calendar mkdir -p /mnt/user/appdata/kids-calendar
``` ```
This is where the SQLite database will live — `docker-compose.unraid.yml` This is where the SQLite database will live — the compose file
bind-mounts it in, instead of using a Docker-managed named volume, so it bind-mounts it in, instead of using a Docker-managed named volume, so it
shows up normally in Unraid's Docker tab and gets picked up by appdata shows up normally in Unraid's Docker tab and gets picked up by appdata
backup plugins (e.g. CA Backup/Restore) like any other app's data. backup plugins (e.g. CA Backup/Restore) like any other app's data.
## 3. Set up `.env` ## 3. Deploy
In the project folder on Unraid (`kids-calendar-src` from step 1): ### Via Compose Manager Plus (recommended)
```bash 1. Docker → Compose → **Add Stack**, name it `kids-calendar`.
cp .env.example .env 2. In the **Compose** tab, paste:
```
```yaml
Edit `.env` and set: services:
kids-calendar:
``` build:
SESSION_SECRET=<a long random value> context: https://git.oservr.com/ort/KCal.git#main
``` dockerfile: Dockerfile
container_name: kids-calendar
Generate one with: ports:
- "3007:3007"
```bash volumes:
openssl rand -hex 32 - /mnt/user/appdata/kids-calendar:/app/data
``` environment:
- SESSION_SECRET=${SESSION_SECRET:?set a long random value in .env}
(Unraid ships `openssl`. If for some reason it's not available, `docker - COOKIE_SECURE=${COOKIE_SECURE:-false}
run --rm node:22-alpine node -e "console.log(require('node:crypto').randomBytes(32).toString('hex'))"` - DISABLE_PUBLIC_SIGNUP=${DISABLE_PUBLIC_SIGNUP:-false}
works too.) restart: unless-stopped
```
Leave `COOKIE_SECURE=false` unless you're putting this behind HTTPS (see
"Reverse proxy" below). 3. In the **ENV** tab, set:
```
## 4. Run it SESSION_SECRET=<output of: openssl rand -hex 32>
COOKIE_SECURE=false
**Via the Compose Manager plugin (recommended):** install "Docker Compose DISABLE_PUBLIC_SIGNUP=false
Manager" from Community Applications, add a new stack pointing at the ```
`kids-calendar-src` folder, and have it use `docker-compose.unraid.yml` 4. **Compose Up**. First run builds the image (a minute or so — it's
(the plugin lets you pick which compose file in the folder to use — if it cloning the repo and running `npm install`), then the container starts
only supports a file literally named `docker-compose.yml`, either rename on port 3007.
`docker-compose.unraid.yml` to that inside your Unraid copy, or symlink
it: `ln -s docker-compose.unraid.yml docker-compose.yml`). Start the ### Via terminal (no plugin needed)
stack from the plugin's UI.
You only need the one compose file and a `.env` next to it — not a full
**Via terminal:** checkout, since Docker fetches the source itself:
```bash ```bash
mkdir -p /mnt/user/appdata/kids-calendar-src
cd /mnt/user/appdata/kids-calendar-src cd /mnt/user/appdata/kids-calendar-src
curl -o docker-compose.unraid.yml \
https://git.oservr.com/ort/KCal/raw/branch/main/docker-compose.unraid.yml
cat > .env <<EOF
SESSION_SECRET=$(openssl rand -hex 32)
COOKIE_SECURE=false
DISABLE_PUBLIC_SIGNUP=false
EOF
docker compose -f docker-compose.unraid.yml up -d --build docker compose -f docker-compose.unraid.yml up -d --build
``` ```
Either way, first boot builds the image (a minute or so), then the ## 4. Use it
container starts and listens on port 3007.
## 5. Use it
Open `http://<unraid-ip>:3007/signup.html`, create the first parent Open `http://<unraid-ip>:3007/signup.html`, create the first parent
account, invite your spouse, add your kids, build out calendars, and grab account, invite your spouse, add your kids, build out calendars, and grab
@@ -108,15 +91,30 @@ each child's kiosk link from the dashboard for their tablet.
## Updating ## Updating
After pulling/copying new code: Docker re-clones the repo's `main` branch fresh every time you build —
there's no separate `git pull` step. Just re-run the build:
```bash - **Compose Manager Plus**: right-click the stack → **Update & Rebuild**
cd /mnt/user/appdata/kids-calendar-src (or **Build & Up** if stopped).
docker compose -f docker-compose.unraid.yml up -d --build - **Terminal**: `docker compose -f docker-compose.unraid.yml up -d --build`
from the folder in the terminal steps above.
Either way, your data in `/mnt/user/appdata/kids-calendar` is untouched.
## Prefer not to make the repo public?
If you'd rather keep `KCal` private, the alternative is authenticating the
git-context fetch with a Gitea access token instead of flipping visibility
— generate a read-only token in Gitea, then reference it via compose
variable substitution so it isn't hardcoded in the file itself:
```yaml
build:
context: https://${GITEA_USER}:${GITEA_TOKEN}@git.oservr.com/ort/KCal.git#main
``` ```
with `GITEA_USER`/`GITEA_TOKEN` set in the stack's ENV tab (or `.env` for
This rebuilds the image and recreates the container; your data in the terminal path) instead of `SESSION_SECRET`'s neighbors above. Ask if
`/mnt/user/appdata/kids-calendar` is untouched. you want this wired up instead.
## Reverse proxy / access from outside your LAN ## Reverse proxy / access from outside your LAN
@@ -124,8 +122,8 @@ If you're exposing this beyond your home network (e.g. via Swag or Nginx
Proxy Manager, both common on Unraid) with a real HTTPS certificate: Proxy Manager, both common on Unraid) with a real HTTPS certificate:
- Point the proxy at `http://<unraid-ip>:3007` internally. - Point the proxy at `http://<unraid-ip>:3007` internally.
- Set `COOKIE_SECURE=true` in `.env` and re-run the `up -d --build` command - Set `COOKIE_SECURE=true` (ENV tab, or `.env` for the terminal path) and
above — otherwise login cookies won't be marked secure and some rebuild — otherwise login cookies won't be marked secure and some
browsers/proxies will refuse to send them back over HTTPS. browsers/proxies will refuse to send them back over HTTPS.
- Once your household(s) exist, consider setting - Once your household(s) exist, consider setting
`DISABLE_PUBLIC_SIGNUP=true` so `/signup.html` stops accepting new `DISABLE_PUBLIC_SIGNUP=true` so `/signup.html` stops accepting new
+8 -1
View File
@@ -1,6 +1,13 @@
services: services:
kids-calendar: kids-calendar:
build: . build:
# Docker/BuildKit clones the repo itself at build time — no manual
# git clone onto the array needed. Requires the repo to allow
# anonymous HTTP read access in Gitea (Settings → Visibility →
# Public); this is a read-only clone, so nothing beyond that is
# needed. #main is the branch to build from.
context: https://git.oservr.com/ort/KCal.git#main
dockerfile: Dockerfile
container_name: kids-calendar container_name: kids-calendar
ports: ports:
- "3007:3007" - "3007:3007"