Ghost
Overview
Ghost is an open source publishing platform for blogs, newsletters and membership sites. This SecureAnyCloud image runs Ghost behind nginx, with Node.js 22 LTS and MySQL 8 on the same instance, so you can publish as soon as the instance boots.
Credentials are generated on the first boot of every instance. Two instances launched from the same Amazon Machine Image never share passwords.
What you get:
- Ghost with Node.js 22 LTS and MySQL 8 on a single instance
- The Ghost process on 127.0.0.1:2368, with nginx reverse proxying port 80 to it
- Site content, members and posts stored in MySQL, bound to the loopback interface only
- Administrator and MySQL credentials generated on first boot: the initial administrator email, the administrator password and the MySQL password are written to
/root/ghost-credentials.txtwith mode 0600, readable only by root - Ghost configured to accept requests on any host, so the site works on whatever public DNS name or IP address visitors use
- Ghost-CLI installed, so upgrades, backups and configuration changes follow the standard Ghost workflows
- 24/7 SecureAnyCloud support
Prerequisites
Before you deploy this image, make sure you have:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group that allows inbound port 22 from your management network and inbound ports 80 and 443 from the networks your visitors use
- The AWS CLI (version 2) installed locally, if you plan to deploy from the command line
Launch the Instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service and select Launch instance. Under Application and OS Images, choose AWS Marketplace AMIs and search for Ghost Publishing Platform. Select the SecureAnyCloud listing, choose Select, then choose Continue on the subscription summary.
Choose an instance type of m5.large or larger, which gives Node.js and MySQL room to work. Choose your EC2 key pair under Key pair (login). Under Network settings, select your VPC and subnet, then create or select a security group that allows inbound port 22 from your management network and inbound ports 80 and 443 from your visitors' networks. Leave the root volume at the default size or larger.
Select Launch instance. First-boot initialisation takes about one minute after the instance state becomes Running and the status checks pass.
Launch the Instance from the AWS CLI
Run the command below to launch an instance from the SecureAnyCloud Ghost Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing and <key-name> with your EC2 key pair name. Replace <subnet-id> with your subnet ID and <security-group-id> with a security group that opens ports 22, 80 and 443.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":30,"VolumeType":"gp3"}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=ghost-01}]'On success the command prints a JSON document. Note the instance ID. When the instance is running, retrieve its public address with aws ec2 describe-instances --instance-ids <instance-id> --query "Reservations[].Instances[].PublicIpAddress" --output text.
Connect and Retrieve Initial Credentials
Connect over SSH with the key pair you selected and the instance's public IP address. The login user depends on the AMI variant you launched. For the Ghost 6 on Ubuntu 24.04 AMI, the SSH login user is ubuntu.
The first-boot service runs before the SSH daemon is ready, so the credentials file is already in place when you first log in.
ssh <login-user>@<public-ip>
sudo cat /root/ghost-credentials.txtThe plain text file lists the Ghost admin URL, the administrator email (sac-admin@<public-ip>), the administrator password, and the MySQL database name, user and password. Copy these values to a password manager or encrypted vault. Do not commit them to source control.
From the same SSH session, confirm that the deployment is healthy:
curl -fsS -o /dev/null -w 'Ghost front page HTTP %{http_code}\n' http://127.0.0.1/A Ghost front page HTTP 200 response confirms that the full stack (nginx, Node.js with Ghost, and MySQL) is serving requests.
Sign In to Ghost Admin
Open a browser and go to http://<public-ip>/ghost/. Ghost shows the admin sign-in form.
Enter the administrator email and password from /root/ghost-credentials.txt, then select Sign in. The public site is at http://<public-ip>/.
Explore the Ghost Admin Dashboard
After you sign in, Ghost opens the admin dashboard, the home of all editorial and configuration work. The left-hand menu lists every management area:
- Posts and Pages for content
- Tags for organising posts
- Members for your audience
- Site (Design, Navigation, Code injection) for theme work
- Settings for global configuration
The dashboard shows traffic, recent posts and member activity. Use Settings to configure outbound mail, members, integrations and the site title.
Change the Administrator Password and Email
For a production deployment, replace the administrator password generated on first boot and set a real administrator email. This makes sure password recovery and system notifications reach you.
Select your avatar at the bottom left of the admin and choose Your profile. Update the email address at the top, then scroll down and use Change password to set a new password. Select Save.
Write Your First Post
Ghost organises content as posts, pages and tags. Open Posts and select New post. Give the post a title, write the body in the editor and add tags from the right-hand sidebar. Select Publish at the top right to schedule the post or publish it immediately.
The editor supports rich text, images, embeds, code blocks, bookmark cards, galleries and HTML cards out of the box. Once published, the post appears on the public site at http://<public-ip>/.
View the Public Site
Browse to http://<public-ip>/ to see the public Ghost site. Ghost ships with the Source theme by default, a clean, fast theme that suits blogs, newsletters and editorial publications.
To switch themes, go to Settings, then Design, then Change theme. There you can upload any Ghost-compatible theme zip or pick one from the marketplace built into Ghost.
Configure Outbound Email
Ghost uses Mailgun to send newsletters and member emails. It uses a separate SMTP provider for transactional mail such as welcome and password-reset messages. For newsletters, open Settings, then Email newsletter.
The documentation at https://ghost.org/docs/config/mail/ covers both Mailgun and the transactional mail config block in /var/www/ghost/config.production.json. To configure transactional mail, edit that file:
sudo nano /var/www/ghost/config.production.jsonSet the mail object to use your SMTP provider (common choices are Amazon SES, SendGrid, Postmark and Mailgun), then restart Ghost:
sudo systemctl restart ghost_sac.serviceEnable HTTPS with Let's Encrypt
For any production Ghost deployment, serve the site over HTTPS so that session cookies and authentication tokens cannot be intercepted. The image ships with nginx, which certbot can configure automatically.
These commands assume a DNS record already points your fully qualified domain name at the instance's public IP address.
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d ghost.your-domain.example \
--non-interactive --agree-tos -m you@your-domain.example \
--redirectWhen certbot finishes, set the Ghost url field in /var/www/ghost/config.production.json to your HTTPS URL and restart Ghost:
sudo sed -i 's#"url": "http://[^"]*"#"url": "https://ghost.your-domain.example"#' /var/www/ghost/config.production.json
sudo systemctl restart ghost_sac.serviceBackups and Maintenance
Back up two data sources together: the MySQL database, and the site files in /var/www/ghost (the Ghost code tree, themes and uploaded content under content/).
sudo mysqldump --single-transaction ghost_prod > /var/backups/ghost-db-$(date +%F).sql
sudo tar --acls --xattrs -czf /var/backups/ghost-files-$(date +%F).tgz -C /var/www ghostCopy both files to an Amazon S3 bucket or another object store.
Ubuntu's unattended-upgrades is enabled by default, so security patches for the kernel and packages apply automatically. To update Ghost itself, use Ghost-CLI:
sudo -u ghost HOME=/tmp bash -c "cd /var/www/ghost && ghost update"Ghost-CLI downloads the new version, migrates the schema and restarts the process in one command.
Scaling Beyond a Single Instance
For larger deployments, move Ghost off the single-instance layout:
- Move MySQL to Amazon RDS for MySQL and update
database.connectionin/var/www/ghost/config.production.json - Put the Ghost web tier behind an Application Load Balancer and scale horizontally with an Auto Scaling group, with the
content/directory on Amazon EFS shared storage - Serve static assets and uploaded media through Amazon CloudFront
- Use Amazon SES for transactional and bulk mail through Ghost's SMTP configuration
The official Ghost documentation at https://ghost.org/docs/ covers each of these.
Screenshots
The Ghost admin sign-in page, available on first boot with no manual setup.
The Ghost admin dashboard after first sign-in.
Composing a post in the Ghost editor.
The published Ghost front page, served on port 80.
Support
SecureAnyCloud provides 24/7/365 expert technical support for this image. Guaranteed response within 24 hours, one hour average for critical issues. Contact sales@secureanycloud.com.
For general Ghost administration questions consult the community at https://forum.ghost.org/ and the documentation at https://ghost.org/docs/.
Deploy on AWS
Launch Ghost Publishing Platform on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com