How to Self-Host Hubzilla with Docker Compose

More Than a Social Network

Hubzilla started as a fork of Friendica in 2012 and evolved into something broader — a decentralized identity platform that happens to include social networking. Its signature feature is nomadic identity: your identity isn’t tied to one server. You can clone your account across multiple Hubzilla instances, and if one goes offline, your identity, connections, and content survive on the others. No other fediverse platform does this. Official site

Beyond social features, Hubzilla includes a wiki, CalDAV/CardDAV server, file storage with WebDAV, a CMS for building web pages, and a permissions system granular enough to control who sees individual posts. It federates via Zot6 (its native protocol), ActivityPub (Mastodon, Pleroma, Misskey), and Diaspora.

FeatureDetails
Protocol SupportZot6, ActivityPub, Diaspora
LicenseMIT
LanguagePHP
Latest Version9.x (rolling release on Codeberg)
Docker ImagesCommunity-maintained (no official image)
Nomadic IdentityYes (unique to Hubzilla)
Built-in FeaturesWiki, CMS, CalDAV, CardDAV, WebDAV, forums

Prerequisites

  • A Linux server (Ubuntu 22.04+ recommended)
  • Docker and Docker Compose installed (guide)
  • 1 GB RAM minimum (2 GB recommended)
  • 10 GB of free disk space
  • A domain name with HTTPS configured (federation breaks without HTTPS)
  • SMTP credentials for email notifications
RequirementMinimumRecommended
RAM1 GB2 GB
CPU1 core2 cores
Disk5 GB20 GB+
NetworkDomain with HTTPSDomain + reverse proxy

Important: Hubzilla requires HTTPS from the start. Using HTTP during initial setup permanently breaks federation and discovery. Configure your reverse proxy before starting Hubzilla for the first time.

Docker Compose Configuration

Hubzilla has no official Docker image. The best community-maintained options are ghcr.io/saiwal/hubzilla-docker (auto-updating, multi-arch) and sebt3/hubzilla (PostgreSQL-based). This guide uses a setup based on the saiwal image with MariaDB, which tracks the latest Hubzilla releases automatically.

Create a project directory:

mkdir -p /opt/hubzilla && cd /opt/hubzilla

Create a .env file with your configuration:

# Database
DB_NAME=hubzilla
DB_USER=hubzilla
DB_PASS=change-this-strong-password
ROOT_PASSWORD=change-this-root-password

# SMTP (required for admin registration)
SSMTP_ROOT=[email protected]
SSMTP_MAILHUB=smtp.yourdomain.com:587
SSMTP_AUTHUSER=your-smtp-user
SSMTP_AUTHPASS=your-smtp-password
SSMTP_USESTARTTLS=YES
SSMTP_FROMLINEOVERRIDE=YES

# Reverse aliases
REVALIASES_ROOT=[email protected]:smtp.yourdomain.com:587
REVALIASES_WWWDATA=[email protected]:smtp.yourdomain.com:587

Create a docker-compose.yml file:

services:
  db:
    image: mariadb:11.4
    container_name: hubzilla-db
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ${ROOT_PASSWORD}
      MYSQL_DATABASE: ${DB_NAME}
      MYSQL_USER: ${DB_USER}
      MYSQL_PASSWORD: ${DB_PASS}
    volumes:
      - db-data:/var/lib/mysql
    networks:
      - hubzilla-net
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 30s
      timeout: 10s
      retries: 5

  app:
    image: ghcr.io/saiwal/hubzilla-docker:latest
    container_name: hubzilla-app
    restart: unless-stopped
    environment:
      HUBZILLA_DB_HOST: db
      HUBZILLA_DB_USER: ${DB_USER}
      HUBZILLA_DB_PASS: ${DB_PASS}
      HUBZILLA_DB_NAME: ${DB_NAME}
      SSMTP_ROOT: ${SSMTP_ROOT}
      SSMTP_MAILHUB: ${SSMTP_MAILHUB}
      SSMTP_AUTHUSER: ${SSMTP_AUTHUSER}
      SSMTP_AUTHPASS: ${SSMTP_AUTHPASS}
      SSMTP_USESTARTTLS: ${SSMTP_USESTARTTLS}
      SSMTP_FROMLINEOVERRIDE: ${SSMTP_FROMLINEOVERRIDE}
      REVALIASES_ROOT: ${REVALIASES_ROOT}
      REVALIASES_WWWDATA: ${REVALIASES_WWWDATA}
    volumes:
      - hubzilla-data:/var/www/html
    ports:
      - "8080:80"
    depends_on:
      db:
        condition: service_healthy
    networks:
      - hubzilla-net

volumes:
  db-data:
  hubzilla-data:

networks:
  hubzilla-net:

Note on image pinning: The saiwal/hubzilla-docker image uses :latest by design — it pulls the newest Hubzilla source code on each container restart. This is intentional behavior for Hubzilla’s rolling release model. If you prefer a frozen version, use sebt3/hubzilla:5.6 (older, PHP 7.4 based, PostgreSQL) instead.

Start the stack:

docker compose up -d

Initial Setup

  1. Ensure your reverse proxy is configured with HTTPS before accessing Hubzilla
  2. Navigate to https://hub.yourdomain.com in your browser
  3. The installer will ask for:
    • Site URL: Must use https:// — never http://
    • Admin email: Used for the first admin account
    • Database settings: Pre-filled from environment variables
  4. Complete the web-based setup wizard
  5. Register your admin account

The first user account created becomes the site administrator. Additional users can be added through the admin panel.

Configuration

Channel Setup

Hubzilla uses channels instead of accounts. One identity can have multiple channels:

  • A personal social channel
  • A blog/CMS channel
  • A forum channel for community discussion

Create channels from Settings → Channel Manager.

Privacy and Permissions

Hubzilla’s permission system is more granular than any other fediverse platform:

Permission LevelDescription
PublicVisible to anyone, including non-members
Logged-in usersVisible to authenticated users on any hub
Connections onlyVisible to confirmed contacts
Specific connectionsVisible to selected individuals
Self onlyPrivate — only visible to you

Configure defaults in Settings → Privacy.

Addons

Enable addons through Admin → Addons:

  • diaspora: Diaspora protocol federation
  • pubcrawl: ActivityPub federation (Mastodon, Pleroma, Misskey)
  • nsfw: Content warnings
  • superblock: Block specific channels
  • openstreetmap: Embed maps in posts

The pubcrawl addon is essential for connecting with the broader fediverse. Enable it immediately after setup.

Nomadic Identity (Cloning)

To clone your identity to another Hubzilla instance:

  1. Create an account on the second Hubzilla instance
  2. Go to Settings → Channel Clone / Export
  3. Enter the URL and credentials of the target hub
  4. Hubzilla synchronizes your identity, connections, and content

If your primary hub goes offline, the clone takes over automatically. This is Hubzilla’s killer feature for resilience.

Advanced Configuration

Custom Themes

Hubzilla ships with several themes. Set the default in Admin → Site → Default Theme. The redbasic theme is the most maintained and customizable.

Storage Quotas

Control disk usage per channel in Admin → Channels. Default storage quota is configurable — important for instances with many users uploading files via WebDAV.

CalDAV/CardDAV

Hubzilla includes a built-in CalDAV/CardDAV server. To use it with external clients (Thunderbird, DAVx5):

  • CalDAV URL: https://hub.yourdomain.com/cdav/calendars/[username]/default/
  • CardDAV URL: https://hub.yourdomain.com/cdav/addressbooks/[username]/default/

Reverse Proxy

Hubzilla requires HTTPS for federation. Set up your reverse proxy before initial configuration.

Nginx Proxy Manager

Create a proxy host:

  • Domain: hub.yourdomain.com
  • Forward hostname: localhost
  • Forward port: 8080
  • SSL: Enable with Let’s Encrypt

For more options, see the Reverse Proxy Setup guide.

Caddy

hub.yourdomain.com {
    reverse_proxy localhost:8080
}

Backup

What to Back Up

DataLocationPriority
Databasedb-data volumeCritical
Application fileshubzilla-data volumeCritical
Environment config.env fileImportant
Uploaded filesInside hubzilla-data (/var/www/html/store/)Critical

Backup Commands

# Database dump
docker compose exec db mariadb-dump -u hubzilla -p${DB_PASS} hubzilla > hubzilla-backup-$(date +%Y%m%d).sql

# File backup
docker run --rm -v hubzilla-data:/data -v $(pwd):/backup alpine \
  tar czf /backup/hubzilla-files-$(date +%Y%m%d).tar.gz -C /data .

With nomadic identity, cloning your channel to a second hub provides a live backup that activates automatically if your primary hub goes down.

For general backup strategies, see our Backup Strategy guide.

Troubleshooting

Federation Not Working After Setup

Symptom: Can’t find or connect to users on other hubs or Mastodon instances.

Fix: Check two things:

  1. The site URL must use https://. If you set it up with http://, you need to start over with a fresh database — this cannot be changed after initial setup.
  2. The pubcrawl addon must be enabled for ActivityPub federation. Go to Admin → Addons and activate it.

Cron Jobs Not Running

Symptom: Posts are delayed, notifications don’t arrive, federation stalls.

Fix: The Docker image runs cron internally. Verify with:

docker compose exec app ps aux | grep cron

If cron isn’t running, restart the app container:

docker compose restart app

Database Connection Errors on Startup

Symptom: App container exits with database connection errors.

Fix: MariaDB takes time to initialize on first boot. Wait 30-60 seconds and check:

docker compose logs db

The depends_on with health check should prevent premature app startup. If the issue persists, verify your .env credentials match in both services.

Storage Space Growing Rapidly

Symptom: The hubzilla-data volume grows unexpectedly large.

Fix: Hubzilla caches remote content (avatars, media from federated posts). Clear old cache from Admin → Server → Expire:

docker compose exec app php /var/www/html/util/typo.php

Monitor disk usage and set appropriate storage quotas per channel.

Cannot Upload Files via WebDAV

Symptom: WebDAV clients connect but file uploads fail.

Fix: Check PHP upload limits inside the container. The default may be too low for large files. Override by mounting a custom PHP config:

volumes:
  - ./custom-php.ini:/usr/local/etc/php/conf.d/uploads.ini:ro

With upload_max_filesize = 100M and post_max_size = 100M.

Resource Requirements

MetricIdleUnder Load
RAM~200 MB~500 MB
CPULowMedium (during federation sync)
Disk300 MB (app)Grows with uploads and cache
Database~50 MB initialGrows with content

Hubzilla is lighter than Mastodon and comparable to Friendica. The PHP-FPM + Nginx architecture (in the sebt3 image) uses slightly less memory than the Apache-based saiwal image.

Verdict

Hubzilla occupies a unique niche — it’s the only platform where your identity survives server failures through nomadic cloning. If data sovereignty and resilience matter more to you than polished UI or mainstream client compatibility, Hubzilla delivers features no other fediverse platform matches: CalDAV, CardDAV, WebDAV, wiki, CMS, forums, and the most granular permission system available.

The downside is ecosystem maturity. Community-maintained Docker images lag behind the rolling-release codebase, documentation is sparse compared to Mastodon or Pleroma, and the user community is small. For most users wanting a fediverse presence, Mastodon or GoToSocial is the practical choice. But if you want the full decentralized identity vision — owning not just your posts but your identity itself — Hubzilla is the only game in town.

FAQ

What’s the difference between Hubzilla and Friendica?

Hubzilla forked from Friendica in 2012 and added nomadic identity, channels, a wiki, CMS, CalDAV/CardDAV, and WebDAV. Friendica stays focused on social networking with multi-protocol federation. Hubzilla is broader but more complex.

Can Hubzilla talk to Mastodon?

Yes, through the pubcrawl addon which enables ActivityPub. You can follow and interact with Mastodon, Pleroma, Misskey, and other ActivityPub-compatible platforms. Some features (nomadic identity, granular permissions) only work between Hubzilla instances.

How does nomadic identity actually work?

You clone your channel to a second Hubzilla instance. Both instances sync automatically — posts, contacts, and settings mirror across hubs. If your primary hub goes offline, the clone becomes active. Your contacts don’t need to re-follow you; the Zot6 protocol handles the failover transparently.

Is Hubzilla actively maintained?

Yes. Development moved from GitHub to Codeberg in 2023. The project has been active since 2012 with consistent contributions, though releases are less frequent than Mastodon. The latest tagged release is 8.6 (July 2023), but development continues on the master branch with Hubzilla 9.x features.

Can I use Hubzilla as a CalDAV/CardDAV server?

Yes. Hubzilla includes a built-in CalDAV and CardDAV server that works with standard clients like Thunderbird, DAVx5 (Android), and Apple Calendar/Contacts. It’s not as feature-complete as dedicated solutions like Radicale or Baikal, but it works for personal use.

Comments