dotenv and linked_files with capistrano 3 - ruby-on-rails

Having a really hard time getting this to work. I just added dotenv gem to accommodate for the Rails 4.1 secrets.yml file. I also have in the .env file the database.yml's password.
To add to my deploy:
set :linked_files, %w{config/database.yml .env}
When I run cap production deploy I get:
/shared/config/database.yml does not exist on 107.170.....
How can I get the database.yml to be added?
I looked at the capistrano touch gem with no luck because after I create the empty files, ActiveRecord throws an error of No 'production' database

Create task for upload your .env and database.yml.Look example below:
desc "Database config"
task :setup_config, roles: :app do
# upload you database.yml from config dir to shared dir on server
put File.read("config/database.yml"), "#{shared_path}/config/database.yml"
# make symlink
run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
# upload you database.yml from config dir to shared dir on server
put File.read(".env"), "#{shared_path}/config/.env"
# make symlink
run "ln -nfs #{shared_path}/config/.env #{current_path}/.env"
end
And add before and after hooks.
Or use dotenv-deployment that contain the same tasks.

Related

How to upload a file to release directory during Capistrano deploy?

The Capistrano production.rb file executes 3 tasks
composer install --no-dev
mkdir storage
upload! ".env.production", ".env"
The first 2 are executed, but the upload fails: "No such file or directory".
I was able to scp the file successfully from the command line.
How to copy a file to the current release directory?
$ cap --version
Capistrano Version: 3.11.0 (Rake Version: 12.3.1)
$ cap production deploy
...
01 mkdir -p ~/public_html/app/releases/20181122210112
...
composer install --no-dev
...
mkdir storage
...
SSHKit::Runner::ExecuteError:
Exception while executing as me#site.com:
scp: ~/public_html/app/releases/20181122210112/.env:
No such file or directory
DEBUG Uploading .env.production 0.0%
...
$
scp the file successfully from the command line:
$ scp .env.production me#site.com:~/public_html/app/releases/20181122210112/.env
production.rb
# use absolute path
set :deploy_to, "/home/user/public_html/app"
namespace :deploy do
desc "Install app dependencies with composer"
after :updated, :build do
on roles(:web) do
within release_path do
execute :composer, "install --no-dev"
execute :mkdir, "storage"
end
end
end
end
namespace :deploy do
desc "Copy Env"
after :finished, :copy do
on roles(:all) do
upload! ".env.production", "#{release_path}/.env"
end
end
end
if your need is to copy your local application.yml to the server, and you are already using capistrano, you can use the capistrano figaro gem, it creates a task to update this file on server. in theory, you could run the task automatically and make this file to be updated. is an old gem, but works like a charm and do the work.

Capistrano + whenever + db database.yml not found

I'm trying to run Capistrano 2.15.5 with Whenever 0.8.4 and Ruby 2.0.0
I've added
set :whenever_command, "bundle exec whenever"
require "whenever/capistrano"
to the end of my deploy.rb file and it always run:
/releases/20150910075216 && bundle exec whenever --update-crontab
app_name --set environment=production --roles db
and fails wth
No such file or directory -
/releases/20150910075216/config/database.yml
because database.yml is in folder /shared/ anyways I don't need the db -
how to get rid of --roles db in the capistrano command?
I have
server("my_server", :app, :web, :db, :primary => true)
because I need the :db for other scripts.
Thanks for help!
David
You should set linked_files Symlink linked files database.yml as following in deploy.rb for capistrano 3
set :linked_files, fetch(:linked_files, []).push('config/database.yml')
Or you can do Symlink manually for older version.
desc "Make symlink for database yml"
task :symlink do
run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
end

how to copy a file to capistrano shared folder

I have file config/secrets.yml which has to be in my remote server in the shared folder. And it is not in my git repo, so it's not updated as other regular files.
I don't know how generate file the first time.
What I have done till the moment is to create a symlink each time I deploy with
run "ln -nfs #{shared_path}/config/secrets.yml #{release_path}/config/secrets.yml"
which will "update" file in each deploy, but the first time? how to generate secret.yml the first time?
You have to add to your .gitignore file:
/config/secrets.yml
the cap task:
task :symlink_config, roles: :app do
run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
run "ln -nfs #{shared_path}/config/secrets.yml #{release_path}/config/secrets.yml"
end
after "deploy:finalize_update", "deploy:symlink_config"
The .yml file in the shared folder I usually create it myself.
If you're using capistrano v3.x, you can easily use the :linked_files configuration variable to achieve this.
You can safely add config/secrets.yml to .gitignore and use capistrano's :linked_files configuration variable.
capistrano generally adds a template line with config/database.yml and the config/secrets.yml to the array when you cap install. You just have to uncomment that line that looks like :
set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml')
Regarding how to generate the secrets.yml file for the first time (it is a one-time task of course), you do have to run rake secret and put the secret key generated out of it, in the file. It looks like this :
development:
secret_key_base: <some alphanumeric hash>
some_key: 338a3312d82
some_secret: f5d9c3214e7b
other_environment: development
other_password: password
production:
secret_key_base: <the key generated with `rake secret`>
some_key: 338a3312d82
some_secret: f5d9c3214e7b
other_environment: development
other_password: password

Capistrano and Carrierwave

I'm deploying a Ruby on Rails and NodeJS application using Capistrano. The uploads folder gets removed on every deploy.
This popped up on several places but it doesn't seem to work:
# Keep File Uploads
task :symlink_uploads do
run "ln -nfs #{shared_path}/rails/uploads #{release_path}/rails/public/uploads"
end
after 'deploy:update_code', 'deploy:symlink_uploads'
the repo:
repo:
/node
/rails
Thanks!
There is another solution to this problem. You can add your uploads dir to Capistrano's shared_children and it will do all the magic automatically. You can find more details in this answer: https://stackoverflow.com/a/9710542/835935
Make sure you remove the existing public/uploads folder, passing -f to ln doesn't cover removing target directories (or at least hasn't done so portably for me)
My symlink directories tasks normally look like
task :symlink_uploads do
run "rm -rf #{release_path}/rails/public/uploads} && ln -nfs #{shared_path}/rails/uploads #{release_path}/rails/public/uploads"
end
Obviously make sure there is nothing in the checked in version of public/uploads that you need!
Did you try
after 'deploy:update_code', ':symlink_uploads'
Your :symlink_uploads task is not in a namespace, so rather do the above or put it in a namespace
namespace :deploy do
task :symlink_uploads do
# ...
end
end
I have similar problem with uploaded file with my RoR app. This is my capistrano tasks:
...
task :link_public_folder, :roles => [:app, :web] do
run "mv -u #{release_path}/public/* #{shared_path}/public"
run "rm -rf #{release_path}/public"
run "ln -s #{shared_path}/public #{release_path}/public"
end
after "deploy:update", "deploy:link_public_folder"
task :setup_config, :roles => :app do
sudo "ln -nfs #{current_path}/config/apache.conf /etc/apache2/sites-available/#{application}"
run "mkdir -p #{shared_path}/config"
run "mkdir -p #{shared_path}/public"
put File.read("config/database.yml"), "#{shared_path}/config/database.yml"
puts "Now edit the config files in #{shared_path}."
end
after "deploy:setup", "deploy:setup_config"
...
Maybe help you
Edit:
I use Carrierwave too.

Carrierwave files with Capistrano

I'm using rails 3.2 with asset and carrierwave for upload some images, they store in /public/uploads/photo/.....
but when I do a cap:deploy (with capistrano) my current directory application doesn't contain the files I uploaded, because capistrano make a new version ....
=== Update ===
After all I use this :
inside :deploy namespace
task :symlink_uploads do
run "ln -nfs #{shared_path}/uploads #{release_path}/public/uploads"
end
and after:
after 'deploy:update_code', 'deploy:symlink_uploads'
=== Re Update ===
The solution of #tristanm is the best way to solve this.
How about this:
# config/deploy.rb
set :shared_children, shared_children + %w{public/uploads}
:shared_children defaults to %w(public/system log tmp/pids) so we're just expanding this list.
EDIT:
Don't forget to run cap deploy:setup after changing :shared_children so that the new targets are created under shared.
EDIT Capistrano 3:
Capistrano 3 uses the linked_dirs setting and doesn't specify public/system as a default anymore.
set :linked_dirs, fetch(:linked_dirs) + %w{public/system public/uploads}
With Capistrano 3 and without needing to redeploy.
Like #tristanm mentioned add this to your config/deploy.rb
# config/deploy.rb
set :linked_dirs, fetch(:linked_dirs) + %w{public/uploads}
To have capistrano create shared/public/uploads
cap deploy:check:linked_dirs
Now cap can create the symlink
cap deploy:symlink:shared
Finally, if you have backups of the uploads you can put them in shared/public/uploads/ and they should work without needing to redeploy.
Capistrano creates new directory for every deploy.
There are some exceptions to it. For example, the log files are shared between the deployment directories because they are just symlinks. You have to create a symlink for public/uploads as well.
Here is the command:
run <<-CMD
rm -rf #{latest_release}/public/uploads &&
ln -s #{shared_path}/uploads #{latest_release}/public/uploads
CMD
Go to your app server shared folder and create an uploads directory.
mkdir uploads
In your deploy.rb file insert these codes under deploy namespace
task :symlink_uploads do
run "rm -rf #{latest_release}/public/uploads && ln -nfs #{shared_path}/uploads #{latest_release}/public/uploads"
end
after 'deploy:update_code', 'deploy:symlink_uploads'
Now delete the old files present already as they won't work. Upload a new file and cap deploy your app again. It should work now.
Using Capistrano 3, I just added this line to my config/deploy.rb
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system public/uploads}
Then, run:
$ cap production deploy

Resources