2026-04-06·5 min read·sota.io team

Deploy Ruby on Rails to Europe — GDPR-Compliant Rails Hosting in 2026

Ruby on Rails turns 21 this year. It powers Shopify, GitHub (still partially), Basecamp, and thousands of B2B SaaS products across Europe. And yet finding a managed, GDPR-compliant PaaS for Rails in 2026 remains harder than it should be.

Heroku was the original Rails home — David Heinemeier Hansson launched Rails in 2004, and Heroku launched in 2007 specifically to host it. For years the two were synonymous. But Heroku removed its free tier in 2022, prices climbed, and crucially: Heroku's EU region is eu-west-1 (Amsterdam, AWS). That's a US-owned company processing your data on US-owned infrastructure, regardless of which European datacenter the servers sit in.

sota.io is a different answer: EU-owned infrastructure on Hetzner Cloud in Germany, flat pricing, and zero DevOps required.

Why "EU Region" on AWS Isn't Enough

GDPR's data transfer rules (Articles 44-49) restrict processing of EU personal data by entities subject to US jurisdiction. The 2020 Schrems II ruling invalidated Privacy Shield and put standard contractual clauses under serious scrutiny — because a US company can be compelled by US law (CLOUD Act, Section 702 FISA) to produce data regardless of where it's stored.

When you deploy to Heroku EU, Railway EU, or Render EU, your data processor is still a US company. The datacenter is in Amsterdam or Frankfurt, but the legal entity processing your data is American.

sota.io's position: Hetzner Cloud GmbH is a German company, regulated under German and EU law. Your Rails app runs in Germany. Your PostgreSQL database lives in Germany. The entire processing chain is EU-owned. GDPR Article 28 DPA available.

Heroku vs Kamal vs sota.io

Rails 7 and 8 introduced Kamal, DHH's own Docker deployment tool. It's powerful, but it's a self-managed solution: you bring your own servers, manage your own SSL, handle your own zero-downtime deployments. Kamal is excellent if you want control. Most teams don't want to manage servers.

sota.io is the managed layer above Kamal's philosophy: the same Docker-based, convention-over-configuration approach, but with the operational side handled. No server provisioning, no kamal setup, no firewall rules.

Featuresota.ioHeroku EUKamal (self-managed)
EU data residencyGermany (EU-owned)Amsterdam (AWS, US-owned)Wherever you host
Managed PostgreSQLIncludedPaid add-on (Heroku Data)Self-managed
Zero-downtime deploysBlue-green, automaticYesYes (but you configure it)
GDPR DPA availableYesLimitedN/A
PricingFlat €9/moUsage-based, expensiveServer cost only
DevOps requiredNoneNoneYes
EU-owned infrastructureYesNoDepends

Deploy Rails to sota.io in 3 Steps

Rails apps deploy as Docker containers. If you don't have a Dockerfile yet, sota.io auto-generates one from your Gemfile.

Step 1: Install the CLI and deploy

curl -fsSL https://sota.io/install.sh | sh
cd my-rails-app
sota deploy

Step 2: Set required environment variables

sota env set RAILS_ENV=production
sota env set SECRET_KEY_BASE=$(rails secret)
sota env set RAILS_SERVE_STATIC_FILES=true

Step 3: Live

Your app gets an HTTPS URL at {project}.sota.io in under 60 seconds.

$ sota deploy

Packaging...           done
Detecting framework... Ruby / Rails
Building image...      done
Deploying...           done

> Live at https://my-rails-app.sota.io

Dockerfile for Rails 7/8

For production Rails apps, a multi-stage Dockerfile keeps your image lean:

# Stage 1: Build dependencies
FROM ruby:3.3-slim-bullseye AS builder
WORKDIR /app

RUN apt-get update -qq && apt-get install -y \
    build-essential \
    libpq-dev \
    nodejs \
    yarn \
    && rm -rf /var/lib/apt/lists/*

COPY Gemfile Gemfile.lock ./
RUN bundle install --without development test --jobs 4

COPY . .
RUN bundle exec rails assets:precompile RAILS_ENV=production

# Stage 2: Runtime image
FROM ruby:3.3-slim-bullseye
WORKDIR /app

RUN apt-get update -qq && apt-get install -y libpq5 && rm -rf /var/lib/apt/lists/*

COPY --from=builder /app .
COPY --from=builder /usr/local/bundle /usr/local/bundle

EXPOSE 3000

CMD sh -c "bundle exec rails db:migrate && bundle exec puma -C config/puma.rb"

Puma is the default Rails application server since Rails 5. It reads the PORT environment variable — sota.io sets PORT=3000 automatically (matching your EXPOSE directive).

PostgreSQL with Active Record

sota.io provides managed PostgreSQL 17 with every project. The connection credentials are auto-injected at runtime via standard PG* environment variables. Your config/database.yml can read them directly:

# config/database.yml
production:
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  url: <%= ENV['DATABASE_URL'] %>

Or if you prefer explicit variables:

production:
  adapter: postgresql
  host: <%= ENV['PGHOST'] %>
  port: <%= ENV['PGPORT'] %>
  database: <%= ENV['PGDATABASE'] %>
  username: <%= ENV['PGUSER'] %>
  password: <%= ENV['PGPASSWORD'] %>

No DATABASE_URL configuration needed on your end — all six variables (DATABASE_URL, PGHOST, PGPORT, PGDATABASE, PGUSER, PGPASSWORD) are available automatically.

Migrations on Startup

Because there is no shell access to running containers, migrations must run as part of the startup command. The CMD in the Dockerfile above handles this:

bundle exec rails db:migrate && bundle exec puma -C config/puma.rb

For zero-downtime migrations on larger apps, use Strong Migrations gem and write backward-compatible migrations — sota.io's blue-green deployment strategy means the old container keeps serving traffic until the new one passes its health check.

Authentication with Devise

Devise is the standard Rails authentication gem. It requires a few secrets to be set:

sota env set SECRET_KEY_BASE=$(rails secret)
sota env set DEVISE_SECRET_KEY=$(rails secret)

For email configuration (password resets, confirmations):

sota env set SMTP_ADDRESS=smtp.postmarkapp.com
sota env set SMTP_PORT=587
sota env set SMTP_USER_NAME=your-postmark-token
sota env set SMTP_PASSWORD=your-postmark-token

Then in config/environments/production.rb:

config.action_mailer.smtp_settings = {
  address: ENV['SMTP_ADDRESS'],
  port: ENV['SMTP_PORT'],
  user_name: ENV['SMTP_USER_NAME'],
  password: ENV['SMTP_PASSWORD'],
}

Shopify App Developers in the EU

Shopify itself is built on Rails. Many EU developers building Shopify apps use the Rails + Shopify API gem stack, and GDPR compliance is a hard requirement for any app listed in the Shopify App Store that handles merchant or customer data.

sota.io is a natural fit for this use case: your Shopify app backend runs in Germany, merchant webhook data stays in the EU, and you have a GDPR DPA to satisfy Shopify's compliance requirements. The flat €9/mo pricing is predictable regardless of webhook volume.

Get Started

Free tier: 5 projects, 256 MB RAM, hosted in Germany. No credit card required.

Join the waitlist at sota.io →

No region selection needed. No GDPR configuration. No managed servers. Your Rails app ships to the EU by default.


See also: Deploy Node.js to Europe · Deploy Python to Europe · Railway Alternative — EU-Native Hosting