> ## Content Index
> Fetch the complete content index at: https://wealthlab.life/llms.txt
> Use this file to discover other available public pages before exploring further.

# How to Deploy Ghost on Vultr with Docker Compose
- URL: https://wealthlab.life/deploy-ghost-vultr-docker/
- Published: 2026-09-04T00:07:22.000Z
- Updated: 2026-09-04T00:07:22.000Z
- Description: Deploy Ghost on a Vultr Cloud Compute instance with Docker Compose, Caddy, MySQL, Firewall rules, backups, and production checks.
- Author: WealthLab
- Tags: Vultr, Ghost, Docker, VPS

*Disclosure: WealthLab.life may earn a commission when you register through some links on this page, at no additional cost to you.*

You can deploy Ghost on Vultr by provisioning an Ubuntu Cloud Compute instance with an SSH key, attaching a Vultr Firewall group, pointing DNS to the server, and running Ghost's official Docker Compose stack behind Caddy. Start with enough memory for Ghost, MySQL, upgrades, and backups—not just the smallest instance that can boot.

## Quick answer and architecture

This walkthrough uses Ghost's official Docker tooling. The stack includes Ghost, MySQL, and Caddy: Caddy handles HTTPS and sends requests to Ghost, while MySQL and the Ghost content directory hold persistent data. Only ports 80, 443, and a tightly scoped SSH port should be reachable from the internet.

- **Vultr Cloud Compute:** runs Ubuntu and the Docker services.
- **Vultr Firewall:** filters inbound traffic before it reaches the instance.
- **Caddy:** terminates TLS and exposes the publication without publishing Ghost's internal port.
- **MySQL and Ghost content:** require separate, application-aware backups.
- **SMTP:** supports password resets, invitations, and transactional mail.

For a provider-neutral explanation first, read [How to Install Ghost with Docker on a VPS](https://wealthlab.life/install-ghost-docker-vps/). This guide focuses on Vultr provisioning, firewall, backup, and recovery choices.

## Requirements

- A domain or subdomain you control.
- A Vultr account with an SSH public key added.
- A current Ubuntu LTS image that Docker supports.
- At least 2 GB RAM as a practical starting point for a small production publication.
- An SMTP provider and verified sending setup.
- An off-server destination for database dumps and Ghost content archives.
- A maintenance plan for updates, monitoring, and restore testing.

A 1 GB instance may be useful for a disposable test, but it leaves little room for MySQL, image pulls, migrations, imports, and temporary memory spikes. Use the [Ghost VPS sizing guide](https://wealthlab.life/ghost-vps-sizing/) to choose capacity from the workload rather than from idle usage.

## 1\. Create a Vultr Firewall group first

In the Vultr customer portal, create a clearly named Firewall group such as `ghost-production`. Add only the inbound rules this deployment requires:

- TCP 80 from all intended IPv4 and IPv6 sources for HTTP validation and redirects;
- TCP 443 from all intended IPv4 and IPv6 sources for the public site;
- TCP 22 only from a trusted administration IP or network when practical.

Do not expose MySQL port 3306 or Ghost port 2368\. If you enable IPv6, create and verify the matching IPv6 rules rather than assuming the IPv4 policy covers both families. Keep a provider console recovery route available before narrowing SSH.

Vultr's documentation describes its Firewall as a stateful, network-level control for incoming traffic. It complements host security; it does not replace operating-system updates, restricted Docker publishing, SSH hardening, or application authentication.

## 2\. Provision the Cloud Compute instance

Open **Products → Compute → Deploy**. For a small publication, a shared-CPU Cloud Compute plan is generally the starting category; choose a different compute family only when measured CPU, storage, or consistency requirements justify it. Select a location near the primary audience and verify the selected plan, image, backup option, and networking features are available there.

Choose a plain supported Ubuntu LTS image. Add your SSH key, attach the `ghost-production` Firewall group, and use descriptive hostname and label values. Vultr also offers a limited-user login option during provisioning; whichever initial account you choose, establish a named administrator and verify key-based access before disabling another access method.

If this deployment fits your needs, [view Vultr through WealthLab's referral link](https://www.vultr.com/?ref=9919874-9J). Confirm current specifications, regional availability, backup behavior, bandwidth terms, and final price in the Vultr portal before deploying.

## 3\. Connect, patch Ubuntu, and protect SSH

```bash
ssh root@YOUR_SERVER_IP
apt update
apt upgrade -y
reboot
```

Reconnect after the reboot. Create a named sudo-capable administrator, copy the SSH key, and prove that a second session works before changing root or password-login policy. A safe sequence matters: locking down SSH before testing the replacement path can turn routine hardening into an outage.

Keep SSH keys passphrase-protected where practical, remove obsolete account and server keys, and document how to use the Vultr web console if network access fails. Do not publish private keys or store them in the Ghost deployment directory.

## 4\. Point DNS to the server

Create an A record for the publication hostname using the instance's public IPv4 address. Add an AAAA record only when IPv6 is enabled and verified end to end. Confirm public resolution before asking Caddy to obtain a certificate:

```bash
getent ahosts blog.example.com
```

Ports 80 and 443 must reach Caddy for the normal HTTPS flow. If Cloudflare or another reverse proxy sits in front, keep one canonical hostname and understand which layer terminates TLS. Conflicting redirects or an incorrect forwarded scheme can create loops and wrong canonical URLs.

## 5\. Install Docker from its official repository

Follow Docker's current Ubuntu installation documentation to configure its apt repository and install Docker Engine, the CLI, containerd, Buildx, and the Compose plugin. Avoid running an unexplained remote script as root. Then verify the installed components:

```bash
docker --version
docker compose version
systemctl is-active docker
```

Membership in the `docker` group provides powerful host-level access, so limit it to administrators. Docker also creates packet-filtering and NAT rules for bridge networks. Docker's documentation warns that published container ports can bypass some `ufw` expectations; verify the effective exposure instead of assuming a host firewall alone protects every published port.

## 6\. Install Ghost's official Docker project

Ghost 6 provides official Docker Compose tooling that includes Ghost, MySQL, and Caddy. Clone it into a predictable location and create local configuration files:

```bash
git clone https://github.com/TryGhost/ghost-docker.git /opt/ghost
cd /opt/ghost
cp .env.example .env
cp caddy/Caddyfile.example caddy/Caddyfile
chmod 600 .env
```

Review the repository and record the deployed commit before starting it. This makes later updates and rollback investigation more understandable than an unrecorded copy of changing files.

## 7\. Configure domain, database secrets, and SMTP

Edit `/opt/ghost/.env`. Set the public domain exactly as DNS and the intended canonical hostname use it. Generate separate random database root and Ghost database passwords:

```bash
openssl rand -hex 32
openssl rand -hex 32
```

Configure SMTP from your provider's current documentation, including host, port, security mode, username, password, and From address. Ghost needs transactional mail for important account flows. SMTP authentication is only one check; confirm actual delivery and review provider events and domain authentication.

Never commit `.env`, paste it into support tickets, or include it in an unencrypted general-purpose archive. Back up the configuration securely because a database dump without the matching deployment details and secrets is not a complete recovery plan.

## 8\. Validate and start the Compose stack

```bash
cd /opt/ghost
docker compose config --quiet
docker compose pull
docker compose up -d
docker compose ps
```

`docker compose config --quiet` catches syntax and interpolation errors without printing the rendered configuration. Do not paste the full rendered Compose output publicly because it can contain secret values. Inspect bounded logs after startup:

```bash
docker compose logs --tail=100 caddy ghost db
```

Open the public HTTPS site and then `https://YOUR_DOMAIN/ghost/` to complete owner setup. Confirm that the public URL, Admin URL, redirects, and canonical tags all use the intended HTTPS hostname.

## 9\. Verify the deployment from outside the server

- The homepage, an article, and `/ghost/` return the expected HTTPS status.
- HTTP redirects to the canonical HTTPS hostname.
- `/robots.txt` and `/sitemap.xml` return 200.
- Only intended public ports are reachable.
- MySQL and Ghost's internal port are not publicly accessible.
- A password-reset or invitation email reaches a real mailbox.
- The services return after a controlled host reboot.
- Disk, memory, swap, and container restarts are monitored.

Use the [Docker VPS production checklist](https://wealthlab.life/docker-vps-checklist/) for a deeper launch review. An “Up” container is not proof that TLS, mail, backups, and recovery work.

## 10\. Build backups around a tested restore

Vultr Automatic Backups provide system-level recovery for the instance's active filesystem. Enable them when they fit your recovery plan, and consider a snapshot before risky maintenance. Neither is a substitute for portable, application-aware copies.

- Create a consistent MySQL export.
- Archive Ghost's content directory and deployment configuration.
- Store protected copies outside the Vultr instance.
- Record image versions, DNS, Firewall rules, and required secrets.
- Restore into a disposable instance and verify posts, images, members, themes, and mail configuration.

A completed backup command proves only that a command finished. A successful restoration is the evidence that matters. Define acceptable data loss and recovery time, then set schedules and retention accordingly.

## 11\. Update Ghost without losing the rollback path

Before an update, read release notes, take application-consistent backups, record running image identifiers, validate Compose, and decide how to roll back. Then pull and recreate the stack:

```bash
cd /opt/ghost
docker compose config --quiet
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=100 ghost
```

Recheck the homepage, Admin, an image-heavy article, SMTP, robots, sitemap, scheduled backups, and current resource use. Avoid unattended major-version jumps and do not delete old recovery material until the new state has passed verification.

## Troubleshooting

### Caddy cannot obtain a certificate

Confirm DNS resolves to this instance, the Vultr Firewall group is attached, ports 80 and 443 are allowed for the correct IP families, and no other process owns those ports. Make the configured Ghost domain match DNS exactly.

### The site enters a redirect loop

Verify Ghost's configured URL is the canonical HTTPS URL. When an upstream proxy terminates TLS, ensure it sends the correct forwarded host and scheme. Remove competing redirect rules until one clear canonical path remains.

### Ghost or MySQL repeatedly restarts

Inspect bounded logs and check free memory, swap, disk space, filesystem permissions, and database health. Small instances can fail during pulls, migrations, imports, or backups even when idle use appeared comfortable.

### Firewall rules look correct but a port is public

Confirm the intended Firewall group is attached to the instance, inspect host listeners and `docker compose ps`, and test from an external network. Account for both Vultr's network firewall and Docker's port-publishing behavior.

### SMTP accepts credentials but mail does not arrive

Check Ghost logs, provider delivery events, domain authentication, verified sender requirements, suppressions, From address, and spam filtering. Authentication success does not prove end-to-end delivery.

## When this setup is not a good fit

A self-managed Vultr instance is a poor fit when nobody can own Linux patching, Docker upgrades, MySQL recovery, monitoring, and incidents. Ghost(Pro) or another managed service may be the safer choice when operating time costs more than infrastructure control. Also pause when the project needs verified compliance, support, or recovery commitments not established by this architecture.

## FAQ

### What Vultr instance size should I use for Ghost?

For a small publication, 2 GB RAM is a practical starting point. Choose 4 GB or more when imports, analytics, traffic, background work, or co-located services need headroom. Measure actual memory, CPU, disk, and database behavior after launch.

### Should I choose Shared CPU or a higher-performance plan?

Shared CPU is a reasonable starting category for many small publications. Choose a higher-performance family when measured workload characteristics or consistency requirements justify it, not because a label sounds faster. Verify current plan specifications in the target location.

### Are Vultr Automatic Backups enough for Ghost?

No. Treat them as one system-level recovery layer. Keep portable MySQL exports, Ghost content, configuration, and required secrets off the instance, and test restoring the whole publication.

### Do I need both Vultr Firewall and Caddy?

Yes. The Vultr Firewall filters inbound network traffic; Caddy handles HTTP routing and TLS. Neither replaces secure SSH, restricted Docker ports, application updates, or backups.

### Can I migrate this Ghost site later?

Yes. Portable database exports, content archives, configuration, DNS notes, and a tested restore procedure make provider migration much safer. Restore and validate on the destination before changing DNS.

## Related WealthLab guides

- [Install Ghost with Docker on any VPS](https://wealthlab.life/install-ghost-docker-vps/)
- [Ghost VPS RAM, CPU, and storage requirements](https://wealthlab.life/ghost-vps-sizing/)
- [Best VPS for Ghost hosting](https://wealthlab.life/best-vps-ghost-hosting/)
- [DigitalOcean vs Vultr](https://wealthlab.life/digitalocean-vs-vultr/)
- [Deploy Ghost on DigitalOcean with Docker Compose](https://wealthlab.life/deploy-ghost-digitalocean-docker/)
- [Docker VPS production checklist](https://wealthlab.life/docker-vps-checklist/)

## Sources checked

- [Ghost's official Docker installation documentation](https://docs.ghost.org/install/docker)
- [Vultr Cloud Compute provisioning documentation](https://docs.vultr.com/products/compute/instances/cloud-compute/provisioning)
- [Vultr Firewall group provisioning documentation](https://docs.vultr.com/products/network/firewall-groups/provisioning)
- [Vultr Firewall rules documentation](https://docs.vultr.com/products/network/firewall-groups/management/rules)
- [Vultr Automatic Backups documentation](https://docs.vultr.com/products/storage/backups/provisioning)
- [Vultr security best-practices guide](https://docs.vultr.com/platform/security-best-practices/vultr-cloud-instances)
- [Docker Engine installation on Ubuntu](https://docs.docker.com/engine/install/ubuntu/)
- [Docker packet filtering and firewall guidance](https://docs.docker.com/engine/network/packet-filtering-firewalls/)

*Official sources reviewed September 4, 2026\. Product availability, requirements, and interfaces can change; verify current documentation before deployment.*