
Complete docker-compose.yml to run Jellyfin, Nextcloud, Home Assistant, Pi-hole, Vaultwarden, Immich, Homepage, Uptime Kuma, Tailscale, and Portainer on an Intel N100 mini PC under 15W.
The Intel N100 mini PC idles at 6-12W. Your refrigerator compressor draws more power. Yet that $170 box can run a fully functional home server โ media streaming, file sync, home automation, ad blocking, password management, photo backup, monitoring, and more โ all simultaneously, all day, every day, for roughly $12-13 in electricity per year.
The problem most people hit isn't the hardware. It's figuring out which services to run, how to combine them without conflict, and how to get it all deployed without spending a weekend fighting Docker networking. There are dozens of self-hosted apps worth running, but running the wrong combination wastes RAM, creates port conflicts, and turns a clean setup into a maintenance headache.
This article solves that. It presents a curated, tested 10-service Docker stack designed specifically for N100 hardware. You get the complete docker-compose.yml โ copy it, adjust a few environment variables, and run docker compose up -d. The stack covers the most common home server use cases, uses under 15W at idle with all services running, and stays under 1.5GB RAM across all containers combined.
Whether you are setting up your first home server or migrating off Raspberry Pi hardware, this stack is a proven starting point for 2026.

This stack is optimized for an Intel N100 mini PC. The Beelink EQ12 is the most widely recommended option in 2026, combining a competitive price (~$170), 16GB DDR5 RAM, dual storage slots (NVMe + SATA), and 6-8W idle power consumption.
Minimum configuration:
The stack described here uses approximately 1.3GB RAM at idle across all 10 services. On a 16GB system, that leaves over 14GB free โ enough headroom for the OS, brief activity spikes, and future services you may want to add.
For a deeper hardware comparison including the N305 and ARM alternatives, see Best Low-Power Mini PCs 2026. If you prefer running these services as LXC containers under Proxmox rather than bare-metal Docker, the Proxmox N100 build guide covers that setup.

Each service below was chosen based on three criteria: it solves a real everyday problem, it runs efficiently on N100 hardware, and it is actively maintained as of 2026. The combination covers the full range of home server use cases without redundancy.

Jellyfin is the leading open-source media server. It handles video, music, and photo libraries with a Netflix-style web interface, mobile apps, and TV clients.
Why it's in the stack: It's the only major media server that is fully free with no feature gating โ hardware transcoding via Intel Quick Sync works without a paid license, unlike Plex. The N100's Intel GPU handles 4K HEVC hardware transcoding efficiently.
RAM usage: ~200MB at idle. Spikes to 300-400MB during active streaming, but this is short-lived.
Config note: Pass the Intel GPU to the container using the /dev/dri device mount. This enables Quick Sync and keeps CPU load low during transcoding. Map your media library directory as a read-only volume.
For a full comparison of Jellyfin against Plex and Emby, including feature differences and streaming performance on N100, see Jellyfin vs Plex vs Emby: Media Server Comparison.
Nextcloud is a self-hosted alternative to Dropbox and Google Drive. It provides file sync, sharing, calendar, contacts, and a large app ecosystem.
Why it's in the stack: File sync is a foundational home server use case. Nextcloud's Docker image is mature and well-documented. Pairing it with Redis for file locking and a dedicated volume for data keeps it fast and reliable.
RAM usage: ~300MB with Redis caching active. The base Nextcloud container uses around 200MB; Redis adds another 50-100MB.
Config note: Use the nextcloud:29-apache image for stability. Redis is configured as the memory cache and file locking backend, which significantly improves performance with multiple concurrent clients. Store data on a separate volume (or external drive) to keep the OS NVMe from filling up.
The Nextcloud Docker Compose setup guide 2026 covers the complete configuration including HTTPS reverse proxy setup and performance tuning.
Home Assistant is the most widely used open-source home automation platform. It integrates with thousands of smart home devices, automations, dashboards, and voice assistants.
Why it's in the stack: If you have any smart home devices โ lights, thermostats, door sensors, plugs โ Home Assistant is the control layer. Running it locally means no cloud dependency and near-instant response times.
RAM usage: ~150MB at idle. Grows proportionally with the number of integrations and history data being tracked, but stays manageable on N100.
Config note: Use network_mode: host for Home Assistant. This is not optional โ many integrations rely on network discovery protocols (mDNS, UPnP, Zigbee over USB) that do not work behind Docker's NAT. Pass USB Zigbee or Z-Wave sticks via device mounts if needed.
See Home Assistant Low-Power Hardware Guide for integration-specific hardware recommendations.
Pi-hole is a network-wide DNS-based ad blocker. It intercepts DNS queries from every device on your network and blocks requests to known ad and tracking domains before a connection is made.
Why it's in the stack: Pi-hole is one of the highest-value services you can run on a home server. It speeds up browsing, eliminates ads on devices that cannot install ad blockers (smart TVs, game consoles, phones), and gives you visibility into what every device on your network is doing.
RAM usage: ~50MB. Pi-hole is extremely lightweight โ it was designed to run on the original Raspberry Pi 1.
Config note: Pi-hole runs on a separate Docker network (pihole) because it needs to listen on port 53 (DNS) and port 80 (admin UI). Running it on the shared network with other services can create port conflicts. Set DNS_1 and DNS_2 to upstream resolvers of your choice (Cloudflare's 1.1.1.1 and 1.0.0.1 are common). After deployment, point your router's DNS to the server's IP to enable network-wide blocking.
For a detailed Pi-hole setup guide including blocklist management, see Pi-hole Setup Guide.
Vaultwarden is a lightweight, self-hosted server compatible with all official Bitwarden clients (browser extensions, mobile apps, desktop). It implements the Bitwarden API in Rust, using a fraction of the resources the official server requires.
Why it's in the stack: A self-hosted password manager means your credential vault never leaves your control. Vaultwarden's Rust implementation is fast and uses almost no resources. All official Bitwarden apps work with it without modification.
RAM usage: ~10MB. This is genuinely one of the most efficient containers you can run โ a Rust binary serving a SQLite database.
Config note: Set SIGNUPS_ALLOWED=false after creating your account to prevent others from registering. Enable admin panel access via a random ADMIN_TOKEN. If you expose this outside your local network (for mobile app sync), put it behind Tailscale or a Cloudflare tunnel rather than exposing it directly.
For the complete setup including browser extension configuration and backup procedures, see Vaultwarden Docker Compose Guide.
Immich is a self-hosted photo and video backup solution designed to replace Google Photos. It includes automatic mobile backup, facial recognition, semantic search, and a polished web/mobile UI.
Why it's in the stack: Google Photos no longer offers unlimited free storage. Immich is the best self-hosted alternative โ it has reached production stability and the mobile apps are genuinely good.
RAM usage: ~400MB combined across the server and machine learning containers. The immich-machine-learning container handles facial recognition and CLIP-based semantic search. If RAM is tight, machine learning can be disabled by removing that container; core backup functionality remains.
Config note: Immich requires two containers: immich-server and immich-machine-learning. Both share the same upload volume. The machine learning container downloads models on first run (~1-2GB). Point the UPLOAD_LOCATION at your external drive rather than the OS NVMe.
For a full walkthrough including mobile app setup and library migration from Google Photos, see Immich Self-Hosted Photos Guide.
Homepage is a modern, static-generated dashboard for self-hosted services. It pulls live status from containers via Docker integration and displays service links, stats, and widgets.
Why it's in the stack: Once you have 10 services running, you need a single place to access them all. Homepage auto-discovers running containers and generates a clean dashboard without manual configuration for each service. It also displays system stats (CPU, RAM, network usage) from the host.
RAM usage: ~30MB. Homepage is a static Next.js application โ it's built at start time and serves pre-rendered HTML.
Config note: Mount the Docker socket (/var/run/docker.sock) as read-only to enable auto-discovery. Customize config/services.yaml for service grouping and config/widgets.yaml for system stats. See Best Home Server Dashboards 2026 for a comparison of Homepage against Homarr and Dashy.
Uptime Kuma is a self-hosted uptime monitoring tool with a clean UI, multiple monitor types (HTTP, TCP, DNS, ping), and notification integrations (Telegram, Discord, email, Slack, and more).
Why it's in the stack: Services go down. Uptime Kuma tells you when they do โ and more importantly, it tells you how often and for how long, so you can identify unreliable services before they become problems. It also monitors external services (your ISP connection, remote servers) alongside local ones.
RAM usage: ~50MB.
Config note: Uptime Kuma persists all data in a single SQLite database stored in its volume. No external database required. Configure notification channels immediately after setup โ alerts are only useful if they reach you.
For a comparison of Uptime Kuma against Beszel and Grafana for home server monitoring, see Beszel vs Uptime Kuma vs Grafana: Home Server Monitoring Comparison.
Tailscale creates an encrypted mesh VPN that lets you access your home server services from anywhere โ on your phone, laptop, or any other device โ without opening ports on your router or configuring a traditional VPN server.
Why it's in the stack: Without remote access, your home server is only useful when you are on your home network. Tailscale solves this with zero router configuration. It uses WireGuard under the hood and routes traffic peer-to-peer when possible (low latency) or through relay servers when direct connection is blocked.
RAM usage: ~20MB. Tailscale runs as a lightweight daemon.
Config note: Set TS_AUTHKEY to a reusable auth key from the Tailscale admin console. This allows the container to authenticate automatically on start. Use Tailscale's subnet routing feature to expose your entire home network (not just the server) to remote devices: TS_EXTRA_ARGS=--advertise-routes=192.168.1.0/24.
For a comparison of Tailscale against Cloudflare Tunnel for remote access, including security trade-offs, see Tailscale vs Cloudflare Tunnel: Home Server Remote Access.
Portainer is a web-based Docker management interface. It provides a visual view of all running containers, allows you to start/stop/restart containers, view logs, edit compose files, and pull updated images โ all from a browser.
Why it's in the stack: Command-line Docker management works, but Portainer reduces the friction of day-to-day operations significantly. Viewing logs across multiple containers, checking which containers are unhealthy, and pulling updates are all faster through the UI. The Community Edition is free with no limitations for single-server use.
RAM usage: ~50MB.
Config note: Mount the Docker socket as read-write (unlike Homepage, Portainer needs write access to manage containers). Portainer stores its configuration in a named volume. Access the setup wizard within the first 5 minutes of first run โ the initial admin account setup times out for security reasons.
The table below shows measured idle resource usage on a Beelink EQ12 (N100, 16GB DDR5, Ubuntu Server 24.04 LTS) with all 10 services running and no active user sessions.
| Service | RAM (idle) | CPU (idle) | Storage (volumes) |
|---|---|---|---|
| Jellyfin | ~200MB | <1% | ~1GB (config + metadata) |
| Nextcloud + Redis | ~300MB | <1% | ~2GB (config; data separate) |
| Home Assistant | ~150MB | <1% | ~500MB |
| Pi-hole | ~50MB | <1% | ~100MB |
| Vaultwarden | ~10MB | <1% | ~50MB |
| Immich (server + ML) | ~400MB | 1-2% | ~500MB (models; photos separate) |
| Homepage | ~30MB | <1% | ~50MB |
| Uptime Kuma | ~50MB | <1% | ~100MB |
| Tailscale | ~20MB | <1% | ~20MB |
| Portainer | ~50MB | <1% | ~100MB |
| Total | ~1.26GB | ~3-5% | ~4.5GB |
On a 16GB system, this leaves approximately 14.7GB of RAM free. The N100's four Gracemont efficiency cores handle this workload without complaint โ idle CPU usage across all containers stays under 5% combined.
Media storage (Jellyfin library, Nextcloud data, Immich photos) is intentionally excluded from the storage column above. Those grow with your data and belong on an external drive, not the OS NVMe.
The following is a production-ready compose file implementing all 10 services. Copy it to /opt/stacks/docker-compose.yml, create a .env file with the required variables (documented below the compose file), and deploy with docker compose up -d.
# /opt/stacks/docker-compose.yml
# N100 Home Server โ 10-Service Stack
# Tested on: Docker 26.x, Docker Compose v2.x, Ubuntu Server 24.04 LTS
networks:
homelab:
driver: bridge
pihole:
driver: bridge
volumes:
jellyfin_config:
nextcloud_data:
nextcloud_db:
redis_data:
homeassistant_config:
pihole_data:
pihole_dnsmasq:
vaultwarden_data:
immich_data:
immich_model_cache:
homepage_config:
uptime_kuma_data:
portainer_data:
services:
# โโโ Media Server โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
jellyfin:
image: jellyfin/jellyfin:latest
container_name: jellyfin
restart: unless-stopped
networks:
- homelab
ports:
- "8096:8096"
volumes:
- jellyfin_config:/config
- ${MEDIA_DIR}:/media:ro
devices:
- /dev/dri:/dev/dri # Intel Quick Sync hardware transcoding
environment:
- JELLYFIN_PublishedServerUrl=http://${SERVER_IP}:8096
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8096/health"]
interval: 30s
timeout: 10s
retries: 3
# โโโ File Sync โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
nextcloud_db:
image: mariadb:11
container_name: nextcloud_db
restart: unless-stopped
networks:
- homelab
volumes:
- nextcloud_db:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=${NEXTCLOUD_DB_ROOT_PASSWORD}
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
- MYSQL_PASSWORD=${NEXTCLOUD_DB_PASSWORD}
redis:
image: redis:7-alpine
container_name: redis
restart: unless-stopped
networks:
- homelab
volumes:
- redis_data:/data
nextcloud:
image: nextcloud:29-apache
container_name: nextcloud
restart: unless-stopped
networks:
- homelab
ports:
- "8080:80"
volumes:
- nextcloud_data:/var/www/html
- ${NEXTCLOUD_DATA_DIR}:/var/www/html/data
environment:
- MYSQL_HOST=nextcloud_db
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
- MYSQL_PASSWORD=${NEXTCLOUD_DB_PASSWORD}
- REDIS_HOST=redis
- NEXTCLOUD_TRUSTED_DOMAINS=${SERVER_IP}
- NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER}
- NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD}
depends_on:
- nextcloud_db
- redis
# โโโ Home Automation โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
homeassistant:
image: ghcr.io/home-assistant/home-assistant:stable
container_name: homeassistant
restart: unless-stopped
network_mode: host # Required for device discovery (mDNS, UPnP)
volumes:
- homeassistant_config:/config
environment:
- TZ=${TZ}
privileged: false
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8123"]
interval: 30s
timeout: 10s
retries: 5
# โโโ DNS Ad Blocking โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
pihole:
image: pihole/pihole:latest
container_name: pihole
restart: unless-stopped
networks:
- pihole
ports:
- "53:53/tcp"
- "53:53/udp"
- "8053:80"
volumes:
- pihole_data:/etc/pihole
- pihole_dnsmasq:/etc/dnsmasq.d
environment:
- TZ=${TZ}
- WEBPASSWORD=${PIHOLE_PASSWORD}
- DNS1=1.1.1.1
- DNS2=1.0.0.1
- DNSMASQ_LISTENING=all
cap_add:
- NET_ADMIN
# โโโ Password Manager โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
networks:
- homelab
ports:
- "8200:80"
volumes:
- vaultwarden_data:/data
environment:
- ADMIN_TOKEN=${VAULTWARDEN_ADMIN_TOKEN}
- SIGNUPS_ALLOWED=false
- WEBSOCKET_ENABLED=true
- LOG_LEVEL=warn
# โโโ Photo Backup โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
immich-server:
image: ghcr.io/immich-app/immich-server:release
container_name: immich_server
restart: unless-stopped
networks:
- homelab
ports:
- "2283:2283"
volumes:
- ${IMMICH_UPLOAD_DIR}:/usr/src/app/upload
- immich_data:/data
- /etc/localtime:/etc/localtime:ro
environment:
- DB_HOSTNAME=immich_db
- DB_USERNAME=immich
- DB_PASSWORD=${IMMICH_DB_PASSWORD}
- DB_DATABASE_NAME=immich
- REDIS_HOSTNAME=redis
depends_on:
- immich_db
- redis
immich-machine-learning:
image: ghcr.io/immich-app/immich-machine-learning:release
container_name: immich_machine_learning
restart: unless-stopped
networks:
- homelab
volumes:
- immich_model_cache:/cache
environment:
- TRANSFORMERS_CACHE=/cache
immich_db:
image: tensorchord/pgvecto-rs:pg16-v0.2.0
container_name: immich_db
restart: unless-stopped
networks:
- homelab
volumes:
- immich_data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=${IMMICH_DB_PASSWORD}
- POSTGRES_USER=immich
- POSTGRES_DB=immich
# โโโ Dashboard โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
homepage:
image: ghcr.io/gethomepage/homepage:latest
container_name: homepage
restart: unless-stopped
networks:
- homelab
ports:
- "3000:3000"
volumes:
- homepage_config:/app/config
- /var/run/docker.sock:/var/run/docker.sock:ro # Read-only for auto-discovery
environment:
- PUID=1000
- PGID=1000
# โโโ Monitoring โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
uptime-kuma:
image: louislam/uptime-kuma:latest
container_name: uptime_kuma
restart: unless-stopped
networks:
- homelab
ports:
- "3001:3001"
volumes:
- uptime_kuma_data:/app/data
# โโโ Remote Access โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
tailscale:
image: tailscale/tailscale:latest
container_name: tailscale
restart: unless-stopped
network_mode: host
cap_add:
- NET_ADMIN
- SYS_MODULE
volumes:
- /var/lib/tailscale:/var/lib/tailscale
- /dev/net/tun:/dev/net/tun
environment:
- TS_AUTHKEY=${TAILSCALE_AUTHKEY}
- TS_STATE_DIR=/var/lib/tailscale
- TS_EXTRA_ARGS=--advertise-routes=${HOME_SUBNET} --accept-routes
# โโโ Docker Management โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
restart: unless-stopped
networks:
- homelab
ports:
- "9000:9000"
volumes:
- portainer_data:/data
- /var/run/docker.sock:/var/run/docker.sock
Create /opt/stacks/.env with the following variables before deploying:
# Server
SERVER_IP=192.168.1.100 # Your server's local IP address
TZ=America/New_York # Your timezone (see: timedatectl list-timezones)
HOME_SUBNET=192.168.1.0/24 # Your home network subnet
# Media directories (adjust to your mount points)
MEDIA_DIR=/mnt/external/media
# Nextcloud
NEXTCLOUD_DATA_DIR=/mnt/external/nextcloud
NEXTCLOUD_DB_ROOT_PASSWORD=change_me_root
NEXTCLOUD_DB_PASSWORD=change_me_nc
NEXTCLOUD_ADMIN_USER=admin
NEXTCLOUD_ADMIN_PASSWORD=change_me_admin
# Pi-hole
PIHOLE_PASSWORD=change_me_pihole
# Vaultwarden
VAULTWARDEN_ADMIN_TOKEN=change_me_long_random_string
# Immich
IMMICH_UPLOAD_DIR=/mnt/external/immich
IMMICH_DB_PASSWORD=change_me_immich
# Tailscale (generate at https://login.tailscale.com/admin/settings/keys)
TAILSCALE_AUTHKEY=tskey-auth-xxxxxxxxxxxx
Replace every change_me_* value with a unique random string. Use openssl rand -hex 32 to generate secure tokens.
These measurements were taken on a Beelink EQ12 (N100, 16GB DDR5, 256GB NVMe) running Ubuntu Server 24.04 LTS, using a Kill-A-Watt meter at the wall.
| State | Power Draw |
|---|---|
| System idle, no Docker containers | 6W |
| All 10 services running, no active use | 10-12W |
| Jellyfin transcoding 1080p (software) | 18-22W |
| Jellyfin transcoding 1080p (Quick Sync HW) | 12-14W |
| Jellyfin transcoding 4K HEVC (Quick Sync HW) | 14-17W |
| Nextcloud file sync (large upload) | 12-15W |
| Immich photo analysis (ML model running) | 14-18W |
The key insight: with hardware transcoding enabled in Jellyfin, even 4K HEVC transcoding stays under 17W peak โ and drops back to 10-12W the moment the stream ends. The N100's Intel UHD Graphics handles Quick Sync more efficiently than its CPU cores handle software transcoding.
Annual electricity cost (10 services running 24/7 at 12W average):
12W ร 8,760 hours/year = 105.1 kWh/year
105.1 kWh ร $0.12/kWh = $12.61/year
At US average electricity rates, running this entire 10-service stack costs about the same as one streaming service subscription per year. For a detailed breakdown of power consumption optimization strategies, see Ultimate Power Consumption Guide for Home Servers.
Install Docker and Docker Compose on Ubuntu Server 24.04 LTS:
# Update system
sudo apt update && sudo apt upgrade -y
# Install Docker using the official convenience script
curl -fsSL https://get.docker.com | sudo sh
# Add your user to the docker group (log out and back in after this)
sudo usermod -aG docker $USER
# Verify Docker is running
docker --version
docker compose version
# Create stack directory
sudo mkdir -p /opt/stacks
sudo chown $USER:$USER /opt/stacks
# Create directories for external data (adjust path to your mount point)
sudo mkdir -p /mnt/external/{media,nextcloud,immich}
sudo chown -R $USER:$USER /mnt/external
cd /opt/stacks
# Copy the docker-compose.yml and .env files to /opt/stacks
# (use the content from the sections above)
# Pull all images before starting (optional but helpful for first-run troubleshooting)
docker compose pull
# Start all services in detached mode
docker compose up -d
# Watch startup logs
docker compose logs -f --tail=50
# Check container status
docker compose ps
# Check for any containers in "Exit" or "Error" state
docker compose ps --filter status=exited
All containers should show running status within 2-3 minutes of first launch. Immich's machine learning container will take longer on first run as it downloads the CLIP and facial recognition models (~1.5GB total).
Log into your router's admin interface and change the primary DNS server to your server's IP address (192.168.1.100 in the example above). Secondary DNS can remain as your ISP's server or a public resolver (1.1.1.1) as fallback.
Access each service at http://YOUR_SERVER_IP:PORT from any device on your network:
| Service | Port | URL | First-Run Action |
|---|---|---|---|
| Jellyfin | 8096 | http://server:8096 | Run setup wizard, add media libraries |
| Nextcloud | 8080 | http://server:8080 | Login with admin credentials from .env |
| Home Assistant | 8123 | http://server:8123 | Create account, add integrations |
| Pi-hole | 8053 | http://server:8053/admin | Set router DNS to server IP |
| Vaultwarden | 8200 | http://server:8200 | Create account, then set SIGNUPS_ALLOWED=false |
| Immich | 2283 | http://server:2283 | Create admin account, install mobile app |
| Homepage | 3000 | http://server:3000 | Edit config/services.yaml to organize links |
| Uptime Kuma | 3001 | http://server:3001 | Create account, add monitors for each service |
| Tailscale | โ | Tailscale admin console | Approve machine in admin console |
| Portainer | 9000 | http://server:9000 | Complete setup wizard within 5 minutes |
Pull updates for all services at once:
cd /opt/stacks
docker compose pull && docker compose up -d
This pulls the latest image for every service and recreates containers where the image changed. Containers with unchanged images are left running.
Back up all configuration volumes:
# Bring down the stack for a clean backup
docker compose down
# Archive all stack config and volumes
tar -czf /mnt/external/backups/stack-backup-$(date +%Y%m%d).tar.gz /opt/stacks /var/lib/docker/volumes
# Restart services
docker compose up -d
For a lighter backup that avoids downtime, back up only the named volumes you care most about (Vaultwarden, Home Assistant, Nextcloud config) using individual docker run --volumes-from commands.
Nextcloud background jobs:
Nextcloud requires a cron job to run background tasks (thumbnail generation, notifications, cleanup). Run it via Docker on a 5-minute schedule:
# Add to crontab: crontab -e
*/5 * * * * docker exec --user www-data nextcloud php -f /var/www/html/cron.php
View logs for a specific service:
docker compose logs -f jellyfin # Follow Jellyfin logs
docker compose logs --tail=100 pihole # Last 100 lines from Pi-hole
Restart a single service without affecting others:
docker compose restart homeassistant
Use Portainer for visual management:
Once Portainer is running, use it for day-to-day operations: checking container health, reading logs across multiple services simultaneously, pulling image updates, and editing environment variables without touching the compose file directly.
Use Homepage as your daily driver:
Homepage's Docker integration will automatically detect running containers and display their status. Configure config/services.yaml to group your services logically (Media, Storage, Automation, Security, etc.) and add widgets for system stats. This single browser tab replaces memorizing 10 different port numbers.
This 10-service stack covers every major home server use case โ media, file sync, home automation, privacy, security, photo backup, monitoring, and remote access โ at a total idle power draw of 10-12W. Annual electricity cost: roughly $12-13.
The N100 is well-suited for this workload because these services spend almost all of their time waiting for I/O, not computing. CPU cores sit idle 95% of the time. The only service that exercises the processor meaningfully is Jellyfin during transcoding, and Intel Quick Sync handles that on the GPU without stressing the CPU cores.
Start with the complete compose file, deploy everything at once, then spend time on each service's initial configuration. Once the foundation is solid, explore what else the self-hosted community has built โ there are dozens of additional services worth adding, and with 14GB of RAM headroom, there is room to grow.
For hardware selection, see Best Low-Power Mini PCs 2026. For power consumption optimization beyond this stack, see Ultimate Power Consumption Guide.

Use Cases
Complete Nextcloud setup guide with Docker Compose for 2026. Replace Google Drive with a self-hosted cloud on an Intel N100 mini PC. Includes Redis caching, MariaDB, and remote access via Tailscale.

Use Cases
Best hardware for Home Assistant in 2026. Run HA on an Intel N100 mini PC at 8-12W idle. Covers HA OS bare metal, Proxmox LXC, and Docker Compose installation methods.

Hardware
New to home servers? Start here. Compare hardware options, discover 8 popular use cases, and learn how to run 10 self-hosted services on an Intel N100 mini PC for just $10/year in electricity.
Use our Power Calculator to estimate how much your server will cost to run 24/7.
Try Power Calculator