The first deployment is work fine.
Padam Shankhadev

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"

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}"

And call the task like so, in your deploy task

namespace :deploy do
after :published, "create_symlink"

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


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

For example: .env.server


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"

And finally call the task inside your deploy task

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

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