Introduction

Self-Hosting dotCMS on a VPS: A Complete Production Guide

Metadata

  • Difficulty: Intermediate

  • Time to complete: 60–90 minutes

  • Prerequisites: Basic Linux CLI comfort, a domain name, a VPS (any provider)

  • Technologies: Ubuntu, Docker, Caddy, PostgreSQL, Portainer, dotCMS

  • What you'll have at the end: A production dotCMS instance running on your own server with HTTPS, a container management UI, and a VPS metrics dashboard


What We're Building

This guide walks you through deploying dotCMS on a self-managed VPS from scratch — not a simplified demo, but a setup you'd actually run in production. By the end, you'll have:

  • A hardened Ubuntu VPS with SSH key authentication and firewall rules

  • Caddy as a reverse proxy with automatic HTTPS (no certificate config required)

  • Docker + Portainer for running and managing containers via a web UI

  • dotCMS deployed and accessible on your domain

  • Homarr dashboard as a central launchpad for all your services

  • Dashdot for real-time VPS metrics (CPU, memory, storage)


Why Self-Host dotCMS?

dotCMS is a hybrid headless CMS — it supports both traditional and headless content delivery. Self-hosting gives you:

  • Full control over your environment, data, and infrastructure

  • Cost efficiency — a VPS running dotCMS + related services can cost $20-50/month depending on your provider

  • No vendor lock-in — your data stays on your server

  • Flexibility to co-host other open-source services alongside dotCMS

Provider note: This guide uses DigitalOcean but every command runs identically on Hetzner, Vultr, Linode, or any Ubuntu VPS. Hetzner is worth considering if cost is a priority — comparable specs at a significantly lower price point.


Prerequisites

Before starting, you need:

  • A VPS running Ubuntu 22.04 LTS (minimum: 4 GB RAM, 2 vCPU, 40 GB SSD; recommended: 8 GB RAM for running dotCMS + companion services)

  • A domain name with DNS access (this guide uses dotcms.info)

  • A local machine with an SSH client

Next up

Chapter 1: VPS and Domain Setup

Continue →