# Ghost

> Install the Ghost blog and newsletter platform from the App Store, set up SMTP mail, create the owner account behind the setup lock, back up and update it.

Source: https://zopanel.net/docs/app-ghost  
Updated: 2026-10-09

Ghost is a publishing platform for blogs, magazines and newsletters, with a fast editor, themes and built-in member sign-ups. ZoPanel runs Ghost 5 in a container with a SQLite database, which suits a personal or small-business blog without a separate database server.

## Requirements

| Item | Value |
| --- | --- |
| Image | `ghost:5-alpine` (Ghost 5) |
| Memory limit | 768 MB, 1 CPU |
| Free disk to install | About 2 GB on the Docker disk (the image plus 1 GB kept free for the server) |
| Database | SQLite, file `content/data/ghost.db` inside the app's data folder |
| Mail | Optional SMTP server, entered at install time |

The website counts toward the account's website limit. As a customer, your package must allow Docker apps and have 768 MB of **RAM (MB)** free for the app.

**Note:** Ghost officially supports only MySQL 8 in production; SQLite runs Ghost in development mode (`NODE_ENV=development`), which is how the official Docker image supports it. This works well for a single blog with moderate traffic. Containers cannot reach the server's own MySQL (see [Network limits](#network-limits)), so ZoPanel uses SQLite.

## Before you install

1. Point the domain's A record to the server.
2. Decide on mail. Ghost needs an SMTP server to send staff invitations, password resets and the sign-in and sign-up links for members. Without mail, you can still publish, but you cannot reset a forgotten password by email and members cannot sign in.
3. If you use a mailbox on this server, create it first under **Email** (for example `blog@example.com`) and note the mail server's host name.

**Important:** The SMTP fields can only be entered when you install. ZoPanel has no form to change them later (see [Change mail settings later](#change-mail-settings-later)).

## Install Ghost

1. Open **App Store** and click **Install** on the **Ghost** card. Customers find **App Store** in their menu; the card at the top shows how many apps and how much memory the package allows.
2. Fill in the fields below and click **Install**.
3. Follow the task log. The first start takes one to two minutes.

| Field | What to enter |
| --- | --- |
| **Domain** | Domain or subdomain of the blog, without `http://`. Ghost's address is set to `https://<domain>`. |
| **Owner** | Administrators only: the hosting account that owns the app. |
| **SMTP server (optional, for email)** | Host name or IP of the mail server, for example `mail.example.com`. Leave empty for no mail; the other mail fields are then ignored. |
| **SMTP port (587 or 465)** | `587` (STARTTLS) or `465` (TLS). Empty means `587`. ZoPanel turns on Ghost's secure mode only for `465`. |
| **SMTP user name** | Usually the full mailbox address. |
| **SMTP password** | The mailbox password. |
| **Sender address (e.g. blog@your-domain)** | The From address. Use the same mailbox as the SMTP user, because most mail servers refuse other senders. |
| **Free SSL (Let's Encrypt)** | Leave on. Ghost redirects to `https://`, so the blog only works once the certificate is issued. |

These field labels come from the app catalog and appear in English in every panel language. ZoPanel passes them to Ghost as `mail__options__host`, `mail__options__port`, `mail__options__auth__user`, `mail__options__auth__pass` and `mail__from`, and adds `mail__transport=SMTP`.

## Create the owner account behind the setup lock

The first person to open Ghost's setup page becomes the site owner, so ZoPanel keeps a new install private.

1. Check the **SSL** tab: the certificate must be issued before you continue, because Ghost only works on `https://`.
2. On the **Docker** tab, click **Open the app (only for me)**. Your browser gets a setup cookie (valid 30 days) and opens the blog.
3. Go to `https://<domain>/ghost`.
4. Fill in the setup form: site title, your full name, email address and a password (Ghost requires at least 10 characters). Click the button to create the account.
5. Back on the **Docker** tab, click **Setup finished — open to everyone**.

Until step 5, visitors see "This app is being set up", and search engines, RSS readers and members cannot reach the blog.

## Essential settings in Ghost

All of these are in Ghost Admin (`https://<domain>/ghost`), under **Settings**:

- **General:** title, description, time zone and publication language.
- **Design and themes:** choose or upload a theme. Uploaded themes are stored in the data folder.
- **Staff:** invite editors and authors. Invitations are sent by email, so they need SMTP.
- **Membership:** whether readers can sign up. Sign-in links are emailed, so they also need SMTP.
- **Newsletters:** Ghost sends bulk newsletters through **Mailgun** only, not through SMTP. To send newsletters, enter a Mailgun domain and API key in Ghost's email newsletter settings. The container reaches Mailgun's API over the internet.

To test mail, invite a staff user with an address you can read, or use **Forgot password** on the sign-in page.

### Change mail settings later

The panel has no form to edit Ghost's environment after install, and Ghost reads its mail settings from that environment. An administrator can install Ghost again with new SMTP values while keeping the content, because the data folder is named after the domain:

1. Make a backup (**Back up now** on the **Backups** card, below).
2. Delete the website, **without** ticking **Also delete all files**. The container is removed, but `/var/lib/zopanel-apps/<instance>/` stays.
3. Install Ghost again on the same domain with the new SMTP values. It starts on the existing content and database. The setup lock is on again: open the app, check that you can sign in, then click **Setup finished — open to everyone**.

**Caution:** Deleting a website also deletes a DNS zone on this server with exactly the same name, and it is refused while an email domain with that name still has mailboxes ("… has N mailboxes: delete its email domain first (Email page)"). This method is therefore simplest when Ghost runs on a subdomain such as `blog.example.com`.

## Data and backups

| What | Where on the server |
| --- | --- |
| Database, images, themes, settings files | `/var/lib/zopanel-apps/<instance>/content/` (mounted at `/var/lib/ghost/content`) |
| SQLite database | `/var/lib/zopanel-apps/<instance>/content/data/ghost.db` |
| Environment file with the SMTP password (root only) | `/var/lib/zopanel-apps/<instance>/.env` |
| Container name | `zp-app-<instance>` |

`<instance>` is the domain with dots replaced by hyphens: `blog.example.com` becomes `blog-example-com`.

**ZoPanel's account backups do not include this folder.** Full account backups and incremental snapshots contain the account's website folders under `/home`, its databases and its mail; Ghost's content is in `/var/lib/zopanel-apps`, outside the account, and is backed up by the **Backups** card on the website's **Docker** tab instead. It also does not count toward the account's disk quota.

To back up Ghost, click **Back up now** on the **Backups** card of the website's **Docker** tab. Administrators can also set a **Schedule** (**Off**, **Every day** or **Every week**; off by default) and how many copies to **Keep** (1–60, default 7), then click **Save**. Each backup archives `/var/lib/zopanel-apps/<instance>/` into `/var/backups/zopanel-apps/<instance>/YYYYMMDD-HHMMSS.tar.gz`, a folder only root can read that does not count toward the account's disk quota. The container is paused (not stopped) for the few seconds of the copy, so the SQLite database is consistent. Older copies beyond **Keep** are removed, and a failed scheduled backup sends administrators the **Backup failed** alert.

To restore, an administrator clicks **Restore** next to a backup. Ghost is stopped and its data replaced with the archive; the current data is kept aside until the restored app starts, and put back if it does not. Changes made since the backup are lost. Each backup also has a delete button (administrators only), and deleting the app together with its files deletes its backups too. Customers can click **Back up now** and see the list; the schedule and restores are done by the provider.

The archives stay on the same server. Copy important ones off it (for example with `scp` or `rclone` from `/var/backups/zopanel-apps/<instance>/`) and store them encrypted, since they contain the SMTP password. To restore on another server, install Ghost on the same domain there, copy the archive into `/var/backups/zopanel-apps/<instance>/` on the new server and click **Restore** on its **Backups** card. This works only when both servers use the same `dockremap` range (`grep dockremap /etc/subuid`).

Ghost's own content export in Ghost Admin (JSON) is a useful second copy, but it does not contain images or themes.

## Update Ghost

Administrators click **Update to latest** on the **Docker** tab: ZoPanel pulls `ghost:5-alpine` again, recreates the container with the same environment and keeps the content folder. Updates stay within Ghost 5. Ghost migrates its database when it starts, so make a backup first (**Back up now**). Customers ask their provider to update.

## Network limits

App containers are cut off from the server's internal network:

- **Mail works.** The container may connect to the server's own public address on ports 25, 465 and 587, and to any mail service on the internet, so a mailbox on this server, Mailgun, Brevo or Amazon SES all work. Use the mail server's public host name, not `localhost` or `127.0.0.1`.
- **No local databases.** Ghost cannot use the server's MySQL/MariaDB or Redis; it keeps SQLite.
- **Integrations and webhooks** to public HTTPS addresses work; targets on private addresses (`10.x`, `192.168.x`, `172.16–31.x`) or the cloud metadata address are refused.

## Troubleshooting

| Symptom or message | What to do |
| --- | --- |
| "the SMTP server must be a host name or IP address" | Enter only the host, for example `mail.example.com`, without `smtp://` or a port. |
| "invalid SMTP port" | Use a number from 1 to 65535, normally `587` or `465`. |
| "invalid sender address" | Enter a plain address such as `blog@example.com`. |
| Browser shows a certificate error or the blog redirects in a loop | SSL is not issued yet. Check that DNS points to the server and issue the certificate on the **SSL** tab. |
| "This website is very busy right now" after install | Ghost is still starting (up to two minutes). The page reloads by itself. |
| Invitations or password-reset emails never arrive | Check **Application output** on the **Docker** tab for mail errors. Usual causes: wrong password, sender different from the SMTP user, port 465 used with a server that expects 587. |
| Newsletter cannot be sent | Configure Mailgun in Ghost's newsletter settings; SMTP is not used for newsletters. |
| "the app did not start listening: …" | Read the log lines in the message, then click **Restart**. A container stopped by the memory limit shows as not running; consider fewer plugins or a larger server. |

## Related

- [App Store and S3 storage](/docs/apps)
- [What each app does](/docs/app-catalog)
- [Email](/docs/email)
- [Backups](/docs/backups)
- [Ghost configuration: mail](https://docs.ghost.org/config/#mail)
- [Ghost supported databases](https://docs.ghost.org/faq/supported-databases)
