<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

a {color:[[ColorPalette::PrimaryMid]];}
a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
a img {border:0;}

h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}

.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}

.header {background:[[ColorPalette::PrimaryMid]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}

.tabSelected{color:[[ColorPalette::PrimaryDark]];
	background:[[ColorPalette::TertiaryPale]];
	border-left:1px solid [[ColorPalette::TertiaryLight]];
	border-top:1px solid [[ColorPalette::TertiaryLight]];
	border-right:1px solid [[ColorPalette::TertiaryLight]];
}
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
.tabContents .button {border:0;}

#sidebar {}
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}

.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
	border:1px solid [[ColorPalette::PrimaryMid]];}
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}

.wizard .notChanged {background:transparent;}
.wizard .changedLocally {background:#80ff80;}
.wizard .changedServer {background:#8080ff;}
.wizard .changedBoth {background:#ff8080;}
.wizard .notFound {background:#ffff80;}
.wizard .putToServer {background:#ff80ff;}
.wizard .gotFromServer {background:#80ffff;}

#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}

.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}

.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}

.tiddler .defaultCommand {font-weight:bold;}

.shadow .title {color:[[ColorPalette::TertiaryDark]];}

.title {color:[[ColorPalette::SecondaryDark]];}
.subtitle {color:[[ColorPalette::TertiaryDark]];}

.toolbar {color:[[ColorPalette::PrimaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}

.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
.tagging .button, .tagged .button {border:none;}

.footer {color:[[ColorPalette::TertiaryLight]];}
.selected .footer {color:[[ColorPalette::TertiaryMid]];}

.sparkline {background:[[ColorPalette::PrimaryPale]]; border:0;}
.sparktick {background:[[ColorPalette::PrimaryDark]];}

.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
.lowlight {background:[[ColorPalette::TertiaryLight]];}

.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}

.imageLink, #displayArea .imageLink {background:transparent;}

.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}

.viewer .listTitle {list-style-type:none; margin-left:-2em;}
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}

.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}

.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
.viewer code {color:[[ColorPalette::SecondaryDark]];}
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}

.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}

.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
.editorFooter {color:[[ColorPalette::TertiaryMid]];}
.readOnly {background:[[ColorPalette::TertiaryPale]];}

#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:'alpha(opacity=60)';}
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}

body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}

h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}

.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}

/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}

#mainMenu .tiddlyLinkExisting,
	#mainMenu .tiddlyLinkNonExisting,
	#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}

.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0 1em 1em; left:0px; top:0px;}

.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}

#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}

#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 0.3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

.wizard {padding:0.1em 1em 0 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0 0; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0;}
.wizardFooter .status {padding:0 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em;}

#messageArea {position:fixed; top:2em; right:0; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em;}
#messageArea a {text-decoration:underline;}

.tiddlerPopupButton {padding:0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em; margin:0;}

.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}

.tabset {padding:1em 0 0 0.5em;}
.tab {margin:0 0 0 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}

#contentWrapper {display:block;}
#splashScreen {display:none;}

#displayArea {margin:1em 17em 0 14em;}

.toolbar {text-align:right; font-size:.9em;}

.tiddler {padding:1em 1em 0;}

.missing .viewer,.missing .title {font-style:italic;}

.title {font-size:1.6em; font-weight:bold;}

.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}

.tiddler .button {padding:0.2em 0.4em;}

.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}

.footer {font-size:.9em;}
.footer li {display:inline;}

.annotation {padding:0.5em; margin:0.5em;}

* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0 0.25em; padding:0 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}

.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0px 3px 0px 3px;}

.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}

.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}

.fieldsetFix {border:0; padding:0; margin:1px 0px;}

.sparkline {line-height:1em;}
.sparktick {outline:0;}

.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}

* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none !important;}
#displayArea {margin: 1em 1em 0em;}
noscript {display:none;} /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
}
/*}}}*/
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
To get started with this blank [[TiddlyWiki]], you'll need to modify the following tiddlers:
* [[SiteTitle]] & [[SiteSubtitle]]: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* [[MainMenu]]: The menu (usually on the left)
* [[DefaultTiddlers]]: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
You'll also need to enter your username for signing your edits: <<option txtUserName>>
These [[InterfaceOptions]] for customising [[TiddlyWiki]] are saved in your browser

Your username for signing your edits. Write it as a [[WikiWord]] (eg [[JoeBloggs]])

<<option txtUserName>>
<<option chkSaveBackups>> [[SaveBackups]]
<<option chkAutoSave>> [[AutoSave]]
<<option chkRegExpSearch>> [[RegExpSearch]]
<<option chkCaseSensitiveSearch>> [[CaseSensitiveSearch]]
<<option chkAnimate>> [[EnableAnimations]]

----
Also see [[AdvancedOptions]]
<<importTiddlers>>
There are a number of things the CLI can do. Important:
You preface the commands with ''heroku'', like @@heroku list@@

|!Command|!Description|
|ps &ndash;&ndash;remote staging|Will run unix process command on app (current directory)|
|ps &ndash;&ndash;app railyard|Runs [[ps]] command on app named railyard|
|list|Lists all your apps. |
|info|List info about application where you are.|
|[[pgbackups]]|Database tasks.|
|info &ndash;&ndash;app myapp|List info about a specific application.|
|[[log|Log files]]|Output log file.|
|[[plugins]]|List plugins you have added.|
|plugins:install <plugin-name>|Install a plugin.|
|run bash|Runs bash shell on Heroku.|
Easy:
<html><pre>
$ heroku create &lt;project-name&gt; --stack cedar
</pre></html>The switch ''stack cedar'' creates a project for a Rails 3 app.
If needed:<html><pre>
$ heroku run rake db:migrate
</pre></html>
[[Introduction]]
First you have to have installed:
*git
*Heroku gem
Here are the steps:
<html><pre>
$ git push heroku master       # Have already commited changes in git FIRST.
$ heroku run rake db:migrate   # Run migrations if you have added migration files.
$ heroku restart               # If you only run migrations, otherwise app will not pick up modified/changed fields.

# We neeed to make sure things are running well, (All looks good) so:
$ heroku ps --app railyard
Process       State               Command
------------  ------------------  ------------------------------
web.1         up for 46m          thin -p $PORT -e $RACK_ENV -R $HER..
</pre></html>
If there was a problem, because we have the [[release]] addon, we can rollback one version:
<html><pre>$ heroku rollback --app railyard
</pre></html>See also [[Reload entire db]]
[[Introduction]]
[[addons]]
[[admin]]
[[backups|pgbackups]]
[[CLI]]
[[clone]]
[[commands]]
[[config]]
[[create]]
[[Create Heroku Project]]
[[database name]]
[[database pull]]
[[database push]]
[[debug]]
[[Deploy to Heroku]]
[[dyno]]
[[error]]
[[git]]
[[Install Heroku]]
[[keys]]
[[Log files]]
[[maintenance]]
[[papertrail]]
[[pgbackups]]
[[plugins]]
[[postgres cli]]
[[ps]]
[[push]] - also push a branch
[[queue]]
[[quick]]
[[release]]
[[Reload entire db]]
[[rename]]
[[run]]
[[SSH]]
[[stack]]
[[staging]]
[[Status]]
[[toolbelt]]
[[upgrade]]
[[Using Rails Console]]
We have to have rails already installed and we will have to have git installed to use Heroku.
<html><pre>
$ gem install heroku
</pre></html>
''Heroku'' is a cloud platform that lets companies build, deliver, monitor and scale apps — we're the fastest way to go from idea to URL, bypassing all those infrastructure headaches. <- Straight from the horse.

This will document using Heroku with Ruby & Rails. Here is the starting unordered list:
*Heroku command line [[install]] (formerly called "toolbelt")
*You'll need to [[login and logout]] on the command line.
*Application from scratch - [[create]]
*Application [[from existing]]
*A [[quick]] view of important things.
*You [[install]]ed. Right?
*Debugging, checkout [[ps]], [[Log files]], [[quick]], [[Deploy to Heroku]], and [[Status]].
/***
|''Name:''|LoadRemoteFileThroughProxy (previous LoadRemoteFileHijack)|
|''Description:''|When the TiddlyWiki file is located on the web (view over http) the content of [[SiteProxy]] tiddler is added in front of the file url. If [[SiteProxy]] does not exist "/proxy/" is added. |
|''Version:''|1.1.0|
|''Date:''|mar 17, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#LoadRemoteFileHijack|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
***/
//{{{
version.extensions.LoadRemoteFileThroughProxy = {
 major: 1, minor: 1, revision: 0, 
 date: new Date("mar 17, 2007"), 
 source: "http://tiddlywiki.bidix.info/#LoadRemoteFileThroughProxy"};

if (!window.bidix) window.bidix = {}; // bidix namespace
if (!bidix.core) bidix.core = {};

bidix.core.loadRemoteFile = loadRemoteFile;
loadRemoteFile = function(url,callback,params)
{
 if ((document.location.toString().substr(0,4) == "http") && (url.substr(0,4) == "http")){ 
 url = store.getTiddlerText("SiteProxy", "/proxy/") + url;
 }
 return bidix.core.loadRemoteFile(url,callback,params);
}
//}}}
Heroku will consolidate your output and place it in the logfile. To see if you have external logs use:
<html><pre>
$ heroku config
...
SYSLOG_URL            => syslog://logs.papertrailapp.com:45366
</pre></html>
To examine log files (Format: timestamp source[process]: message):
<html><pre>
$ heroku logs
2011-03-11T13:09:01-08:00 heroku[router]: GET s888.heroku.com/stylesheets/all.css dyno=web.1 queue=0 wait=0ms service=3ms bytes=922
2011-03-11T13:09:01-08:00 app[web.1]: ...
2011-07-04T19:14:31+00:00 heroku[slugc]:←[0m Slug compilation started
2011-07-04T19:14:38+00:00 heroku[api]:←[0m Deploy 8d7b66c by rtfminc@gmail.com
2011-07-04T19:14:38+00:00 heroku[api]:←[0m Release v98 created by rtfminc@gmail.com
2011-07-04T19:14:39+00:00 heroku[web.1]:←[0m State changed from up to bouncing
2011-07-04T19:14:39+00:00 heroku[web.1]:←[0m State changed from bouncing to created
2011-07-04T19:14:39+00:00 heroku[web.1]:←[0m State changed from created to starting
2011-07-04T19:14:39+00:00 heroku[slugc]:←[0m Slug compilation finished
2011-07-04T19:14:39+00:00 heroku[deployhooks]:←[0m Notified New Relic about the deploy
2011-07-04T19:14:56+00:00 heroku[web.1]:←[0m State changed from starting to up
2011-07-04T19:15:01+00:00 heroku[web.1]:←[0m Stopping process with SIGTERM
</pre></html>
Examples:
<html><pre>
$ heroku logs -n 200                    # To print out last 200 lines..
$ heroku logs -n 200 --app railyard     # If more then one app
$ heroku logs --tail --app railyard     # To tail the log (have to upgrade logging)
</pre></html>
[[Introduction]]
[[Index]]

!!Other
[[Rails|http://rails.rtfm.tiddlyspot.com/]]
[[Git|http://git.rtfm.tiddlyspot.com/]]

/***
|''Name:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
	major: 1, minor: 0, revision: 2, 
	date: new Date("Apr 19, 2007"),
	source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
	coreVersion: '2.2.0 (Beta 5)'
};

config.macros.option.passwordCheckboxLabel = "Save this password on this computer";
config.macros.option.passwordInputType = "password"; // password | text
setStylesheet(".pasOptionInput {width: 11em;}\n","passwordInputTypeStyle");

merge(config.macros.option.types, {
	'pas': {
		elementType: "input",
		valueField: "value",
		eventName: "onkeyup",
		className: "pasOptionInput",
		typeValue: config.macros.option.passwordInputType,
		create: function(place,type,opt,className,desc) {
			// password field
			config.macros.option.genericCreate(place,'pas',opt,className,desc);
			// checkbox linked with this password "save this password on this computer"
			config.macros.option.genericCreate(place,'chk','chk'+opt,className,desc);			
			// text savePasswordCheckboxLabel
			place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));
		},
		onChange: config.macros.option.genericOnChange
	}
});

merge(config.optionHandlers['chk'], {
	get: function(name) {
		// is there an option linked with this chk ?
		var opt = name.substr(3);
		if (config.options[opt]) 
			saveOptionCookie(opt);
		return config.options[name] ? "true" : "false";
	}
});

merge(config.optionHandlers, {
	'pas': {
 		get: function(name) {
			if (config.options["chk"+name]) {
				return encodeCookie(config.options[name].toString());
			} else {
				return "";
			}
		},
		set: function(name,value) {config.options[name] = decodeCookie(value);}
	}
});

// need to reload options to load passwordOptions
loadOptionsCookie();

/*
if (!config.options['pasPassword'])
	config.options['pasPassword'] = '';

merge(config.optionsDesc,{
		pasPassword: "Test password"
	});
*/
//}}}
This will drop the db and then reload it. Then go thru all migrations and finally load the seed data.
<html><pre>
$ heroku pg:reset --db SHARED_DATABASE_URL
←[0KResetting SHARED_DATABASE_URL (DATABASE_URL)
 !    WARNING: Potentially Destructive Action
 !    This command will affect the app: s888
 !    To proceed, type "s888" or re-run this command with --confirm s888

> s888
...
$ heroku rake db:migrate      # Old
$ heroku run rake db:migrate  # New
$ heroku rake db:seed         # Old
$ heroku run rake db:seed     # New
</pre></html>See also [[Deploy to Heroku]]
List our SSH keys:
<html><pre>
$ heroku keys
=== 3 keys for rtfminc@gmail.com
ssh-rsa AAAAB3NzaC...nM3a+yMQ== rob@rtfm.ca
ssh-rsa AAAAB3NzaC...igUGOeuQ== rtfminc@gmail.com
</pre></html>
Add keys:
<html><pre>
$ heroku keys:add                                # from default ssh location.
$ heroku keys:add /c/Docs/ssh/rvr/id_rsa.pub     # Add keys from specific location.
</pre></html>
Remove keys:
<html><pre>
$ heroku keys:remove <email>
</pre></html>
...have heroku...
Heroku Notes
To determine the status of the Heroku system, go to: http://status.heroku.com/
Locally you can also check via CLI: @@heroku status@@
/***
Description: Contains the stuff you need to use Tiddlyspot
Note, you also need UploadPlugin, PasswordOptionPlugin and LoadRemoteFileThroughProxy
from http://tiddlywiki.bidix.info for a complete working Tiddlyspot site.
***/
//{{{

// edit this if you are migrating sites or retrofitting an existing TW
config.tiddlyspotSiteId = 'heroku.rtfm';

// make it so you can by default see edit controls via http
config.options.chkHttpReadOnly = false;
window.readOnly = false; // make sure of it (for tw 2.2)
window.showBackstage = true; // show backstage too

// disable autosave in d3
if (window.location.protocol != "file:")
	config.options.chkGTDLazyAutoSave = false;

// tweak shadow tiddlers to add upload button, password entry box etc
with (config.shadowTiddlers) {
	SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';
	SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");
	OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");
	DefaultTiddlers = DefaultTiddlers.replace(/^/,"[[WelcomeToTiddlyspot]] ");
	MainMenu = MainMenu.replace(/^/,"[[WelcomeToTiddlyspot]] ");
}

// create some shadow tiddler content
merge(config.shadowTiddlers,{

'TspotOptions':[
 "tiddlyspot password:",
 "<<option pasUploadPassword>>",
 ""
].join("\n"),

'TspotControls':[
 "| tiddlyspot password:|<<option pasUploadPassword>>|",
 "| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . .  " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<br>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",
 "| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[blog|http://tiddlyspot.blogspot.com/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"
].join("\n"),

'WelcomeToTiddlyspot':[
 "This document is a ~TiddlyWiki from tiddlyspot.com.  A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //What now?// &nbsp;&nbsp;@@ Before you can save any changes, you need to enter your password in the form below.  Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",
 "<<tiddler TspotControls>>",
 "See also GettingStarted.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Working online// &nbsp;&nbsp;@@ You can edit this ~TiddlyWiki right now, and save your changes using the \"save to web\" button in the column on the right.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// &nbsp;&nbsp;@@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick.  You can make changes and save them locally without being connected to the Internet.  When you're ready to sync up again, just click \"upload\" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Help!// &nbsp;&nbsp;@@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]].  Also visit [[TiddlyWiki.org|http://tiddlywiki.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help.  If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// &nbsp;&nbsp;@@ We hope you like using your tiddlyspot.com site.  Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."
].join("\n"),

'TspotSidebar':[
 "<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . .  " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"
].join("\n")

});
//}}}
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 17/04/2016 17:30:56 | rvr | [[/|http://heroku.rtfm.tiddlyspot.com/]] | [[store.cgi|http://heroku.rtfm.tiddlyspot.com/store.cgi]] | . | [[index.html | http://heroku.rtfm.tiddlyspot.com/index.html]] | . |
| 12/09/2016 12:27:25 | rvr | [[/|http://heroku.rtfm.tiddlyspot.com/]] | [[store.cgi|http://heroku.rtfm.tiddlyspot.com/store.cgi]] | . | [[index.html | http://heroku.rtfm.tiddlyspot.com/index.html]] | . |
| 07/12/2016 15:54:26 | rvr | [[/|http://heroku.rtfm.tiddlyspot.com/]] | [[store.cgi|http://heroku.rtfm.tiddlyspot.com/store.cgi]] | . | [[index.html | http://heroku.rtfm.tiddlyspot.com/index.html]] | . |
| 22/09/2017 16:01:55 | rvr | [[/|http://heroku.rtfm.tiddlyspot.com/]] | [[store.cgi|http://heroku.rtfm.tiddlyspot.com/store.cgi]] | . | [[index.html | http://heroku.rtfm.tiddlyspot.com/index.html]] | . | ok |
| 23/09/2017 11:56:03 | rvr | [[/|http://heroku.rtfm.tiddlyspot.com/]] | [[store.cgi|http://heroku.rtfm.tiddlyspot.com/store.cgi]] | . | [[index.html | http://heroku.rtfm.tiddlyspot.com/index.html]] | . |
| 30/09/2017 18:23:39 | rvr | [[/|http://heroku.rtfm.tiddlyspot.com/]] | [[store.cgi|http://heroku.rtfm.tiddlyspot.com/store.cgi]] | . | [[index.html | http://heroku.rtfm.tiddlyspot.com/index.html]] | . |
| 18/09/2020 21:42:57 | rvr | [[/|http://heroku.rtfm.tiddlyspot.com/]] | [[store.cgi|http://heroku.rtfm.tiddlyspot.com/store.cgi]] | . | [[index.html | http://heroku.rtfm.tiddlyspot.com/index.html]] | . |
| 22/08/2022 16:36:32 | rvr | [[/|http://heroku.rtfm.tiddlyspot.com/]] | [[store.cgi|http://heroku.rtfm.tiddlyspot.com/store.cgi]] | . | [[index.html | http://heroku.rtfm.tiddlyspot.com/index.html]] | . | ok |
| 22/08/2022 16:46:19 | rvr | [[/|http://heroku.rtfm.tiddlyspot.com/]] | [[store.cgi|http://heroku.rtfm.tiddlyspot.com/store.cgi]] | . | [[index.html | http://heroku.rtfm.tiddlyspot.com/index.html]] | . |
| 22/08/2022 17:01:27 | rvr | [[/|http://heroku.rtfm.tiddlyspot.com/]] | [[store.cgi|http://heroku.rtfm.tiddlyspot.com/store.cgi]] | . | [[index.html | http://heroku.rtfm.tiddlyspot.com/index.html]] | . |
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.3|
|''Date:''|Feb 24, 2008|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
	major: 4, minor: 1, revision: 3,
	date: new Date("Feb 24, 2008"),
	source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	coreVersion: '2.2.0'
};

//
// Environment
//

if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false;	// true to activate both in Plugin and UploadService
	
//
// Upload Macro
//

config.macros.upload = {
// default values
	defaultBackupDir: '',	//no backup
	defaultStoreScript: "store.php",
	defaultToFilename: "index.html",
	defaultUploadDir: ".",
	authenticateUser: true	// UploadService Authenticate User
};
	
config.macros.upload.label = {
	promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
	promptParamMacro: "Save and Upload this TiddlyWiki in %0",
	saveLabel: "save to web", 
	saveToDisk: "save to disk",
	uploadLabel: "upload"	
};

config.macros.upload.messages = {
	noStoreUrl: "No store URL in parmeters or options",
	usernameOrPasswordMissing: "Username or password missing"
};

config.macros.upload.handler = function(place,macroName,params) {
	if (readOnly)
		return;
	var label;
	if (document.location.toString().substr(0,4) == "http") 
		label = this.label.saveLabel;
	else
		label = this.label.uploadLabel;
	var prompt;
	if (params[0]) {
		prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0], 
			(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
	} else {
		prompt = this.label.promptOption;
	}
	createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);
};

config.macros.upload.action = function(params)
{
		// for missing macro parameter set value from options
		if (!params) params = {};
		var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
		var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
		var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
		var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
		var username = params[4] ? params[4] : config.options.txtUploadUserName;
		var password = config.options.pasUploadPassword; // for security reason no password as macro parameter	
		// for still missing parameter set default value
		if ((!storeUrl) && (document.location.toString().substr(0,4) == "http")) 
			storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
		if (storeUrl.substr(0,4) != "http")
			storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
		if (!toFilename)
			toFilename = bidix.basename(window.location.toString());
		if (!toFilename)
			toFilename = config.macros.upload.defaultToFilename;
		if (!uploadDir)
			uploadDir = config.macros.upload.defaultUploadDir;
		if (!backupDir)
			backupDir = config.macros.upload.defaultBackupDir;
		// report error if still missing
		if (!storeUrl) {
			alert(config.macros.upload.messages.noStoreUrl);
			clearMessage();
			return false;
		}
		if (config.macros.upload.authenticateUser && (!username || !password)) {
			alert(config.macros.upload.messages.usernameOrPasswordMissing);
			clearMessage();
			return false;
		}
		bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password); 
		return false; 
};

config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir) 
{
	if (!storeUrl)
		return null;
		var dest = bidix.dirname(storeUrl);
		if (uploadDir && uploadDir != '.')
			dest = dest + '/' + uploadDir;
		dest = dest + '/' + toFilename;
	return dest;
};

//
// uploadOptions Macro
//

config.macros.uploadOptions = {
	handler: function(place,macroName,params) {
		var wizard = new Wizard();
		wizard.createWizard(place,this.wizardTitle);
		wizard.addStep(this.step1Title,this.step1Html);
		var markList = wizard.getElement("markList");
		var listWrapper = document.createElement("div");
		markList.parentNode.insertBefore(listWrapper,markList);
		wizard.setValue("listWrapper",listWrapper);
		this.refreshOptions(listWrapper,false);
		var uploadCaption;
		if (document.location.toString().substr(0,4) == "http") 
			uploadCaption = config.macros.upload.label.saveLabel;
		else
			uploadCaption = config.macros.upload.label.uploadLabel;
		
		wizard.setButtons([
				{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption, 
					onClick: config.macros.upload.action},
				{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
				
			]);
	},
	options: [
		"txtUploadUserName",
		"pasUploadPassword",
		"txtUploadStoreUrl",
		"txtUploadDir",
		"txtUploadFilename",
		"txtUploadBackupDir",
		"chkUploadLog",
		"txtUploadLogMaxLine"		
	],
	refreshOptions: function(listWrapper) {
		var opts = [];
		for(i=0; i<this.options.length; i++) {
			var opt = {};
			opts.push();
			opt.option = "";
			n = this.options[i];
			opt.name = n;
			opt.lowlight = !config.optionsDesc[n];
			opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
			opts.push(opt);
		}
		var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
		for(n=0; n<opts.length; n++) {
			var type = opts[n].name.substr(0,3);
			var h = config.macros.option.types[type];
			if (h && h.create) {
				h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
			}
		}
		
	},
	onCancel: function(e)
	{
		backstage.switchTab(null);
		return false;
	},
	
	wizardTitle: "Upload with options",
	step1Title: "These options are saved in cookies in your browser",
	step1Html: "<input type='hidden' name='markList'></input><br>",
	cancelButton: "Cancel",
	cancelButtonPrompt: "Cancel prompt",
	listViewTemplate: {
		columns: [
			{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
			{name: 'Option', field: 'option', title: "Option", type: 'String'},
			{name: 'Name', field: 'name', title: "Name", type: 'String'}
			],
		rowClasses: [
			{className: 'lowlight', field: 'lowlight'} 
			]}
};

//
// upload functions
//

if (!bidix.upload) bidix.upload = {};

if (!bidix.upload.messages) bidix.upload.messages = {
	//from saving
	invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
	backupSaved: "Backup saved",
	backupFailed: "Failed to upload backup file",
	rssSaved: "RSS feed uploaded",
	rssFailed: "Failed to upload RSS feed file",
	emptySaved: "Empty template uploaded",
	emptyFailed: "Failed to upload empty template file",
	mainSaved: "Main TiddlyWiki file uploaded",
	mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
	//specific upload
	loadOriginalHttpPostError: "Can't get original file",
	aboutToSaveOnHttpPost: 'About to upload on %0 ...',
	storePhpNotFound: "The store script '%0' was not found."
};

bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
	var callback = function(status,uploadParams,original,url,xhr) {
		if (!status) {
			displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
			return;
		}
		if (bidix.debugMode) 
			alert(original.substr(0,500)+"\n...");
		// Locate the storeArea div's 
		var posDiv = locateStoreArea(original);
		if((posDiv[0] == -1) || (posDiv[1] == -1)) {
			alert(config.messages.invalidFileError.format([localPath]));
			return;
		}
		bidix.upload.uploadRss(uploadParams,original,posDiv);
	};
	
	if(onlyIfDirty && !store.isDirty())
		return;
	clearMessage();
	// save on localdisk ?
	if (document.location.toString().substr(0,4) == "file") {
		var path = document.location.toString();
		var localPath = getLocalPath(path);
		saveChanges();
	}
	// get original
	var uploadParams = new Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
	var originalPath = document.location.toString();
	// If url is a directory : add index.html
	if (originalPath.charAt(originalPath.length-1) == "/")
		originalPath = originalPath + "index.html";
	var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
	var log = new bidix.UploadLog();
	log.startUpload(storeUrl, dest, uploadDir,  backupDir);
	displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));
	if (bidix.debugMode) 
		alert("about to execute Http - GET on "+originalPath);
	var r = doHttp("GET",originalPath,null,null,username,password,callback,uploadParams,null);
	if (typeof r == "string")
		displayMessage(r);
	return r;
};

bidix.upload.uploadRss = function(uploadParams,original,posDiv) 
{
	var callback = function(status,params,responseText,url,xhr) {
		if(status) {
			var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
			displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);
			bidix.upload.uploadMain(params[0],params[1],params[2]);
		} else {
			displayMessage(bidix.upload.messages.rssFailed);			
		}
	};
	// do uploadRss
	if(config.options.chkGenerateAnRssFeed) {
		var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
		var rssUploadParams = new Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
		var rssString = generateRss();
		// no UnicodeToUTF8 conversion needed when location is "file" !!!
		if (document.location.toString().substr(0,4) != "file")
			rssString = convertUnicodeToUTF8(rssString);	
		bidix.upload.httpUpload(rssUploadParams,rssString,callback,Array(uploadParams,original,posDiv));
	} else {
		bidix.upload.uploadMain(uploadParams,original,posDiv);
	}
};

bidix.upload.uploadMain = function(uploadParams,original,posDiv) 
{
	var callback = function(status,params,responseText,url,xhr) {
		var log = new bidix.UploadLog();
		if(status) {
			// if backupDir specified
			if ((params[3]) && (responseText.indexOf("backupfile:") > -1))  {
				var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
				displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
			}
			var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
			displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);
			store.setDirty(false);
			log.endUpload("ok");
		} else {
			alert(bidix.upload.messages.mainFailed);
			displayMessage(bidix.upload.messages.mainFailed);
			log.endUpload("failed");			
		}
	};
	// do uploadMain
	var revised = bidix.upload.updateOriginal(original,posDiv);
	bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);
};

bidix.upload.httpUpload = function(uploadParams,data,callback,params)
{
	var localCallback = function(status,params,responseText,url,xhr) {
		url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
		if (xhr.status == 404)
			alert(bidix.upload.messages.storePhpNotFound.format([url]));
		if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
			alert(responseText);
			if (responseText.indexOf("Debug mode") >= 0 )
				responseText = responseText.substring(responseText.indexOf("\n\n")+2);
		} else if (responseText.charAt(0) != '0') 
			alert(responseText);
		if (responseText.charAt(0) != '0')
			status = null;
		callback(status,params,responseText,url,xhr);
	};
	// do httpUpload
	var boundary = "---------------------------"+"AaB03x";	
	var uploadFormName = "UploadPlugin";
	// compose headers data
	var sheader = "";
	sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
	sheader += uploadFormName +"\"\r\n\r\n";
	sheader += "backupDir="+uploadParams[3] +
				";user=" + uploadParams[4] +
				";password=" + uploadParams[5] +
				";uploaddir=" + uploadParams[2];
	if (bidix.debugMode)
		sheader += ";debug=1";
	sheader += ";;\r\n"; 
	sheader += "\r\n" + "--" + boundary + "\r\n";
	sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
	sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
	sheader += "Content-Length: " + data.length + "\r\n\r\n";
	// compose trailer data
	var strailer = new String();
	strailer = "\r\n--" + boundary + "--\r\n";
	data = sheader + data + strailer;
	if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
	var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; ;charset=UTF-8; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
	if (typeof r == "string")
		displayMessage(r);
	return r;
};

// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
{
	if (!posDiv)
		posDiv = locateStoreArea(original);
	if((posDiv[0] == -1) || (posDiv[1] == -1)) {
		alert(config.messages.invalidFileError.format([localPath]));
		return;
	}
	var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
				store.allTiddlersAsHtml() + "\n" +
				original.substr(posDiv[1]);
	var newSiteTitle = getPageTitle().htmlEncode();
	revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
	revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
	revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
	revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
	revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
	return revised;
};

//
// UploadLog
// 
// config.options.chkUploadLog :
//		false : no logging
//		true : logging
// config.options.txtUploadLogMaxLine :
//		-1 : no limit
//      0 :  no Log lines but UploadLog is still in place
//		n :  the last n lines are only kept
//		NaN : no limit (-1)

bidix.UploadLog = function() {
	if (!config.options.chkUploadLog) 
		return; // this.tiddler = null
	this.tiddler = store.getTiddler("UploadLog");
	if (!this.tiddler) {
		this.tiddler = new Tiddler();
		this.tiddler.title = "UploadLog";
		this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
		this.tiddler.created = new Date();
		this.tiddler.modifier = config.options.txtUserName;
		this.tiddler.modified = new Date();
		store.addTiddler(this.tiddler);
	}
	return this;
};

bidix.UploadLog.prototype.addText = function(text) {
	if (!this.tiddler)
		return;
	// retrieve maxLine when we need it
	var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
	if (isNaN(maxLine))
		maxLine = -1;
	// add text
	if (maxLine != 0) 
		this.tiddler.text = this.tiddler.text + text;
	// Trunck to maxLine
	if (maxLine >= 0) {
		var textArray = this.tiddler.text.split('\n');
		if (textArray.length > maxLine + 1)
			textArray.splice(1,textArray.length-1-maxLine);
			this.tiddler.text = textArray.join('\n');		
	}
	// update tiddler fields
	this.tiddler.modifier = config.options.txtUserName;
	this.tiddler.modified = new Date();
	store.addTiddler(this.tiddler);
	// refresh and notifiy for immediate update
	story.refreshTiddler(this.tiddler.title);
	store.notify(this.tiddler.title, true);
};

bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir,  backupDir) {
	if (!this.tiddler)
		return;
	var now = new Date();
	var text = "\n| ";
	var filename = bidix.basename(document.location.toString());
	if (!filename) filename = '/';
	text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
	text += config.options.txtUserName + " | ";
	text += "[["+filename+"|"+location + "]] |";
	text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
	text += uploadDir + " | ";
	text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
	text += backupDir + " |";
	this.addText(text);
};

bidix.UploadLog.prototype.endUpload = function(status) {
	if (!this.tiddler)
		return;
	this.addText(" "+status+" |");
};

//
// Utilities
// 

bidix.checkPlugin = function(plugin, major, minor, revision) {
	var ext = version.extensions[plugin];
	if (!
		(ext  && 
			((ext.major > major) || 
			((ext.major == major) && (ext.minor > minor))  ||
			((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
			// write error in PluginManager
			if (pluginInfo)
				pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
			eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
	}
};

bidix.dirname = function(filePath) {
	if (!filePath) 
		return;
	var lastpos;
	if ((lastpos = filePath.lastIndexOf("/")) != -1) {
		return filePath.substring(0, lastpos);
	} else {
		return filePath.substring(0, filePath.lastIndexOf("\\"));
	}
};

bidix.basename = function(filePath) {
	if (!filePath) 
		return;
	var lastpos;
	if ((lastpos = filePath.lastIndexOf("#")) != -1) 
		filePath = filePath.substring(0, lastpos);
	if ((lastpos = filePath.lastIndexOf("/")) != -1) {
		return filePath.substring(lastpos + 1);
	} else
		return filePath.substring(filePath.lastIndexOf("\\")+1);
};

bidix.initOption = function(name,value) {
	if (!config.options[name])
		config.options[name] = value;
};

//
// Initializations
//

// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);

// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");

//optionsDesc
merge(config.optionsDesc,{
	txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
	txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
	txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
	txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
	txtUploadUserName: "Upload Username",
	pasUploadPassword: "Upload Password",
	chkUploadLog: "do Logging in UploadLog (default: true)",
	txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"
});

// Options Initializations
bidix.initOption('txtUploadStoreUrl','');
bidix.initOption('txtUploadFilename','');
bidix.initOption('txtUploadDir','');
bidix.initOption('txtUploadBackupDir','');
bidix.initOption('txtUploadUserName','');
bidix.initOption('pasUploadPassword','');
bidix.initOption('chkUploadLog',true);
bidix.initOption('txtUploadLogMaxLine','10');


// Backstage
merge(config.tasks,{
	uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}
});
config.backstageTasks.push("uploadOptions");


//}}}

You can go into the Heroku console from your local computer simply with @@heroku console@@:
<html><pre>
$ heroku run console
Ruby console for s888.heroku.com
>> Rails.env
=> "production"
>> Rails.env.production?
=> true
</pre></html>
This document is a ~TiddlyWiki from tiddlyspot.com.  A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.

@@font-weight:bold;font-size:1.3em;color:#444; //What now?// &nbsp;&nbsp;@@ Before you can save any changes, you need to enter your password in the form below.  Then configure privacy and other site settings at your [[control panel|http://heroku.rtfm.tiddlyspot.com/controlpanel]] (your control panel username is //heroku.rtfm//).
<<tiddler TspotControls>>
See also GettingStarted.

@@font-weight:bold;font-size:1.3em;color:#444; //Working online// &nbsp;&nbsp;@@ You can edit this ~TiddlyWiki right now, and save your changes using the "save to web" button in the column on the right.

@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// &nbsp;&nbsp;@@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick.  You can make changes and save them locally without being connected to the Internet.  When you're ready to sync up again, just click "upload" and your ~TiddlyWiki will be saved back to tiddlyspot.com.

@@font-weight:bold;font-size:1.3em;color:#444; //Help!// &nbsp;&nbsp;@@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]].  Also visit [[TiddlyWiki.org|http://tiddlywiki.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help.  If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].

@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// &nbsp;&nbsp;@@ We hope you like using your tiddlyspot.com site.  Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions.
There are numerous addons that Heroku has, some free others or more resources will cost. To see what you have installed, select "My Apps" from top menu and select resources beside the app you want to examine.
Currently I have:
|!Addon|!Description|
|release|free, only 2 versions, manage software releases|
|memcache|free - 5mb|
|custom domains|Points to one custom domain, more cost.|
|expanded logging|log|
|PG backups|~PostGres SQL backups|
|Shared db|Free - 5 MB|
|newrelic|free - basic performance monitoring.|
!!To admin an Heroku application.
You can use 
''$ heroku run bash''

!!To admin the database.
You can use the gem: ''admin_data''   (ie: http://railyardmedia.com/admin_data)
You can use 
''$ heroku run console''
You can clone an Heroku application to a new place. Make sure you have added your ssh [[keys]].
<html><pre>
$ heroku       # To login to the Heroku toolbelt.
$ heroku keys  # To check. You'll need to have your ssh keys added.
$ git clone git@heroku.com:railyard.git
</pre></html>
Here are some Heroku commands, there are run like: @@heroku <command> <options>@@
|!Command|!Description|
|config|Shows configuration settings.|
|console|Rails console command.|
|[[create]]|Create a Heroku application.|
|info|List info for app.|
|[[keys]]|Add SSH keys.|
|list|List your Heroku apps.|
|login|Login with your creds.|
|[[pgbackups]]|Herokus backup command.|
|[[ps]]|unix ps command.|
|rake|Rails rake command.|
|restart|Restart Heroku dynos, esentially the app.|
|run|run processes|
|[[stack]]|Shows which stack you are running on.|
|watch|unix watch command.|
To display the config parameters for your app, use @@heroku config &ndash;&ndash; appname@@
Omit appname if you are in the app directory you want.
<html><pre>
$ heroku config  --app libations
  DATABASE_URL=postgres://xmjnm...:5432/d6j4134l7kdqm1
  LANG=en_US.UTF-8
  RACK_ENV=production
  RAILS_ENV=production
  RAILS_SERVE_STATIC_FILES=enabled
  SECRET_KEY_BASE=592a...dad6bb23
</pre></html>
You can add to config, keys to cloud accounts by...
<html><pre>
heroku config:set JB007=this.is.top.secret
</pre></html>You can also see these at the website.
You can create an app on a specific [[stack]] or just go for default.
If you don't specify <your-app>, Heroku will pick a fun name for you.
<html><pre>
heroku create &lt;your-app&gt;                           # Default stack chosen
</pre></html>
See also [[rename]].
Example:
<html><pre>
$ heroku create banana666
  Creating banana666... done, stack is cedar-14
  https://banana666.herokuapp.com/ | https://git.heroku.com/banana666.git
  Git remote heroku added

# You can see we already have an app here!
$ git remote -v
  heroku  https://git.heroku.com/banana666.git (fetch)
  heroku  https://git.heroku.com/banana666.git (push)
  origin  git@bitbucket.org:rtfminc/banana_app.git (fetch)
  origin  git@bitbucket.org:rtfminc/banana_app.git (push)

$ git push heroku main   (or master)
...
  Launching... done, v5
  remote: https://banana666.herokuapp.com/ deployed to Heroku
</pre></html>We are on our way.
Not 100% clear, but am guessing that Heroku names db such as
copper ... gray is using Heroku Postgres COLOR naming scheme
But they also use ~DATABASE_URL, which is pulled from the [[config]] vars.
See what your dbs are: @@heroku pg:info@@

To access your db, the credentials are found via: @@heroku pg:credentials DATABASE@@
To pull data from db:

This no longer works.

First : try [[pgbackups]]

<html><pre>
$ heroku db:pull                        // To pull whole db
$ heroku db:pull --tables campaigns     // To pull individual tables
$ heroku db:pull --app railyard         // To specify which app
</pre></html>This will pull from Heroku and write over your local db - determined by the database.yaml file.
You might also look at [[database push]]
To push data from a local machine up to your heroku DB:

<html><pre>
$ heroku db:push  --app railyard   # Use --confirm railyard to skip confirmation of this desctructive action.
Loaded Taps v0.3.23
Auto-detected local database: mysql2://root@localhost/railyard_development?encoding=utf8
Warning: Data in the app 'railyard' will be overwritten and will not be recoverable.
 ...
Sending schema
Schema:        100% |==========================================| Time: 00:00:49
...
Sending data
12 tables, 135 records
...</pre></html>You can also load ''individual'' tables:<html><pre>
$ heroku db:push --help
...
 -t, --tables TABLES  # only push the specified tables

$ heroku db:push --tables campaign
Loaded Taps v0.3.23
Auto-detected local database: mysql2://root@localhost/railyard_development?encoding=utf8
Warning: Data in the app 'railyard' will be overwritten and will not be recoverable.
...
</pre></html>Did have problems with the push sending no new files? Had to do the whole db.
Note that the gem ''taps'' (gem install taps) must be installed. Also the ''sqlite3.dll'' should be in the ruby directory (C:\ruby\Ruby192\bin)
Heroku uses ''dynos'' to apply computing resources to applications. There are two different dynos: web and worker dynos.
!!web dyno
*The web dyno provides a single process to respond to HTTP requests and run application code. 
*More web dynos allow you to process concurrent HTTP requests.
*A basic Heroku app has one free web dyno

!!worker dyno
*This dyno runs background process to run your app and  jobs in the queue. 
*Adding more workers allows you to run jobs in parallel.
Error messages...
You can heroku-ize and existing app. 

This is old - needs fixing


First, add ruby version to Gemfile, like @@ruby "2.3.1"@@
Goto the app directory, of course you have git and the Heroku toolbelt [[install]]ed and simply add:
<html><pre>
$ heroku create libare
  Creating ⬢ libare... done
  https://libare.herokuapp.com/ | https://git.heroku.com/libare.git
$ git config --list | grep herok
  remote.heroku.url=https://git.heroku.com/libare.git
  remote.heroku.fetch=+refs/heads/*:refs/remotes/heroku/*

$ git push heroku master      # Use this to push code to Heroku. 
  Counting objects: 324, done.
...
remote:  !     Precompiling assets failed.
...
remote: !	Push rejected to libare.
...
error: failed to push some refs to 'https://git.heroku.com/libare.git'

# We need to specify assets - visit Heroku dashboard and add.

$ heroku config
  === libare Config Vars
  S3_BUCKET: libarephoto
  S3_KEY:    A...AQ
  S3_REGION: us-east-1
  S3_SECRET: gA...F
</pre></html>
NOTE...if any of the above are incorrect you'll get an error when you try and connect like the following:
@@Excon::Error::Socket (getaddrinfo: Name or service not known (SocketError)):@@
Let's continue:
<html><pre>
$ git push heroku master  
...
  remote: -----> Launching...
  remote:        https://libare.herokuapp.com/ deployed to Heroku
  remote: Verifying deploy... done.
  To https://git.heroku.com/libare.git


$ heroku run rake db:migrate
  Running rake db:migrate on ⬢ libare... up, run.7371 (Free)
  ...

$ heroku run rake db:seed
...
  fini...
</pre></html>
 
You can only deploy with git.
More Git goodness: http://git.rtfm.tiddlyspot.com/
First thing, you must install Heroku CLI.
<html><pre>
$ curl https://cli-assets.heroku.com/install-ubuntu.sh | sh 

$  heroku --version
heroku/7.62.0 linux-x64 node-v14.19.0
</pre></html>
SSH keys are used:
<html><pre>
$ heroku keys           # List your keys.
$ heroku keys:add       # Add SSH keys, look in default place.
  Found an SSH public key at /home/fred/.ssh/id_rsa.pub
  ? Would you like to upload it to Heroku? Yes
  Uploading /home/fred/.ssh/id_rsa.pub SSH key... done

$ heroku keys:remove adam@workstation.local   # Remove keys not used.
</pre></html>
It will
Logging in will redirect you to a web page to confirm. 
<html><pre>
$ heroku login
	Opening browser to https://cli-a...
	Logging in... done
	Logged in as yourEmail@biteme.com
</pre></html> 
To logout:
<html><pre>
$ heroku logout
Local credentials cleared.
</pre></html>
Creds are stored at: @@~/.netrc@@
When uploaded code to Heroku, and its a live app with heavy traffic, you will want to do this:
<html><pre>
$ heroku maintenance:on
$ git push heroku
$ heroku run rake db:migrate
$ heroku maintenance:off
</pre></html>
Heroku does have logs, but I have set up [[Papertrail|http://papertrail.com]] to handle most of the logging because its a lot cheaper. 
<html><pre>
$ heroku config
...
SYSLOG_URL  => syslog://logs.papertrailapp.com:45366
</pre></html>
To backup your data use ''pgbackups''. See also [[database push]].
<html><pre>
$ heroku pg:backups capture             # To capture backups of db.
$ heroku pg:backups info                # To see logs.
$ heroku pg:backups capture --expire    # To remove older backups
$ heroku pg:backups                     # List backups, names like: b001 and SHARED_DATABASE_URL
 
$ heroku pgbackups:capture b001        # To capture a specific db, also below format
$ heroku pgbackups:capture SHARED_DATABASE_URL

$ heroku pgbackups:url b001            # Will create download link at amazon cloud for you to download.
$ heroku pgbackups:restore b001        # Will restore from backups at Heroku
$ heroku pgbackups:restore &lt;url&gt;mydb.dump?authparameters   # Will restore from some url.

# Capture db from production app and transfer to different environments.
$ heroku pg:transfer
$ heroku pg:transfer --help
...have not tried this yet. may need to run postgresql locally
...also try..
heroku pg:pull DATABASE mylocaldb 
heroku pg:push mylocaldb
May need to set vars
$ PGUSER=postgres PGPASSWORD=password heroku pg:pull HEROKU_POSTGRESQL_MAGENTA mylocaldb
</pre></html>
Plugins are not [[addons]].
Plugins allow developers to extend the functionality of the Heroku command interface, adding commands or features. 
<html><pre>
$ heroku plugins:install heroku-vim
  Installing plugin heroku-vim... done
$ heroku plugins
  heroku-vim 1.0.1
</pre></html>
To view your db in Heroku:
<html><pre>
heroku run rails console
or
heroku pg:psql
or
heroku pg:psql --app libations
</pre></html>
And proceed as normal....
The ''process'' command:
<html><pre>
$ heroku ps --app railyard
Process       State               Command
------------  ------------------  ------------------------------
web.1         up for 1h           thin -p $PORT -e $RACK_ENV -R $HER..
</pre></html>
There are three logs files merged into herokus log file: 
*application - our application
*system - from the system
*api - admin or other developers, like deploy
Its more versatile when used with [[Log files]]. Logs are built up of four parts:
@@ timestamp source[process]: message@@

Examples of source (of log file) and processes are: 
*heroku[router]
*heroku[nginx]
*heroku[slugc]
*heroku[web.1]
*heroku[deployhooks]
*heroku[api]    #from a deploy
*app[web.1]     # web = dyno
*app[web.2]
*deployhooks]
Here are some typical examples:
<html><pre>
$ heroku logs --ps web.1 --app railyard
$ heroku logs --ps worker.1 --app railyard
$ heroku logs --source heroku --ps router --app railyard
$ heroku logs --source heroku --app railyard
$ heroku logs --source heroku  --ps router --app railyard

$ heroku logs --ps nginx  --app railyard
$ heroku logs --ps web --app railyard
</pre></html>
''Push'' is a Git command.
To push your changes from your machine to Heroku:
<html><pre>
$ git push heroku
  Counting objects: 61, done.
  Delta compression using up to 4 threads.
  Compressing objects: 100% (43/43), done.
  Writing objects: 100% (45/45), 4.70 KiB | 0 bytes/s, done.
  Total 45 (delta 17), reused 0 (delta 0)
  remote: Compressing source files... done.
  remote: Compressing source files... done.
  remote: Building source:
  ... then many messages about the build process...
  remote: https://banana666.herokuapp.com/ deployed to Heroku
  remote: Verifying deploy... done.
  To https://git.heroku.com/banana666.git
   1ddf670..30c6129  master -> master
</pre></html>
!!Push a Branch
You'll need slightly different syntax:
@@Fail:@@ ''git push heroku ''
@@Correct:@@ ''git push heroku mybranch:master''
Any processes that take more than two seconds to complete (or 500ms for a web request), you should consider a queue. 
The queue will be processed by the [[worker dynos|dyno]].
See http://devcenter.heroku.com/articles/queueing
Typically this is working with images.
Here are some often used, important & misc things:
*Local [[Status]]
*Something wrong? See [[Log files]].
*List all your apps: @@heroku list@@ or @@heroku apps@@
*Can you connect to Heroku? Run: @@ssh -v git@heroku.com@@
**Look thru output for: @@debug1: Authentication succeeded (publickey).@@
*Download code from Heroku to new location: [[clone]].
*Heroku [[pgbackups]] or check out the [[postgres cli]].
Heroku creates ''releases'' whenever you deploy, add an addon or change vars. You can 
*list releases via @@heroku release@@
*rollback to a release via @@heroku rollback@@
See http://devcenter.heroku.com/articles/releases
To see your releases:
<html><pre>
$ heroku releases
Rel   Change                          By                    When
----  ----------------------          ----------            ----------
v160  Deploy 2f2673c                  rtfminc@gmail.com     6 minutes ago
v159  Deploy 34e2b2e                  rtfminc@gmail.com     20 hours ago

$ heroku releases:info v160
=== Release v160
Change:      Deploy 2f2673c
By:          rtfminc@gmail.com
When:        7 minutes ago
Addons:      custom_domains:basic, logging:expanded, memcache:5mb, newrelic:standard, pgbackups:basic, releases:basic, shared-databa
se:5mb
Config:      BUNDLE_WITHOUT        => development:test
             DATABASE_URL          => postgres://smimmqibui:eLJx-6DCuL0PY8VmU8yO@ec2-50-17-213-60.compute-1.amazonaws.com/smimmqibui
...
</pre></html>
To rollback a release:
<html><pre>
$ heroku rollback
Rolled back to v159
</pre></html>
Advanced release management will allow you to rollback to any prior version
<html><pre>
$ heroku rollback v42
Rolled back to v42
</pre></html>
To rename an app:
<html><pre>
git remote rename &lt;old&gt; &lt;new&gt;
</pre></html>
Heroku has the ''run'' command, as  ''heroku run''
<html><pre>
$ heroku run bash    # runs bash shell for your app
$ heroku run bash --app railyard

$ heroku run rake db:migrate   # To run a rake task

</pre></html>
The stack is the os plus the ruby/rails libraries. You can see what stack you are on:
<html><pre>
$ heroku stack
  aspen-mri-1.8.6
* bamboo-ree-1.8.7
  bamboo-mri-1.9.2
</pre></html>In this case, We are using  bamboo-ree-1.8.7, which is Debian 5.0 + Ruby 1.9.2. To upgrade:
<html><pre>
$ heroku stack:migrate bamboo-mri-1.9.2
</pre></html>This will 
There is a staging server, running production code.
We did this by creating a staging environment and then renaming it.
<html><pre>
$ heroku create --stack bamboo-mri-1.9.2 --remote staging
Creating evening-journey-8966.... done
...
$ heroku rename stagingyard --app evening-journey-8966
...
$ heroku rake db:migrate --remote staging
...
$ heroku ps --remote staging           # To see its running ok
$ heroku console --app stagingyard     # To run console
</pre></html>
We can visit the site as: http://stagingyard.heroku.com
When we make changes, we need to:
<html><pre>
$ git push staging master
$ heroku rake db:migrate --app stagingyard     # If db changes
</pre></html>
You can upgrade xxx by
<html><pre>
$ heroku addons:upgrade logging:expanded
</pre></html>