keepcalculator

06 Numbers and Powers

Fix Capistrano Deployment Failures on Rails

Card No. 06·43124 · Updated · Standard formula, shown below

This guide walks you through diagnosing and fixing the most common Capistrano deployment failures on Rails applications. You’ll learn how to read error logs, identify the root cause, and apply targeted fixes for issues like permission errors, missing dependencies, database problems, and asset compilation failures.

What You’ll Need

  • Access to your Rails application’s repository and deployment server (SSH access)
  • Basic familiarity with the command line and Rails project structure
  • Your Capistrano configuration files (Capfile, config/deploy.rb, config/deploy/ directory)
  • Your application’s log files (production.log, capistrano.log, and system logs)

Step-by-Step

  1. Reproduce the failure and capture output
    Run the failing command manually: cap production deploy. Do not use --quiet or --silent. Capture the full output, including any stack traces. The error message usually points to the failing task, such as deploy:assets:precompile or deploy:migrate.
  2. Check the Capistrano log
    Look at log/capistrano.log on your local machine. It contains a detailed history of all commands run on the server. The last commands before the failure often reveal where the problem started.
  3. Verify SSH connectivity and permissions
    Run ssh deploy@your-server to confirm you can log in. Check that the deploy user has write permissions to the release and shared directories: ls -la /var/www/yourapp/releases. If permissions are wrong, fix them with chown -R deploy:deploy /var/www/yourapp (adjust paths to your setup).
  4. Check Ruby and Bundler versions on the server
    Capistrano uses the server’s Ruby environment. Run ruby -v and bundle -v on the server. If they don’t match your Gemfile’s required versions, install the correct ones using rbenv or rvm. Update .ruby-version and Gemfile if needed.
  5. Inspect the Gemfile.lock
    Ensure Gemfile.lock is committed to the repository. If it’s missing, run bundle install locally and commit the lock file. Capistrano uses this to install exact gem versions on the server.
  6. Check the shared directory symlinks
    Capistrano symlinks files from shared/ into each release (e.g., config/database.yml, log/, tmp/). If a symlink target is missing, deployment fails. Verify that shared/config/database.yml exists and has correct permissions. If not, create it and set correct values.
  7. Test database connectivity
    If the migration task fails, check the database configuration in shared/config/database.yml. Run RAILS_ENV=production bundle exec rails db:create db:migrate manually on the server to see the exact database error. Common issues: wrong host, missing credentials, or the database server not accepting remote connections.
  8. Check asset precompilation
    If the failure is in deploy:assets:precompile, run RAILS_ENV=production bundle exec rails assets:precompile manually. Look for missing gems (like sassc or terser) or Node.js/Yarn issues. Ensure Node.js is installed if your assets require JavaScript compilation.
  9. Verify the secrets and credentials
    Rails 5.2+ uses config/credentials.yml.enc. Make sure the RAILS_MASTER_KEY is set on the server, usually in shared/config/master.key or as an environment variable. Without it, the app can’t decrypt secrets and may fail during boot.
  10. Check the puma/unicorn configuration
    If deployment succeeds but the app doesn’t come up, check the app server config. Ensure the socket path in shared/pids/ and shared/sockets/ exists and is writable. Look at the application logs in shared/log/production.log for startup errors.
  11. Look at the system logs
    If the app server fails to start, check system logs: journalctl -u your-app (if using systemd) or tail -f /var/log/syslog. This often reveals missing environment variables or permission issues.
  12. Rollback if necessary
    If you can’t fix the issue quickly, run cap production deploy:rollback to revert to the last good release. This restores the previous version and gets the site back up while you debug.

Common Mistakes

  • Forgetting to commit Gemfile.lock – Without it, bundler resolves versions differently on the server, causing dependency conflicts.
  • Hardcoding server-specific paths – Using absolute paths in your app code that don’t exist on the server. Use Rails.root or relative paths.
  • Ignoring the shared directory – Not creating the required files in shared/ (like database.yml) before first deploy. Always set up shared files first.
  • Using the wrong Ruby version – The server may have a different Ruby than your local machine. Always specify the Ruby version in .ruby-version and install it on the server.
  • Not checking the release directory permissions – If the deploy user can’t write to releases/, the deploy fails immediately. Ensure the directory is owned by the deploy user.
  • Skipping the asset precompile test – Many failures happen because assets compile locally but not on the server due to missing system libraries (like libv8 for therubyracer). Test precompilation on the server.

Tips

  • Use a staging environment first – Deploy to a staging server that mirrors production to catch issues before they affect users.
  • Keep your Capistrano version up to date – Newer versions have better error messages and support for modern Rails. Check your Gemfile for the capistrano gem version.
  • Set up a CI pipeline – Run tests and asset precompilation in CI to catch issues before deployment.
  • Use environment variables for secrets – Instead of storing secrets in files, use a tool like dotenv or the server’s environment variables. This reduces the risk of missing keys.
  • Monitor your log files – Set up log rotation and monitoring for production.log and capistrano.log to detect issues early.
  • Document your server setup – Write down the exact Ruby version, Node version, and system packages needed. This makes it easier to reproduce and fix issues.

Troubleshooting

If the above steps don’t resolve the issue, try these additional checks:

  • Check the exact error line – The error message often includes a file and line number. Search that error online or in the Rails issue tracker. Many errors have known solutions.
  • Run the deploy with verbose output – Use cap production deploy --trace to see every task that runs. This helps identify which task is failing.
  • Check for disk space – Run df -h on the server. A full disk can cause writes to fail silently. Clean up old releases with cap production deploy:cleanup.
  • Verify the server’s timezone – If your app uses time-sensitive logic, a timezone mismatch can cause issues. Set the server’s timezone to UTC or your app’s expected timezone.
  • Check for firewall or SELinux issues – If the app can’t connect to the database or external services, check if the server’s firewall or SELinux is blocking connections. Temporarily disable SELinux to test, but re-enable it after.
  • Compare with a working deployment – If you have another environment (staging) that works, compare the server configurations. Differences in Ruby, Node, or system packages can be the culprit.

Frequently Asked Questions

Why does my deployment fail with a permission denied error?

This usually means the deploy user doesn’t have write access to the release or shared directories. Check the ownership of /var/www/yourapp and its subdirectories, and ensure the deploy user is the owner or in the correct group.

What does “Could not find gem ‘rails’ in any of the gem sources” mean?

This means Bundler on the server can’t find the gems listed in your Gemfile. This often happens when Gemfile.lock is not committed, or when the server’s Ruby version is incompatible. Run bundle install on the server manually to see the exact error.

How do I fix a database connection error during migration?

Check the shared/config/database.yml file for correct host, port, username, and password. Test the connection manually with RAILS_ENV=production bundle exec rails db:create. Also ensure the database server allows connections from your app server’s IP.

Why does asset precompilation fail with a Node.js error?

Rails uses Node.js for JavaScript compression. If Node.js isn’t installed or is an incompatible version, precompilation fails. Install Node.js (LTS version) on the server and ensure it’s in the PATH for the deploy user.

What should I do if the deploy succeeds but the app shows a 500 error?

Check shared/log/production.log for the stack trace. Common causes include missing database tables, missing secrets, or incorrect file permissions. The log will point you to the exact issue.

How can I rollback to the previous release?

Run cap production deploy:rollback. This will symlink the previous release and restart the app server. If that fails, you can manually switch the symlink: ln -s /var/www/yourapp/releases/20240101120000 /var/www/yourapp/current and restart the app.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →