# How to Deploy a Ruby on Rails App on PandaStack (Step-by-Step)
Rails is one of those frameworks that should be easy to deploy but historically hasn't been. Heroku used to handle all of it — now you have to figure it out yourself. This guide shows you how to do it on PandaStack with a minimal Dockerfile and a managed PostgreSQL database.
What You'll Need
- A Rails app (Rails 7+)
- Docker installed locally
- A PandaStack account (free tier works)
- A GitHub repository
Step 1: Add a Dockerfile
Create a Dockerfile in your Rails root:
FROM ruby:3.3-slim
RUN apt-get update -qq && apt-get install -y \
build-essential \
libpq-dev \
nodejs \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /rails
COPY Gemfile Gemfile.lock ./
RUN bundle install --without development test
COPY . .
RUN SECRET_KEY_BASE_DUMMY=1 bundle exec rails assets:precompile
EXPOSE 3000
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]Add a .dockerignore:
.git
log/
tmp/
test/
spec/
node_modules/
.envStep 2: Configure for Production Environment
Make sure your config/database.yml reads from the DATABASE_URL environment variable:
production:
url: <%= ENV['DATABASE_URL'] %>
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>Set RAILS_ENV=production and RAILS_SERVE_STATIC_FILES=true in your PandaStack environment variables — the latter because you're not running a separate Nginx in front of the container.
Step 3: Create a Managed PostgreSQL Database
In the PandaStack dashboard, go to Databases → New Database → PostgreSQL. Once provisioned, you'll get a DATABASE_URL that looks like:
postgresql://user:password@host:5432/dbnameCopy this for the next step.
Step 4: Deploy via Dashboard
- 1Go to Projects → New Project → Container App
- 2Connect your GitHub repository
- 3PandaStack builds the Docker image automatically on each push
- 4Add environment variables:
- DATABASE_URL — your managed PostgreSQL connection URL
- RAILS_ENV=production
- SECRET_KEY_BASE — generate with bundle exec rails secret
- RAILS_SERVE_STATIC_FILES=true
Step 5: Run Database Migrations
After the first deploy, open the PandaStack terminal or run:
panda exec --app my-rails-app -- bundle exec rails db:migrateFor subsequent deploys, you can add a migration step to your deployment config or handle it as part of your container startup.
Step 6: Handle Background Jobs (Sidekiq)
If you use Sidekiq, deploy it as a second container pointing at the same codebase with a different command:
CMD ["bundle", "exec", "sidekiq"]Or use PandaStack's cronjob feature for lightweight scheduled tasks:
panda cronjob create \
--name "rails-housekeeping" \
--image your-org/rails-app:latest \
--schedule "0 2 * * *" \
--command "bundle exec rails cleanup:run"Common Issues
Asset precompilation fails: Make sure RAILS_ENV=production is set at build time and your asset pipeline is configured correctly. The SECRET_KEY_BASE_DUMMY=1 trick lets assets compile without a real secret key.
Database connection errors: Double-check the DATABASE_URL is set correctly in PandaStack environment variables. Don't put it in the Dockerfile.
Slow boot times: Add config.eager_load = true in production.rb for faster request handling after startup.
Resources
- PandaStack docs: [docs.pandastack.io](https://docs.pandastack.io)
- Dashboard: [dashboard.pandastack.io](https://dashboard.pandastack.io)
- CLI install:
npm install -g @pandastack/cli