One server, two applications

Free preview 3 min to read

A server with a public IP address has one port 443, and two applications both want it. How that conflict is resolved is the whole subject of this course.

Why you'd want this

The usual cases are a marketing site beside the product, a staging environment beside production, and a side project that doesn't justify its own machine.

This application's VPS runs one service today, newbieonrails, plus its Postgres accessory, and the machine isn't busy. A second small application would fit.

The naive approaches and why they fail

Different ports: example.com:3000 works, and nobody will accept it. Ports aren't a user-facing concept, and TLS certificates are issued per hostname, not per port.

Different IP addresses: this works, and it costs money per address. On a small VPS, you usually have one.

One container serving both: now they share a deploy, a Ruby version and a failure. They aren't two applications any more.

flowchart TB
  I["one IP, one port 443"] --> Q{"how do two apps share it?"}
  Q --> A["different ports: users will not accept it"]
  Q --> B["different IPs: costs money, usually unavailable"]
  Q --> C["one container: not two applications any more"]
  Q --> D["one proxy routing by hostname"]
  D --> Y["this is the answer"]

The answer

One process owns 443 and routes by hostname.

The browser sends the hostname in two places: in the TLS handshake, as Server Name Indication, before any encrypted data, and in the Host header afterwards.

Server Name Indication is the important one, because it's what lets the proxy choose the right certificate before decryption is possible. Without it, one address could serve only one certificate, which is how it worked before SNI existed.

What this asks of Kamal

kamal-proxy already does this. Routing by hostname is how the proxy works, and a single-app deployment is the case where the routing table has one entry.

The configuration in this repository lists newbieonrails.com,www.newbieonrails.com, two hostnames already routing to one container. Adding a second application uses the same mechanism with a different destination, and that continuity is why this is a short course.

Key takeaways

  • A server has one port 443, and two applications both want it.
  • Separate ports and extra IP addresses aren't workable answers.
  • One process owns 443 and routes by hostname to different containers.
  • Server Name Indication carries the hostname before decryption, so the right certificate is chosen.
  • kamal-proxy already routes by hostname, and one application is the one-entry case.
Lesson 1 of 7 · free

Keep going with lesson 2

How the routing works

How kamal-proxy runs apart from applications, updates routing entries per deploy, and handles certificates on port 80.

A free account also gives you the quizzes, your progress and notes, and the discussion.

Type to start searching...