Self-host Ghost CMS on your VPS using the Unihost template in Portainer. Open Templates, select Ghost CMS, enter the database connection settings and deploy the stack. Configure the public site URL, enable HTTPS through a reverse proxy, and set up SMTP for email. Back up both the database and the Ghost content volume before updating.

Applies to: Ghost CMS deployed with Docker and Portainer on Linux. Production database compatibility depends on the Ghost version.

Requirements

Before starting, prepare:

  • A Linux VPS with Docker and Portainer.
  • A database accessible from the Ghost container. The original Unihost template uses MariaDB. Current Ghost production documentation supports MySQL 8.
  • A domain and access to its DNS settings.
  • Nginx Proxy Manager or Traefik for HTTPS.
  • Free disk space for content and backups.

Ghost recommends at least 1 GB RAM for a basic installation, but a Docker stack with a database and proxy needs additional resources. Plan capacity according to the actual workload.

Steps

Step 1. Select the Ghost CMS template

In Portainer, open Templates → Application → Ghost CMS. Select the Unihost template and enter the required parameters. If you are new to Portainer, see the Portainer introduction. What is Portainer?.

Ghost CMS application template in Portainer

Step 2. Configure the database and site URL

The existing template asks for a database host, name, user and password. It can create a database during deployment when supported by its database component. Check that the database is compatible with your Ghost version.

Ghost CMS template database settings and Ghost URL

For an official Ghost container, the main environment settings are:

url=https://blog.example.com
database__client=mysql
database__connection__host=db
database__connection__user=ghost
database__connection__password=REPLACE_WITH_STRONG_PASSWORD
database__connection__database=ghost

The url value must exactly match your public HTTPS domain. Keep database passwords out of public repositories and client-side code.

Step 3. Deploy Ghost and configure HTTPS

After deploying Ghost, publish the website through Nginx Proxy Manager (NPM):

  1. Create a DNS A record for blog.example.com pointing to the VPS.
  2. Open NPM → Hosts → Proxy Hosts → Add Proxy Host.
  3. Enter blog.example.com in Domain Names and select Scheme: http.
  4. Set Forward Hostname / IP to the Ghost service hostname reachable from NPM, and Forward Port to 2368.
  5. Under SSL, request a Let’s Encrypt certificate, enable Force SSL and save.

Make sure NPM can reach Ghost over Docker networking. Set Ghost url to https://blog.example.com and use https://blog.example.com/ghost for administration.

Nginx Proxy Manager installation and HTTPS setup

Traefik with Portainer is an alternative for HTTPS.

blog.example.com -> SERVER_IP

Nginx Proxy Manager proxy host for Ghost port 2368

The screenshot illustrates the original HTTP proxy setup. For a public site, publish Ghost via HTTPS and use the same https:// domain in url.

Ghost database shown in phpMyAdmin

Ghost CMS homepage after deployment

Open the site, then visit /ghost to create the administrator account.

https://blog.example.com/ghost

Ghost CMS administrator setup screen

Step 4. Configure SMTP email

Ghost needs transactional email for invitations, password resets and other messages. Add SMTP environment settings in the Portainer stack and use credentials from your mail provider:

mail__transport=SMTP
mail__from=blog@example.com
mail__options__host=smtp.example.com
mail__options__port=587
mail__options__secure=false
mail__options__auth__user=SMTP_USERNAME
mail__options__auth__pass=SMTP_PASSWORD

For port 587 use STARTTLS where supported; for port 465 use implicit TLS and mail__options__secure=true. Sending bulk newsletters may require a separate provider integration such as Mailgun.

Step 5. Back up the database and content

Back up the database and the persistent /var/lib/ghost/content volume. For MySQL use mysqldump; for the original MariaDB-based template use mariadb-dump. Run the appropriate command on the Docker host:

docker exec DB_CONTAINER sh -c 'exec mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" ghost' > ghost-db-backup.sql
docker exec DB_CONTAINER sh -c 'exec mariadb-dump -u root -p"$MARIADB_ROOT_PASSWORD" ghost' > ghost-db-backup.sql
docker exec GHOST_CONTAINER tar -czf - -C /var/lib/ghost content > ghost-content-backup.tar.gz

Use the actual container name and authentication method. Keep a separate backup of Ghost content and configuration, store copies off-server and test restoration.

Step 6. Update the Ghost image

In Portainer, back up all data, review the Ghost release notes and database requirements, then change the image tag to a compatible release and redeploy the stack without deleting volumes. Major-version updates may require database and theme compatibility checks.

Verify

Confirm that Ghost and its database are running, the site opens through HTTPS, /ghost is accessible, email delivery works and both database and content backups are available. Check logs if necessary:

docker ps
docker logs --tail 50 GHOST_CONTAINER

Troubleshooting

Ghost cannot connect to the database

Check database__connection__host, username, password, database name and Docker networking. Ghost production releases officially support MySQL 8.

The site redirects incorrectly or HTTPS fails

Verify DNS, the reverse proxy, the TLS certificate and the url environment variable. The proxy must forward the HTTPS scheme.

Email is not sent

Check SMTP host, port, credentials, TLS mode and Ghost logs.

FAQ

Is self-hosted Ghost free?

Yes. Ghost is open-source software, but you must pay for infrastructure and any optional email services.

How do I set up email in Ghost?

Configure mail__transport=SMTP and the mail__options__* settings for your provider, redeploy the container and test an email.

How do I update Ghost in Docker?

Back up the database and content, select a compatible image tag in Portainer and redeploy while preserving volumes.

How much RAM does Ghost need?

Ghost lists at least 1 GB RAM for a basic installation. A Docker stack with MySQL and a reverse proxy needs extra memory, depending on traffic.

Related Articles

Ghost(Pro) or self-hosted?

Ghost(Pro) Self-hosted Ghost
Managed hosting Your own VPS or dedicated server
Provider-managed updates You manage updates and backups
Subscription fee Infrastructure and service costs

Host Ghost CMS with Unihost

Deploy Ghost and other applications on your own infrastructure using Portainer templates.

Official Ghost configuration documentation