How to self-host Ghost on AWS using Lightsail

                How to self-host Ghost on AWS using Lightsail


This post assumes that you are already familiar with the Ghost platform and already have an AWS account.

In this post, I'm going to show you how to set up a Ghost blog using AWS Lightsail. We're using Lightsail instead of EC2 because of the easy-to-use interface and standardized pricing tiers it offers. Cost-wise, Lightsail is a great option as it's free to use for the first three months on it's $3.50, $5, and $10 tiers.

Let's get started.

Create VPS Instance with Ghost install

Once logged in to the AWS console, navigate to Lightsail and click: create instance

Choose Linux/Unix for your instance image along with the Ghost blueprint.

I will be choosing the smallest instance plan for this demo but feel free to choose the best plan to suit your needs. Give your instance a name and click:

Create instance.

Now that your instance is running, we should assign it a static IP. On the homepage of the Lightsail console, navigate to Networking. Once there, click create static IP. Attach it to your instance and click Create.

Navigate back to the instance page. The cool thing about Lightsail is that we can connect using SSH in the browser, so you don't have to use the terminal or a third-party application. Click Connect using SSH.

Inside the terminal, type cat bitnami_application_password to find out your access password. The default user will be

You can navigate to your Ghost site by copying and pasting the static IP of your instance in the address bar. This should look like http://<example-static-ip>. In my case, it is

You should now see your new Ghost site.

Open the admin panel by navigating to http://<example-static-ip/ghost>. In my case, that is Enter your credentials from the ssh session and log in.

Once logged in, it would be best to change the username email & password to something secure and easy for you to remember.

Configure Mailgun email

To update the email configuration details, connect via SSH to the server again. The ghost configuration file location path is:


You can edit it using your favorite text editor, I will use vim. Type the command:

$ vim /opt/bitnami/ghost/config.production.json

and find the lines:

"mail": {
  "transport": "Direct"

Replace those lines with this snippet while using your own user and pass:

"mail": {
  "transport": "SMTP",
  "options": {
		"service": "Mailgun",
		"host": "",
		"port": 587,
		"secureConnection": false,
		"auth": {
		"user": "postmaster@sandbox2b6ff9d855f54e4387ee55962ba5",
		"pass": "d995a43582a6bcff242c67de755df5e1"

Log in to your Mailgun account to get your config details from the dashboard.

After you have updated your email configuration details, restart Ghost by running in your server console:

sudo /opt/bitnami/ restart ghost.

Email newsletter configuration

Retrieve your Mailgun API keys by navigating to the Mailgun Dashboard -> API Keys and copy the key. Head back to your Ghost admin and navigate to Settings -> Email newsletter -> Email newsletter settings and click on expand. Paste the Mailgun Domain and Mailgun API key.

If you want to test if your transactional emails are working, you can select Staff from the Ghost dashboard menu, then in the top right, click on Invite people, to try to send emails through Ghost.

Add CDN (content delivery network)

CDNs help you accelerate the content delivery of your website. This will also help us to set up our SSL certificate so that website is secure and allow us to setup a custom domain name.

To create the CDN, from your Lightsail dashboard, navigate to the Networking tab, and click on Create distribution:

Start by selecting the Ghost server as origin. This means that the traffic that the CDN receives will route to Ghost, which will cache it.

Scroll down to the Caching behavior section, select the option Best for WordPress, then click on the link Show all settings.

Go to Directory and Files overrides section, and delete those two caching behaviors for the folders wp-includes and wp-content. You can do that by clicking on the bin icon to the right.

Focus on the Advanced cache settings section below. This seems to be the only way to access it. Perhaps this will be updated in the future.

Now, click on the edit button next to “...forward the HTTP headers I specify” section and add the options:

X-Forwarded-Proto / X-Forwarded-For.

Press enter after inputting each.

As mentioned below, we’re passing these headers to not get into an SSL redirect loop.

Scroll down to name your distribution and click Create distribution.

On the CDN details screen, you can see that we’re getting a domain name for the distribution in the form of https://****

Let's now use this moment update Ghost to recognize that host as the domain for the blog. To do that, we will connect via SSH into the server, edit our config.production.json, and enter our custom domain name.

Once you have connected to your server by SSH, enter

$ vim /opt/bitnami/ghost/config.production.json

into the command line. In the line where the public URL for the blog is specified, enter your custom domain name. For example, our domain name is

After you have updated your custom domain, restart Ghost by running in your server console sudo /opt/bitnami/ restart ghost.

Enable SSL

We will need to edit Apache’s configuration to pass the headers specified earlier in the CDN. Edit the Apache’s configuration file by running this command in the server terminal:

  sudo vi /opt/bitnami/apache2/conf/httpd.conf

Find this section, and add RequestHeader set X-Forwarded-Proto "https", as shown below:

<IfModule headers_module>
    # Avoid passing HTTP_PROXY environment to CGI's on this or
    # backend servers which have lingering "httpoxy" defects.
    # 'Proxy' request header is undefined by the IETF, not list
    RequestHeader unset Proxy early
    RequestHeader set X-Forwarded-Proto "https"

After updating the domain and SSL config, remember to restart Ghost and Apache:

sudo /opt/bitnami/ restart ghost
sudo /opt/bitnami/ restart apache

Set up a custom domain.

Head to the Lightsail dashboard, select the Networking tab, then click on your CDN-Ghost distribution, and select the Custom domains tab.

As you can see, the toggle to enable your custom domain is disabled because we don’t have a valid SSL certificate, and we're enforcing SSL traffic through the CDN. Click Create a certificate and then enter the domain name that you want to use, and click on the Create button.

We have to validate that we own the domain name, so we must add an entry to our DNS table in the registrar of where we registered the domain. This could be different depending on which domain provider you have, but it’s pretty much going to be the same across all registrars. You will add a CNAME entry, as shown below:

After you create the CNAME entry, the domain will be valid but not in use. Press the switch that will enable your domain so we can associate the custom domain to the CDN now.

Create another CNAME entry from the domain name to CloudFront. In my case, it’d be something like: | CNAME ********

Now you can navigate to your domain, which will be secured by HTTPS with a powerful CDN to handle an influx of traffic!


Now you're all ready to launch! This is a great way to host a Ghost blog for an affordable monthly price. This setup will require maintenance and you will have to update it yourself with every new Ghost version that is released.

Great! Check your inbox and click the link.
Sorry, something went wrong. Please try again.