<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Thomas van Latum</title>
    <description>The latest articles on DEV Community by Thomas van Latum (@thomasvl).</description>
    <link>https://dev.to/thomasvl</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F93098%2F55ade9df-c393-4f8f-9f95-cec1b56cb54e.png</url>
      <title>DEV Community: Thomas van Latum</title>
      <link>https://dev.to/thomasvl</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thomasvl"/>
    <language>en</language>
    <item>
      <title>Ghost blog on App Engine</title>
      <dc:creator>Thomas van Latum</dc:creator>
      <pubDate>Mon, 29 Apr 2019 06:00:00 +0000</pubDate>
      <link>https://dev.to/thomasvl/ghost-blog-on-app-engine-9nh</link>
      <guid>https://dev.to/thomasvl/ghost-blog-on-app-engine-9nh</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fvanlatum-dev-images%2F2019%2F04%2FBlog1-1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fvanlatum-dev-images%2F2019%2F04%2FBlog1-1.jpg" alt="Ghost blog on App Engine"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this blog we will explore how to host a Ghost blog on Google App Engine.&lt;/p&gt;

&lt;p&gt;App Engine is a very scalable and reliable system but it comes with a couple of things you need to consider. For example you can't store files or images in App Engine because your blog runs in containers. But we can serve those files from Google Cloud Storage with a custom storage adapter.&lt;/p&gt;

&lt;p&gt;Because the current cloud platform storage adapter does not seem to work with the most recent version of ghost I wrote up a storage adapter that works with Google Cloud Platform: &lt;a href="https://github.com/thomas-vl/ghost-gcs" rel="noopener noreferrer"&gt;https://github.com/thomas-vl/ghost-gcs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You also can't use the sqlite3 database so you need a public accessible mysql database. If you have a webhosting with direct admin you can add '%' to the list of Access Hosts to make it public available.&lt;/p&gt;

&lt;p&gt;Let's jump in and build our ghost blog!&lt;/p&gt;

&lt;p&gt;Pre requisites:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start by &lt;a href="https://console.cloud.google.com/projectcreate" rel="noopener noreferrer"&gt;creating a project&lt;/a&gt; on Google Cloud Platform.&lt;/li&gt;
&lt;li&gt;Create a &lt;a href="https://console.cloud.google.com/storage/create-bucket" rel="noopener noreferrer"&gt;storage bucket&lt;/a&gt; to store your images.&lt;/li&gt;
&lt;li&gt;Create a &lt;a href="https://console.cloud.google.com/iam-admin/serviceaccounts/create" rel="noopener noreferrer"&gt;service account&lt;/a&gt;
a. Give your service account a name and click create.
b. Add the Storage Admin role to your service account.
c. Generate a json key by clicking Create Key and Create&lt;/li&gt;
&lt;li&gt;Download and install &lt;a href="https://cloud.google.com/sdk/" rel="noopener noreferrer"&gt;gcloud&lt;/a&gt; on your machine&lt;/li&gt;
&lt;li&gt;Make sure you have a mysql on your own hosting or &lt;a href="https://console.cloud.google.com/sql/create-instance-mysql" rel="noopener noreferrer"&gt;cloud SQL&lt;/a&gt; database on GCP&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Building your app:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create an empty directory on your machine&lt;/li&gt;
&lt;li&gt;Create 'app.yaml' with the following content
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;runtime: custom
env: flex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create 'Dockerfile' with the following content
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM ghost

COPY config.production.json /var/lib/ghost/config.production.json

#install the google cloud storage adapter
WORKDIR /var/lib/ghost
COPY credentials.json /var/lib/ghost/credentials.json
RUN npm install ghost-gcs --no-save 
WORKDIR /var/lib/ghost/content/adapters/storage/ghost-gcs/
ADD https://raw.githubusercontent.com/thomas-vl/ghost-gcs/master/export.js index.js

WORKDIR /var/lib/ghost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create 'config.production.json' with the following content
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "url": "{appengine url}",
    "server": {
      "port": 8080,
      "host": "0.0.0.0"
    },
    "database": {
      "client": "mysql",
      "connection": {
        "host": "{db ip}",
        "port": "{db port}",
        "user": "{db user}",
        "password": "{db password}",
        "database": "{db name}"
      }
    },
    "mail": {
      "transport": "Direct"
    },
    "logging": {
      "transports": [
        "file",
        "stdout"
      ]
    },
    "process": "systemd",
    "paths": {
      "contentPath": "/var/lib/ghost/content"
    },
    "storage": {
        "active": "ghost-gcs",
        "ghost-gcs": {
            "key": "credentials.json",
            "bucket": "{bucket name}"
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Change the following parameters:&lt;br&gt;
a. {appengine url} - usually &lt;a href="https://your-project-id.appspot.com" rel="noopener noreferrer"&gt;https://your-project-id.appspot.com&lt;/a&gt;&lt;br&gt;
b. {db ip} - your mysql database ip address&lt;br&gt;
c. {db port} - usually 3306&lt;br&gt;
d. {db user} - your mysql user&lt;br&gt;
e. {db password} - your mysql password&lt;br&gt;
f. {db name} - your msql database name&lt;br&gt;
g. {bucket name} - the full name of the bucket created in the prerequisites&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you move the downloaded service account credentials file to your current directory and rename it to credentials.json&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In Terminal or PowerShell go to the created directory and run the following command&lt;br&gt;&lt;br&gt;
&lt;code&gt;gcloud app deploy&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Enjoy blogging on your self hosted ghost blog!&lt;/p&gt;

</description>
      <category>appengine</category>
      <category>ghost</category>
    </item>
  </channel>
</rss>
