Deploy Ruby on Rails on Your Own Server

Push your Rails app and Temps takes it from there — installing gems, precompiling assets, running migrations, and serving with Puma and automatic HTTPS. No config files needed.


Quickstart

From your project root, deploy with your preferred package manager:

npx @temps-sdk/cli up

A Gemfile on its own is not a detection signal, so set the nixpacks-ruby preset on the project first (or nixpacks to let Nixpacks choose). Without it the build stops with "Could not auto-detect project type from files".

With that preset selected, the build runs bundle install, handles the asset pipeline, and starts your app with bundle exec rails server -b 0.0.0.0 -p ${PORT:-3000}. Specify your Ruby version in a .ruby-version file — the Ruby build has no default and fails without one.


What Temps handles automatically

FeatureHow Temps handles it
Installbundle install
Assetsbundle exec rails assets:precompile
Migrationsbundle exec rails db:migrate on every deploy
App serverPuma
HTTPSLet's Encrypt, auto-renewed
PortPORT env var injected, defaults to 3000
Action CableWebSocket support via reverse proxy

Managed services

Add PostgreSQL and Redis from Project → Services → Add Service. Temps injects DATABASE_URL and REDIS_URL automatically.

npx @temps-sdk/cli environments vars set RAILS_ENV production -e production

npx @temps-sdk/cli environments vars set SECRET_KEY_BASE "$(openssl rand -hex 64)" -e production

Background jobs with Sidekiq

Add a Procfile to run Sidekiq alongside your web process:

web: bundle exec puma -C config/puma.rb
worker: bundle exec sidekiq

Temps runs each process type as a separate container.


Action Cable

Action Cable WebSockets work out of the box. Set config.action_cable.allowed_request_origins to include your domain:

# config/environments/production.rb
config.action_cable.allowed_request_origins = ["https://yourdomain.com"]

Platform behavior

These rules apply to every app deployed on Temps, regardless of framework.

The one requirement: your app must listen on the port in the PORT environment variable and bind to 0.0.0.0 — not localhost or 127.0.0.1. Temps runs your app in a container and routes traffic from the host, so an app bound to localhost only accepts connections from inside the container and will fail its health check.

Health checks

After your container starts, Temps sends HTTP GET requests to verify it is healthy before routing traffic to it.

  • Path: / (the root of your application)
  • Success: 2 consecutive responses with a 2xx or 3xx status code
  • Timeout: 300 seconds (5 minutes) for the app to become healthy
  • Retry interval: every 5 seconds

Connection errors while the app is still starting are retried without penalty. If the app returns 4xx or 5xx errors for 60 consecutive seconds, the deployment fails. Customize the check by adding a .temps.yaml to your repository root:

.temps.yaml
health:
  path: /health
  status: 200
  interval: 30
  timeout: 5
  retries: 3
Add a dedicated /health endpoint that returns a simple 200. This avoids issues where / requires authentication or returns a redirect.

Auto-injected environment variables

Temps injects these variables into every deployment automatically:

VariableValueDescription
PORTResolved portThe port your app must listen on
HOST0.0.0.0Bind address
SENTRY_DSNAuto-generatedError tracking endpoint
TEMPS_API_URLYour Temps URLPlatform API endpoint
TEMPS_API_TOKENDeployment tokenAuthentication for Temps SDKs
OTEL_EXPORTER_OTLP_ENDPOINTYour Temps OTLP URLOpenTelemetry trace collection
OTEL_SERVICE_NAMEProject nameService identifier for traces

You do not need to configure these manually. They are available in process.env (Node.js), os.environ (Python), os.Getenv (Go), and the equivalent in other languages.


Next Steps

Was this page helpful?