Reset Postgres DB on Heroku

In a Rails application you can you this tasks on localhost to reset the database.

rake db:drop
rake db:create
rake db:migrate

And that will delete the db schema, create a new one and run all migrations to create the tables. This is awesome!
But if try to run this on heroku:

heroku run rake db:drop

Than you will get an exception, because you don’t have permission to delete dbs on Heroku. If you want to reset your database on Heroku you have to use this command:

heroku pg:reset DATABASE_URL

this is equal to “rake db:drop” and “rake db:create”. After that you still have to run:

heroku run rake db:migrate

That worked pretty good for me.
Just wanted to share my experience.

CSS broke Heroku Deployment

Today I did a “git push heroku master” do deploy an application. And than suddenly I got a big exception and the build failed.

CssBrakesBuild

The funny thing is that CSS is the root of the problem. This CSS line here broke the deployment:

height: inherit important!;

Indeed it should be:

height: inherit !important;

Heroku is very sensible 🙂

Seamless Deployment with Heroku

By default there is no seamless deployment on Heroku. That means, if you do a git push, your app gets deployed and there is a little downtime. That’s just because how Heroku works. At first they kill your running dynos, then they build the new app, deploy it on new dynos and finally boot up the new dynos.

But there is a new “preboot” feature in the Heroku labs. With that the procedure looks like that:

  1. Code push
  2. Run buildpack; store slug
  3. Boot new dynos
  4. Switch routing
  5. Kill old dynos

With that “preboot” Feature you don’t have any down times. You can activate the “preboot” feature for your app with this command:

heroku labs:enable -a myapp preboot

Now you can directly do “git push heroku master” and 3 minutes later your new version is online without any downtimes. I just tried it for VersionEye and it works perfectly for me.

That also means that there 2 different versions of the app online for round about 2 minutes. There is a short overlap for a short amount of time. That can be dangerous if you do big db migrations. For this kind of deployments you should disable the feature with

heroku labs:disable -a myapp preboot

Multiple Heroku Accounts on one machine

To have multiple accounts on Heroku is no fun. Specially not if you are a developer and you have to push multiple apps into multiple heroku accounts.

The problem is that the heroku toolbelt authentification is based on ssh certificates. If you create your very first heroku app on your machine, heroku will take your default ssl certificate to authenticate you. Every fingerprint can be only used for one account. It is not possible to use a specific certificate / fingerprint in multiple heroku accounts.

The solution is to have a certificate / fingerprint for every heroku account.

If you want to switch the heroku account you can do it like this:

> heroku logout
> heroku login

The heroku toolbelt will ask you for email and password. After the login process you should check your keys:

> heroku keys

Now you should see the key, which is related to the heroku account, you are logged in right now. if there is no key, you can create a new one with this command here:

ssh-keygen -t rsa -C "<YOUR_EMAIL_ADDRESS>" -f  ~/.ssh/id_rsa_heroku_second_account

Now you can add your new created key with this command:

> heroku keys:add

Now you will see a listing of all your keys. Just select the one you created above.

Now you have to add the key to your key chain:

> ssh-add ~/.ssh/id_rsa_heroku_second_account

With this command here you can see all keys in your key chain:

> ssh-add -l

If you see here multiple keys then you still could have problems by pushing code to the heroku Accout. If you get this Error Message by pushing to heroku:

!  Your key with fingerprint XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX is not authorized to access <YOUR_PROJECT>.

Then the problem is that your ssh client is sending the wrong fingerprint. You can resolve this by removing the first (default) entry with this command:

> ssh-add -r <PATH_TO_YOUR_DEFAULT_CERTIFICAT>

After that the new created certificat should be the only one you see if you type in:

> ssh-add -l

Now you should be able to execute:

> git push heroku master

without problems. At least that worked for me.

 

Cron Jobs on Heroku

Heroku is an App Engine for Ruby on Rails … and other Languages and Frameworks. Heroku is running your application and you don’t have to care about hardware or IT-Infrastructure. It is one abstraction layer above the Amazon Cloud EC2.

First of all, there are no cron jobs on Heroku. Because it is an App Engine you don’t have access to the linux os and the native cron daemon or crontab. Forget it! You have to use heroku worker dynos. Keep reading.

Usually you push your rails app via git to Heroku like this:

git push heroku master

and then it will be deployed on x web dynos. There are different kind of dynos. The default is “web”. If you want to do some background jobs you need a “worker” dyno. You can add worker dynos with this command:

heroku ps:scale worker=1

Now you have to create a Procfile in the root of your application. That can look like this:

web: bundle exec rails server -p $PORT
worker: bundle exec rake do_work

The Procfile is defining the different types of dynos which are available for your application. With “heroku ps:scale” you can scale the dyno types. If you want to have 7 web dynos and 1 worker just execute this:

heroku ps:scale web=7 worker=1

And Heroku will immediately deploy your web application on 7 web dynos and your background job on 1 worker dyno. That is fucking awesome!

All right we added one worker dyno and we defined in the Procfile that “bundle exec rake do_work” should be executed on the worker dyno. Now we just have to define the task “do_work” in the Rakefile.

There are different GEMs for scheduling jobs. For example clockwork, rufus and Qu. I prefer a more simple/native way. With a couple lines of code you can write your own scheduler. This rake task here is executing jobs at a given time. In this example every day at 07:00 AM.


task :do_work => :environment do
  puts "START"

  start_hour = 7
  start_minute = 0

  until 2 < 1 do
    now = Time.now
    hour = now.hour
    minute = now.min
    if hour == start_hour && minute == start_minute

      puts " do work #{Time.now}"

      # execute code here !!!

      if Time.now.hour == start_hour && Time.now.min == start_minute
        sleep(60)
      end
    end
  end
end

Just replace the comment with your code. And push it to heroku

heroku maintenance:on
git push heroku master
heroku maintenance:off

That’s it.