No description
  • Shell 95.6%
  • Python 4.4%
Find a file
Luna 868869e801 docs(bridges): add ess-helm wiring guide for femdev.nl
Patterns:
- One-time HTTP serve setup per bridge container (busybox httpd on :9876)
- Init container fetches registration.yaml over LAN on pod start
- List-driven templating pattern for scalable bridge addition
- Verification commands + 5 common pitfalls

Pairs with the 14 ct/*.sh bridge deploy scripts from 9ed2efe.
2026-06-25 22:55:52 +02:00
.github/workflows fix(workflow): check changes against HEAD, not working-tree-vs-index 2026-06-25 20:22:12 +02:00
ct feat(bridges): add 14 Matrix bridge deploy scripts 2026-06-25 22:55:52 +02:00
docs docs(bridges): add ess-helm wiring guide for femdev.nl 2026-06-25 22:55:52 +02:00
images Initial commit: 500+ Incus app templates 2026-06-22 12:09:00 +02:00
install feat(bridges): add 14 Matrix bridge deploy scripts 2026-06-25 22:55:52 +02:00
misc feat(bridges): add 14 Matrix bridge deploy scripts 2026-06-25 22:55:52 +02:00
profiles Initial commit: 500+ Incus app templates 2026-06-22 12:09:00 +02:00
scripts feat(bridges): add 14 Matrix bridge deploy scripts 2026-06-25 22:55:52 +02:00
tools Migrate all URLs from GitHub to Codeberg 2026-06-22 13:41:33 +02:00
.gitignore gitignore: exclude transient cache files from gen_docs.sh 2026-06-25 14:58:09 +02:00
colima-Darwin-arm64 fix(arm64): mail-archiver — pre-install .NET SDK via dotnet-install.sh with retry + post-eval rebuild fallback 2026-06-24 00:51:43 +02:00
common.sh Fix: prepend INCUS_BASE into piped script instead of --env 2026-06-22 22:36:25 +02:00
CONTRIBUTING.md Migrate all URLs from GitHub to Codeberg 2026-06-22 13:41:33 +02:00
debug-storage.sh Update debug-storage.sh: load function from remote common.sh 2026-06-22 14:31:11 +02:00
fix-compat-local.sh Migrate all URLs from GitHub to Codeberg 2026-06-22 13:41:33 +02:00
fix-master.sh fix-master.sh: exclude self from stale-URL check 2026-06-22 13:42:12 +02:00
gen_all.sh Fix: prepend INCUS_BASE into piped script instead of --env 2026-06-22 22:36:25 +02:00
gen_docs.sh feat(site): redesign docs site with real logo + modern dark theme 2026-06-25 17:47:23 +02:00
LICENSE Initial commit: 500+ Incus app templates 2026-06-22 12:09:00 +02:00
README.md docs: document auto-regen pipeline in README 2026-06-25 13:55:34 +02:00

Incus Logo

Incus Helper Scripts

One-command application deployment for Incus containers

Quick StartTemplatesUsageDevelopment


Inspired by the Proxmox VE Community Helper Scripts, this project provides ready-to-run scripts that deploy applications inside Incus containers with zero configuration.

Each application has two scripts:

  • ct/<app>.sh — runs on the Incus host, creates the container with appropriate resources, then triggers the install
  • install/<app>-install.sh — runs inside the container, installs the application and configures it

Quick Start

# Deploy Nginx in 10 seconds
bash <(curl -fsSL https://codeberg.org/luna-dj/incus-scripts/raw/branch/main/ct/nginx.sh)

# Deploy PostgreSQL
bash <(curl -fsSL https://codeberg.org/luna-dj/incus-scripts/raw/branch/main/ct/postgresql.sh)

# Deploy Ollama (LLM inference)
bash <(curl -fsSL https://codeberg.org/luna-dj/incus-scripts/raw/branch/main/ct/ollama.sh)

Prerequisites: Incus 6.0+ installed and initialized.

📦 Available Templates

Category Application Port Resources
Reverse Proxy Nginx 80 1CPU / 512MB / 4GB
Nginx Proxy Manager 81 1CPU / 1GB / 6GB
Traefik 8080 1CPU / 512MB / 4GB
Database PostgreSQL 16 5432 2CPU / 1GB / 8GB
Redis 6379 1CPU / 512MB / 4GB
MinIO (S3) 9001 2CPU / 2GB / 20GB
AI / LLM Ollama 11434 4CPU / 8GB / 30GB
Media Jellyfin 8096 2CPU / 2GB / 20GB
Immich 2283 4CPU / 4GB / 50GB
Cloud Nextcloud 80 2CPU / 2GB / 20GB
Password Manager Vaultwarden 80 1CPU / 1GB / 8GB
Smart Home Home Assistant 8123 2CPU / 2GB / 20GB
DNS AdGuard Home 80 1CPU / 512MB / 4GB
Dashboard Homarr 7575 1CPU / 1GB / 6GB
Monitoring Uptime Kuma 3001 1CPU / 1GB / 6GB
📋 View full variable reference

Each script accepts these environment variables to override defaults:

Variable Default Description
var_cpu per-app CPU cores (e.g., 2)
var_ram per-app RAM in MB (e.g., 2048)
var_disk per-app Disk in GB (e.g., 10)
var_os ubuntu OS image (e.g., alpine, debian)
var_version 24.04 OS version (e.g., 12 for Debian)
var_instance app name Instance name override
var_ipv4 auto Static IPv4 address (e.g., 10.0.0.50)
var_profile default Incus profile to use
var_tags per-app Comma-separated tags for metadata
var_unprivileged true Run unprivileged container
var_type container container or virtual-machine
var_image auto Full image alias override
var_storage auto Storage pool name
var_network auto Network bridge name

Example with overrides:

var_cpu=4 var_ram=4096 var_disk=50 var_ipv4=10.0.0.50 \
  bash <(curl -fsSL https://.../ct/postgresql.sh)

🚀 Usage

Deploy an application

# Use the defaults
bash <(curl -fsSL https://codeberg.org/luna-dj/incus-scripts/raw/branch/main/ct/nginx.sh)

# With custom resources
var_cpu=2 var_ram=2048 var_disk=20 \
  bash <(curl -fsSL https://...<app>.sh)

Run install in an existing instance

incus exec <instance> -- bash -c "$(curl -fsSL https://codeberg.org/luna-dj/incus-scripts/raw/branch/main/install/<app>-install.sh)"

Manage instances

# List all instances
bash <(curl -fsSL https://codeberg.org/luna-dj/incus-scripts/raw/branch/main/tools/incus-list.sh)

# Backup an instance
bash <(curl -fsSL https://codeberg.org/luna-dj/incus-scripts/raw/branch/main/tools/incus-backup.sh) my-instance

# Backup all instances
bash <(curl -fsSL https://codeberg.org/luna-dj/incus-scripts/raw/branch/main/tools/incus-backup.sh) --all

# Update all instances
bash <(curl -fsSL https://codeberg.org/luna-dj/incus-scripts/raw/branch/main/tools/incus-update-all.sh)

Profiles

Pre-defined profiles make it easy to standardize resources across instances:

# Load the app profile
incus profile create app
incus profile edit app < profiles/profile-templates.yaml
incus launch images:ubuntu/24.04 my-app --profile default --profile app

🏗 Project Structure

incus-helper-scripts/
├── ct/                      # Container creation scripts (run on host)
│   ├── nginx.sh
│   ├── postgresql.sh
│   └── ...
├── install/                 # In-container install scripts
│   ├── nginx-install.sh
│   ├── postgresql-install.sh
│   └── ...
├── misc/                    # Shared framework
│   ├── incus-build.func     # Container creation functions
│   └── incus-install.func   # In-container installation helpers
├── tools/                   # Utility scripts
│   ├── incus-list.sh
│   ├── incus-backup.sh
│   └── incus-update-all.sh
├── profiles/                # Incus profile templates
│   └── profile-templates.yaml
├── images/                  # Image reference docs
│   └── incus-image-aliases.md
├── common.sh                # Shared utilities (colors, logging, helpers)
├── CONTRIBUTING.md
├── LICENSE
└── README.md

🛠 Development

Adding a new template

Each app needs two files:

  1. ct/<app>.sh — Host-side script that creates the container:
#!/usr/bin/env bash
source /dev/stdin <<<"$(curl -fsSL https://codeberg.org/luna-dj/incus-scripts/raw/branch/main/common.sh)"
source /dev/stdin <<<"$(curl -fsSL https://codeberg.org/luna-dj/incus-scripts/raw/branch/main/misc/incus-build.func)"

APP="My App"
var_tags="${var_tags:-tag1,tag2}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-10}"

header_info "$APP"
variables
check_existing_instance
create_instance

INSTALL_URL="https://codeberg.org/luna-dj/incus-scripts/raw/branch/main/install/myapp-install.sh"
incus_exec "$var_instance" -- bash -c "$(curl -fsSL "$INSTALL_URL")"

IP=$(get_instance_ip "$var_instance")
echo "Access: http://${IP}:<port>"
  1. install/<app>-install.sh — In-container install script:
#!/usr/bin/env bash
source /dev/stdin <<<"$(curl -fsSL https://codeberg.org/luna-dj/incus-scripts/raw/branch/main/common.sh)"
source /dev/stdin <<<"$(curl -fsSL https://codeberg.org/luna-dj/incus-scripts/raw/branch/main/misc/incus-install.func)"

header_info "My App"
setting_up_container
network_check
configure_apt

# Install your app here...

print_completion "My App" "$IP" "<port>"

Running locally (without the repo)

# Clone the repo
git clone https://codeberg.org/luna-dj/incus-scripts
cd incus-helper-scripts

# Run a script directly
bash ct/nginx.sh

# Or source the functions
source common.sh
source misc/incus-build.func
# ... use functions directly

📚 Advanced

Networking

Each container gets an IP via DHCP by default. For a static IP:

var_ipv4="10.0.0.50" bash ct/postgresql.sh

Proxy devices forward host ports to container ports:

incus config device add <instance> proxy-8080 proxy \
  listen=tcp:0.0.0.0:8080 connect=tcp:127.0.0.1:80

Storage

Mount additional storage:

incus config device add <instance> media disk \
  source=/mnt/media path=/media

Updates

Re-running a ct script on an existing instance triggers the update_script function (if implemented). Otherwise:

# Re-run just the install part
incus exec <instance> -- bash -c "$(curl -fsSL https://.../install/<app>-install.sh)"

🧪 Testing

# Check all scripts have the right header
grep -l "^#!/usr/bin/env bash" ct/*.sh | wc -l

# Shellcheck validation
shellcheck ct/*.sh install/*.sh misc/*.func tools/*.sh

# Check for common variables
grep "var_cpu=" ct/*.sh | wc -l

🤝 Contributing

We welcome contributions! See CONTRIBUTING.md for guidelines.

Auto-syncing from upstream

The ct/ and install/ scripts for almost all 600+ apps are automatically regenerated from community-scripts/ProxmoxVE:

  • Schedule: Daily at 06:00 UTC (.github/workflows/regen.yml)
  • Manual: Run from the Actions tab → "Regen from upstream" → "Run workflow"
  • Script: scripts/regen-from-upstream.py
  • Output: Pull request with all changes; merges to main mirror to Codeberg

Apps with hand-written fixes (e.g. mail-archiver arm64 .NET SDK workaround) are listed in CUSTOM_INSTALL_APPS in scripts/regen-from-upstream.py and never overwritten by the regen.

To regenerate locally:

python3 scripts/regen-from-upstream.py

📄 License

MIT — see LICENSE.

🙏 Acknowledgements