commit
6d41e9ac2f
19 changed files with 11116 additions and 0 deletions
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
node_modules/
|
||||
npm-debug.log*
|
||||
|
||||
content/data/*.db
|
||||
content/logs/
|
||||
config.production.json
|
||||
content/data/ghost-local.db
|
||||
|
||||
content/themes/*
|
||||
!content/themes/.gitkeep
|
2
.profile
Normal file
2
.profile
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Generate the Ghost JSON config file when Heroku dyno starts-up.
|
||||
bin/create-config
|
45
LICENSE
Normal file
45
LICENSE
Normal file
|
@ -0,0 +1,45 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Coby Chapple
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 Swastik Nath
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
1
Procfile
Normal file
1
Procfile
Normal file
|
@ -0,0 +1 @@
|
|||
web: npm start --production
|
138
README.md
Normal file
138
README.md
Normal file
|
@ -0,0 +1,138 @@
|
|||
# [Ghost 2.X](https://github.com/TryGhost/Ghost) on [Heroku](http://heroku.com)
|
||||
|
||||
Ghost is a free, open, simple blogging platform. Visit the project's website at <http://ghost.org>, or read the docs on <http://support.ghost.org>.
|
||||
|
||||
[![GitHub issues](https://img.shields.io/github/issues/SNathJr/ghost-on-heroku)](https://github.com/SNathJr/ghost-on-heroku/issues)
|
||||
[![GitHub forks](https://img.shields.io/github/forks/SNathJr/ghost-on-heroku)](https://github.com/SNathJr/ghost-on-heroku/network)
|
||||
[![GitHub stars](https://img.shields.io/github/stars/SNathJr/ghost-on-heroku)](https://github.com/SNathJr/ghost-on-heroku/stargazers)
|
||||
|
||||
## Disclaimer
|
||||
|
||||
This is a fork with some improvements from https://github.com/cobyism/ghost-on-heroku. I have forked and improved this repository as the original developer seemed to have abandoned his repo recently. In this repository I have upgraded ghost to ghost 2.X and added cloudinary as a free storage alternative to amazon's s3. If you are still interested with the ghost 1.0 version please visit the original repository.
|
||||
|
||||
## Ghost version 2.X
|
||||
|
||||
The latest release of Ghost is now supported! Changes include:
|
||||
|
||||
* Requires MySQL database, available through either of two add-ons:
|
||||
* [JawsDB](https://elements.heroku.com/addons/jawsdb) (deploy default)
|
||||
* [ClearDB](https://elements.heroku.com/addons/cleardb)
|
||||
* `PUBLIC_URL` config var renamed to `APP_PUBLIC_URL` to give it alphabetical precedence
|
||||
* The app is configured to use `Cloudinary File Storage` by default.
|
||||
|
||||
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)
|
||||
|
||||
### step-by-step tutorial
|
||||
|
||||
The following video is a step by step tutorial:
|
||||
|
||||
[![thumbnail](https://img.youtube.com/vi/cODvhXMHgYI/0.jpg)](https://www.youtube.com/watch?v=cODvhXMHgYI)
|
||||
|
||||
### Things you should know
|
||||
|
||||
After deployment,
|
||||
- First, visit Ghost at `https://YOURAPPNAME.herokuapp.com/ghost` to set up your admin account
|
||||
- The app may take a few minutes to come to life
|
||||
- Your blog will be publicly accessible at `https://YOURAPPNAME.herokuapp.com`
|
||||
- If you subsequently set up a [custom domain](https://devcenter.heroku.com/articles/custom-domains) for your blog, you’ll need to update your Ghost blog’s `APP_PUBLIC_URL` environment variable accordingly
|
||||
- If you create a lot of content or decide to scale-up the dynos to support more traffic, a more substantial, paid database plan will be required.
|
||||
|
||||
#### 🚫🔻 Do not scale-up beyond a single dyno
|
||||
|
||||
[Ghost does not support multiple processes.](https://docs.ghost.org/faq/clustering-sharding-multi-server/)
|
||||
|
||||
If your Ghost app needs to support substantial traffic, then use a CDN add-on:
|
||||
|
||||
* [Fastly](https://elements.heroku.com/addons/fastly)
|
||||
* [Edge](https://elements.heroku.com/addons/edge).
|
||||
|
||||
#### Configuring S3 file uploads
|
||||
|
||||
The blog is configured to use Cloudinary file storage by default. If you want to configure S3 file storage, create an S3 bucket on Amazon AWS, and then specify the following details as environment variables on the Heroku deployment page (or add these environment variables to your app after deployment via the Heroku dashboard):
|
||||
|
||||
- `S3_ACCESS_KEY_ID` and `S3_ACCESS_SECRET_KEY`: **Required if using S3 uploads**. These fields are the AWS key/secret pair needed to authenticate with Amazon S3. You must have granted this keypair sufficient permissions on the S3 bucket in question in order for S3 uploads to work.
|
||||
|
||||
- `S3_BUCKET_NAME`: **Required if using S3 uploads**. This is the name you gave to your S3 bucket.
|
||||
|
||||
- `S3_BUCKET_REGION`: **Required if using S3 uploads**. Specify the region the bucket has been created in, using slug format (e.g. `us-east-1`, `eu-west-1`). A full list of S3 regions is [available here](http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region).
|
||||
|
||||
- `S3_ASSET_HOST_URL`: Optional, even if using S3 uploads. Use this variable to specify the S3 bucket URL in virtual host style, path style or using a custom domain. You should also include a trailing slash (example `https://my.custom.domain/`). See [this page](http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html) for details.
|
||||
|
||||
Once your app is up and running with these variables in place, you should be able to upload images via the Ghost interface and they’ll be stored in Amazon S3. :sparkles:
|
||||
|
||||
##### Provisioning an S3 bucket using an add-on
|
||||
|
||||
If you’d prefer not to configure S3 manually, you can provision the [Bucketeer add-on](https://devcenter.heroku.com/articles/bucketeer)
|
||||
to get an S3 bucket (Bucketeer starts at $5/mo).
|
||||
|
||||
To configure S3 via Bucketeer, leave all the S3 deployment fields blank and deploy your
|
||||
Ghost blog. Once your blog is deployed, run the following commands from your terminal:
|
||||
|
||||
```bash
|
||||
# Provision an Amazon S3 bucket
|
||||
heroku addons:create bucketeer --app YOURAPPNAME
|
||||
|
||||
# Additionally, the bucket's region must be set to formulate correct URLs
|
||||
# (Find the "Region" in your Bucketeer Add-on's web dashboard.)
|
||||
heroku config:set S3_BUCKET_REGION=us-east-1 --app YOURAPPNAME
|
||||
```
|
||||
|
||||
### How this works
|
||||
|
||||
This repository is a [Node.js](https://nodejs.org) web application that specifies Ghost as a dependency, and makes a deploy button available.
|
||||
|
||||
* Ghost and Casper theme versions are declared in the Node app's [`package.json`](package.json)
|
||||
* Versions are locked and managed using [yarn](https://yarnpkg.com)
|
||||
* Scales across processor cores in larger dynos via [Node cluster API](https://nodejs.org/dist/latest-v10.x/docs/api/cluster.html)
|
||||
|
||||
## Updating source code
|
||||
|
||||
Optionally after deployment, to push Ghost upgrades or work with source code, clone this repo (or a fork) and connect it with the Heroku app:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/snathjr/ghost-on-heroku
|
||||
cd ghost-on-heroku
|
||||
|
||||
heroku git:remote -a YOURAPPNAME
|
||||
heroku info
|
||||
```
|
||||
|
||||
Then you can push commits to the Heroku app, triggering new deployments:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "Important changes"
|
||||
git push heroku master
|
||||
```
|
||||
|
||||
Watch the app's server-side behavior to see errors and request traffic:
|
||||
|
||||
```bash
|
||||
heroku logs -t
|
||||
```
|
||||
|
||||
See more about [deploying to Heroku with git](https://devcenter.heroku.com/articles/git).
|
||||
|
||||
### Upgrading Ghost
|
||||
|
||||
This repository locks Ghost to the "last tested good version" using the standard `yarn.lock` file. If you want to upgrade Ghost on your own,
|
||||
you will need to clone or fork this repo as described above. You will then be able to run:
|
||||
|
||||
```bash
|
||||
yarn upgrade ghost
|
||||
git add package.json yarn.lock
|
||||
git commit -m 'Update dependencies'
|
||||
git push heroku master
|
||||
```
|
||||
|
||||
If you're worried about packages beyond the root `ghost` server being outdated, you can check using `yarn outdated`.
|
||||
|
||||
## Problems?
|
||||
|
||||
If you have problems using your instance of Ghost, you should check the [official documentation](http://support.ghost.org/) or
|
||||
open an issue on [the official issue tracker](https://github.com/TryGhost/Ghost/issues). If you discover an issue with the
|
||||
deployment process provided by *this repository*, then [open an issue here](https://github.com/snathjr/ghost-on-heroku).
|
||||
|
||||
## License
|
||||
|
||||
Released under the [MIT license](./LICENSE), just like the Ghost project itself.
|
41
app.json
Normal file
41
app.json
Normal file
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"name": "Ghost on Heroku",
|
||||
"description": "Just a blogging platform",
|
||||
"logo": "https://cdn.rawgit.com/TryGhost/Ghost-Admin/61fe83dff375a145d5272a5382aa2c72bd994830/public/assets/img/large.png",
|
||||
"repository": "https://github.com/snathjr/ghost-on-heroku",
|
||||
"scripts": {
|
||||
"postdeploy": "bin/init-deployment"
|
||||
},
|
||||
"success_url": "/ghost",
|
||||
"addons": [
|
||||
"jawsdb",
|
||||
"mailgun",
|
||||
"cloudinary"
|
||||
],
|
||||
"env": {
|
||||
"APP_PUBLIC_URL": {
|
||||
"description": "The HTTPS URL of this app: either your custom domain or default 'herokuapp.com' hostname.",
|
||||
"value": "https://YOURAPPNAME.herokuapp.com"
|
||||
},
|
||||
"S3_ACCESS_KEY_ID": {
|
||||
"description": "(Optional) Set your AWS Access Key ID to enable S3 file storage. Defaults to Cloudinary storage",
|
||||
"required": false
|
||||
},
|
||||
"S3_ACCESS_SECRET_KEY": {
|
||||
"description": "AWS Access Secret Key, if using S3 file storage.",
|
||||
"required": false
|
||||
},
|
||||
"S3_BUCKET_NAME": {
|
||||
"description": "Name of your S3 bucket on AWS, if using S3 file storage.",
|
||||
"required": false
|
||||
},
|
||||
"S3_BUCKET_REGION": {
|
||||
"description": "Region of your S3 bucket on AWS, if using S3 file storage.",
|
||||
"required": false
|
||||
},
|
||||
"S3_ASSET_HOST_URL": {
|
||||
"description": "Optional custom CDN asset host url, if using S3 file storage.",
|
||||
"required": false
|
||||
}
|
||||
}
|
||||
}
|
3
bin/common/env-values.js
Normal file
3
bin/common/env-values.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
mysqlDatabaseUrl: process.env.MYSQL_DATABASE_URL || process.env.JAWSDB_URL || process.env.CLEARDB_DATABASE_URL
|
||||
}
|
14
bin/copy-themes.sh
Normal file
14
bin/copy-themes.sh
Normal file
|
@ -0,0 +1,14 @@
|
|||
themes=(
|
||||
casper
|
||||
attila
|
||||
london
|
||||
massively
|
||||
bleak
|
||||
the-shell
|
||||
vapor
|
||||
)
|
||||
|
||||
for theme in "${themes[@]}"
|
||||
do
|
||||
cp -Rf "node_modules/$theme" content/themes
|
||||
done
|
130
bin/create-config
Executable file
130
bin/create-config
Executable file
|
@ -0,0 +1,130 @@
|
|||
#!/usr/bin/env node
|
||||
// Ghost Configuration for Heroku
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var url = require('url');
|
||||
|
||||
var envValues = require('./common/env-values');
|
||||
var appRoot = path.join(__dirname, '..');
|
||||
|
||||
function createConfig() {
|
||||
var fileStorage, storage;
|
||||
|
||||
if (!!process.env.S3_ACCESS_KEY_ID) {
|
||||
fileStorage = true
|
||||
storage = {
|
||||
active: 's3',
|
||||
's3': {
|
||||
accessKeyId: process.env.S3_ACCESS_KEY_ID,
|
||||
secretAccessKey: process.env.S3_ACCESS_SECRET_KEY,
|
||||
bucket: process.env.S3_BUCKET_NAME,
|
||||
region: process.env.S3_BUCKET_REGION,
|
||||
assetHost: process.env.S3_ASSET_HOST_URL
|
||||
}
|
||||
}
|
||||
} else if (!!process.env.BUCKETEER_AWS_ACCESS_KEY_ID) {
|
||||
fileStorage = true
|
||||
storage = {
|
||||
active: 's3',
|
||||
's3': {
|
||||
accessKeyId: process.env.BUCKETEER_AWS_ACCESS_KEY_ID,
|
||||
secretAccessKey: process.env.BUCKETEER_AWS_SECRET_ACCESS_KEY,
|
||||
bucket: process.env.BUCKETEER_BUCKET_NAME,
|
||||
region: process.env.S3_BUCKET_REGION,
|
||||
assetHost: process.env.S3_ASSET_HOST_URL
|
||||
}
|
||||
}
|
||||
} else if (!!process.env.CLOUDINARY_URL) {
|
||||
fileStorage = true
|
||||
storage = {
|
||||
active: 'ghost-storage-cloudinary',
|
||||
'ghost-storage-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 {
|
||||
fileStorage = false
|
||||
storage = {}
|
||||
}
|
||||
|
||||
config = {
|
||||
url: process.env.APP_PUBLIC_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: getMysqlConfig(envValues.mysqlDatabaseUrl),
|
||||
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;
|
||||
}
|
||||
|
||||
function getMysqlConfig(connectionUrl) {
|
||||
if (connectionUrl == null) {
|
||||
return {};
|
||||
}
|
||||
|
||||
var dbConfig = url.parse(connectionUrl);
|
||||
if (dbConfig == null) {
|
||||
return {};
|
||||
}
|
||||
|
||||
var dbAuth = dbConfig.auth ? dbConfig.auth.split(':') : [];
|
||||
var dbUser = dbAuth[0];
|
||||
var dbPassword = dbAuth[1];
|
||||
|
||||
if (dbConfig.pathname == null) {
|
||||
var dbName = 'ghost';
|
||||
} else {
|
||||
var dbName = dbConfig.pathname.split('/')[1];
|
||||
}
|
||||
|
||||
var dbConnection = {
|
||||
host: dbConfig.hostname,
|
||||
port: dbConfig.port || '3306',
|
||||
user: dbUser,
|
||||
password: dbPassword,
|
||||
database: dbName
|
||||
};
|
||||
return dbConnection;
|
||||
}
|
||||
|
||||
var configContents = JSON.stringify(createConfig(), null, 2);
|
||||
fs.writeFileSync(path.join(appRoot, 'config.production.json'), configContents);
|
11
bin/init-deployment
Executable file
11
bin/init-deployment
Executable file
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
echo "Initializing the deployment…"
|
||||
echo "pwd →"
|
||||
pwd
|
||||
echo "config.production.json →"
|
||||
cat "config.production.json"
|
||||
|
||||
bin/wait-for-db
|
||||
|
||||
knex-migrator init --mgpath node_modules/ghost
|
21
bin/wait-for-db
Executable file
21
bin/wait-for-db
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
var mysql = require('mysql');
|
||||
var envValues = require('./common/env-values');
|
||||
|
||||
console.error(`Awaiting MySQL database…`);
|
||||
pingDatabaseUntilConnected();
|
||||
|
||||
function pingDatabaseUntilConnected() {
|
||||
var connection = mysql.createConnection(envValues.mysqlDatabaseUrl);
|
||||
connection.query('SELECT 1', function (error, results, fields) {
|
||||
if (error) {
|
||||
console.error(`Database not yet available: ${error.message}`);
|
||||
setTimeout(pingDatabaseUntilConnected, 5000);
|
||||
} else {
|
||||
console.error('Database connected.');
|
||||
connection.end();
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
}
|
26
config.development.json
Normal file
26
config.development.json
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"url": "http://localhost:2368/",
|
||||
"server": {
|
||||
"port": 2368,
|
||||
"host": "127.0.0.1"
|
||||
},
|
||||
"database": {
|
||||
"client": "sqlite3",
|
||||
"connection": {
|
||||
"filename": "content/data/ghost-local.db"
|
||||
}
|
||||
},
|
||||
"mail": {
|
||||
"transport": "Direct"
|
||||
},
|
||||
"logging": {
|
||||
"transports": [
|
||||
"file",
|
||||
"stdout"
|
||||
]
|
||||
},
|
||||
"process": "local",
|
||||
"paths": {
|
||||
"contentPath": "content"
|
||||
}
|
||||
}
|
1
content/adapters/storage/ghost-storage-cloudinary
Symbolic link
1
content/adapters/storage/ghost-storage-cloudinary
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../node_modules/ghost-storage-cloudinary/
|
1
content/adapters/storage/s3
Symbolic link
1
content/adapters/storage/s3
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../node_modules/ghost-storage-adapter-s3/
|
0
content/data/.gitkeep
Normal file
0
content/data/.gitkeep
Normal file
0
content/themes/.gitkeep
Normal file
0
content/themes/.gitkeep
Normal file
10631
package-lock.json
generated
Normal file
10631
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
32
package.json
Normal file
32
package.json
Normal file
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"name": "ghost-on-heroku",
|
||||
"description": "Just a blogging platform on Heroku.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/snathjr/ghost-on-heroku.git"
|
||||
},
|
||||
"bugs": "https://github.com/TryGhost/Ghost/issues",
|
||||
"private": true,
|
||||
"version": "2.27.0",
|
||||
"dependencies": {
|
||||
"casper": "github:tryghost/Casper#2.10.6",
|
||||
"ghost": "2.27.0",
|
||||
"ghost-storage-adapter-s3": "^2.8.0",
|
||||
"ghost-storage-cloudinary": "^1.1.4",
|
||||
"mysql": "^2.17.1",
|
||||
"attila": "github:zutrinken/attila#1.13.0",
|
||||
"london": "github:tryghost/london#1.0.0",
|
||||
"massively": "github:tryghost/massively#1.0.2",
|
||||
"bleak": "github:zutrinken/bleak#1.4.0",
|
||||
"the-shell": "github:mityalebedev/The-Shell#v2.0.0",
|
||||
"vapor": "github:sethlilly/Vapor#v1.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "10.X"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node server.js",
|
||||
"postinstall": "bash bin/copy-themes.sh"
|
||||
}
|
||||
}
|
9
server.js
Normal file
9
server.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
var ghost = require('ghost');
|
||||
|
||||
// Run a single Ghost process
|
||||
ghost()
|
||||
.then( ghostServer => ghostServer.start() )
|
||||
.catch( error => {
|
||||
console.error(`Ghost server error: ${error.message} ${error.stack}`);
|
||||
process.exit(1);
|
||||
});
|
Loading…
Reference in a new issue