October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk11 min

How to Deploy a Web App Using Kamal on a VPS (Step-by-Step)

Deploy a Dockerized web app on a VPS with Kamal: install it locally, configure deploy.yml and secrets, set DNS and HTTPS, bootstrap with kamal setup, then release with kamal deploy.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Install Kamal on your laptop or CI runner—not on the VPS—then let it connect over SSH, build and push your Docker image, install or use Docker on the server, and route traffic through kamal-proxy. The practical flow is: create a Dockerfile, run kamal init, configure config/deploy.yml and .kamal/secrets, point DNS at the VPS, run kamal setup once, and use kamal deploy for subsequent releases.

What Kamal does on a VPS

Kamal is a deployment tool that you run from a development computer or CI runner. It uses SSH to control Docker on one or more servers, rather than requiring a Kamal installation on the VPS itself. Your checked-out application is built into a container image, the image is pushed to a registry, and the server pulls and runs it.

As an Amazon Associate I earn from qualifying purchases.

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.

A kamal-proxy process sits in front of the application container. It listens on ports 80 and 443, performs a health check, and changes the active route from the old container to the new one only after the new container is ready. That is the mechanism behind Kamal’s normal zero-downtime release behavior.

Read the official Kamal documentation for the release-specific syntax. Kamal and kamal-proxy defaults can change, and the available version was not established here.

#1 Best Overall
HP ProLiant DL360 G7 1U RackMount 64-bit Server - Dual 6-Core X5675 Xeon 3.06GHz CPUs - 72GB PC3-10600R RAM - 4x900GB 10K SAS SFF HDD - P410i RAID, 4xGigaBit NIC - 2 PSU (Renewed)
  • HP ProLiant DL360 G7 Business Server, the perfect enterprise server or small business server!
  • Processors: Dual (2) Xeon X5675 6-Core 3.06 GHz 12MB CPUs Max Turbo 3.46 GHz
  • Memory: 72GB (4 x 16GB) DDR3 PC3-10600R Memory; Storage: 3.6TB (4 x 900GB) 10K 12Gb/s SAS 2.5" HDDs
  • Power: Redundant Power Supplies; RAID: HP Smart Array P410i-a 12Gb/s with 4×GigaBit NIC
  • Hard drives and memory upgrades included separately NOT installed, installation required.

Prerequisites and decisions

Complete these items before writing the deployment file. Skipping one usually produces an avoidable failure during setup.

  • A deployment machine: your laptop, a dedicated build host, or a CI runner with Ruby, Git, Docker build capability, and an SSH client. Current third-party installation guides describe Ruby 2.7 or newer, but that requirement was not confirmed against the official installation page; check the documentation for the Kamal version you install.
  • A VPS: a public IPv4 address, an SSH account, enough CPU, memory, disk, and bandwidth for your application and its image layers, and a firewall that permits SSH plus HTTP (80) and HTTPS (443).
  • An SSH key: the deployment account must be able to log in non-interactively. A separate non-root account is preferable; grant it the Docker permissions required by your server’s operating system instead of routinely deploying as root.
  • A Dockerfile: it must build a production image and start the web process on the port you will expose through the proxy.
  • A container registry: Docker Hub, GHCR, or a private registry all work. The registry hostname, username, and password or token are needed by Kamal.
  • A DNS name: create an A record such as app.example.com pointing to the VPS public IPv4 address. Add an AAAA record only when IPv6 is correctly configured and reachable on that server.
  • A health endpoint: the application should answer GET /up with HTTP 200 when it is ready to receive production traffic. If your framework uses another path, configure that path explicitly.

DNS must resolve publicly before automatic HTTPS can succeed. A local hosts-file entry is not sufficient for a public certificate challenge.

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

Install Kamal and create its configuration

Run these commands from the application repository on the deployment machine:

gem install kamal
kamal version
kamal init

kamal version confirms which client you installed. kamal init scaffolds config/deploy.yml and .kamal/secrets. Commit the deployment configuration, but keep secret values out of version control. Add .kamal/secrets to the repository’s ignore rules if the scaffold has not already done so.

Write a deploy.yml that matches your application

The following is a minimal single-VPS example. Replace every example value with your own service name, image, host, registry, and port.

service: myapp

image: registry.example.com/acme/myapp

servers:
  web:
    - 203.0.113.10

proxy:
  host: app.example.com
  app_port: 3000
  ssl: true

env:
  clear:
    RAILS_ENV: production
  secret:
    - DATABASE_URL
    - SECRET_KEY_BASE

registry:
  server: registry.example.com
  username: deployer
  password:
    - KAMAL_REGISTRY_PASSWORD

Service and image

service names the running application and is also used by Kamal when it creates containers and proxy routes. image is the full registry path that Kamal builds and pushes. The server must be able to pull that exact image, so the registry hostname in the image and the registry.server value should agree.

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

Servers and roles

The web role lists the VPS address. You can list more hosts when you need redundancy, but a one-host deployment remains a single point of failure. Kamal command flags allow you to target selected roles or hosts during an operation.

Rank #2
Quiet Rackmount Computer (3.8-4.6GHz AMD Ryzen 7 5700G CPU, 32GB RAM, 2TB SSD, W11 Pro) - 2U Rack Mount Server or Workstation Desktop PC for Home or Business
  • [CPU] AMD Ryzen 7 5700G Processor (8 Cores, 16 Threads, 3.8 GHz Base Clock Speed up to 4.6 GHz Max Boost Clock Speed) for Gaming and Content Creation with 7nm Leading Edge Technology | [STORAGE] 2TB PCIe NVMe M.2 SSD - Experience Hyper-Fast Bootup and Data Transfer thats up to 30x Faster Performance than a Traditional Hard Drive.
  • Graphics: Integrated AMD Radeon Graphics | [RAM] 32GB DDR4 RAM 3200 Gaming Memory for Seamless Multitasking from Multiple Web Pages to Playing Games Online Simultaneously | [OS] Windows 11 Pro x64
  • 2x 3.5" Drive Bays | 4x Expansion Slots | mATX Motherboard | ATX PSU
  • [BUY WITH CONFIDENCE] Empowered PCs are Assembled in the USA, Rigorously Stress-Tested Before Shipping, and Supported with Lifetime Technical and Diagnostic Support and 3-Year Limited Hardware Warranty.

Proxy and application port

proxy.host is the public hostname used for routing and certificate issuance. Set app_port to the port on which the container listens; if you omit it, the proxy default is 80. Kamal-proxy forwards requests from ports 80 and 443 to that internal application port.

With ssl: true on a single host, kamal-proxy can obtain and renew a Let’s Encrypt certificate automatically. Port 443 must be reachable from the internet for the ACME challenge. SSL redirect is enabled when SSL is enabled. Forwarded headers are disabled by default in that mode unless you turn them on explicitly, so enable the setting if your framework needs the original protocol or client headers.

Environment values

Put non-sensitive, deployment-wide values under env.clear. List sensitive variable names under env.secret; their values come from the secrets file and are injected during deployment. Do not place database passwords, signing keys, API tokens, or registry credentials directly in the committed YAML file.

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

Unless you change it, the proxy checks GET /up. Configure your application so that this endpoint does not depend on a browser session and returns 200 only when the process is ready. The default proxy response timeout is 30 seconds; a slow startup or a health handler that waits on an unavailable dependency can therefore prevent activation.

Path and timeout behavior

The proxy strips path prefixes by default. If your application must receive the original prefix, set strip_path_prefix: false. Set a larger response_timeout only when your workload genuinely needs it; increasing the timeout can hide a hung application rather than fix it.

Store registry and application secrets safely

Populate .kamal/secrets on the deployment machine with the variables named in your configuration. A typical file contains entries like:

KAMAL_REGISTRY_PASSWORD=replace-with-a-registry-token
DATABASE_URL=postgres://user:[email protected]:5432/myapp
SECRET_KEY_BASE=replace-with-a-long-random-value

Protect the file with restrictive permissions and provide equivalent variables in the CI runner’s secret store when deploying automatically. The registry credential must have permission to push the image from the deployment machine and to pull it from the VPS. If the registry is private, a failed login or expired token stops setup before the application can start.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
Dell PowerEdge R730xd Server 24B SFF 2U, 2X Intel Xeon E5-2690 v4 2.6Ghz (28-cores Total), 128GB DDR4 RAM, 4X 1.2TB 10K SAS 2.5” 12Gb/s HDD, H730P 2GB RAID, NIC 10Gb + I350 1Gb (Renewed)
  • Dell PowerEdge R730xd 24B SFF 2U Server
  • 2x Intel Xeon E5-2690 v4 2.6Ghz 14-Core (28-cores Total)
  • 128GB DDR4 RAM – 4x 1.2TB 10K SAS 2.5” 12Gb/s
  • Dell H730P mini 2GB 12Gb/s RAID
  • 2x 750W PSU - 2x 10Gb SFP+ 2x 1Gb (RJ45) NIC

kamal env push is available when you need to push updated environment values to the server. Treat an environment change as an operational change: review it, deploy it through the same controlled process, and restart or redeploy the service when the application needs to read the new value.

Point DNS and open the VPS firewall

  1. Create an A record for the exact hostname in proxy.host, for example app.example.com, with the VPS public IPv4 address.
  2. Wait until public DNS resolvers return that address. Query the record from outside your local network if possible.
  3. Allow inbound TCP 22 for SSH from the addresses that administer the server, TCP 80 for HTTP and the certificate challenge, and TCP 443 for HTTPS.
  4. If you publish an AAAA record, verify that the VPS, firewall, Docker host, and application all support IPv6. An incorrect AAAA record can make some visitors fail even while IPv4 appears healthy.

Do not enable automatic HTTPS until the hostname resolves to this VPS and port 443 is reachable. Kamal cannot complete the certificate challenge against a private address, stale DNS target, or blocked port.

Run the first bootstrap with kamal setup

From the repository revision you intend to release, run:

kamal setup

This is the one-time bootstrap for each newly prepared server. The operation normally performs the following sequence:

  1. Connects to the listed server over SSH.
  2. Installs Docker when it is missing or prepares the host to run Docker.
  3. Logs in to the configured container registry.
  4. Builds the checked-out application image and pushes it to the registry.
  5. Pulls the image onto the VPS and starts the application container.
  6. Starts kamal-proxy and configures the host and port route.
  7. Waits for the health check, normally GET /up, to return HTTP 200.
  8. Switches traffic to the new container only after that check succeeds.
  9. Stops the old container, when one exists, and prunes unused images according to Kamal’s cleanup behavior.

Watch the command output for the first failing stage. A successful image build does not prove that the application is reachable: the container must start, the port must be correct, and the health endpoint must respond through the proxy.

Deploy later releases without downtime

Commit your application and Dockerfile changes, check out the exact revision to release, and run:

kamal deploy

Kamal builds that checked-out version, pushes the image, starts a new container, waits for the health check, and asks kamal-proxy to move traffic from the old container to the new one. Existing requests can finish on the old container while new requests are directed to the healthy replacement.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
Rosewill 4U Server Chassis Rackmount Case | 15 3.5" HDD Bays | E-ATX Compatible | 6 Front 120mm Fans, 2 Rear 80mm Fans | 2X USB 3.0 | Front Panel Lock and Key | Silver/Black - RSV-L4500U
  • Spacious Chassis: This huge 4U server case comes with 15 internal 3.5" HDD bays.
  • Expandable & E-ATX Compatible: 7 PCI expansion slots and E-ATX compatibility gives you growth options for all of your needs.
  • Exceptional Cooling: 8 pre-installed cooling fans provide excellent airflow and heat protection. 3 front 120mm PWM fans, 3 middle 120mm fans and 2 rear 80mm fans ensure your drives and chassis avoid overheating.
  • Desired Features: Front panel LED indicators for power, HDD, and LAN status monitoring allow quick, easy visual assessment. Additional utility with 2 USB 3.0 port and built-in front panel lock.

Useful deployment options include:

Option Purpose
--skip-push Skip pushing the image when the required image is already available in the registry.
--roles Limit the operation to selected configured roles.
--hosts Limit the operation to specific hosts.
--destination Override the deployment destination for the command.
--config-file Use another configuration file; the default is config/deploy.yml.

Use kamal redeploy when the server is already bootstrapped and you need a deployment without repeating bootstrap-only work such as initial proxy startup, registry login, and pruning. It is not a substitute for the first kamal setup.

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

How kamal-proxy decides whether to switch traffic

The proxy keeps the old route in place while the replacement container starts. It calls the configured health path on the application port. A 200 response from /up indicates readiness; connection failures, a wrong port, non-200 responses, or a timeout leave the old route active instead of sending users to a broken container.

That check should be cheap and deterministic. If it performs a database migration, waits on an external API, or requires authentication, a deploy can time out even though the web process itself is running. Keep readiness checks focused on the dependencies required to serve requests and perform heavier diagnostics separately.

For advanced use, kamal-proxy also has a standalone command shape such as kamal-proxy deploy <service> --target host:port, with optional host and TLS flags. Normal Kamal deployments invoke the proxy for you, so use the standalone interface only when you have a deliberate reason to manage proxy operations separately.

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

Troubleshoot the failures that stop most VPS deployments

Symptom Likely cause What to check or fix
Certificate issuance fails DNS still points elsewhere, the hostname is not public, or TCP 443 is blocked. Confirm the public A/AAAA answers, open 443, and retry after DNS has propagated.
Proxy reports an unhealthy container No /up endpoint, a non-200 response, wrong app_port, or startup longer than the timeout. Request the endpoint locally inside the container, verify the listening port, inspect logs, and adjust the health path or timeout only when justified.
Registry login or pull fails Wrong server name, username, token, expired credential, or missing secret variable. Check the names in registry and .kamal/secrets; verify that the token can push and the VPS can pull.
SSH connection fails Incorrect host, key, account, firewall rule, or server-side SSH configuration. Test a direct SSH connection using the same account and key, then correct the server entry or firewall.
Old code keeps serving The new image was not pushed, the wrong revision was checked out, or the command targeted another host or role. Confirm the Git revision, image tag output, destination, and selected roles; rerun without --skip-push when the registry lacks the image.
Setup stops partway through A bootstrap component such as the proxy or an accessory did not restart cleanly. Use kamal proxy reboot or kamal accessory reboot for the affected component, then run kamal deploy again.

When investigating, start with the first error in the command output rather than the final cascade of failures. Inspect the container logs on the VPS, confirm that the process is listening on the configured port, and test the health endpoint from the same network path used by the proxy.

Operational practices for a safer Kamal host

  • Use a dedicated deployment account and SSH key, and remove access when a person or CI runner no longer needs it.
  • Restrict registry tokens to the permissions required for image push and pull. Rotate them in the registry and in .kamal/secrets together.
  • Keep the VPS operating system, Docker engine, and application base image patched. Kamal deploys your container; it does not replace host maintenance.
  • Back up databases and persistent uploads independently of the application container. Replacing a container must not delete irreplaceable data.
  • Monitor disk usage because each release creates image layers. Pruning helps, but set an alert before the filesystem fills and blocks both Docker and SSH operations.
  • Test a rollback procedure before an incident: identify the last known-good revision, check it out, and run kamal deploy so the proxy can return traffic to a healthy image.
  • Pin and review dependency versions in the application image. Kamal’s zero-downtime switch cannot correct a migration that is incompatible with both the old and new application versions.

What this single-VPS design does—and does not—provide

A one-host Kamal deployment gives you repeatable image-based releases, an automated proxy, health-gated traffic switching, and optional automatic certificates without requiring a separate orchestration cluster. It does not make the VPS highly available: a host outage, a full disk, a broken kernel, or a network failure still takes the application offline. Multiple hosts, external databases, backups, monitoring, and a tested disaster-recovery plan are separate design decisions.

Kamal also does not infer your application’s runtime requirements. You remain responsible for Dockerfile correctness, migrations, persistent storage, background workers, cron jobs, firewall policy, and observability. Configure those as explicit services, roles, or accessories only after you understand their failure and restart behavior.

Quick Recap

Bestseller No. 1
HP ProLiant DL360 G7 1U RackMount 64-bit Server - Dual 6-Core X5675 Xeon 3.06GHz CPUs - 72GB PC3-10600R RAM - 4x900GB 10K SAS SFF HDD - P410i RAID, 4xGigaBit NIC - 2 PSU (Renewed)
HP ProLiant DL360 G7 1U RackMount 64-bit Server - Dual 6-Core X5675 Xeon 3.06GHz CPUs - 72GB PC3-10600R RAM - 4x900GB 10K SAS SFF HDD - P410i RAID, 4xGigaBit NIC - 2 PSU (Renewed)
Processors: Dual (2) Xeon X5675 6-Core 3.06 GHz 12MB CPUs Max Turbo 3.46 GHz; Power: Redundant Power Supplies; RAID: HP Smart Array P410i-a 12Gb/s with 4×GigaBit NIC
$349.00
Bestseller No. 3

Release checklist

  • Dockerfile builds locally and starts the production web process.
  • Deployment machine has the supported Ruby/Kamal installation and SSH access.
  • config/deploy.yml names the correct image, host, role, proxy hostname, and application port.
  • Secrets exist locally or in CI and are not committed.
  • Registry credentials can push and pull the image.
  • DNS resolves the proxy hostname to the VPS; IPv6 is published only when tested.
  • Ports 22, 80, and 443 are permitted according to your access policy.
  • GET /up returns 200 from a ready container.
  • You have run kamal setup for a new host, or selected kamal deploy/kamal redeploy appropriately for an existing one.
  • Backups, logs, disk alerts, and a rollback revision are available before exposing the service to users.

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.

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.

Leave a Reply

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

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.