The first deployment is work fine.
Padam Shankhadev
1

Capistrano will create a new release folder for each deployment. To keep hold of the files/folders in each deployment, you need to store them in a separate file path and add a symlink to your release folder during deployment.

For example:

Set shared path variable in you staging.rb/production.rb file

set :shared_path, '/home/user/web/shared'

Write a task in deploy.rb to create the storage folder in the shared path

desc "Create shared folders"
task :create_storage_folder do
on roles(:all) do
execute "mkdir -p #{shared_path}/storage"
execute "mkdir #{shared_path}/storage/app"
execute "mkdir #{shared_path}/storage/framework"
execute "mkdir #{shared_path}/storage/framework/cache"
execute "mkdir #{shared_path}/storage/framework/sessions"
execute "mkdir #{shared_path}/storage/framework/views"
execute "mkdir #{shared_path}/storage/logs"
end
end

You could use the following task to create symlink between the content of shared path to release path

desc "Symbolic link for shared folders"
task :create_symlink do
on roles(:app) do
within release_path do
execute "rm -rf #{release_path}/storage"
execute "ln -s #{shared_path}/storage/ #{release_path}"
end
end
end

And call the task like so, in your deploy task

namespace :deploy do
after :published, "create_symlink"
end

As for the permission issue, you need to make sure, your user for php process, nginx and user when you deploy, all are in sync. You can watch the following video by Chris Fidao to learn more about user permissions and other stuffs regarding a server.

Copying .env file is a little tricky. Since, it contains your username and passwords, and also other secret credentials, you do not want those in your configuration files. What you want to do is, store those data in the server and copy it to your release path on each deployment.

For that, create a sed file somewhere in your server.

For example: environment_variables.sed

s|%db_database%|databasename|g
s|%db_username%|username|g
s|%db_password%|password|g

Create a environment variables placeholder file in the root your project.

For example: .env.server

DB_DATABASE=%db_database%
DB_USERNAME=%db_username%
DB_PASSWORD=%db_password%

Set path to the folder containing environment_variables.sed in you staging.rb/production.rb file

set :env_path, '/home/user/web/env'

Create a task in your deploy.rb file to replace the placeholders with actual value and create .env file in your release path.

desc "Set environment variables"
task :set_variables do
on roles(:app) do
puts ("--> Copying environment configuration file")
execute "cp #{release_path}/.env.server #{release_path}/.env"
puts ("--> Setting environment variables")
execute "sed --in-place -f #{fetch(:env_path)}/environment_variables.sed #{release_path}/.env"
end
end

And finally call the task inside your deploy task

namespace :deploy do
after :updated, "set_variables"
end
Show your support

Clapping shows how much you appreciated Sumit Chhetri’s story.