44

I have set up a RoR environement on AWS' elastic beanstalk. I am able to ssh into my EC2 instance. My home directory is /home/ec2-user, which is effectively empty. If I move up a directory, there is also a /home/webapp directory that i do not have access to.

Is there a way to run a rake command or rails console on my elastic beanstalk instance?

If I type rails console I get Usage: rails new APP_PATH [options] If I type RAILS_ENV=production bundle exec rails console, I get "Could not locate Gemfile"

gitb
  • 1,010
  • 2
  • 10
  • 19
  • finally... I found the solution. look at this https://gist.github.com/tarom/e99fa97c3916c6717baa it worked for me. – 김진언 Nov 12 '15 at 13:28

12 Answers12

59

For rails, jump to /var/app/current then as @juanpastas said, run RAILS_ENV=production bundle exec rails c

kross
  • 3,575
  • 2
  • 27
  • 54
  • 3
    `cd $EB_CONFIG_APP_CURRENT` goes to /var/app/current. `sudo RAILS_ENV=production bundle exec rails c` gives `bundler: command not found: rails`. If I specify the path to rails, `sudo RAILS_ENV=production bundle exec /usr/local/bin/rails c`, I get `Could not find addressable-2.3.6 in any of the sources`. There is something strange going on with how Beanstalk and/or Passenger bundles gems, maybe related to the shared gems described in [this answer](http://stackoverflow.com/a/13657473/550712). – Mark Berry Feb 03 '15 at 01:10
  • see my answer: it should solve all problems: https://stackoverflow.com/a/60585463/3090068 – Yuki Inoue Mar 08 '20 at 07:45
43

Don't know why, but since EBS runs everything as root, this worked for me:

sudo su
bundle exec rails c production
everyman
  • 3,127
  • 1
  • 28
  • 33
  • 3
    Yep, this worked for me too. ```cd /var/app current; sudo su; bundle exec rails c ``` Not sure why but production at the end wasn't needed. – Adam Jun 27 '16 at 11:45
  • This actually runs your rails in `root` user; but current Elastic Beanstalk platform assumes you run rails application in `webapp` user. So, I'd argue we should use `webapp` for what ever command we are using, and doing so is explained in my answer see my answer: it should solve all problems: https://stackoverflow.com/a/60585463/3090068 – Yuki Inoue Mar 08 '20 at 07:47
14

None of these solutions mentioned here worked for me, so I cooked up a little script that I put in script/aws-console.

You can run it from the /var/app/current directory as root:

eb ssh
cd /var/app/current
sudo script/aws-console

My script can be found as a Gist here.

wrdevos
  • 1,806
  • 15
  • 17
8

None of the other answers worked for me so I went looking - this is working for me now on an elastic beanstalk 64bit amazon linux 2016.03 V2.1.2 ruby 2.2 (puma) stack

cd /var/app/current
sudo su
rake rails:update:bin
bundle exec rails console

that returns me the expected console

Loading production environment (Rails 4.2.6)
irb(main):001:0>
Jeremiah
  • 162
  • 2
  • 11
  • Where are you typing `cd/var/app/current`? Is it on your local machine? It says `-bash: cd: /var/app/current: No such file or directory` for me. – Ka Mok Jan 23 '18 at 04:08
  • @KaMok - nah, you need to open an ssh connection to your EB instance - something like `eb ssh myinstancename` - type 'yes' for the auth key and then you'll get dumped to a console where you can type the above. – Jeremiah Jan 24 '18 at 04:16
  • You don't need `myinstancename` if you're `cd` into the directory. – Ka Mok Jan 24 '18 at 17:12
2

I like to create an eb_console file at the root of my rails app, then chmod u+x it. It contains the following:

ssh -t ec2-user@YOUR_EC2_STATION.compute.amazonaws.com  'cd /var/app/current && bin/rails c'

This way, I just have to run:

./eb_console

like I would have run heroku run bundle exec rails c.

Sébastien Saunier
  • 1,597
  • 2
  • 16
  • 26
2

For Ruby 2.7:

if you don't need environment variables:

BUNDLE_PATH=/var/app/current/vendor/bundle/ bundle exec rails c

It looks like environment variables are not loaded automatically anymore, which might prevent rails console from starting. I solved it by creating this .ebextensions file:

# Simply call `sudo /var/app/scripts/rails_c`

commands:
  create_script_dir:
    command: "mkdir -p /var/app/scripts"
    ignoreErrors: true
files:
  "/var/app/scripts/export_envvars":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/opt/elasticbeanstalk/.rbenv/shims/ruby

      if __FILE__ == $0
          require 'json'
          env_file = '/var/app/scripts/envvars'
          env_vars = env_vars = JSON.parse(`/opt/elasticbeanstalk/bin/get-config environment`)

          str = ''
          env_vars.each do |key, value|
              new_key = key.gsub(/\s/, '_')
              str << "export #{new_key}=\"#{value}\"\n"
          end

          File.open(env_file, 'w') { |f| f.write(str) }
      end
  "/var/app/scripts/rails_c":
    mode: "000755"
    owner: root
    group: root
    content: |
      . ~/.bashrc
      /var/app/scripts/export_envvars
      . /var/app/scripts/envvars
      cd /var/app/current
      /opt/elasticbeanstalk/.rbenv/shims/bundle exec rails c
user3033467
  • 755
  • 9
  • 20
1

For the latest ruby version, please use the following command:

BUNDLE_PATH=/opt/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/ bundle exec rails c production

Running it with sudo is not needed.

Malay
  • 323
  • 4
  • 8
0

add an eb extension shortcut:

# .ebextensions/irb.config
files:
  "/home/ec2-user/irb":
    mode: "000777"
    owner: root
    group: root
    content: |
      sudo su - -c 'cd /var/app/current; bundle exec rails c'

then:

$ eb ssh
$ ./irb
irb(main):001:0>
simj
  • 91
  • 1
  • 6
0
#!/bin/sh

shell_join () {
  ruby -r shellwords -e 'puts Shellwords.join(ARGV)' "$@"
}


command_str () {
  printf 'set -e; . /etc/profile.d/eb_envvars.sh; . /etc/profile.d/use-app-ruby.sh; set -x; exec %s\n' "$(shell_join "$@")"
}

exec sudo su webapp -c "$(command_str "$@")"

Put above file somewhere in your source code, deploy, eb ssh into the eb instance, cd /var/app/current, and then execute path/to/above/script bin/rails whatever argumeents you usually use.

Reason why I have written above script is:

  1. When using sudo, it drops some environment variables which might actually be needed for your rails app; so manually load the profiles which the Elastic Beanstalk platform provides.
  2. Current Beanstalk ruby platform assumes you run rails application on user webapp, a non-login-able user, so it would be wise to run your command in this user.
Yuki Inoue
  • 2,652
  • 4
  • 27
  • 40
0

For Ruby 2.7:

As someone said, if you don't need env vars, run the following

BUNDLE_PATH=/var/app/current/vendor/bundle/ bundle exec rails c

However, if you need ENV, I recommend doing this as per AWS doc: https://aws.amazon.com/premiumsupport/knowledge-center/elastic-beanstalk-env-variables-linux2/

tl;dr

On Amazon Linux 2, all environment properties are centralised into a single file called /opt/elasticbeanstalk/deployment/env. No user can access these outside the app. So, they recommend to add some hook scripts after deploy to basically create a copy.

#!/bin/bash

#Create a copy of the environment variable file.
cp /opt/elasticbeanstalk/deployment/env /opt/elasticbeanstalk/deployment/custom_env_var

#Set permissions to the custom_env_var file so this file can be accessed by any user on the instance. You can restrict permissions as per your requirements.
chmod 644 /opt/elasticbeanstalk/deployment/custom_env_var

#Remove duplicate files upon deployment.
rm -f /opt/elasticbeanstalk/deployment/*.bak

If because of some reason you don't want to run as root, do the following to pass env vars from root into new user environment:

sudo -u <user> -E env "PATH=$PATH" bash -c 'cd /var/app/current/ && <wtv you want to run>'
jpgbarbosa
  • 690
  • 4
  • 13
-1

None of these were working for me, including the aws-console script. I finally ended up creating a script directory in /var/app/current and then creating a rails file in that directory as outline by this answer on another SO question.

eb ssh myEnv
cd /var/app/current
sudo mkdir script
sudo vim script/rails

Add this to file and save:

echo #!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.

APP_PATH = File.expand_path('../../config/application',  __FILE__)
require File.expand_path('../../config/boot',  __FILE__)
require 'rails/commands'

Then make it executable and run it:

sudo chmod +x script/rails
sudo script/rails console

And it worked.

Community
  • 1
  • 1
jangosteve
  • 1,522
  • 1
  • 13
  • 26
-2

You have to find the folder with your Gemfile :p.

To do that, I would take a look in you web server config there should be a config that tells you where your app directory is.

Maybe you know where your app is.

But in case you don't know, I would give a try to:

grep -i your_app_name /etc/apache/*
grep -i your_app_name /etc/apache/sites-enabled/*

To search files containing your_app_name in Apache config.

Or if you are using nginx, replace apache above by nginx.

after you find application folder, cd into it and run RAILS_ENV=production bundle exec rails c.

Making sure that your application is configured to run in production in Apache or nginx configuration.

sites
  • 19,991
  • 16
  • 81
  • 136
  • There is no directory /etc/apache or /etc/nginx. As far as I can tell, elastic beanstalk uses passenger. And there was no /etc/passenger directory either. – gitb Oct 30 '13 at 15:28
  • usually, I use passenger on top of nginx or Apache... so Apache or nginx should be there... weird... – sites Oct 30 '13 at 19:46
  • In Beanstalk, the gemfile is in `/var/app/current`. The `$EB_CONFIG_APP_CURRENT` environment variable points there. – Mark Berry Feb 03 '15 at 01:12