Files
portainer-core/docs/reference/CONTAINERS.md
T

37 KiB

Container Reference Guide

Documentation of all deployed containers in the tower-of-joy infrastructure

Last Updated: 2025-11-16


Infrastructure Layer

Portainer

Portainer provides the web-based container management interface for the entire stack, offering visual control over Docker containers, stacks, images, volumes, and networks. It serves as the primary management tool for deploying and monitoring all other services, with GPU device management enabled for allocation to ML and transcoding workloads. The interface replaces the need for manual Docker CLI operations and provides real-time container logs, stats, and control.

Property Value
Image portainer/portainer-ce:latest
Container Name portainer
Access URL http://192.168.86.149:8001
External Access LAN only (behind firewall)
Port Mapping 8001:9000 (HTTP), 8443:9443 (HTTPS)
Network Mode Host
Restart Policy always
Volume Mounts portainer_data:/data, /var/run/docker.sock
Resource Limits None
GPU Required No
Dependencies None (base service)

PostgreSQL Shared

PostgreSQL Shared is a centralized PostgreSQL 17 database server providing isolated database instances for multiple applications across the infrastructure, including Authentik (SSO), Gitea (Git hosting), and future services requiring relational database storage. It implements a shared infrastructure pattern where each application gets its own database and user credentials while sharing the same PostgreSQL instance for resource efficiency. The service stores all database data on the HDD with automated backups scheduled to the backups directory, providing persistent storage with volume-based data retention across container updates.

Property Value
Image postgres:17
Container Name postgres-shared
Access URL N/A (internal database server)
External Access No (docker-dataplane network only)
Port Mapping 5432:5432 (PostgreSQL)
Network Mode Bridge (docker-dataplane)
Restart Policy unless-stopped
Volume Mounts /home/jpmschweitzer/docker-data/postgres-shared/data:/var/lib/postgresql/data, /home/jpmschweitzer/docker-data/postgres-shared/backups:/backups
Environment POSTGRES_PASSWORD=<secure-password>, POSTGRES_DB=postgres, TZ=Europe/Amsterdam, PGDATA=/var/lib/postgresql/data/pgdata
Resource Limits None
GPU Required No
Dependencies docker-dataplane network
Databases authentik (Authentik SSO), gitea (Git hosting), organizr (Organizr dashboard), postgres (default/admin)
Database Users authentik_user, gitea_user, organizr_user, postgres (superuser)
Health Check pg_isready -U postgres (30s interval)
Backup Strategy /backups volume for pg_dump exports

Initialization: Databases and users for authentik and gitea are created by the postgres-init.sh script.

Adding Organizr Database:

  1. Generate a secure password for the organizr_user.
  2. In Portainer, navigate to the postgres-shared service.
  3. Go to the "Env" tab and add a new environment variable:
    • Name: ORGANIZR_DB_PASSWORD
    • Value: Your generated password
  4. Redeploy the postgres-shared service. This will trigger the postgres-init.sh script to create the organizr database and user.

Redis Shared

Redis Shared is a centralized Redis 7 key-value store providing cache, session storage, and message queue capabilities for multiple applications, with logical database isolation (DB 0-15) allowing each service to maintain separate keyspaces within the same Redis instance. It implements a shared infrastructure pattern where applications like Authentik use DB 0 for sessions/cache while future services can use DB 1-15, eliminating the need for separate Redis containers per application. The service stores data on the HDD for persistence across restarts, with AOF (Append-Only File) enabled for durability and optional RDB snapshots for backup points.

Property Value
Image redis:7-alpine
Container Name redis-shared
Access URL N/A (internal cache server)
External Access No (docker-dataplane network only)
Port Mapping 6379:6379 (Redis)
Network Mode Bridge (docker-dataplane)
Restart Policy unless-stopped
Volume Mounts /home/jpmschweitzer/docker-data/redis-shared/data:/data
Command redis-server --appendonly yes --dir /data
Resource Limits None
GPU Required No
Dependencies docker-dataplane network
Database Allocation DB 0: Authentik, DB 1-15: Available for future services
Persistence AOF (Append-Only File) enabled for durability
Health Check redis-cli ping returns PONG (30s interval)
Connection String redis://redis-shared:6379/0 (DB 0), redis://redis-shared:6379/1 (DB 1), etc.

Nginx Proxy Manager

Nginx Proxy Manager serves as the unified reverse proxy and SSL certificate manager, providing a web-based interface for routing HTTP/HTTPS traffic to backend services with automatic Let's Encrypt certificate provisioning. It consolidates access to all web services through a single entry point with path-based or subdomain routing, eliminating the need to remember individual service ports. The service handles SSL termination, proxy host configuration, and access list management through an intuitive dashboard.

Property Value
Image jc21/nginx-proxy-manager:latest
Container Name nginx-proxy-manager
Access URL http://192.168.86.149:81
External Access LAN + Internet (ports 80/443 forwarded)
Port Mapping 81:81 (Admin), 80:80 (HTTP), 443:443 (HTTPS)
Network Mode Host
Restart Policy unless-stopped
Volume Mounts ~/docker-data/nginx-proxy-manager/data:/data, ~/docker-data/nginx-proxy-manager/letsencrypt:/etc/letsencrypt
Resource Limits None
GPU Required No
Dependencies None (reverse proxy for other services)

Ollama

Ollama is a GPU-accelerated large language model server that provides a REST API for running local LLM inference with models up to 13B parameters, leveraging the RTX 2080 Ti's 11GB VRAM for fast on-device AI capabilities. It manages model downloads, quantization, and serving through a simple API compatible with OpenAI's format, supporting use cases like code generation, chat applications, and text processing without cloud dependencies. The service stores models on the SSD for quick loading times and maintains persistent model storage across container restarts.

Property Value
Image ollama/ollama:latest
Container Name ollama
Access URL http://192.168.86.149:11434
External Access LAN only (API endpoint)
Port Mapping 11434:11434 (API)
Network Mode Bridge (custom network)
Restart Policy unless-stopped
Volume Mounts ~/docker-data/ollama/models:/root/.ollama
Resource Limits Memory: 8GB, GPU: 11GB VRAM
GPU Required Yes (NVIDIA RTX 2080 Ti)
GPU Configuration NVIDIA_VISIBLE_DEVICES=all, NVIDIA_DRIVER_CAPABILITIES=compute,utility
Dependencies NVIDIA Container Toolkit
Typical Models llama3.2:3b (~2GB), mistral:7b (~4GB), codellama:7b (~4GB)

Code-Server

Code-Server provides a browser-based Visual Studio Code IDE running directly on the host system, offering a persistent development environment with full access to host-level configurations, filesystems, and systemd services without the limitations of containerization. It replaces traditional SSH access by providing a rich IDE experience that survives network disconnections through session persistence, with integrated terminal access, file explorer, git integration, and extension support. The service runs as a systemd service on the host, listening on localhost and exposed externally through Nginx Proxy Manager with SSL encryption and multi-layer authentication for secure remote development access.

Property Value
Deployment Type Host-based systemd service (NOT containerized)
Binary Location /usr/bin/code-server
Service Name code-server.service
Access URL (LAN) http://127.0.0.1:8084 (localhost only)
Access URL (Public) https://code.schweitz.net
External Access Yes (via NPM reverse proxy with SSL)
Port Binding 127.0.0.1:8084 (not exposed to network)
User/Group jpmschweitzer:jpmschweitzer
Restart Policy always (systemd)
Config Location ~/.config/code-server/config.yaml
Data Storage (SSD) ~/docker-data/code-server/user-data/ (settings, workspace), ~/docker-data/code-server/extensions/ (extensions)
Resource Limits None (native host process)
GPU Required No
Dependencies NPM (reverse proxy), systemd
Authentication Triple-layer: NPM access list, code-server password, SSL certificate
WebSocket Support Required (enabled via NPM proxy)
Typical Memory ~200-500MB (depends on workspace size)
Setup Guide docs/code-server-setup.md

Networking Layer

Headscale

Headscale is a self-hosted control server for Tailscale's mesh VPN protocol, creating a private software-defined network across all connected devices with end-to-end encryption and zero-configuration NAT traversal. It enables secure remote access to all homelab services from anywhere without exposing ports to the internet, using a custom 10.99.0.0/16 IP range for the mesh network. The service manages device registration, authentication, and mesh routing while maintaining full data sovereignty compared to the hosted Tailscale control plane.

Property Value
Image headscale/headscale:latest
Container Name headscale
Access URL http://192.168.86.149:8085
External Access LAN only (control server)
Port Mapping 8085:8080 (Web/API), 9090:9090 (Metrics)
Network Mode Bridge (custom network)
Restart Policy unless-stopped
Volume Mounts ~/docker-data/headscale/config:/etc/headscale, ~/docker-data/headscale/data:/var/lib/headscale
Resource Limits None
GPU Required No
Dependencies None
Network Range 10.99.0.0/16 (mesh IPs)
Pre-Auth Keys 24-hour expiration

Monitoring Layer

Uptime Kuma

Uptime Kuma monitors the availability and response times of all infrastructure and application services, providing real-time status dashboards with historical uptime tracking, incident detection, and notification capabilities. It performs HTTP, TCP, and ICMP checks at configurable intervals against each service endpoint, alerting on downtime events through multiple notification channels including email, Discord, and Slack. The service maintains a SQLite database of uptime history and response time metrics accessible through a clean web interface.

Property Value
Image louislam/uptime-kuma:latest
Container Name uptime-kuma
Access URL http://192.168.86.149:3001
External Access LAN only (monitoring dashboard)
Port Mapping 3001:3001 (Web UI)
Network Mode Bridge
Restart Policy unless-stopped
Volume Mounts ~/docker-data/uptime-kuma:/app/data
Resource Limits None
GPU Required No
Dependencies None (monitors other services)
Database SQLite (persistent in volume)
Check Intervals 60 seconds (configurable)

Netdata

Netdata provides comprehensive real-time system performance monitoring with per-second metric collection for CPU, RAM, disk I/O, network traffic, and Docker container resource usage, displaying everything through interactive web dashboards with zero configuration required. It collects thousands of metrics automatically with minimal overhead, offering drill-down capabilities from system-wide views to per-container and per-process analysis. The service maintains short-term metric history in RAM and can stream data to long-term storage backends for historical analysis.

Property Value
Image netdata/netdata:latest
Container Name netdata
Access URL http://192.168.86.149:19999
External Access LAN only (metrics dashboard)
Port Mapping 19999:19999 (Web UI)
Network Mode Host (for full system visibility)
Restart Policy unless-stopped
Volume Mounts /proc:/host/proc:ro, /sys:/host/sys:ro, /var/run/docker.sock:/var/run/docker.sock:ro
Capabilities SYS_PTRACE, apparmor:unconfined
Resource Limits None (monitoring overhead ~1-3% CPU)
GPU Required No
Dependencies Docker socket (read-only)
Metric Retention ~1 hour (RAM-based)

Organizr

Organizr serves as a comprehensive unified dashboard that consolidates all homelab services into a single tabbed interface with integrated homepage widgets showing real-time statistics from Jellyfin streams, Netdata metrics, Uptime Kuma status checks, and download client activity. It provides customizable authentication per-tab with support for SSO integration, user management with group-based access control, and a mobile-responsive interface for managing the entire infrastructure from anywhere. The service acts as a central hub replacing the need for multiple bookmarks or remembering service ports, offering both quick-access tabs and homepage cards with live data feeds from connected services.

Property Value
Image organizr/organizr:latest
Container Name organizr
Access URL (LAN) http://192.168.86.149:9999
Access URL (Public) https://home.schweitz.net
External Access Yes (via NPM reverse proxy with SSL)
Port Mapping 9999:80 (HTTP), 443:443 (HTTPS)
Network Mode Bridge
Restart Policy unless-stopped
Volume Mounts ~/docker-data/organizr:/config
Environment DB_TYPE=pgsql, DB_HOST=postgres-shared, DB_PORT=5432, DB_NAME=organizr, DB_USER=organizr_user, DB_PASS=${ORGANIZR_DB_PASSWORD}
Resource Limits None
GPU Required No
Dependencies PostgreSQL Shared
Database PostgreSQL on postgres-shared (database organizr)
Database Size ~5-10MB (typical)
Integrated Services Jellyfin, Netdata, Uptime Kuma
Authentication Internal (supports SSO, Plex OAuth, LDAP)

Configuration:

  1. In Portainer, navigate to the organizr stack.
  2. Go to the "Env" tab and ensure the following environment variables are set:
    • DB_TYPE=pgsql
    • DB_HOST=postgres-shared
    • DB_PORT=5432
    • DB_NAME=organizr
    • DB_USER=organizr_user
    • DB_PASS: This should be a secret. Create a secret in Portainer named ORGANIZR_DB_PASSWORD and set its value to the password you generated for the organizr_user.
  3. Redeploy the organizr stack.

Optimization Layer

Watchtower

Watchtower automatically monitors all running containers for updated images and performs rolling updates on a configurable schedule, ensuring the infrastructure stays current with security patches and feature releases without manual intervention. It checks Docker Hub and configured registries daily at 4 AM, pulls new images when available, gracefully stops containers, deploys updated versions, and cleans up old images to prevent disk bloat. The service logs all update activities and can send notifications through various channels when updates occur.

Property Value
Image containrrr/watchtower:latest
Container Name watchtower
Access URL N/A (background service)
External Access N/A
Port Mapping None (no exposed ports)
Network Mode Bridge
Restart Policy unless-stopped
Volume Mounts /var/run/docker.sock:/var/run/docker.sock
Environment WATCHTOWER_CLEANUP=true, WATCHTOWER_SCHEDULE=0 0 4 * * *
Resource Limits None
GPU Required No
Dependencies Docker socket (read-write for updates)
Schedule Daily at 4:00 AM
Cleanup Automatic (removes old images)

Maintenance Container

The maintenance container runs scheduled automation tasks including nightly Docker configuration backups with 30-day retention, disk space monitoring, log cleanup, and future expansion for health checks and system maintenance scripts. It executes cron-based jobs at 3 AM daily to archive all Docker Compose configurations, container settings, and persistent data to the backup directory on the HDD with timestamped snapshots. The container provides a centralized location for all homelab automation without cluttering the host system with multiple cron entries.

Property Value
Image alpine:latest
Container Name maintenance
Access URL N/A (background service)
External Access N/A
Port Mapping None (no exposed ports)
Network Mode Bridge
Restart Policy unless-stopped
Volume Mounts ~/docker-data:/source:ro, /mnt/media/backups:/backups
Command Runs crond with custom crontab
Resource Limits None
GPU Required No
Dependencies None
Schedule Daily at 3:00 AM (backups)
Backup Retention 30 days
Backup Size ~94MB per snapshot

Application Layer

Open WebUI

Open WebUI is a feature-rich, self-hosted web interface for interacting with large language models via Ollama, providing a ChatGPT-like experience with support for multiple models, conversation history, RAG (Retrieval-Augmented Generation), web search integration, and user authentication. It offers a modern chat interface with streaming responses, markdown rendering, code syntax highlighting, and conversation management, enabling seamless switching between different LLM models and maintaining persistent chat histories in a local database. The service integrates directly with the local Ollama instance for GPU-accelerated inference without cloud dependencies, supporting features like web search via DuckDuckGo, document upload for context, and multi-user access with authentication. It is documented at: https://docs.openwebui.com/

Property Value
Image ghcr.io/open-webui/open-webui:main
Container Name open-webui
Access URL http://192.168.86.149:82
External Access LAN only (not yet proxied)
Port Mapping 82:8080 (HTTP)
Network Mode Bridge (custom network: ai-network)
Restart Policy unless-stopped
Volume Mounts ~/docker-data/open-webui:/app/backend/data
Environment OLLAMA_BASE_URL=http://192.168.86.149:11434, DEFAULT_MODELS=llama3.2:3b, ENABLE_RAG_WEB_SEARCH=true, ENABLE_OLLAMA_API=true, WEBUI_AUTH=true, RAG_WEB_SEARCH_ENGINE=duckduckgo, AUDIO_STT_ENGINE=openai, AUDIO_TTS_ENGINE=openai
Resource Limits None
GPU Required No (uses Ollama for GPU inference)
Dependencies Ollama (ML inference backend)
Database SQLite (persistent in volume)
Authentication Built-in user management
Integrated Services Ollama, DuckDuckGo (web search)

Core API

Core API provides OpenAI-compatible HTTP functions for Open WebUI, extending LLM capabilities with AI orchestration, web scraping, and content processing services in a hot-reload development environment. The service implements Phase 1 of the AI Orchestrator plan, providing /v1/chat/completions and /v1/models endpoints with full OpenAI API compatibility, model aliasing (gpt-3.5-turbo → gemma:7b), and streaming support via Server-Sent Events. It uses Trafilatura for intelligent content extraction with BeautifulSoup fallback, offering configurable content length limits and optional link extraction optimized for feeding webpage content to language models. The service runs on Python 3.12 with mounted source code for instant updates, maintaining a persistent venv in docker-data for fast container restarts and development agility.

Property Value
Image python:3.12
Container Name core-api
Access URL http://192.168.86.149:8083
API Documentation http://192.168.86.149:8083/docs (Swagger UI)
External Access LAN only (internal API)
Port Mapping 8083:8083 (HTTP)
Network Mode Bridge (custom network: ai-dataplane)
Restart Policy unless-stopped
Volume Mounts /home/jpmschweitzer/Projects/portainer-core/services/core-api:/app (source code), ~/docker-data/core-api/venv:/venv (dependencies), ~/docker-data/core-api/logs:/app/logs (logs)
Environment APP_NAME=Core API, APP_VERSION=1.0.0-phase1, DEBUG=true, PORT=8083, LOG_LEVEL=INFO, PYTHONPATH=/app, Model aliases: ALIAS_GPT35=gemma:7b, ALIAS_GPT4=mistral:7b
Command Hot-reload with uvicorn: --reload --reload-dir /app/src
Resource Limits None
GPU Required No (proxies requests to Ollama which uses GPU)
Dependencies Ollama (model inference), Open WebUI (consumes this API), ai-dataplane network
Framework FastAPI 0.115.0, Uvicorn 0.32.0, Pydantic 2.10.4, httpx 0.28.1
Key Features OpenAI-compatible API (/v1/chat/completions, /v1/models), Model aliasing (OpenAI → local models), Streaming & non-streaming responses, Web scraping (Trafilatura, BeautifulSoup), Hot-reload development, OpenAPI spec, Infrastructure management (Portainer, Uptime Kuma)
AI Orchestrator Phase 1 Complete - OpenAI API wrapper with model routing. Phase 2+ will add memory systems, multi-agent workflows, and tool integration.
Health Check GET /health (30s interval) - checks API status and Ollama connectivity
Monitoring API Full CRUD for Uptime Kuma monitors via Socket.IO: GET /infrastructure/monitors, POST /infrastructure/monitors, GET /infrastructure/monitors/{id}, PUT /infrastructure/monitors/{id}, DELETE /infrastructure/monitors/{id}

Creating Monitors via API:

# Create a TCP port monitor for Redis
curl -X POST http://192.168.86.149:8083/infrastructure/monitors \
  -H "Content-Type: application/json" \
  -d '{
    "type": "port",
    "name": "Redis Shared - Port Check",
    "hostname": "redis-shared",
    "port": 6379,
    "interval": 60,
    "retryInterval": 60,
    "maxretries": 3,
    "notificationIDList": [],
    "accepted_statuscodes": ["200-299"]
  }'

# Create a PostgreSQL database monitor (note URL-encoded password)
curl -X POST http://192.168.86.149:8083/infrastructure/monitors \
  -H "Content-Type: application/json" \
  -d '{
    "type": "postgres",
    "name": "PostgreSQL Shared",
    "interval": 60,
    "retryInterval": 60,
    "maxretries": 3,
    "notificationIDList": [],
    "accepted_statuscodes": ["200-299"],
    "databaseConnectionString": "postgres://user:password@postgres-shared:5432/postgres"
  }'

Important: When creating database monitors with passwords containing special characters (/, =, +, etc.), URL-encode them in the connection string (e.g., /%2F, =%3D).


Jellyfin

Jellyfin is a GPU-accelerated media server that organizes, streams, and transcodes video, music, and photo libraries with hardware encoding via NVIDIA NVENC, enabling smooth 4K playback across multiple simultaneous clients without taxing the CPU. It provides a Netflix-like interface accessible through web browsers, mobile apps, and smart TV clients, with automatic metadata fetching, subtitle support, and user management for family sharing. The service stores configuration and cache on the SSD for responsive browsing while accessing massive media libraries on the 3.7TB HDD, supporting direct play when possible and GPU-accelerated transcoding when format conversion is needed.

Property Value
Image jellyfin/jellyfin:latest
Container Name jellyfin
Access URL http://192.168.86.149:8096, https://media.schweitz.net
External Access LAN + Internet (via NPM reverse proxy)
Port Mapping 8096:8096 (HTTP), 8920:8920 (HTTPS), 7359:7359/udp (Discovery), 1900:1900/udp (DLNA)
Network Mode Bridge
Restart Policy unless-stopped
Volume Mounts ~/docker-data/jellyfin/config:/config, ~/docker-data/jellyfin/cache:/cache, /mnt/media/jellyfin:/media:ro
Environment NVIDIA_VISIBLE_DEVICES=all, NVIDIA_DRIVER_CAPABILITIES=all
User 1000:1000 (UID:GID)
Resource Limits Memory: 4GB, GPU: 11GB VRAM (shared)
GPU Required Yes (NVIDIA RTX 2080 Ti)
GPU Configuration NVENC hardware encoding, NVDEC hardware decoding
Dependencies NVIDIA Container Toolkit, NPM (for external access)
Media Storage /mnt/media/jellyfin (HDD)
Transcoding Hardware-accelerated (H.264/H.265)

Nextcloud

Nextcloud is a self-hosted cloud storage and collaboration platform providing file sync, sharing, calendar, contacts, and collaborative document editing with a web interface and mobile apps, replacing cloud services like Dropbox or Google Drive while maintaining full data sovereignty. It runs as a multi-container stack with a MariaDB database for metadata, Redis for caching and file locking, and the main PHP application container, with the application configuration stored on SSD for responsiveness while user data resides on the HDD for capacity. The service integrates behind Nginx Proxy Manager with SSL at https://cloud.schweitz.net, offering external access for file synchronization from anywhere while maintaining automated background job execution through the maintenance container's cron system.

Property Value
Image nextcloud:stable
Container Name nextcloud
Access URL (LAN) http://192.168.86.149:8082
Access URL (Public) https://cloud.schweitz.net
External Access Yes (via NPM reverse proxy with SSL)
Port Mapping 8082:80 (HTTP)
Network Mode Bridge (custom network: nextcloud_nextcloud-network)
Restart Policy unless-stopped
Volume Mounts ~/docker-data/nextcloud/config:/var/www/html (SSD), /mnt/media/nextcloud/data:/var/www/html/data (HDD)
Environment MYSQL_HOST=nextcloud-db, MYSQL_DATABASE=nextcloud, MYSQL_USER=nextcloud, REDIS_HOST=nextcloud-redis, TZ=Europe/Amsterdam
Resource Limits None
GPU Required No
Dependencies MariaDB 10.11 (nextcloud-db), Redis Alpine (nextcloud-redis), NPM (reverse proxy), Maintenance container (cron jobs)
Database MariaDB on SSD (~100MB)
Cron Jobs Background tasks every 5 minutes (via maintenance container)
Storage Split Config/apps on SSD, user data on HDD
Features File sync, calendar, contacts, document editing, photo gallery, mobile apps

Samba

Samba provides SMB/CIFS network file sharing for seamless access to homelab storage from Windows, macOS, Linux, and mobile devices, exposing curated shares for media libraries, downloads, and backups with configurable read-only and read-write permissions. It runs as a single container on the samba_default network, serving three shares: Media (read-write access to Jellyfin content), Downloads (read-write for torrent clients), and Backups (read-only for safe data recovery). The service uses password authentication for the user jpmschweitzer and stores its minimal configuration on the SSD while directly mounting HDD paths for zero-copy file access with native performance.

Property Value
Image dperson/samba
Container Name samba
Access URL \\192.168.86.149 or \\tower-of-joy
External Access LAN only (ports firewalled)
Port Mapping 139:139 (NetBIOS), 445:445 (SMB)
Network Mode Bridge (custom network: samba_default)
Restart Policy unless-stopped
Volume Mounts ~/docker-data/samba:/share/config (SSD config), /mnt/media/jellyfin:/share/media (Media share), /mnt/media/downloads:/share/downloads (Downloads share), /mnt/media/backups:/share/backups:ro (Backups read-only)
Environment TZ=Europe/Amsterdam, USERID=1000, GROUPID=1000
Command Share configs: Media (browseable, guest access), Downloads (no guest), Backups (read-only, browseable)
Resource Limits None
GPU Required No
Dependencies UFW firewall rules (ports 139, 445), Host Samba service disabled
Shares 3 total: Media (R/W), Downloads (R/W), Backups (R/O)
Authentication Username/password (jpmschweitzer)
Client Compatibility Windows, macOS, Linux, iOS, Android

Gitea

Gitea is a lightweight, self-hosted Git service providing repository hosting, issue tracking, pull requests, code review, and CI/CD integration through a clean web interface accessible via both HTTPS and SSH. It runs as a multi-container stack with a PostgreSQL database for metadata storage, offering GitHub-like functionality including organizations, teams, wikis, webhooks, and automated Actions workflows while maintaining complete data sovereignty and minimal resource overhead. The service stores all Git repositories and configuration on the SSD for fast access, integrates behind Nginx Proxy Manager with SSL at https://git.schweitz.net for web access, and exposes SSH on port 2222 for standard Git operations without conflicting with the host's SSH service.

Property Value
Image gitea/gitea:latest
Container Name gitea
Access URL (LAN) http://192.168.86.149:3002
Access URL (Public) https://git.schweitz.net
External Access Yes (via NPM reverse proxy with SSL)
Port Mapping 3002:3000 (HTTP), 2222:22 (SSH)
Network Mode Bridge (custom network: gitea_gitea-network)
Restart Policy unless-stopped
Volume Mounts ~/docker-data/gitea/data:/data (SSD - repos, config)
Environment USER_UID=1000, USER_GID=1000, GITEA__database__* (PostgreSQL connection), TZ=Europe/Amsterdam
Resource Limits None
GPU Required No
Dependencies PostgreSQL 14 (gitea-db), NPM (reverse proxy)
Database PostgreSQL on SSD (~50MB)
SSH Access Port 2222 - git clone ssh://git@git.schweitz.net:2222/user/repo.git
Features Git hosting, Organizations/teams, Issues/PRs, Code review, Wikis, Webhooks, Gitea Actions (CI/CD), GitHub/GitLab migration
SSH Config Tip Add to ~/.ssh/config: Host git.schweitz.net / Port 2222 / User git for seamless cloning

Quick Reference Tables

Service Access Matrix

Service LAN URL Internet Access Primary Function
Portainer http://192.168.86.149:8001 No Container management
PostgreSQL Shared postgres-shared:5432 No (internal) Shared database server
Redis Shared redis-shared:6379 No (internal) Shared cache/session store
NPM http://192.168.86.149:81 Yes (admin) Reverse proxy admin
Code-Server https://code.schweitz.net Yes Browser-based IDE
Ollama http://192.168.86.149:11434 No ML model API
Headscale http://192.168.86.149:8085 No VPN control server
Uptime Kuma http://192.168.86.149:3001 No Uptime monitoring
Netdata http://192.168.86.149:19999 No System metrics
Heimdall http://192.168.86.149:8888 No Service dashboard
Organizr https://home.schweitz.net Yes Unified dashboard
Open WebUI http://192.168.86.149:82 No LLM chat interface
Core API http://192.168.86.149:8083 No API functions & infrastructure mgmt
Jellyfin https://media.schweitz.net Yes Media streaming
Nextcloud https://cloud.schweitz.net Yes Cloud storage & sync
Gitea https://git.schweitz.net Yes Git repository hosting
Samba \\192.168.86.149 No Network file shares
Watchtower N/A (background) N/A Auto-updates
Maintenance N/A (background) N/A Automated tasks

GPU-Enabled Services

Service GPU Usage VRAM Requirements Purpose
Ollama Compute, Utility 2-10GB (model dependent) LLM inference
Jellyfin Video Encode/Decode ~1-2GB (during transcode) Media transcoding

Total VRAM Available: 11GB (RTX 2080 Ti)


Storage Distribution

Service Config Location (SSD) Data Location (HDD) Typical Size
Portainer Docker volume: portainer_data N/A ~100MB
PostgreSQL Shared N/A ~/docker-data/postgres-shared/data/ Data: 100MB-5GB (depends on databases), Backups: variable
Redis Shared N/A ~/docker-data/redis-shared/data/ ~10-100MB (AOF + RDB snapshots)
NPM ~/docker-data/nginx-proxy-manager/ N/A ~50MB
Code-Server ~/.config/code-server/, ~/docker-data/code-server/ N/A Config: ~5MB, Extensions: ~50-200MB, User data: ~50MB
Ollama ~/docker-data/ollama/models/ Alt: /mnt/media/ollama/ 2-15GB per model
Headscale ~/docker-data/headscale/ N/A ~10MB
Uptime Kuma ~/docker-data/uptime-kuma/ N/A ~50MB
Netdata RAM-based (ephemeral) N/A ~200MB RAM
Heimdall ~/docker-data/heimdall/ N/A ~20MB
Organizr ~/docker-data/organizr/ N/A ~50MB
Open WebUI ~/docker-data/open-webui/ N/A ~100MB
Core API ~/docker-data/core-api/, /home/jpmschweitzer/Projects/portainer-core/services/core-api/ (source) N/A Venv: ~200MB, Logs: ~10MB
Jellyfin ~/docker-data/jellyfin/ /mnt/media/jellyfin/ Config: ~500MB, Media: ~2TB
Nextcloud ~/docker-data/nextcloud/ /mnt/media/nextcloud/data/ Config: ~200MB, DB: ~100MB, User data: variable
Gitea ~/docker-data/gitea/ N/A Data: ~100MB, DB: ~50MB, Repos: variable
Samba ~/docker-data/samba/ Mounts: /mnt/media/ (shares) Config: ~5MB
Maintenance N/A /mnt/media/backups/ ~94MB per backup

SSD Usage (docker-data): ~6-11GB (configs, caches, databases) HDD Usage (/mnt/media): ~2.1TB / 3.6TB (58% used)


Network Architecture

As of 2025-11-15, all services have been consolidated to the docker-dataplane bridge network for simplified service discovery and inter-container communication. This consolidation replaced 12+ legacy networks with a single unified network, enabling all services to communicate using container names as DNS hostnames.

Network Name Containers Purpose
docker-dataplane Ollama, Open WebUI, Core API, Qdrant, Uptime Kuma, PostgreSQL Shared, Redis Shared, Headscale, Nextcloud, Gitea, Samba, Watchtower, Maintenance, Organizr, Netdata Unified service mesh for all containerized applications
host Portainer, NPM Direct host port access for infrastructure management

Benefits of Consolidation:

  • Service Discovery: All services reachable via http://container-name:port (e.g., http://postgres-shared:5432)
  • Simplified Monitoring: Uptime Kuma can monitor all services on docker-dataplane
  • Shared Infrastructure: postgres-shared and redis-shared accessible to all applications
  • Network Cleanup: Removed 7 obsolete networks (stacks_default, ai-dataplane, various stack-specific networks)

Container Name Resolution Examples:

# From any container on docker-dataplane
curl http://uptime-kuma:3001      # Uptime Kuma API
curl http://ollama:11434           # Ollama LLM API
psql -h postgres-shared -U postgres  # PostgreSQL connection
redis-cli -h redis-shared          # Redis connection

Restart Policies

Policy Containers Behavior
always Portainer Restart on failure, on Docker daemon restart
unless-stopped All others Restart on failure, but not after manual stop

Maintenance Schedule

Service Task Frequency Time
Watchtower Container updates Daily 4:00 AM
Maintenance Config backups Daily 3:00 AM
Maintenance Nextcloud background jobs Every 5 minutes Continuous
Maintenance Log cleanup Weekly Sunday 3:30 AM
Docker Image pruning Monthly 1st of month

Last Updated: 2025-11-16 System: tower-of-joy (tower-of-joy v0.5.0-optimization)