Self-Hosting Webtrees with Docker Compose

What Is Webtrees?

Webtrees is the leading open-source web application for genealogy. It lets you build, edit, and share your family tree through a browser-based interface with support for the GEDCOM standard. Import existing family data from desktop genealogy software (Ancestry, FamilySearch, Gramps), collaborate with relatives, and keep your genealogical records under your own control. It replaces Ancestry.com and MyHeritage with a privacy-respecting, self-hosted alternative.

Official site: webtrees.net | GitHub

Prerequisites

  • A Linux server (Ubuntu 22.04+ recommended)
  • Docker and Docker Compose installed (guide)
  • 1 GB of free disk space
  • 512 MB of RAM minimum
  • A domain name (recommended for sharing with family)

Docker Compose Configuration

services:
  webtrees:
    image: ghcr.io/nathanvaughn/webtrees:2.2.5
    container_name: webtrees
    restart: unless-stopped
    ports:
      - "8080:80"
    environment:
      - PRETTY_URLS=true
      - HTTPS=false
      - HTTPS_REDIRECT=false
      - LANG=en-US
      - BASE_URL=http://localhost:8080
      - DB_TYPE=mysql
      - DB_HOST=webtrees-db
      - DB_PORT=3306
      - DB_NAME=webtrees
      - DB_USER=webtrees
      - DB_PASS=changeme_db
      - DB_PREFIX=wt_
      - WT_USER=admin
      - WT_NAME=Admin
      - WT_PASS=changeme_admin
      - [email protected]
    depends_on:
      webtrees-db:
        condition: service_healthy
    volumes:
      - webtrees-data:/var/www/webtrees/data
    networks:
      - webtrees-net

  webtrees-db:
    image: mariadb:11.4
    container_name: webtrees-db
    restart: unless-stopped
    environment:
      - MYSQL_ROOT_PASSWORD=changeme_root
      - MYSQL_DATABASE=webtrees
      - MYSQL_USER=webtrees
      - MYSQL_PASSWORD=changeme_db
    volumes:
      - webtrees-dbdata:/var/lib/mysql
    networks:
      - webtrees-net
    healthcheck:
      test: ["CMD-SHELL", "healthcheck.sh --connect --innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  webtrees-data:
  webtrees-dbdata:

networks:
  webtrees-net:

Change these values before starting:

  • DB_PASS and MYSQL_PASSWORD — set to a strong password (must match)
  • MYSQL_ROOT_PASSWORD — set to a different strong password
  • WT_PASS — your admin login password
  • WT_EMAIL — your email address
  • BASE_URL — your public URL if using a domain

Start the stack:

docker compose up -d

Initial Setup

Open http://your-server-ip:8080 in your browser. If you set WT_USER, WT_PASS, and WT_EMAIL in the environment, the admin account is created automatically on first run.

Importing a GEDCOM File

  1. Log in as admin
  2. Go to Control Panel → Manage Family Trees
  3. Click Create a family tree or Import from GEDCOM
  4. Upload your .ged file (exported from Ancestry, FamilySearch, Gramps, etc.)
  5. Webtrees parses the file and creates the tree — large files (50,000+ individuals) may take a few minutes

Privacy Settings

Webtrees has granular privacy controls:

  • Show living people — restrict visibility to authorized users only
  • Access levels — visitor, member, editor, moderator, manager, administrator
  • Individual privacy — mark specific people as private regardless of global settings
  • GEDCOM restrictions — honor privacy flags embedded in the GEDCOM file

Configuration

Key Environment Variables

VariableDefaultDescription
BASE_URLPublic URL (include protocol and port)
DB_TYPEmysqlDatabase type: mysql, pgsql, sqlite
PRETTY_URLStrueUse clean URLs instead of index.php?route=
HTTPSfalseSet to true if behind an HTTPS reverse proxy
HTTPS_REDIRECTfalseRedirect HTTP to HTTPS
LANGen-USDefault language
WT_USERAdmin username (only used on first run)
WT_PASSAdmin password (only used on first run)

Using SQLite Instead of MariaDB

For small family trees (under 10,000 individuals), you can skip MariaDB and use SQLite:

environment:
  - DB_TYPE=sqlite
  - DB_NAME=webtrees

Remove the webtrees-db service and the depends_on directive.

Reverse Proxy

When behind a reverse proxy with HTTPS, set:

BASE_URL=https://family.example.com
HTTPS=true
HTTPS_REDIRECT=true

For proxy configuration, see Reverse Proxy Setup.

Backup

Back up these volumes:

  • webtrees-data — uploaded media, GEDCOM imports, configuration
  • webtrees-dbdata — the MariaDB database with all genealogical records

Database dump:

docker compose exec webtrees-db mariadb-dump -u webtrees -p webtrees > webtrees-backup-$(date +%Y%m%d).sql

Also export your GEDCOM periodically: Control Panel → Manage Family Trees → Export.

For a full backup strategy, see Backup Strategy.

Troubleshooting

”Database Connection Failed” on First Start

Symptom: Webtrees shows a database error immediately after starting.

Fix: The MariaDB container needs time to initialize. Wait 30 seconds and refresh. The healthcheck in the Compose file handles this, but on slow systems it may need more time. Check: docker compose logs webtrees-db.

GEDCOM Import Fails for Large Files

Symptom: Timeout or memory error when importing a large GEDCOM.

Fix: Increase PHP memory and timeout limits. Add to the webtrees service:

environment:
  - PHP_MEMORY_LIMIT=512M
  - PHP_MAX_EXECUTION_TIME=600

Media Files Not Displaying

Symptom: Photos linked in GEDCOM records show broken image icons.

Fix: GEDCOM media paths must match the upload directory structure. After import, upload media files to the correct location via Control Panel → Manage Media.

Resource Requirements

  • RAM: ~100 MB idle, ~300 MB with large trees
  • CPU: Low — page generation is lightweight
  • Disk: ~50 MB for the application, plus your media files

Verdict

Webtrees is the most capable self-hosted genealogy application. GEDCOM import/export means you’re never locked in, and the privacy controls let you share selectively with family members. The interface looks dated compared to Ancestry.com, but the functionality is comprehensive — charts, timelines, statistics, and media management all work well. For anyone serious about genealogy who doesn’t want to pay Ancestry $20+/month or trust them with sensitive family data, webtrees is the clear choice.

Comments