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.
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 |
| 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), so ZoPanel uses SQLite.
Before you install
- Point the domain's A record to the server.
- 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.
- 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).
Install Ghost
- 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.
- Fill in the fields below and click Install.
- 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.
- Check the SSL tab: the certificate must be issued before you continue, because Ghost only works on
https://. - On the Docker tab, click Open the app (only for me). Your browser gets a setup cookie (valid 30 days) and opens the blog.
- Go to
https://<domain>/ghost. - 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.
- 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:
- Make a backup (Back up now on the Backups card, below).
- Delete the website, without ticking Also delete all files. The container is removed, but
/var/lib/zopanel-apps/<instance>/stays. - 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
localhostor127.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
- What each app does
- Backups
- Ghost configuration: mail
- Ghost supported databases