Skip to content

Commit

Permalink
Wait for MySQL during deployment
Browse files Browse the repository at this point in the history
  • Loading branch information
mars committed Aug 30, 2017
1 parent 06181a0 commit c0e1dd1
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 40 deletions.
2 changes: 1 addition & 1 deletion .profile
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Generate the Ghost JSON config file when Heroku dyno starts-up.
node create-config.js
bin/create-config
1 change: 0 additions & 1 deletion Procfile
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
web: npm start --production
release: knex-migrator migrate --mgpath node_modules/ghost
63 changes: 29 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,25 @@

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>.

## Note regarding Ghost version 1.X
## Ghost version 1.X

The latest release of Ghost is now supported! Changes include:

* Requires MySQL database, available through two add-ons,
* [JawsDB](https://elements.heroku.com/addons/jawsdb)
* 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)
* S3 storage adapter had been updated but should be compatible
* `HEROKU_URL` config var renamed to `PUBLIC_URL` to avoid using Heroku's namespace
* now uses [Node cluster API](https://nodejs.org/dist/latest-v6.x/docs/api/cluster.html) to scale across processor cores in larger dynos

## Deploying on Heroku

```bash
git clone https://github.com/cobyism/ghost-on-heroku
cd ghost-on-heroku

heroku create YOURAPPNAME
heroku addons:create jawsdb
heroku addons:create mailgun
heroku addons:create bucketeer # optional for file uploads
heroku config:set PUBLIC_URL=https://YOURAPPNAME.herokuapp.com

git push heroku master

heroku run 'knex-migrator init --mgpath node_modules/ghost'
heroku restart
```
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)

### Things you should know

- After deployment,
* you may need to upgrade the database add-on to have enough connections
* visit the admin area at `https://YOURAPPNAME.herokuapp.com/ghost` to set up your blog.
- Your blog will be publicly accessible at `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 `PUBLIC_URL` environment variable accordingly.
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 `PUBLIC_URL` environment variable accordingly
- If you create much content or decide to scale-up the dynos to support more traffic, a more substantial, paid database plan will be required.

#### Using with file uploads disabled

Expand Down Expand Up @@ -72,20 +55,32 @@ configure your Ghost blog and enable uploads.

### How this works

This repository is essentially a minimal web application that specifies [Ghost as a dependency](https://github.com/TryGhost/Ghost/wiki/Using-Ghost-as-an-NPM-module), and makes a deploy button available.
This repository is a [Node.js](https://nodejs.org) web application that specifies [Ghost as a dependency](https://docs.ghost.org/v1.0.0/docs/using-ghost-as-an-npm-module), and makes a deploy button available.

* Ghost and Casper theme versions are declared in the Node app's [`package.json`](package.json)
* Scales across processor cores in larger dynos via [Node cluster API](https://nodejs.org/dist/latest-v6.x/docs/api/cluster.html)

## Updating
## Updating source code

After deploying your own Ghost blog, you can update it by running the following commands:
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/cobyism/ghost-on-heroku
cd ghost-on-heroku

heroku git:remote -a YOURAPPNAME
heroku info
```
heroku git:clone --app YOURAPPNAME && cd YOURAPPNAME
git remote add origin https://github.com/cobyism/ghost-on-heroku
git pull origin master # may trigger a few merge conflicts, depending on how long since last update

Then you can push commits to the Heroku app, triggering new deployments:

```bash
git add .
git commit -m "Important changes"
git push heroku master
```

This will pull down the code that was deployed to Heroku so you have it locally, attach this repository as a new remote, attempt to pull down the latest version and merge it in, and then push that change back to your Heroku app instance.
See more about [deploying to Heroku with git](https://devcenter.heroku.com/articles/git).


## Problems?
Expand Down
3 changes: 3 additions & 0 deletions bin/common/env-values.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
mysqlDatabaseUrl: process.env.MYSQL_DATABASE_URL || process.env.JAWSDB_URL || process.env.CLEARDB_DATABASE_URL
}
10 changes: 7 additions & 3 deletions create-config.js → bin/create-config
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
#!/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;

Expand Down Expand Up @@ -56,15 +60,15 @@ function createConfig() {
storage: storage,
database: {
client: 'mysql',
connection: getMysqlConfig(process.env.JAWSDB_URL || process.env.CLEARDB_DATABASE_URL),
connection: getMysqlConfig(envValues.mysqlDatabaseUrl),
debug: false
},
server: {
host: '0.0.0.0',
port: process.env.PORT
},
paths: {
contentPath: path.join(__dirname, '/content/')
contentPath: path.join(appRoot, '/content/')
}
};

Expand Down Expand Up @@ -102,4 +106,4 @@ function getMysqlConfig(connectionUrl) {
}

var configContents = JSON.stringify(createConfig(), null, 2);
fs.writeFileSync(path.join(__dirname, 'config.production.json'), configContents);
fs.writeFileSync(path.join(appRoot, 'config.production.json'), configContents);
8 changes: 8 additions & 0 deletions bin/init-deployment
Original file line number Diff line number Diff line change
@@ -1,3 +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 changes: 21 additions & 0 deletions bin/wait-for-db
Original file line number Diff line number Diff line change
@@ -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);
}
});
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"dependencies": {
"casper": "github:tryghost/Casper#2.0.3",
"ghost": "^1.7.1",
"ghost-storage-adapter-s3": "^2.3.0"
"ghost-storage-adapter-s3": "^2.3.0",
"mysql": "^2.14.1"
},
"engines": {
"node": "6.11.x"
Expand Down

0 comments on commit c0e1dd1

Please sign in to comment.