Skip to content

Instantly share code, notes, and snippets.

Last active Feb 3, 2016
What would you like to do?
Wordpress as Twelve-Factor. Please check for the real thing!
mkdir wordpress
cd wordpress
git init
curl -LO
curl -LO
git add composer.json .gitignore
git commit -m "composer plus wordpress prerequisites"
composer require ext-gd:* johnpbloch/wordpress wpackagist-plugin/amazon-web-services wpackagist-plugin/amazon-s3-and-cloudfront wpackagist-plugin/sendgrid-email-delivery-simplified
git add composer.json composer.lock
git commit -m "require ext-gd, wordpress and plugins"
curl -LO
git add wp-config.php
git commit -m "wp-config with many env vars"
curl -L > wordpress/.htaccess
git add wordpress/.htaccess
git commit -m "htaccess"
curl -LO
git add Procfile
git commit -m "Heroku Procfile"
composer require wp-cli/wp-cli
curl -LO
git add composer.json composer.lock wp-cli.yml
git commit -m "WP-CLI"
heroku create
heroku addons:create jawsdb
heroku addons:create bucketeer
heroku addons:create sendgrid
heroku config:set $(curl '' | sed -E -e "s/^define\('(.+)', *'(.+)'\);$/WORDPRESS_\1=\2/" -e 's/ //g')
git push heroku master
# as an alternative to the next step, to interactively provide info (use a format like "" with your app name for the URL), you can run:
# heroku run 'vendor/bin/wp core install --prompt'
heroku run 'composer wordpress-setup-core-install -- --title="Wordpress on Heroku" --admin_user=admin --admin_password=admin --url=""'
heroku run 'composer wordpress-setup-finalize'
heroku open
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
"repositories": [
"type": "composer",
"url": ""
"extra": {
"wordpress-install-dir": "wordpress",
"installer-paths": {
"wordpress/wp-content/mu-plugins/{$name}/": ["type:wordpress-muplugin"],
"wordpress/wp-content/plugins/{$name}/": ["type:wordpress-plugin"],
"wordpress/wp-content/themes/{$name}/": ["type:wordpress-theme"]
"scripts": {
"wordpress-setup-core-install-prompt": "wp core install --prompt",
"wordpress-setup-core-install": "wp core install --skip-email",
"wordpress-setup-clear-home": "wp option delete home || true",
"wordpress-setup-configure-s3": "echo '{\"domain\":\"path\",\"copy-to-s3\":\"1\",\"serve-from-s3\":\"1\",\"ssl\":\"request\"}' | wp option add tantan_wordpress_s3 --format=json",
"wordpress-setup-enable-plugins": "wp plugin activate amazon-web-services amazon-s3-and-cloudfront sendgrid-email-delivery-simplified",
"wordpress-setup": [
"wordpress-setup-finalize": [
web: vendor/bin/heroku-php-apache2 wordpress/
path: wordpress
apache_modules: [ mod_rewrite ]
disabled_commands: [ "core config" ]
$db = array_merge(['port' => 3306], parse_url(getenv('JAWSDB_URL')?:getenv('CLEARDB_DATABASE_URL')));
define('DB_NAME', substr($db['path'], 1));
define('DB_USER', $db['user']);
define('DB_PASSWORD', $db['pass']);
define('DB_HOST', $db['host'].':'.$db['port']);
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');
$table_prefix = 'wp_';
define('AS3CF_BUCKET', getenv('S3_BUCKET')?:getenv('BUCKETEER_BUCKET_NAME'));
if(getenv('S3_REGION')) define('AS3CF_REGION', getenv('S3_REGION'));
define('SENDGRID_AUTH_METHOD', 'credentials');
define('SENDGRID_SEND_METHOD', 'api');
define('AUTH_KEY', getenv('WORDPRESS_AUTH_KEY') ?:'put your unique phrase here');
define('SECURE_AUTH_KEY', getenv('WORDPRESS_SECURE_AUTH_KEY') ?:'put your unique phrase here');
define('LOGGED_IN_KEY', getenv('WORDPRESS_LOGGED_IN_KEY') ?:'put your unique phrase here');
define('NONCE_KEY', getenv('WORDPRESS_NONCE_KEY') ?:'put your unique phrase here');
define('AUTH_SALT', getenv('WORDPRESS_AUTH_SALT') ?:'put your unique phrase here');
define('SECURE_AUTH_SALT', getenv('WORDPRESS_SECURE_AUTH_SALT')?:'put your unique phrase here');
define('LOGGED_IN_SALT', getenv('WORDPRESS_LOGGED_IN_SALT') ?:'put your unique phrase here');
define('NONCE_SALT', getenv('WORDPRESS_NONCE_SALT') ?:'put your unique phrase here');
define('FORCE_SSL_ADMIN', true);
define('FORCE_SSL_LOGIN', true);
define('WP_DEBUG', true);
define('WP_DEBUG_DISPLAY', false);
define('WP_DEBUG_LOG', false); // this is correct - we don't want errors to go to debug.log, but to the default destination
define('DISALLOW_FILE_MODS', true);
define('DISABLE_WP_CRON', in_array(getenv('DISABLE_WP_CRON'), ['true', '1', 'yes'], true) ? true : false);
if(!defined('ABSPATH')) define('ABSPATH', dirname(__FILE__) . '/wordpress/'); // should not be necessary
require_once(ABSPATH . 'wp-settings.php');
// installs using a Heroku button do not know the URL, so they use as the site URL, which we need to fix
if(function_exists('get_option') && get_option('siteurl') == '') {
update_option('siteurl', set_url_scheme($url = 'http://'.$_SERVER['HTTP_HOST']));
header("Location: $url".$_SERVER['REQUEST_URI']);

This comment has been minimized.

Copy link

@xavriley xavriley commented Feb 1, 2016


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment