How to use capistrano v3 and shared config files with ERB - ruby-on-rails

I'm converting my RoR app to use capistrano v3. I have a number of configuration file that are generated by ERB. Most of these files, like like /etc/logrotate.d/app_name, are referenced external to my app. So I like the idea of linking them to my shared/config directory. Capistrano supports managing linked files via the linked_files array. So far so good. But, the files to be linked don't technically exist until I run ERB. And capistrano runs :deploy:check:linked_files as the first step of :starting, at which point the files don't exist and the check fails.
So my question is, what's a really good way to handle this? Do I check in empty config files in my config directory, let capistrano link them to shared, and then overwrite them via ERB at a later stage? That doesn't feel good. I can't generate them before the :starting task because on an initial deploy the source tree isn't there yet. Any suggestions?

Related

Where should I save standalone non-ruby scripts in my Rails app?

This is a simple question, but I haven't been able to find an exact answer to it anywhere.
I have a standalone Python script which I am using in my Rails app. What is the appropriate folder I should save it in according to convention, so that I can push it to production (currently running it from my computer's desktop)? I think the answer is lib/assets but I want to make sure.
I don't think there is an exact answer for this question.
If it is a ruby script, it is usually placed in lib or bin.
From the rails folder descriptions in Getting Started with Rails guide:
bin/ Contains the rails script that starts your app and can contain
other scripts you use to setup, deploy or run your application.
lib/ Extended modules for your application.
You could put it in lib/assets folder as it reflects your understanding that it is an external asset used in the system.

Add Seeds file after Dokku build

I am using dokku-alot to deploy my Rails 4 app to my staging server and everything is working just swell.
One requirement I have with my current project is in regards to seed file data. I've had to keep my seeds.rb file out of version control because of sensitive information. However, I can't figure out how to add the seeds.rb file into the container after a build.
I've tried ssh root#myhost ap_name which gets me into the VM but even if I scp the files into there, the container doesn't see them. How can I drop a few files where my rails code is in the docker image?
Depending on how much information is in your seeds.rb file, you could use environmental variables. This the solution I ended up using.
You basically set the variable: config:set my-app SECRET=whateversupersecretinfo. Then in your code, you can extract that app variable by using ENV['SECRET']. (This works pretty much the same in Heroku) Not sure if that would solve your use case, but leaving this answer here for posterity.
subnote: In Node.js you can extract these variables like process.env.SECRET

How to Tell Engine Yard to Not Delete a File in the .gitignore

To give you some context, I'm trying to use Figaro to safely add in environment variables without having to worry about security risks. The problem is is that I can't seem to get Engine Yard to play nice with production.
I went and did a touch application.yml and then vim application.yml, i, and then command+v to insert that api keys and what not. I know the ENV['VARIABLES'] work because of development and all my rspec and cucumber tests (which utilize the APIs), passed.
When I've got everything ready, I add within the .gitignore:
# Ignore application configuration
/config/application.yml
Afterwards, I deploy the site. I open it up and data isn't going to the APIs anymore. OK...
cd into config and discover application.yml isn't there anymore. Paste it back in... Redeploy the site since now it understands it has to ignore that file and I'm not seeing changes on production. Check back... and its gone again!
Stumped on what's going on.
Simply putting a file into your deployed application's filesystem will not work because you get a clean environment each time you deploy. EngineYard cannot know that you want that particular file copied to that particular location without a little bit of extra work.
Their official recommendation is to put your YAML configuration files in /data/<app>/shared/config and symlink them to /data/<app>/current/config each time you deploy using deploy hooks.

Excluding a file type from the asset pipeline

I have several PSD files stored in my images folder. It's nice to keep these files there for development, but I don't want them to be served. Is there a config somewhere that would allow me to prevent a filetype from being precompiled?
Your best bet might be to exclude these files during deployment. For example, with Heroku if you add a .slugignore file to the root of your project you can exclude certain files from being included. This also has the added benefit of decreasing spin up times on Heroku. An example configuration would be:
*.psd
*.pdf
doc
You should be able to do something similar with Capistrano.
Edit:
This post shows how to do something similar for Capistrano deploys:
Excluding files from being deployed with Capistrano while still under version control with Git

Capistrano: Version control for files in shared/

When Capistrano deploys a Rails app, it creates a shared/ directory to store files that should be shared across releases and not re-exported every time. In my application I have several things in the shared/ directory that rarely change (so they belong there rather than in the application tree), but I'd still like them to be version controlled for the times when they do change.
What is the best way to approach version controlling those files but keeping them separate from the repository Capistrano is exporting from?
The /shared directory is really for un-versioned data. For example, you might store bundled gems so that you don't have to re-install all your gems every release. You can also store you logs there so they don't get overwritten every time you deploy. You can store pid files there so you don't loose the process ids of critical processes during a deploy. You might even store user generated or partially processed data there so that it is not removed during a release. If a file is meant to be versioned and has the chance of changing though, I would recommend keeping it with the rest of your files and out of the shared directory.
That said, you can always also write deploy scripts to pre-populate data in your shared directory, like database configuration files. These scripts will get run on each deploy and can be entirely customized. For example, your database config script might only write the config file if it doesn't already exist.
Another common use of the shared directory is for configuration files. Versioning and source control for configuration files is a very good idea, but should managed in a system configuration management tool. In my environment, I manage code releases with Capistrano and system configuration with Puppet. That way, there is still source control over configuration files, but they are kept distinct from the code deploy process. In turn, the code deploy process is kept independent of system configuration.

Resources