Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversHalloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan Now×
Skip to content
World desk11 min

How to Deploy Sinatra Ruby Web Apps on an Ubuntu VPS

Deploy a Sinatra Rack app reliably on an Ubuntu VPS with Puma, systemd, nginx, Let’s Encrypt HTTPS, least-privilege users, and UFW.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Deploy a Sinatra app on an Ubuntu VPS by running Puma as a supervised systemd service, placing nginx in front of Puma, and terminating HTTPS with Let’s Encrypt. Keep Puma private on loopback or a Unix socket, expose only nginx publicly, and manage secrets and firewall rules with least privilege.

What the production setup looks like

Sinatra is a Rack application framework; it does not choose a concurrency model. The Rack handler supplies the server process and concurrency, so this guide uses Puma. The request path is:

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.
  • DNS points your domain to the VPS public address.
  • nginx listens on ports 80 and 443.
  • nginx proxies requests to Puma on a loopback TCP port or Unix socket.
  • Puma runs your Sinatra application in the foreground under systemd.
  • systemd restarts Puma when it exits and starts it automatically at boot.

Sinatra 4.0.0 does not support Ruby versions older than 2.7.8. Select a currently supported stable Ruby version for your Sinatra release, then pin the exact application dependencies in Gemfile.lock.

Prerequisites and decisions

  • An Ubuntu VPS with sudo access and a public IPv4 address, and IPv6 if you intend to publish an AAAA record.
  • A registered domain whose DNS you can edit.
  • Your Sinatra source code, a Gemfile, and a committed Gemfile.lock.
  • A supported Ruby installation method, such as the version manager selected by your project or an Ubuntu package that meets Sinatra’s requirement.
  • Administrative SSH access that will remain available while you create a non-root deployment account.

Choose an application directory before deploying. The examples use /srv/myapp, a Unix account named deploy, the domain example.com, and Puma on 127.0.0.1:9292. Replace these consistently with your values.

#1 Best Overall
Sale
TOZO A1 Wireless Earbuds Bluetooth 5.3 Light Weight in Ear Headphones | IPX5 Waterproof,2 Mics for AI Calls,Immersive Premium Sound Bass Headset with Charging Case,32 EQ via App Black
  • [Ultra-Lightweight Ear Buds Designed for Small Ears] Each earbud weighs only 3.7g and features a compact, ergonomic in-ear design made especially for small ears. Secure, low-profile, and comfortable for workouts, all-day wear or overnight sleeping.The ultra-slim profile sits flush in your ear with no hard edges poking or rubbing, so you can even sleep on your side without discomfort.
  • [Immersive Stereo Sound with TOZO OrigX Technology] TOZO OrigX tuning delivers clear vocals, balanced mids, and natural stereo sound for music, podcasts, and videos.
  • [Long Battery Life for Daily Use] Get up to 7 hours of playtime on a single charge, with up to 32 hours total using the charging case—ideal for workdays, commuting, and extended listening sessions.
  • [Bluetooth 5.3 & Stable Connection] Bluetooth 5.3 provides fast pairing, stable wireless performance, and reduced dropouts as you move around home or office.
  • [Deep Bass with Clear Vocals] High-performance drivers produce punchy bass while keeping vocals clean and detailed for everyday listening.

1. Prepare Ubuntu securely

Create a least-privilege administrator

Keep your existing root or provider console session open until the new account has successfully logged in. Create the account and grant administrative access:

sudo adduser deploy
sudo usermod -aG sudo deploy

Test a separate SSH session as deploy before changing any SSH policy. Use SSH keys where possible, protect private keys, and avoid routine work as root. If you later disable password authentication or direct root login, make that change only after key-based access and console recovery have been verified.

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.

Update packages and create the application directory

sudo apt update
sudo apt full-upgrade -y
sudo mkdir -p /srv/myapp
sudo chown -R deploy:deploy /srv/myapp

Use a different owner or group if your operational policy separates code ownership from the service account. The important properties are that Puma can read the release and write only to directories that genuinely need runtime data.

2. Install and pin Ruby and Bundler

Install Ruby with the method your project supports. A version manager is useful when several applications need different Rubies; a distribution package can be simpler when one system-wide version is sufficient. Whichever method you choose, record the Ruby version in the project’s version file and keep the lockfile under version control.

After switching to the deployment account and entering the application directory, install the locked gems:

su - deploy
cd /srv/myapp
bundle config set --local deployment true
bundle install

The deployment setting tells Bundler to use the locked dependency set and install into the deployment layout. If your application uses a different Bundler layout, follow that project convention, but do not silently update dependencies on the server. Commit intentional dependency changes from development and redeploy the resulting lockfile.

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

Install Puma if it is not already in the Gemfile:

bundle add puma

Run that command during development or a controlled dependency update, commit the changed Gemfile and lockfile, and then run bundle install on the VPS. Do not place credentials in the Gemfile, repository, or shell history.

Rank #2
Sale
Smart Watch for Men Women Compatible with iPhone Samsung Android Phone 1.69 inch Full Touch Screen IP68 Waterproof Bluetooh Fitness Tracker Heart Rate/Sleep Monitor (Black)
  • 【IP68 Waterproof Multifunctinal Smart Watch】Torjalph fitness activity tracker smart watch is IP68 waterproof technology ,you can wear it when swimming,handwashing,it's rain-proof which means that you perform multiple exercise modes outside without worrying about sweat or rain corroding your fitness smart watch,and this watch equipped with a 230 mAh large capacity battery magnetic charging ,and this sports activity tracker watch can be used 5-7 days If fully charged.
  • 【Larger 1.83'' Full Screen Watch & Multi-dial Selection】1.83 inch full HD color touch screen smart watch for men / women provides excellent 240*284 resolution image quality ,This Bluetooth smart watch offers a better touch experience and remarkable immersion and ,more than 200 watch faces for you to choose from App"Da Fit ", you can change the dial style according to your mood to wear keeping the world on your wrist
  • 【Accurate Activity Tracker Smart Watch 】sports watch activity tracker uses sweat and dust resistant breathable silicone strap, our Fitness Tracker Smart Watch for Android iOS Phones supports 12 sports modes,walking,running,bicycle,swimming,badminton,basketball,football,rope skipping. This bluetooth calls smart watch for men women is lightweight and stylish, bringing more convenient and relaxing sports experience while also providing more protection.
  • 【Your 24 Hour Personal Daily Health Monitor】Fitness watch for women men full touch screen IP67 waterproof bluetooth smartwatch for Android iOS Phones with heart rate blood pressure monitor multifunction Andriod smart watch with steps counter sleep monitor sports fitness watch, monitoring blood oxygen saturation allows you to understand your physical condition in real time to track fitness progress ,to know your health status in time.
  • 【More Functions Bluetooth Call Smart Watch】This fitness activity smart watch full screen for iPhone and Android phones includes a bunch of new features including:The bluetooth smart watch can hang up the phone, receive and display WhatsAPP /Text /Facebook /Twitter /Messenger reminder.Support sedentary reminder, alarm clock, stopwatch, timer,weather information,music control, remote camera control compatible with Android 5.0 and above or iOS 9.0 and above smartphones.

3. Provide a Rack entry point

For a reproducible Puma launch, add config.ru at the application root. A classic Sinatra application can use:

# config.ru
require './app'
run Sinatra::Application

The require path must match your actual application file. If the file is named differently or lives in a subdirectory, change the require line accordingly. Keep the file in the deployed release so Puma and systemd always start the same Rack application.

You may also have an application-specific Puma configuration file. For a loopback TCP listener, a minimal config/puma.rb can contain:

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.
bind 'tcp://127.0.0.1:9292'
environment ENV.fetch('RACK_ENV', 'production')
threads 0, 5

Choose worker and thread values based on your application and available memory; the deployment evidence does not establish a universal performance setting. Start conservatively and monitor memory, response errors, and queueing before increasing concurrency.

4. Run Puma manually before adding systemd

Validate the application from its directory first. This separates Ruby, Bundler, and application errors from service-manager errors:

cd /srv/myapp
RACK_ENV=production bundle exec puma -b tcp://127.0.0.1:9292

If you have a Puma configuration file, use it explicitly:

RACK_ENV=production bundle exec puma -C config/puma.rb

Puma also documents the direct Sinatra form:

ruby app.rb -s Puma

Use that form only when your application’s launch file is designed for it. For the systemd deployment below, keep Puma in the foreground rather than daemonizing it. In another SSH session, test the listener:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
New Bee Guitar Cable 10ft Electric Instrument Bass AMP Cord
  • [Low Noise High Fidelity] New bee guitar cord with 22AWG oxygen-free-copper center conductors provides enhanced signal transfer, the PVC insulation material and the high-density stranded copper double shield provide noise rejection for quiet operation
  • [Ideal for Choice] New bee 1/4 straight and right angle metal connectors, ensures a secure connection in any instrument, pedal, or amp jack. L shape great fro on stage guitar stands
  • [Wide Compatible] Suitable for mixer, power amplifier, microphone, effector, decoder, equalizer, electoronic organ, electric guitar, electric bass and other electronic equipments. Widely used in the installation of smart home, karaoke speaker, professional stage audio, etc
  • [Easy Disassemble] Making incidental repairs quick and easy! Very nice, flexible cable
  • [Dont Hesite to Order] 24 hours customer services and professional technology team are standing by
curl -i http://127.0.0.1:9292/

Stop the foreground process with Ctrl-C after it returns a valid response. Fix missing gems, incorrect require paths, environment variables, migrations, and bind errors now.

5. Run Puma under systemd

Create a stable executable

Systemd should execute an absolute path rather than depending on an interactive shell’s Ruby version manager initialization. From the application directory, create a Bundler binstub:

bundle binstubs puma --path bin

This creates /srv/myapp/bin/puma. If your chosen Ruby toolchain requires a different absolute executable, use that path in the unit instead.

Store production environment variables safely

Create a root-owned environment file so secrets are not committed with the code:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo install -o root -g root -m 600 /dev/null /etc/myapp.env
sudoedit /etc/myapp.env

Use one variable per line, for example:

RACK_ENV=production
SESSION_SECRET=replace-with-a-long-random-value

Do not paste real credentials into deployment scripts, issue trackers, or public repositories. If your application needs a database or external service, add only the variables it actually consumes.

Create the unit file

Create /etc/systemd/system/myapp.service:

[Unit]
Description=Sinatra application served by Puma
After=network.target

[Service]
Type=simple
User=deploy
Group=deploy
WorkingDirectory=/srv/myapp
EnvironmentFile=/etc/myapp.env
Environment=RACK_ENV=production
ExecStart=/srv/myapp/bin/puma -C /srv/myapp/config/puma.rb
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

WorkingDirectory makes relative requires and files resolve predictably. The dedicated user limits the effect of an application compromise. Restart=always handles unexpected exits, while the foreground Puma process gives systemd a process to supervise. If your project does not use config/puma.rb, replace ExecStart with /srv/myapp/bin/puma -b tcp://127.0.0.1:9292.

Load, enable, and inspect the service

sudo systemctl daemon-reload
sudo systemctl enable myapp.service
sudo systemctl start myapp.service
sudo systemctl status myapp.service
sudo journalctl -u myapp.service -e

After editing the unit, run sudo systemctl daemon-reload again. Use sudo systemctl restart myapp.service for a controlled restart and sudo journalctl -u myapp.service -f to follow live output. Confirm that Puma is listening before configuring nginx:

Rank #4
BSIMB 15.6" Digital Family Calendar & Chore Chart, No Subscription Fees
  • Digital Family Calendar: BSIMB digital calendar wall touch screen puts an end to your chaotic life. Designed for busy families, the digital calendar keeps you organised and in step with your family. Assign different colours and tasks to each family member to make family scheduling easier and more intuitive.
  • Easy Setup and Auto-Sync: Plug in, connect to WLAN and auto-syn your electric calendar in minutes. Digital wall calendar compatible with Google calendar, iCloud calendar, Outlook calendar, Cozi calendar and Yahoo calendar. Add events directly on the device or through the ecalendar app. Electronic calendar stays current whether you're at work or traveling—no manual updates needed.
  • All-In-One Home Assistant: Smart calendar builds habits and encourage independence with personalised chores. Display daily meal plan to reduce the daily ‘What's for dinner?’ stress. To-do lists keep track of everything you want. Turning chores into valuable achievements with stars and rewards, making life easier and more enjoyable.
  • Manage Anytime Anywhere: BSIMB electronic calendar for family stay connected with the powerful ecalendar app. Access and manage your digital wall calendar anytime, anywhere with free features like stars & rewards, photo screensaver, chore charts, meals plans, to-do lists etc. Electronic planner paid features like Magic Import tailor advanced tools for users with special needs.
  • Stay in Touch with Loved Ones: Share photos or videos from your phone to electronic wall calendar with app, instantly update your life moment, and keep in touch with your family, especially those who are far away; you can also surprise your smart calendar digital wall by sending him a wish card; it's also great for keeping tech-illiterate elders in touch with the youngsters.
curl -i http://127.0.0.1:9292/

6. Put nginx in front of Puma

Install nginx and create a server block for the domain. Puma should remain bound to loopback or a protected Unix socket; nginx is the public edge service.

sudo apt install nginx -y
sudoedit /etc/nginx/sites-available/myapp

For the loopback TCP example, use:

server {
    listen 80;
    listen [::]:80;
    server_name example.com;

    location / {
        proxy_pass http://127.0.0.1:9292;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Enable the site, remove the default site if it would catch the same request, test syntax, and reload:

sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/myapp
sudo nginx -t
sudo systemctl reload nginx

If you select a Unix socket instead, configure Puma and nginx with the identical socket path and permissions, then adapt proxy_pass to that socket. A socket can avoid a TCP port, but it adds directory and ownership requirements. Loopback TCP is often easier to diagnose and is still inaccessible from the network when Puma binds specifically to 127.0.0.1.

Check both layers when a request fails:

sudo systemctl status nginx
sudo systemctl status myapp.service
curl -i http://127.0.0.1:9292/
curl -i http://example.com/

7. Point DNS at the VPS and add HTTPS

Create DNS records

Create an A record for example.com pointing to the VPS IPv4 address. Add an AAAA record only when the VPS has working IPv6 and nginx is configured to serve it. DNS propagation and resolver caching can delay the change; verify that the domain resolves to the intended server before requesting a certificate.

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

Issue a Let’s Encrypt certificate with Certbot

Ubuntu documents Let’s Encrypt as a free, automated certificate authority trusted by major browsers and clients. The HTTP-01 validation method generally requires port 80 to be reachable, so keep nginx serving the HTTP server block during issuance.

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d example.com

Add another -d option for each hostname that should be covered, such as a separately validated www name. Certbot’s nginx plugin edits the matching server block and reloads nginx after obtaining the certificate. Review the resulting configuration rather than assuming every hostname or redirect matches your policy.

Verify renewal

Let’s Encrypt certificates are valid for 90 days. Ubuntu’s Certbot setup installs a systemd timer that attempts renewal twice a day. Test the complete renewal path without replacing a live certificate:

sudo systemctl list-timers | grep certbot
sudo certbot renew --dry-run

If another service terminates TLS or nginx is reloaded outside Certbot’s control, configure an appropriate renewal hook so the service loads the renewed certificate. A successful dry run confirms the renewal procedure, not merely that a certificate exists today.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

8. Configure UFW without locking yourself out

Allow SSH before enabling UFW. The standard ports are 22 for SSH, 80 for HTTP validation and redirects, and 443 for HTTPS:

sudo ufw allow 22
sudo ufw insert 1 allow 80
sudo ufw allow 443
sudo ufw enable
sudo ufw status

Adapt port numbers and source restrictions to your SSH configuration and VPS provider. If SSH uses a nonstandard port, allow that port instead of 22. Do not expose Puma’s 9292 listener publicly; bind it to loopback and omit it from UFW rules. Before closing your current session, open a second SSH connection and confirm it works.

Deployment updates and rollback habits

Simple in-place update

For a small application, update the checked-out code, install the locked gems, and restart Puma:

cd /srv/myapp
git pull --ff-only
bundle install
sudo systemctl restart myapp.service
sudo systemctl status myapp.service
curl -i http://127.0.0.1:9292/

Run migrations or other release tasks explicitly, with a backup and a rollback plan. Restart only after the new code and dependencies are present. Keep the previous commit available so you can return to it if health checks fail.

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

Versioned releases

For applications that need safer rollbacks, deploy each release into a separate directory, point a stable path such as /srv/myapp/current at the selected release, and set systemd’s WorkingDirectory and ExecStart to that stable path. Change the symlink atomically, then restart Puma and verify the local and external paths. Keep old releases until the new one has passed checks, while removing old secrets and build artifacts according to your retention policy.

Choosing the main deployment options

Decision Option A Option B Use when
Process supervision systemd supervising foreground Puma Platform-managed service Use systemd when you control the VPS and want native boot ordering, logs, and restart policy. Use a platform service when your provider owns process management.
Public edge nginx proxying to Puma Direct Puma exposure nginx is preferable when you need public ports, TLS termination, redirects, and a private application listener. Direct exposure removes a layer but makes Puma the internet-facing server.
Puma bind Loopback TCP Unix socket Loopback TCP is straightforward to test. A Unix socket can be appropriate on one host when its path, directory, and permissions are managed consistently.
Ruby installation Distribution package Version manager Use the package for a simple, uniform host. Use a version manager when projects require different Ruby versions. In both cases, pin the project version and lockfile.
Release strategy In-place update Versioned releases In-place deployment is simpler for a small service. Versioned directories make rollback and auditability easier.
Certificate automation Certbot nginx plugin Centralized ACME workflow Certbot is convenient when this nginx instance terminates TLS. A centralized workflow can fit teams that manage certificates across many servers.

Troubleshooting by symptom

Puma exits immediately

  • Run the exact ExecStart command as the deploy user from /srv/myapp.
  • Check sudo journalctl -u myapp.service -e for missing gems, an invalid Ruby path, a failed require, or absent environment variables.
  • Confirm that config.ru requires the actual application file and calls run Sinatra::Application for a classic Sinatra app.
  • Verify that the configured port is free with sudo ss -ltnp | grep 9292.

Nginx returns 502 Bad Gateway

  • Check that sudo systemctl status myapp.service reports active and that curl http://127.0.0.1:9292/ succeeds.
  • Ensure nginx’s proxy_pass address exactly matches Puma’s bind address and port.
  • Run sudo nginx -t and inspect nginx’s error log for connection-refused or permission errors.

A Unix socket reports that it is already bound

Puma’s systemd documentation warns that, when a release-path socket differs from the socket supplied by systemd, Puma may try to bind it again and report There is already a server bound to:. Define one authoritative socket path and remove stale socket files only after stopping the service. Do not configure competing socket activation and Puma bind settings without understanding which process owns the socket.

Certbot cannot validate the domain

  • Confirm that DNS resolves publicly to this VPS, not an old address or a different proxy.
  • Confirm nginx is running and port 80 is allowed through both UFW and any VPS provider firewall.
  • Use the exact hostname in the -d option and ensure its nginx server_name matches.
  • Run sudo certbot renew --dry-run after correcting the configuration.

SSH access disappears after enabling UFW

Use the VPS provider’s console or recovery channel, allow the actual SSH port, and test a second SSH session before disconnecting the first. The firewall should protect the host without removing your administrative path.

End-to-end verification checklist

  1. Resolve the domain and confirm its A or AAAA record points to the VPS.
  2. Check sudo systemctl status myapp.service and verify Puma is listening only on the intended internal address.
  3. Run sudo nginx -t, then reload nginx and check its status.
  4. Request the app locally from Puma with curl -i http://127.0.0.1:9292/.
  5. Request the public HTTP and HTTPS URLs and verify the expected host and redirect behavior.
  6. Inspect Puma and nginx logs for application exceptions, upstream failures, or permission errors.
  7. Run sudo certbot renew --dry-run and confirm the renewal timer is present.
  8. Review sudo ufw status and ensure only required public ports are allowed.

Once these checks pass, future releases become a repeatable cycle: deploy the locked code, run any required release task, restart Puma, test the local listener, test nginx, and monitor the service logs.

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

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 *

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.

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
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

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.