Skip to main content

How Docker Changed the Self-Hosting Landscape

·OSSAlt Team
dockerself-hostingcontainersdevops2026

How Docker Changed the Self-Hosting Landscape

Before Docker, self-hosting meant dependency hell, configuration nightmares, and "it works on my machine." Docker turned one-week projects into one-minute deploys.

Before and After

Installing Mattermost (2015 vs 2026)

2015 (Manual Installation):

  1. Install Go runtime
  2. Install PostgreSQL
  3. Configure database users and permissions
  4. Download Mattermost binary
  5. Create system user
  6. Configure Mattermost (config.json — 200+ settings)
  7. Set up Nginx reverse proxy
  8. Configure SSL certificates (manually with Let's Encrypt)
  9. Create systemd service
  10. Configure logrotate
  11. Set up backup cron jobs

Time: 4-8 hours. Error-prone. Different on every Linux distro.

2026 (Docker):

services:
  mattermost:
    image: mattermost/mattermost-team-edition:latest
    environment:
      MM_SQLSETTINGS_DRIVERNAME: postgres
      MM_SQLSETTINGS_DATASOURCE: postgres://mm:password@db:5432/mattermost
    ports: ["8065:8065"]
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: mm
      POSTGRES_PASSWORD: password
      POSTGRES_DB: mattermost
    volumes: ["db_data:/var/lib/postgresql/data"]
volumes:
  db_data:
docker compose up -d

Time: 5 minutes. Works identically on any machine.

The 5 Ways Docker Changed Everything

1. Eliminated Dependency Hell

The old problem:

App A needs Python 3.8
App B needs Python 3.11
Both need different versions of libssl
PostgreSQL 14 conflicts with PostGIS on Ubuntu 22.04

Docker's solution: Each app runs in isolation with its own dependencies. No conflicts, ever.

Container A: Python 3.8, libssl 1.1
Container B: Python 3.11, libssl 3.0
Container C: PostgreSQL 16, PostGIS 3.4

They don't see each other. They can't conflict.

2. Made Deploys Reproducible

Before Docker:

  • "It works on my machine" was a meme for a reason
  • Development, staging, and production environments differed
  • Setup instructions were outdated within months

After Docker:

  • docker compose up works the same everywhere
  • The Docker image IS the deployment artifact
  • If it works locally, it works on the server

3. Simplified Updates

Before:

# Hope the new version doesn't break your config
sudo apt update && sudo apt upgrade
# Fix broken dependencies
# Manually migrate database schema
# Restart services in the right order
# Roll back if something breaks (good luck)

After:

docker compose pull    # Download new images
docker compose up -d   # Restart with new versions
# Something broke?
docker compose down
# Change image tag back to previous version
docker compose up -d   # Instant rollback

4. Enabled One-Command Tools

Docker images let projects ship ready-to-run software:

ToolDocker CommandWhat You Get
Uptime Kumadocker run -p 3001:3001 louislam/uptime-kumaFull monitoring dashboard
Vaultwardendocker run -p 8080:80 vaultwarden/serverPassword manager
Plausibledocker compose up (3 containers)Privacy-first analytics
PocketBaseSingle binary (no Docker needed!)Full backend

5. Created the Self-Hosting Ecosystem

Docker standardized how software is packaged and deployed, which enabled:

  • Docker Hub: 100K+ official images, searchable, versionable
  • Coolify/Dokku: PaaS tools built on Docker
  • Portainer: GUI for managing containers
  • Watchtower: Automatic container updates
  • Awesome-selfhosted: Community curated list of self-hostable tools

Docker Compose: The Self-Hoster's Best Friend

Docker Compose lets you define multi-container applications in a single file:

Example: Full Monitoring Stack

services:
  grafana:
    image: grafana/grafana:latest
    ports: ["3000:3000"]
    volumes: ["grafana_data:/var/lib/grafana"]

  prometheus:
    image: prom/prometheus:latest
    ports: ["9090:9090"]
    volumes: ["./prometheus.yml:/etc/prometheus/prometheus.yml"]

  node-exporter:
    image: prom/node-exporter:latest
    pid: host
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro

volumes:
  grafana_data:

Three services. One file. One command. Full observability stack.

The Docker Compose Pattern

Every self-hosted tool follows the same pattern:

services:
  app:                          # The application
    image: company/tool:latest  # Official image
    environment:                # Configuration via env vars
      DATABASE_URL: postgres://...
    ports: ["8080:8080"]        # Exposed port
    depends_on: [db]            # Start order

  db:                           # Database
    image: postgres:16          # Standard database image
    volumes: ["data:/var/lib/postgresql/data"]  # Persistent storage

volumes:
  data:                         # Named volume for data persistence

Once you understand this pattern, you can deploy anything.

What Docker Didn't Solve

Still Requires Some Knowledge

TaskDocker Helps?What You Still Need
Initial server setupPartialSSH, firewall, basic Linux
NetworkingPartialDNS, reverse proxy concepts
SSL certificatesNoCaddy/Traefik/Nginx config
BackupsNoBackup scripts, offsite storage
MonitoringNoSeparate monitoring setup
SecurityPartialFirewall rules, update policies

Docker's Overhead

ConcernReality
RAM usageEach container adds 10-50 MB overhead
Disk usageImages can be 100-500 MB each
ComplexityDocker itself needs updating and monitoring
NetworkingDocker networking can be confusing
StorageVolume management requires attention

The Tools Built on Docker

Docker's standardization enabled an ecosystem of management tools:

ToolWhat It DoesWhy It Matters
CoolifyFull PaaS (deploy, monitor, SSL)Makes Docker invisible
PortainerDocker GUI (manage containers, images, volumes)Visual management
WatchtowerAuto-update containersHands-off maintenance
TraefikReverse proxy + auto-SSLDynamic routing for containers
CaddyReverse proxy + auto-SSLSimpler config than Traefik
DuplicatiBackup Docker volumesAutomated backups

The Impact on Open Source

Docker changed how open source projects think about distribution:

Before Docker:

  • Ship source code
  • Write installation guides for 5+ Linux distros
  • Users compile from source or use package managers
  • "Installation" section of README = 2 pages

After Docker:

  • Ship a Docker image
  • One installation guide works everywhere
  • Users docker pull and run
  • "Installation" section = 3 lines

This lowered the barrier for:

  1. Users — Anyone can run complex software
  2. Developers — Ship once, works everywhere
  3. Projects — Focus on features, not installation support

The Bottom Line

Docker didn't just change self-hosting — it made it possible for non-sysadmins. The combination of:

  • Docker images → Standardized packaging
  • Docker Compose → Declarative multi-service deployments
  • Docker Hub → Centralized distribution
  • PaaS tools (Coolify) → GUI on top of Docker

...turned self-hosting from a specialized skill into something any developer can do in an afternoon.


Find Docker-ready open source tools at OSSAlt.