Agentless Continuous Deployment: Streamlining Production Deployments on Ubuntu VPS with Kamal 2
The Evolution of Continuous Deployment: Moving Beyond Heavy Agents
For years, engineering teams looking to establish robust Continuous Deployment (CD) pipelines faced a stark architectural choice. On one side stood heavy enterprise orchestration platforms like Kubernetes, which introduce significant cognitive overhead and infrastructure costs. On the other side were traditional CI/CD runners and server-side agents like GitLab Runner, Jenkins agents, or custom systemd daemons. While effective, these server agents introduce distinct liabilities: they consume valuable RAM and CPU on the host machine, widen the security attack surface by requiring persistent listening ports, and suffer from 'configuration drift' over time.
Kamal 2 disrupts this paradigm by championing an agentless architecture. Originally developed by 37signals to power Basecamp and HEY, Kamal leverages standard SSH commands and Docker containerization to manage production deployments from the outside. By moving the orchestration logic entirely to the deployment client (such as your local machine or a GitHub Actions runner), Kamal 2 turns any standard Ubuntu Virtual Private Server (VPS) into a high-performance, self-contained application host without installing a single management daemon.
Why Kamal 2 is Ideal for VPS Environments
Deploying software directly to a Virtual Private Server (VPS) is highly cost-effective, but managing applications manually via SSH is error-prone. Kamal 2 bridges the gap between raw infrastructure and complex container orchestrators by offering several key advantages:
- Zero Server Footprint: There is no master node, no agent process, and no external daemon running on your Ubuntu VPS. If Docker and SSH are installed, your server is ready.
- Absolute Security: Communication happens exclusively over standard, encrypted SSH. You do not need to open inbound ports for deployment tools; if you can securely SSH into your server, Kamal can deploy to it.
- Seamless Zero-Downtime Rollovers: Kamal 2 utilizes a built-in proxy system that boots new application containers, runs health checks, and dynamically swaps traffic before stopping old containers.
- Automated Asset and Configuration Management: Kamal handles SSL certificate generation, environment variables, and Docker registry authentication out of the box.
"Simplicity is a prerequisite for reliability. By removing the agent layer, Kamal 2 reduces the moving pieces in a deployment pipeline to the absolute minimum required to safely run a container."
Prerequisites and Environment Setup
Before initiating your first agentless deployment with Kamal 2, you must prepare your local development workstation and your remote Ubuntu VPS. Ensure you have the following components configured:
1. Local Workstation Requirements
Your local machine (or your CI/CD runner) acts as the execution brain. It requires:
- Ruby: Kamal is distributed as a Ruby gem. Ruby 3.0 or higher is recommended.
- Docker: Required locally if you intend to build container images on your workstation prior to pushing them to a registry.
2. Remote Ubuntu VPS Configuration
Your Ubuntu server needs a pristine, minimalistic setup. Log in via SSH and perform the following baseline preparations:
# Update system packages
sudo apt update && sudo apt upgrade -y
# Install Docker Engine
sudo apt install apt-transport-https ca-certificates curl software-properties-common -y
curl -fsSL [https://download.docker.com/linux/ubuntu/gpg](https://download.docker.com/linux/ubuntu/gpg) | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] [https://download.docker.com/linux/ubuntu](https://download.docker.com/linux/ubuntu) $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update && sudo apt install docker-ce docker-ce-cli containerd.io -y
# Enable Docker to run without sudo for your deployment user
sudo usermod -aG docker $USERAdditionally, ensure your local SSH key is added to the ~/.ssh/authorized_keys file on the remote server, granting passwordless sudo-less access to the Docker daemon.
Step-by-Step Configuration of Kamal 2
With your environment prepared, install Kamal locally by executing gem install kamal. Navigate to your application's root directory and run kamal init. This command generates a standardized configuration file structure, including the core configuration file: config/deploy.yml.
Analyzing the Deploy Configuration
Open config/deploy.yml and structure it to reflect your infrastructure setup. Below is a comprehensive blueprint for a production deployment:
service: corporate-api
image: your-docker-registry-username/corporate-api
servers:
web:
hosts:
- 203.0.113.42 # Replace with your Ubuntu VPS IP address
registry:
server: index.docker.io
username: your-docker-registry-username
password:
- KAMAL_REGISTRY_PASSWORD
env:
secret:
- DATABASE_URL
- RAILS_MASTER_KEY
proxy:
ssl: true
host: api.yourdomain.com
healthcheck: /upThis declarative structure tells Kamal exactly what your application is named, where its Docker image lives, which VPS hosts the web service, and how the proxy should route incoming HTTPS traffic safely through standard health checks.
Executing the Agentless Deployment Pipeline
With the configuration complete, the initial initialization and continuous lifecycle updates are handled via straightforward terminal commands execution. The process flows seamlessly from code to container.
1. Infrastructure Provisioning
Run the initialization command to set up the server infrastructure for the first time:
kamal setupWhen you trigger this command, Kamal performs a series of sequential automated tasks over SSH:
- Connects to the Ubuntu VPS and verifies Docker availability.
- Logins into your specified container registry from the remote server.
- Bootstraps the internal Kamal Proxy container to manage incoming traffic.
- Acquires Let's Encrypt SSL certificates automatically for your configured domain.
- Builds your application image locally (or via a remote builder), pushes it to the registry, pulls it down to the VPS, and starts the container.
2. Standard Continuous Deployment Workflows
Once the initial setup is successful, subsequent code updates do not require running the full setup suite. For daily continuous deployment, a single command is used:
kamal deployDuring a standard deployment, Kamal boots the new version of your container alongside the old version on the Ubuntu host. It continuously hits the /up endpoint specified in your configuration. Once the new container returns a successful 200 OK status code, Kamal instructs the proxy to reroute incoming connections to the new container instantly, then gracefully shuts down and removes the old container instance. This guarantees zero downtime for your end users.
Best Practices for Production Environments
Operating an agentless CD architecture demands adherence to operational hygiene to maintain stability and performance over time:
- Automate via CI/CD Runners: Do not run deployments manually from developer laptops in production. Embed Kamal into your GitHub Actions or GitLab CI workflows. Store the
SSH_PRIVATE_KEYandKAMAL_REGISTRY_PASSWORDsecurely as repository secrets. - Prune Remote Assets Routinely: Because Kamal pulls new Docker images for every deployment, disk usage on your Ubuntu VPS will steadily increase. Run
kamal pruneweekly via a cron job to automatically remove legacy images and containers. - Robust Error Recovery: If a deployment fails due to a runtime exception or a misconfigured environment variable, quickly revert to the last functional container instantly using
kamal rollback.
Conclusion
Kamal 2 represents a major milestone for devops efficiency. By removing complex server-side orchestration agents, it returns control to developers while slashing infrastructure resource requirements. Combining an entry-level Ubuntu VPS with Kamal 2 delivers a fast, highly secure, zero-downtime continuous deployment engine capable of supporting significant production workloads without operational complexity.
