How to configure Rails 5 with webpack on AWS Fargate - ruby-on-rails

I have a docker using rails 5 with react and I am using webpack for the js.
Can i run both rails and node.js (to handle react) on the same AWS task definition (i.e same docker inside Fargate) or do I need to split it in 2 AWS task definitions; One for rails and one for node.js?
I would prefer having everything onto one task definition but I am struggling to find example script for it.
I probably need to tune the webpacker.yml but can't find the right configuration.
Also i wondering how to manage the port 3000 from rails and 3035 from node
Did anybody went through similar case before? or try to do similar thing?
Thanks

If possible, I would recommend precompiling your assets in your Rails container, rather than running a dynamic node.js process to do this on the fly.
Something like:
bundle exec rake assets:precompile
In your Dockerfile should work out.

Related

Why does webpacker:compile insert a specific hostname in the javascript_pack_tag?

I've just taken over a Webpack project and am new to Webpack.
Project was deploying to Heroku fine. I ran
rake webpacker:compile
and now, after deploying, I see that
javscript_pack_tag 'application'
has inserted this in the HTML:
<script src="http://0.0.0.0:8080/packs/application.js"></script>
How has a hostname and port from localhost made its way into the system? I can see this information in public/packs/manifest.json but how do I configure webpacker to use the relative path so that the pack will be included on any server?
The tag that's been inserted also doesn't include the expiration hash at the end, so it's not found on Heroku even if I do use the right hostname.
I suspect this is because I'm running webpack:compile with development settings. How do I access these settings?
And finally - is it best practice to run webpack:compile as part of the Heroku deployment process, and how do I set this up?
Thanks,
Louise
Old question, but for anyone else who finds themselves here, I just bumped into something similar after upgrading to webpacker/webpack 4.
After some exploring, I noticed that running webpack directly via node did not prepend the hostname. I had a hunch which turned out to be correct: webpacker was using my ASSET_HOST environment variable to prefix all my packs, and because I was configuring my development env with a .env my development asset host was being used.
Once I moved that to .env.development (so it wasn't being referenced as a base env file for production targeted builds as well) all my manifest resources ended being generated with relative paths as expected.
This wasn't a problem with webpacker 3.x, but I guess something in the webpacker 4.x build pipeline must tie in a little more closely with the rails asset pipeline...

How to setup pgbouncer with rails on heroku?

Heroku recently decreased number of available connections to production database (from 500 to 60). Opened connections were consuming a lot of memory and causing problems, so it seems like a step in right direction.
My app has more than 100 concurrent processes which all access database at same time. Heroku suggests using https://github.com/gregburek/heroku-buildpack-pgbouncer to fix this issue.
I wasn't able to find any proper guide on how to do this. I was able to install and enable buildpack, but I have no ide what these configuration variables do and how do they work. With default configuration, i get tons of ActiveRecord::ConnectionTimeoutError errors.
Does anyone has experience with this and if can please provide provide step-by-step guide on how to do this properly and how to configure everything that needs to be configured?
What version of Rails are you running on? I just deployed pgbouncer to our production webapp using these steps (for a Rails 3.2 app running on Ruby 2.0)
Create .buildpacks file in root directory app that contains the text
https://github.com/gregburek/heroku-buildpack-pgbouncer.git#v0.2.2
https://github.com/heroku/heroku-buildpack-ruby.git
I created a file called disable_prepared_statements_monkey_patch.rb in config/initializers that contained the code posted by cwninja in this thread: https://github.com/gregburek/heroku-buildpack-pgbouncer/pull/7
Modified my Procfile to add
bin/start-pgbouncer-stunnel
before
bundle exec unicorn -p $PORT -c ./config/unicorn.rb
executed
heroku config:set PGBOUNCER_PREPARED_STATEMENTS=false --app yourapp
heroku config:add BUILDPACK_URL=https://github.com/ddollar/heroku-buildpack-multi.git --app yourapp
deployed the new .buildpacks and Procfile changes to production
It worked as advertised after that point. The first time I deployed I neglected to disable prepared statements, which caused my application to blow up with lots of 'duplicate prepared statement errors'. If you're using Rails 4.1 or above the monkey patch is apparently not necessary, however I guess there's a bug in Rails 3.2 that doesn't parse pgbouncer's change to the database URL in such a way that prepared statements are actually disabled.

Start sidekiq from an exploded war

Our current production deployment uses jenkins to deploy a warble generated war file to Tomcat. The whole thing works like a charm. The problem I'm running into however is how to kick start up sidekiq's workers on this machine via "bundle exec sidekiq [options]". Ideally I'd love to avoid setting up a whole seperate ruby environment on this machine just to do this, but either way to run properly, sidekiq needs access to the exploded/installed apps environment etc.
Is there an accepted way to do something like this? Is there a better way to startup sidekiq in instances like this beyond bundle?
This project may be of help. It allows you to package anything that can be a rake task into a jar file. Their documentation has some specific notes about warbler use. Have a look!
For notes on how to run Sidekiq from outside of the command line run something like this from your project root:
cat $(bundle show sidekiq)/bin/sidekiq
You should see some lines:
cli = Sidekiq::CLI.instance
cli.parse
cli.run
If you read into the CLI class, you'll notice that parse takes either ARGV as the default argument, but you can override it with your own arguments:
cli.parse "-q myqueue -e production".split(' ')

Start up required additional services (resque, redis) with `rails server` command

I would like my development environment for Rails to automatically start redis and resque (and potentially in other projects, mongod, mysql-server etc.) for me, in the following cases:
When starting up the development server rails server.
Additionally, it would be nice if the following cases detect already running services, and, if not running start them up too:
Rake rspec, rspec /spec, when running tests.
When starting up a rails console.
When shutting down the rails server, the started child-services should be shut down too.
What is the correct place for such additional startup scripts?
And how to avoid them being started in production too (where I run everything trough /etc/init.d services)?
A lot of these built-in tasks are available as rake tasks already.
You can create a master rake task that does it all.
For example, with resque, you get "rake resque:start" "rake resque:scheduler:start", etc.
You can create a generic "start" task that depends on the rest. Similarly, a "stop" task would shut everything down.
So you would do:
rake start # starts all associated processes
rake stop # stops them all
This is also very use to use from Capistrano, when you end up deploying your code somewhere else. Rake tasks are very easy to call from Capistrano.
I think it's really better to do that in some external script. Do it in your rails server command can be really annoying to anyone to try your code.
By example, in one year, a nez developper come to your project. He can be desoriented if your rails server commande launch a such of other application in background.
In same idea, if you do that you need maintain your code in your rails env. Can be a little tricky. Maintain an independant script can be more usefull.
You can add your script in script directory. That be a good pratice. But not when you launch a command with a manual who do not that.

What's the best way to deploy a JRuby on Rails application to Tomcat?

I'm looking at ways to deploy a Ruby on Rails app (running on JRuby) to a Tomcat instance for testing.
The tomcat instance is running on a Solaris server that I can SSH to. I've looked at using Capistrano, but there doesn't seem to be a lot out there about using it to deploy to Tomcat, or even about running it under JRuby, and I keep hitting bugs in Capistrano due to the Windows/JRuby environment my PC is running (yeah, it's corporate - not my choice, but I've got to live with it).
I'm using warble to build the .war file, and the app deploys and runs fine once I manually copy it up and deploy it. I'm wanting something easier and more automated to actually get it there.
Anyone done this before? Documentation on the web seems pretty thin.
I am running a Rails project using JRuby and deploying to a Tomcat server. I have chosen to deploy with Capistrano because it automates just about everything. I had to make a few minor modifications to Capistrano's deployment lifecycle in order to get it to run on Tomcat:
Step 1: I created a warble task to be run on the server after Capistrano updates the code:
desc "Run the warble command to deploy the site"
namespace(:deploy) do
task :warble do
run ". ~/.profile;cd #{release_path};warble"
end
end
And hooked it into Capistrano lifecycle using:
after 'deploy:update_code', 'deploy:warble'
My Tomcat server has a symlink pointing to the #{release_path}/tmp/war directory created by warble. If you don't like this, you can easily modify the warble task to move the war file into the Tomcat directory instead.
Step 2: I overrode the deploy:start and deploy:stop tasks so that they kick off the Tomcat server instead of a Mongrel server:
desc "Starts the Tomcat Server"
namespace(:deploy) do
task :start do
sudo "#{tomcat_home}/bin/startup.sh"
end
end
desc "Shutdown the Tomcat Server"
namespace(:deploy) do
task :stop do
sudo "#{tomcat_home}/bin/shutdown.sh"
end
end
I run Capistrano tasks using MRI rather than the JRuby interpreter.
I don't have much experience on this, so I don't know if I can give you the BEST way, but if Capistrano doesn't work, and you can't have a separate MRI install just to run it, you have just a few alternatives left:
Try running plain Rake and write your own deployment target:
http://www.gra2.com/article.php/deploy-ruby-on-rails-applications-rake
Or use Ant or Maven.
Or if it just ONE server you have to deploy to, you could just hack together two Ruby scripts - one that listens on the server for shutdown/startup requests, and one local that you run to: Send shutdown, scp over the file, send startup.
By the way, have you submitted any integration bugs you find with Capistrano to the JRuby team? I'm sure they'd be happy to have any contribution.
:)
Might be worth looking at 'Vlad the deployer' it adds remote_task to Rake allowing you to run tasks on a remote server. Personally however I prefer to have a standard Rake task on the server, ssh in and run that task - which would then do an svn checkout, make the WAR file, whatever...
I would probably use Ant for this. After all, it's just another WAR file, right? I don't know which version of Tomcat you're using but version 4.1x comes with an Ant task for deploying to Tomcat.
There's a few Capistrano recipes for deploying to Tomcat -- I built one into a gem called capistrano-tomcat. It takes a WAR you've built (probably with Warbler) and deploys and starts a Tomcat instance on a remote server.
The source is up on Github: http://github.com/rhunter/capistrano-tomcat

Resources