add Ghost starter (#105)

* add ghost starter

* add missing newline
This commit is contained in:
Faraz Patankar
2021-05-21 10:47:38 +04:00
committed by GitHub
parent 149752cb26
commit cd424471b6
11 changed files with 8086 additions and 0 deletions

1
examples/ghost/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
node_modules/

View File

@@ -0,0 +1 @@
{}

2
examples/ghost/.profile Normal file
View File

@@ -0,0 +1,2 @@
# Generate config.production.json file in the root dir.
bin/create-config

32
examples/ghost/README.md Normal file
View File

@@ -0,0 +1,32 @@
---
title: Ghost
description: A self-hosted version of Ghost using a MySQL database
tags:
- ghost
- mysql
---
# Ghost example
This example deploys self-hosted version of [Ghost](https://ghost.org/). Internally it uses a MySQL database to store the data.
[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/new/template?template=https%3A%2F%2Fgithub.com%2Frailwayapp%2Fexamples%2Ftree%2Fmaster%2Fexamples%2Fghost&plugins=mysql&envs=CLOUDINARY_URL%2CMAILGUN_SMTP_LOGIN%2CMAILGUN_SMTP_PASSWORD&optionalEnvs=CLOUDINARY_URL%2CMAILGUN_SMTP_LOGIN&CLOUDINARY_URLDesc=For+file+storage.+If+you+do+not+add+this%2C+your+images+won%27t+persist+between+deploys)
## ✨ Features
- Ghost
- MySQL
## 💁‍♀️ How to use
- Click the Railway button 👆
- Add the environment variables
- If you do not add the `CLOUDINARY_URL` environment variable, your images/files will not be persisted between deploys.
- Add the `MAILGUN_SMTP_LOGIN` and `MAILGUN_SMTP_PASSWORD` variables if you want to invite users to your admin panel or send emails to your subscribers when you publish a new post.
## 📝 Notes
- Railway's filesystem is ephemeral which is why any changes to the filesystem are not persisted between deploys. This is why, this example uses Cloudinary for storage.
- The above limitation also affects the way themes work with Ghost, we use the `bin/themes.sh` script to copy over the themes every time you deploy. That way, the theme is always present.
- To add a theme, first add the package as a dependency to the `package.json` file and then add it to the list of themes in the `bin/themes.sh` file.
- Do NOT add a theme directly using the Ghost UI, it will look like it worked but will break whenever you deploy your app again.

View File

@@ -0,0 +1,30 @@
#!/usr/bin/env node
/*
Ghost internally uses the `mysql` library which does not support the `caching_sha2_password`
authentication method and hence does not work properly with MySQL 8.
So we use this function to tell MySQL to authenticate our user using the
`mysql_native_password` method by using the `mysql2` library which then allows Ghost to use
our database with that same authentication method.
*/
var mysql = require("mysql2");
alterAuthenticationMethod();
function alterAuthenticationMethod() {
var connection = mysql.createConnection(process.env.MYSQL_URL);
connection.query(
"ALTER USER `root`@`%` IDENTIFIED WITH mysql_native_password BY ?",
[process.env.MYSQLPASSWORD],
function (err, results, fields) {
if (err)
console.log("There was an error altering the authentication method.");
connection.end(function (err) {
if (err) console.log("There was an error closing the connection.");
});
}
);
}

View File

@@ -0,0 +1,2 @@
mkdir -p ./content/adapters/storage
cp -r ./node_modules/ghost-storage-cloudinary ./content/adapters/storage/cloudinary

View File

@@ -0,0 +1,86 @@
#!/usr/bin/env node
/*
This file creates and writes our production config after the build has been completed.
Make changes here if you want to use a different image storage service or email provider.
*/
var fs = require("fs");
var path = require("path");
var appRoot = path.join(__dirname, "..");
function createConfig() {
var fileStorage, storage;
if (process.env.CLOUDINARY_URL) {
console.log("CLOUDINARY_URL found, setting storage to cloudinary");
fileStorage = true;
storage = {
active: "cloudinary",
cloudinary: {
useDatedFolder: false,
upload: {
use_filename: true,
unique_filename: false,
overwrite: false,
folder: "ghost-blog-images",
tags: ["blog"],
},
fetch: {
quality: "auto",
secure: true,
cdn_subdomain: true,
},
},
};
} else {
console.log("CLOUDINARY_URL not found, setting storage to false");
fileStorage = false;
storage = {};
}
config = {
url: "https://" + process.env.RAILWAY_STATIC_URL,
logging: {
level: "info",
transports: ["stdout"],
},
mail: {
transport: "SMTP",
options: {
service: "Mailgun",
auth: {
user: process.env.MAILGUN_SMTP_LOGIN,
pass: process.env.MAILGUN_SMTP_PASSWORD,
},
},
},
fileStorage: fileStorage,
storage: storage,
database: {
client: "mysql",
connection: {
host: process.env.MYSQLHOST,
port: process.env.MYSQLPORT,
user: process.env.MYSQLUSER,
password: process.env.MYSQLPASSWORD,
database: process.env.MYSQLDATABASE,
},
pool: { min: 0, max: 5 },
debug: false,
},
server: {
host: "0.0.0.0",
port: process.env.PORT,
},
paths: {
contentPath: path.join(appRoot, "/content/"),
},
};
return config;
}
var configContents = JSON.stringify(createConfig(), null, 2);
fs.writeFileSync(path.join(appRoot, "config.production.json"), configContents);

10
examples/ghost/bin/themes.sh Executable file
View File

@@ -0,0 +1,10 @@
themes=(
casper
lyra
)
mkdir -p content/themes/
for theme in "${themes[@]}"
do
cp -Rf "node_modules/$theme" content/themes/$theme
done

1
examples/ghost/index.js Normal file
View File

@@ -0,0 +1 @@
var ghost = require("ghost");

View File

@@ -0,0 +1,22 @@
{
"name": "ghost",
"version": "0.0.1",
"description": "Deploy Ghost v4 on Railway",
"main": "index.js",
"author": "farazpatankar",
"license": "MIT",
"engines": {
"node": "12.X"
},
"dependencies": {
"casper": "github:TryGhost/Casper#main",
"ghost": "^4.3.3",
"ghost-storage-cloudinary": "^2.1.5",
"lyra": "github:TryGhost/lyra#master",
"mysql2": "^2.2.5"
},
"scripts": {
"start": "node index.js",
"postinstall": "bin/alter-auth-method && bash bin/cloudinary.sh && bash bin/themes.sh"
}
}

7899
examples/ghost/yarn.lock Normal file

File diff suppressed because it is too large Load Diff