Why does this Travis deploy to Heroku fail? - ruby

I use Travis CI to build a Ruby app. The app is deployed to Heroku after a successful build. After upgrading from Cedar to Cedar-14 and changing Ruby version to 2.1.4 (as this was required for the stack upgrade) the deploy step fails when Heroku precompiles the project. I have tried various deploy strategies but without success. The logs don’t specify the invalid url which makes it hard to track the troubleshoot this issue. From the deploy log:
Running: rake assets:precompile
rake aborted!
ArgumentError: invalid url
/tmp/build_4345603424563456/vendor/bundle/ruby/2.1.0/gems/redis-3.0.7/lib/redis/client.rb:364:in `_parse_options’
When I push the app straight to Github, the deploy is successful and the stack upgrades to Cedar-14.
So, why does the Heroku deploy step suddenly fail when using Travis CI?

This issue was solved by passing the url to the Redis initialization constructor explicitly instead of using the 'old' way of passing the parsed symbols. The old way seems to work best (if not exclusively) with versions before Rails 4. This was confirmed by the Redis To Go documentation on Heroku: Redis To Go
Rails 4
REDIS = Redis.new(:url => redis_url_string)
pre-Rails 4
uri = URI.parse(redis_url)
REDIS = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
For another, similar issue, see this post: Why does Travis fail to connect use Redis cache_store when deploying to Heroku?

Related

Why can't I deploy rails project running on legacy stack (bamboo)?

I have not yet migrated my rails project to the cedar stack.
I want to push some bug fixes to my production app on heroku,
but here is the response:
$ git push heroku master
remote: ! bamboo-mri-1.9.2 stack not supported.
fatal: unable to access 'https://git.heroku.com/project.git/': The requested URL returned error: 400
Is it still possible to deploy legacy apps running on bamboo?
Thanks!
The problem is resolved by using git over ssh, instead of over https.
https transport is unsupported on the legacy bamboo stack. Here's
the heroku article:
https://devcenter.heroku.com/articles/git#ssh-git-transport
For ssh transport, you have to jump through a few hoops to bring up
your connection. I found this article very helpful.

Heroku Rails 4 could not connect to server: connection refused

Using postgres.
Haven't been able to push.
Tried this without any luck:
config.assets.initialize_on_precompile = false
-----> Preparing app for Rails asset pipeline
Running: rake assets:precompile
rake aborted!
could not connect to server: Connection refused
Is the server running on host "127.0.0.1" and accepting
TCP/IP connections on port 5432?
The accepted answer did not fully resolve this. I tried to find a solution for 2-3 hours without success, then this worked:
In your app directory.
heroku labs:enable user-env-compile
it is still failing?
heroku labs:disable user-env-compile
heroku labs:enable user-env-compile
Then it worked for me, just had to remove and do again.
The following config is no longer needed in Rails 4. Compiling assets must work without it.
config.assets.initialize_on_precompile = false
config.assets.initialize_on_precompile = false
Include that in application.rb, ABOVE module APPNAME
I had originally included it inside
class Application < Rails::Application
Edit: actually, the above didn't fix it.
I had to do this
https://devcenter.heroku.com/articles/labs-user-env-compile
Try executing locally
bundle exec rake assets:precompile RAILS_ENV=production
It might be because of devise gem as in my case. You might be missing secret key in devise initializer. try adding
config.secret_key = "PROVIDE-KEY"
The heroku dev center talks about troubleshooting this. Basically your rails4 app should not rely on having config vars present during runtime.
https://devcenter.heroku.com/articles/rails-asset-pipeline#troubleshooting
If you're using Rolify pre version 3.5 then it might be that:
https://github.com/EppO/rolify/issues/221

When or where in a custom Heroku buildpack are config vars available in the environment?

I understand that running a rake task that expects the environment to fully work requires that the DB connection can actually be stablished. Basically, that's the reason why Heroku needs asset pipeline precompilations to run before the environment can be loaded.
That's why this line is needed to deploy rails 3.X apps to the Cedar:
config.assets.initialize_on_precompile = false
Now, I'm trying to build a custom build pack that needs a rake task to do other assets compilations to make the app work as expected. This is because I have internationalized JS asset files and use https://github.com/fnando/i18n-js
I need to run rake i18n:js:export and that requires the environment. *Is there any point in the buildpack where I can add this call and be sure that the connection to the DB of the Rails app will work? * Loading the environment is as a requirement of this task and I don't know how to work it out and it gives the typical error:
rake aborted!
could not connect to server: Connection refused
Is the server running on host "127.0.0.1" and accepting
TCP/IP connections on port 5432?
Naturally, I can compile locally and then deploy. But the buildpack seems like the right tool to solve this matter in an automated way. Thanks for the help!
Check out the user env Heroku labs feature: https://devcenter.heroku.com/articles/labs-user-env-compile

How to restart Heroku worker using heroku gem

I'm struggling to find how to call the equivalent of (taken from this article):
heroku restart worker.1
using the heroku gem. I see there are restart and ps_restart methods but don't see where I can specify to only restart this 1 worker and not the whole app.
Here is the command to restart any particular process
heroku ps:restart worker.1 --app APP_NAME
I'm doing specific worker restarts from within the app using a cron. Like this:
heroku = Heroku::Client.new(ENV['APP_USERNAME'], ENV['APP_PASSWORD'])
heroku.ps_restart(ENV['APP_NAME'], :ps =>'worker.1')
From the Heroku API Doc
Use the "heroku-api" gem, NOT the "heroku" gem. Using the "heroku" gem this way still works (as of today), but is deprecated. It's meant to be used via the console.
https://github.com/heroku/heroku.rb
The api gem looks very easy to use. Grab you API key from the heroku website, put it in your app config variables, and call:
require 'heroku-api'
heroku.post_ps_restart('app', 'ps' => 'web.1') # restart 'web.1' process for 'app' app
Currently, you have to take the "platform-api" gem (documentation here) from heroku because the "heroku" gem is not working anymore and the "heroku-api" gem is used to interact with the Heroku Legacy API. The Legacy API will be sunset on April 15th, 2017.
First you have to create an oAuth token via the heroku toolbelt command line tool:
$ heroku plugins:install heroku-cli-oauth
$ heroku authorizations:create -d "Platform API example token"
Created OAuth authorization.
ID: 2f01aac0-e9d3-4773-af4e-3e510aa006ca
Description: Platform API example token
Scope: global
Token: e7dd6ad7-3c6a-411e-a2be-c9fe52ac7ed2
Use the Token value when instantiating a client:
require 'platform-api'
heroku = PlatformAPI.connect_oauth('e7dd6ad7-3c6a-411e-a2be-c9fe52ac7ed2')
restart a specific dyno with this command:
heroku.dyno.restart(app_id_or_app_name, dyno_id_or_dyno_name)
or restart all with this command:
heroku.dyno.restart_all(app_id_or_app_name)
You can get the ids of all your apps with
heroku.app.list
And the ids of the app's dynos via
heroku.dyno.list(app_id_or_app_name)
To expand on coderuby's answer a bit:
heroku = PlatformAPI.connect_oauth(ENV['PLATFORM_API_TOKEN'])
worker_ids = heroku.dyno
.list(ENV['HEROKU_APP_NAME'])
.select { |dyno| dyno['type'] == 'worker' }
.map { |dyno| dyno['id'] }
worker_ids.each do |id|
heroku.dyno.restart(ENV['HEROKU_APP_NAME'], id)
end
Having set the appropriate environment variables. You could include this in a rake task then have Heroku's scheduler run it when you see fit.

Heroku RACK_ENV says "development" on Thin, but "staging" on Unicorn

I came across this behavior and was wondering if anyone else had seen it. I have a workaround so it's not a show-stopper.
I created a new app on Heroku with a Cedar stack. When demonstrating multiple environments I added the following config var:
heroku config:add RACK_ENV=staging --app appname
I visually verified that the environment var was set, then put the following route in my simple Sinatra example:
get '/?' do
ENV['RACK_ENV']
end
When I tested locally on my laptop, I received the expected development.
When I pushed to Heroku and hit the same route on herokuapp.com I got development instead of staging.
I switched the web server from Thin to Unicorn through the Procfile and pushed the changes back up to Heroku.
Now when I hit the route, I get the expected staging.
Has anyone else seen this? My workaround on another project where I was running Thin was to key the environment off of the New Relic app name. (I didn't switch to Unicorn because I need New Relic to work and currently Cedar and New Relic and Unicorn work together).
I had the same problem with sinatra and thin on the cedar stack using heroku's example sinatra app. The RACK_ENV refuses to be set to anything but development. (Heroku seems to think that it's RACK_ENV is set, since running 'heroku config' displays the environment you set, however in the app it's always development).
The same app on the bamboo stack had no problems.
EDIT: I submitted a ticket to heroku about this and got a really quick response which fixed the bug for me:
QUOTE:
It looks like there's a small bug in our default Procfile if you're using thin. Can you create a Procfile with the following in it?
web: bundle exec thin start -R config.ru -e $RACK_ENV -p $PORT
You can also set both your RACK_ENV and RAILS_ENV to staging using the Heroku gem ... then it works as expected. I think it may be a problem with Heroku.

Resources