I am working on a web app, hosting the source code on Github and running the app on Heroku. Everything works fine, but I have on issue I can't wrap my head around. Before the deploying my code, I run some scripts to optimize the code (minifying, concatenating files etc.). The heroku app only uses the optimized version of the app.
Basically, I have two folders: dev
and production
. Dev
contains the source code I write, production
is produced by my build scripts (I use grunt and requirejs). Currently, both folders are in my Git repository and both are pushed to Github and Heroku. What I'd rather like is to only have dev
on Github and only production
on Heroku.
I read some articles how to setup different branches for Heroku, as described in this blog. Could I setup a production branch and only have the production
folder in there while keeping the dev
folder to my master branch? Or would I need separate repositories?
Has anyone tried something similar? I would assume that this is not something out of the ordinary.
You may want to simply consider using the heroku .slugignore
file (ref https://devcenter.heroku.com/articles/slug-compiler).
This file would allow you remove the dev
folder from the package that heroku deploys to each server instance, while allowing you to keep all your code in the same repository.
The root of the problem is thinking about the deployment strategy as one where you upload final bits to your server, where the bits are an artefact of building your repository. In such cases, builds are usually stored and archived separately from the source.
Heroku's model is slightly different from this in that it assumes your repository is the artefact to deploy. The difference is slight, but in your case, it just means that you need to commit to your repository the bits you want heroku to serve.
Another way of thinking about it is that you could do without your production
folder, and as part of starting your server, the script would be run to generate the production
folder files. This would allow you to remove the production
folder, and keep your repository clean at the cost of running this process on every start of your server. This may prove to be prohibitively expensive and undesirable (there are limits to how long Heroku will wait for a server to startup before it gives up on it), but hopefully helps in providing some clarity around the Heroku and git relationship.
This situation is a bit unusual. But here are some ideas:
dev
folder.Create a rake
file with two tasks in it: rake deploy:production
and rake deploy:postprocess_files
. Those tasks might look something like this:
namespace :deploy do
task :production do
puts "turn on 'maintenance page' on heroku"
system "heroku maintenance:on"
puts "deploying to production"
system "git push heroku-prod master"
puts "post processing files..."
system "heroku run rake production:postprocess_files"
puts "take off maintenance page"
system "heroku maintenance:off"
puts "done"
end
task :postprocess_files do
puts "run postprocessing of files on heroku"
... add commands here to post process the files.
end
end
Then deploy to production using rake deploy:production
rather than pushing using git directly. The rake file will then:
Note that the second rake task in your file has the commands to do the post processing on your files and is invoked to run on heroku by the first rake task.
As an alternative, it's possible you may be able to extend the assets:precompile task that Heroku runs as part of each deploy. That's essentially what you're doing anyway -- preparing assets for deployment to production.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With