Rails 8 with Solid Queue 1.1 deployed with Capistrano
While configuring my Ruby on Rails application, I ran into unexpected challenges setting up Solid Queue 1.1.3. With PostgreSQL as the database and Capistrano handling deployments (though I haven’t explored Kamal yet), I anticipated a straightforward setup—but version 1 introduced some complexities.
After researching blog posts, GitHub issues, and troubleshooting along the way, I’ve compiled this guide to help others overcome similar configuration hurdles more easily.
Server setup
I use the one Fotbo VPS (referral link) with Postgres manually preinstalled and configured Capistrano for deployment on Debian 12. To run Solid Queue, I set up systemd
as was mentioned in the first good documentation I found from Rob Zolkos.
So, we need to define the systemd service in a file located in your deploy users home folder (in my case, the use name is deploy
):
/home/deploy/.config/systemd/user/solid_queue.service
Insert the configurations (change the <my app>
and /home/deploy/.rbenv/shims/ruby
to your values):
[Unit]
Description=solid_queue for my app
After=syslog.target network.target
[Service]
Type=simple
Environment=RAILS_ENV=production
WorkingDirectory=/home/deploy/<my app>/current
ExecStart=/home/deploy/.rbenv/shims/ruby -- /home/deploy/<my app>/current/bin/jobs
ExecReload=/bin/kill -TSTP $MAINPID
ExecStop=/bin/kill -TERM $MAINPID
Environment=MALLOC_ARENA_MAX=2
RestartSec=1
Restart=on-failure
SyslogIdentifier=solid_queue
[Install]
WantedBy=default.target
Take a note to the ExecStart
command, since the Solid Queue changed the way to start the service I used the binstub command, previously it was rake solid_queue:start
Reload the daemon after adding the configurations so the new service is loaded:
$ systemctl --user daemon-reload
Start the service:
$ systemctl --user start solid_queue.service
Check the status:
$ systemctl --user status solid_queue.service
● solid_queue.service — solid_queue for my_app
Loaded: loaded (/home/deploy/.config/systemd/user/solid_queue.service; enabled; preset: enabled)
Active: active (running) since Sat 2025-02-22 10:23:51 UTC; 24h ago
...
Enable the service to start at boot:
$ systemctl --user enable solid_queue.service
Enable the service to keep running when the deploy user is logged out:
$ sudo loginctl enable-linger
This is all that you should do on the server.
Application setup
Solid Queue gem
I created the app using Rails 8, so the Solid Queue gem was already added to the Gemfile. But in case you are migrating from Rails 7, just follow the gem's documentation:
$ bundle add solid_queue
$ bin/rails solid_queue:install
This will configure Solid Queue as the production Active Job backend, create the configuration files
Solid Queue READMEand
config/queue.yml
, and create the
config/recurring.yml
. It'll also create a
db/queue_schema.rb
executable wrapper that you can use to start Solid Queue.
bin/jobs
Once you've done that, you will then have to add the configuration for the queue database in.
config/database.yml
# config/database.yml
production:
primary: &primary_production
<<: *default
database: app_production
username: app
password: <%= ENV["APP_DATABASE_PASSWORD"] %>
queue:
<<: *primary_production
database: app_production_queue
migrations_paths: db/queue_migrate
Check the config/environments/production.rb
so it has these lines:
config.active_job.queue_adapter = :solid_queue
config.solid_queue.connects_to = { database: { writing: :queue } }
Then run
in production to ensure the database is created and the schema is loaded. In my case this command didn't create the database, so I created it manually, but for some reason I received the db:prepare
PG::UndefinedTable: ERROR: relation "solid_queue_jobs" does not exist
error when I tried to schedule the job for later.
After the investigation, I found the Loading schema in production GitHub Issue where as temporal solution was this suggestion to loaded the schema in a rails console with:
ActiveRecord::Base.establish_connection(:queue)
load 'db/queue_schema.rb'
After that, my background job was successfully scheduled 🎉!
Capistrano setup
To get the solid_queue
systemd service to restart during the deployment, I added these tasks to deploy.rb
file:
# solid queue
set :solid_queue_systemd_unit_name, "solid_queue.service"
namespace :solid_queue do
desc "Quiet solid_queue (start graceful termination)"
task :quiet do
on roles(:app) do
execute :systemctl, "--user", "kill", "-s", "SIGTERM", fetch(:solid_queue_systemd_unit_name), raise_on_non_zero_exit: false
end
end
desc "Stop solid_queue (force immediate termination)"
task :stop do
on roles(:app) do
execute :systemctl, "--user", "kill", "-s", "SIGQUIT", fetch(:solid_queue_systemd_unit_name), raise_on_non_zero_exit: false
end
end
desc "Start solid_queue"
task :start do
on roles(:app) do
execute :systemctl, "--user", "start", fetch(:solid_queue_systemd_unit_name)
end
end
desc "Restart solid_queue"
task :restart do
on roles(:app) do
execute :systemctl, "--user", "restart", fetch(:solid_queue_systemd_unit_name)
end
end
end
after "deploy:starting", "solid_queue:quiet"
after "deploy:updated", "solid_queue:stop"
after "deploy:published", "solid_queue:start"
after "deploy:failed", "solid_queue:restart"
So when you run cap production deploy
the solid_queue service will be restarted automatically by Capistrano.
Mission Control — Jobs
This gem provides a Rails-based frontend to Active Job adapters. If you are familiar with Sidekiq Dashboard, this gem does the same for the Solid Queue jobs, in a separate route, it gives you the ability to check all the background jobs statistics, pause, restart failed, etc.
The setup is simple:
$ bundle add mission_control-jobs
$ bin/rails mission_control:jobs:authentication:configure
In the prompt, you need to set the user name for the basic auth, these credentials will be saved in the Rails.application.credentials
mission_control:
http_basic_auth_user: dev
http_basic_auth_password: secret
Mount Mission Control Job's engine where you wish to have it accessible from your app, in your
file:routes.rb
Rails.application.routes.draw do
# ...
mount MissionControl::Jobs::Engine, at: "/jobs"
Now you can open the /jobs
path in your browser, enter the credentials you added, and you should see the Mission Control:

This is how it looks on my fresh set up.
Conclusion
Ruby on Rails is a powerful framework that enables fast development. However, you might encounter challenges due to changes in configurations and approaches across different open-source gems. Fortunately, the community is welcoming, and you can always find tips, suggestions, and assistance. If you haven't already, consider sharing your knowledge or joining the community. Here's a post on why Rails is excellent for solo development.