Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk12 min

How to Provision a Rails Server on a VPS with Ansible

Build a repeatable Rails VPS with Ansible by separating host provisioning from releases and defining Ruby, PostgreSQL, Puma, Nginx, systemd, secrets, handlers and rollback as code.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Provision a Rails VPS with Ansible by defining the entire host as code: a supported Ubuntu LTS image, a locked Ruby and dependency set, PostgreSQL, Puma, Nginx, systemd services, users, firewall rules and deployment directories. A conventional production path is Nginx → Puma → Rails, with PostgreSQL beside the application. Keep first-boot provisioning separate from application releases, store secrets outside Git, and make every task safe to run repeatedly.

The workflow below assumes an Ubuntu 22.04 (Jammy) VPS, SSH-key access and an account with sudo or root privileges. It uses roles for common host setup, Ruby, PostgreSQL, the Rails application, Puma, Nginx and releases.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What the finished server looks like

A small Rails deployment can run on one VPS when its responsibilities are explicit. Nginx accepts HTTP and HTTPS traffic, serves eligible static files and proxies dynamic requests to Puma. Puma runs the Rails process as an unprivileged application user. PostgreSQL provides the database, while systemd starts, stops and supervises Puma (and any workers). Ansible installs and configures each layer.

Layer Responsibility Managed by
Operating system Packages, users, time, firewall, logs and build libraries common role
Ruby runtime Ruby version required by the Gemfile, Bundler and JavaScript tooling ruby role
Database PostgreSQL server, application database and least-privilege role postgresql role
Application Release checkout, gems, environment configuration and compiled assets rails_app and deploy roles
Application server Puma unit, sockets or ports, workers and restart behavior puma role
Web proxy Nginx virtual host, TLS termination, static files and proxy headers nginx role
Process supervision Boot persistence, controlled restarts and service status systemd

This division is more than cosmetic. It lets you rebuild a host without mixing one-time operating-system work with a particular application release, and it gives each change a clear owner.

#1 Best Overall
Elebase USB to USB C Adapter for iPhone 18 Pro Max,USBC Car Charger Adapter | 4Pack Type C Female to A Male Cable Converter for Apple Duo 17 16 15 14 Plus,iWatch Watch 12 11 10,iPad 9 8 Air,Airpods 5 4
  • Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
  • Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
  • Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
  • Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
  • 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.

Prerequisites and decisions to make first

Choose a supported base image

Start with a supported Ubuntu LTS VPS. The documented example uses Ubuntu 22.04 Jammy. Record the image and region in your infrastructure notes; package names, service behavior and security support depend on that choice.

Prepare access without making the application root

Have an SSH key and privileged access before Ansible connects. Bootstrap a dedicated deployment user, place its public key in authorized_keys, and grant only the sudo commands that provisioning and release tasks need. The Rails process, Puma and workers should run as this unprivileged user, not as root.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Lock the software inputs

Put the operating-system assumptions, Ruby version, Rails dependency set, PostgreSQL version, Nginx version, Puma version and Ansible version in version-controlled variables or release documentation. The Gemfile and lockfile remain authoritative for Ruby dependencies; Ansible should not silently select the latest runtime or package.

Decide where state lives

Choose the application path, shared configuration path, release retention policy, database location and backup destination before writing roles. A single VPS keeps PostgreSQL local and avoids network latency, but it also makes the host a shared failure domain. A managed database moves backup, restore and failover duties to the provider, introduces a network dependency and normally costs more; the exact monthly amounts are not established here.

Use a repository that mirrors the architecture

A compact repository can be organized like this:

ansible.cfg
inventories/
  production/
    hosts.yml
    group_vars/
      all.yml
      rails.yml
playbooks/
  site.yml
  release.yml
roles/
  common/
  ruby/
  postgresql/
  rails_app/
  puma/
  nginx/
  deploy/

Keep host names and non-secret defaults in inventory and group variables. Put credentials, RAILS_MASTER_KEY and provider tokens in an encrypted variable store, a protected environment file or another deployment secret mechanism. Never commit those values to the repository. Restrict the file owner and mode so only the deployment user or the service that needs a value can read it.

Define explicit variables

At minimum, define variables for the application name, deploy user, application root, repository URL, requested revision, Ruby version, Bundler version, database name, database role, database host, Puma bind address, worker settings, domain names, TLS paths and release retention. Keep environment-specific values in the production inventory rather than embedding them in role tasks.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Sale
Anker USB-C Hub, 5-in-1 USB Hub for Laptops, 4K HDMI Multiport Adapter | USB C Dongle with 90W Max Power Delivery, 3×5Gbps USB A Data Ports, for MacBook, Dell, and More (Charger Not Included)
  • 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
  • 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
  • Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
  • 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
  • What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.

Compose roles in one site playbook

A site playbook should apply roles in dependency order. A representative composition is:

---
- name: Provision Rails hosts
  hosts: rails
  become: true
  roles:
    - common
    - ruby
    - postgresql
    - rails_app
    - puma
    - nginx
    - deploy

Ansible describes playbooks as repeatable, reusable configuration-management and multi-machine deployment artifacts. Treat this file as the contract for a complete host, not as a bag of imperative commands.

Bootstrap the host safely

  1. Confirm connectivity. Test the inventory and SSH key with ansible -i inventories/production/hosts.yml rails -m ansible.builtin.ping. Fix DNS, the key, the remote user or sudo policy before running changes.
  2. Create the deployment identity. Use ansible.builtin.user to create the deploy user, install its authorized key with ansible.posix.authorized_key and configure narrowly scoped sudo access. Do not remove your recovery account until the new login has been tested in a second session.
  3. Apply the baseline. Run the common role for package updates, time configuration, firewall policy, log retention and required build libraries. Limit inbound traffic to SSH, HTTP and HTTPS, plus database access on a private network when another host genuinely needs it.
  4. Check the result. Verify the Ansible facts, service manager, free disk space, hostname, clock and listening ports before installing application software.

Do not hide bootstrap work in an unguarded shell script. If a command is unavoidable, give it a clear condition such as creates, set an intentional changed_when result and make its check-mode behavior understandable.

Build the Ruby and Rails runtime

Install the version the application requests

The ruby role should install the Ruby version required by the Gemfile, configure the selected version manager (the representative stack uses rbenv), install the pinned Bundler version and install the JavaScript tooling needed by the Rails asset pipeline. Expose all of those choices as variables so a review shows exactly what a host will receive.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Install compilers and native libraries in common or ruby, then run dependency installation as the deploy user. A root-owned gem directory or a root-owned application checkout will later prevent releases from writing caches, logs or compiled assets.

Keep application and runtime paths predictable

Create the application directory with ansible.builtin.file, set ownership to the deploy user and separate immutable release directories from shared data such as uploaded files, logs and environment configuration. The release role should point a stable current path at the selected release so Puma and Nginx do not need to change on every deploy.

Rank #3
Sale
Anker USB C Hub, 7in1 Multi-Port USB Adapter, 4K@60Hz USBC to HDMI Splitter | 85W Max PD, 2 USB 3.0 & 1 USBC Data Ports, SD/TF Card Reader, for Laptops/Mac and Other Type C Devices (Charger Not Included)
  • Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
  • Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
  • Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
  • Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
  • What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.

Install and constrain PostgreSQL

Install the server and create least-privilege identities

The postgresql role installs the selected PostgreSQL version, starts it at boot and creates an application database and role. The application role should own only the database objects it requires; reserve superuser access for administration. Keep the database on the VPS only if its disk, memory and recovery requirements fit the host.

Restrict connections

For a same-host Rails application, bind PostgreSQL to local access where practical. If a private-network application host must connect remotely, allow only that network in PostgreSQL rules and the firewall. Do not open the database to the public internet merely to simplify setup.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Make backups useful

Provisioning a database is not a backup strategy. Configure a recurring backup destination, monitor failures and perform restore drills. Before a migration that can remove or transform data, take a verified backup and document how to restore it.

Provision the Rails application directory

  1. Create shared paths. Make directories for releases, shared configuration, logs, sockets and persistent uploads. Set ownership and restrictive modes with the file module.
  2. Fetch a known revision. Use ansible.builtin.git to check out an explicit tag or commit rather than an unbounded branch. A release should be reproducible from its revision and lockfiles.
  3. Install gems. Run Bundler as the deploy user with the production settings required by the application. Avoid running dependency commands as root.
  4. Install JavaScript dependencies and compile assets. Use the project’s locked dependency files and compile assets before switching the live symlink. Keep temporary build output out of the shared directory.
  5. Expose configuration. Link or render a protected environment file containing the Rails master key, database credentials and provider tokens. Ensure only the deploy user and the relevant service account can read it.
  6. Run a pre-switch check. Confirm that the release boots, can load its credentials and can reach PostgreSQL before pointing current at it.

Do not combine a checkout, migration and service restart into one opaque shell command. Separate tasks make failures visible and allow a release to be left untouched when an earlier step fails.

Configure Puma under systemd

Render a dedicated unit

The puma role should template a systemd unit that runs Puma as the deploy user, sets the working directory to the stable current release, loads the protected environment and writes logs to the locations you monitor. The unit should use the application’s Puma configuration for bind address, threads, workers and preload behavior.

Use the fully qualified ansible.builtin.systemd_service module to enable, start, stop and restart the unit. The shorter systemd name is a backward-compatible alias, but the qualified name avoids collection-name conflicts. If the same role must support hosts with different init systems, ansible.builtin.service is the portability layer that proxies to the detected service manager.

Rank #4
Sale
UGREEN USB to USB C Adapter Combo 4-Pack, 10Gbps USB C Converter Space Gray | Data transfer & Fast charging for MacBook, iPhone 17/16/15, iPad, Samsung Galaxy, Apple Watch
  • Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
  • Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
  • Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
  • Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
  • Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft

Attach handlers to configuration changes

Notify a handler when the unit, Puma configuration or environment wiring changes. The handler should run a controlled daemon reload followed by a restart only when necessary. A normal idempotent play should not bounce Puma on every run.

- name: Render Puma unit
  ansible.builtin.template:
    src: puma.service.j2
    dest: /etc/systemd/system/myapp-puma.service
    mode: '0644'
  notify: Restart Puma

- name: Ensure Puma is enabled and running
  ansible.builtin.systemd_service:
    name: myapp-puma.service
    enabled: true
    state: started

Choose restart or reload deliberately. A restart is simpler but interrupts in-flight requests unless your Puma and proxy configuration provide an appropriate graceful behavior. A reload may preserve workers, but only if the unit and application support it.

Put Nginx in front of Rails

Render the virtual host

The nginx role installs Nginx and templates a virtual host for the application domain. Proxy requests to Puma’s local socket or loopback port, pass the original host and forwarding headers, set sensible request and proxy timeouts, and serve precompiled static assets from the current release only when the Rails configuration expects Nginx to do so.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Validate before reloading

Run Nginx’s configuration test as a task and notify a reload handler only after it succeeds. A syntax error must leave the last known-good configuration running. Keep TLS termination at Nginx with an automated certificate-renewal process, and test renewal rather than assuming the timer works.

Handle WebSockets and streaming intentionally

If the application uses Action Cable, server-sent events or other long-lived responses, configure the proxy and Puma behavior for those connection types and test them through the public endpoint. Ordinary request forwarding is not proof that streaming works.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Separate provisioning from releases

Provisioning installs packages, users, directories, service definitions and baseline configuration. A release procedure changes application code and data. Keeping them separate means a rebuilt VPS can be provisioned first, while a failed application release can be rolled back without re-running operating-system changes.

Best Value
Sale
Anker USB C Hub, 5-in-1 USBC to HDMI Splitter with 4K Display | 85W Max PD, 1 Powered USB-C 5Gbps & 2 Powered USB-A 3.0 5Gbps Data Ports, for MacBook Pro, MacBook Air, Dell and More (Black)
  • 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
  • Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
  • Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
  • HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
  • What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.

A repeatable release sequence

  1. Fetch the requested revision into a new release directory.
  2. Install the locked Ruby and JavaScript dependencies as the deploy user.
  3. Render or link shared configuration and verify that the release can load its credentials.
  4. Compile assets.
  5. Take a verified database backup when the migration is destructive or otherwise risky.
  6. Run database migrations explicitly and record their result.
  7. Run application checks or a health command against the new release.
  8. Switch the stable current path to the release.
  9. Restart or gracefully reload Puma through systemd.
  10. Run local and external health checks, then retain enough previous releases for the documented rollback procedure.

Capistrano-style releases fit this directory-and-symlink model. Container or Kamal-style workflows instead package the application into an image and replace containers. Containers can improve image reproducibility and make rollback to an image straightforward, while a single VPS still requires host, network, storage and certificate maintenance. The better choice depends on the team’s familiarity and whether image builds are already part of its delivery system.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Make Ansible tasks idempotent

An idempotent role converges a host to the desired state instead of repeating side effects. Prefer the package, user, file, template, git and service modules. For commands that have no suitable module:

  • Use creates or removes to prevent repeating one-time work.
  • Set changed_when from a reliable result rather than reporting a change every run.
  • Use failed_when only when the command’s exit behavior requires it.
  • Make check mode meaningful, or clearly document the task that cannot predict changes.
  • Notify handlers instead of restarting services in every task.

Run the site playbook twice against a test VPS. The second run should report no unexplained changes. Review every reported change; an apparently harmless repeated migration, package upgrade or service restart can create a production outage.

Verification after provisioning

Host and service checks

  • Confirm the deploy user can connect with its SSH key and has only the intended sudo rights.
  • Check that the firewall exposes SSH, HTTP and HTTPS and no unintended database port.
  • Use systemd status and journal output to verify Puma and PostgreSQL are enabled and running.
  • Check disk space, log rotation and the ownership of releases, shared files and sockets.

Application checks

  • Call a local Rails health endpoint through Puma and confirm a successful database query.
  • Request the public HTTPS endpoint through Nginx and verify forwarding, static assets and redirects.
  • Exercise authentication, background jobs, WebSockets or streaming when the application uses them.
  • Inspect Nginx, Puma, Rails and PostgreSQL logs for startup warnings, permission errors and connection failures.

Failure branches

If Puma fails to start, inspect the systemd journal first, then verify the current symlink, Ruby and Bundler versions, environment file permissions, database connectivity and the Puma bind path. If Nginx returns a gateway error, confirm that Puma is listening where the virtual host expects and that the proxy user can access the socket. If a migration fails, do not automatically retry destructive SQL: preserve the failed release, restore from a verified backup when necessary and follow the application’s migration recovery plan.

Security and reliability checklist

  • Use SSH keys and disable password login when your recovery process supports it.
  • Limit inbound ports to SSH, HTTP and HTTPS, with private-network database access only where required.
  • Keep RAILS_MASTER_KEY, database credentials and provider tokens outside source control.
  • Run Rails, Puma and workers as an unprivileged application user.
  • Terminate TLS at Nginx, automate certificate renewal and test renewal before expiry is an emergency.
  • Rotate and retain logs, monitor disk health and alert on failed Puma, worker and database services.
  • Back up PostgreSQL and perform restore drills, not just backup jobs.
  • Take a verified backup before migrations that may be irreversible.
  • Pin all application and infrastructure versions, and update those pins deliberately.

Choosing between common deployment options

Decision Option A Option B What changes operationally
Ruby web serving Nginx plus Puma Passenger Puma uses a separate Ruby process supervised by systemd; Passenger integrates more of the process lifecycle into the web-server model. Compare team familiarity, worker supervision, memory behavior and deployment tooling.
Database location PostgreSQL on the VPS Managed PostgreSQL Local placement avoids network latency and an extra service, but you own backups, restores, upgrades, isolation and failover. Managed placement shifts much of that work to the provider while adding network dependency and recurring cost.
Release method Capistrano-style directories and symlinks Container or Kamal workflow Directory releases make a conventional VPS easy to inspect and roll back; images improve artifact reproducibility but require image storage, build automation and container-host maintenance.

Rollback and ongoing maintenance

A rollback plan must name the exact command or playbook, the release to restore, the service action and the database decision. Code can usually be pointed back to a retained release; a migration that changed the schema may not be reversible. Treat schema changes as a compatibility problem: deploy code that can work with both versions when possible, then remove old structures in a later release.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Schedule deliberate maintenance for OS packages, Ruby, Rails, PostgreSQL, Nginx, Puma and Ansible. Test updates on a disposable VPS or staging host, review the resulting Ansible diff, apply changes during a maintenance window and verify the same health checks used after a release. Version drift is a deployment risk when the host silently receives latest packages, so upgrades should be visible, reviewed and pinned.

The practical operating model

The safest small Rails VPS is not the one with the fewest files; it is the one whose desired state can be reconstructed. Keep the Ubuntu image and every runtime version explicit, compose focused roles, let handlers restart services only after validated configuration changes, and run releases as a separate, observable workflow. With secrets outside Git, least-privilege services, tested backups and a documented rollback, the VPS becomes repeatable infrastructure rather than a server that only one person knows how to repair.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.