Skip to content

Commit 2a51d9a

Browse files
justin808claude
andcommitted
Fix Thruster and HTTP/2 configuration for Control Plane deployment
CRITICAL FIX: Change workload protocol from http2 back to http Root cause identified through live debugging on Control Plane: - Thruster IS running correctly in the container - Thruster handles HTTP/2 on the public-facing TLS connection - Control Plane's load balancer expects HTTP/1.1 from the container - Setting protocol: http2 causes 502 "protocol error" What I discovered: 1. Accessed live QA app: qa-react-webpack-rails-tutorial-687 2. Verified Thruster is running: PID 1 is "thrust bin/rails server" 3. Rails responds correctly on localhost:3000 4. But external requests get 502 with "protocol error" 5. Issue: Protocol mismatch between load balancer and container The correct architecture: - End User → HTTPS/HTTP2 → Control Plane Load Balancer - Load Balancer → HTTP/1.1 → Thruster in Container - Thruster → HTTP/1.1 → Rails (localhost:3000) Changes: 1. Update rails.yml: protocol: http2 → protocol: http 2. Add detailed explanation in rails.yml comments 3. Update .controlplane/readme.md with correct configuration 4. Update docs/thruster.md with protocol explanation 5. Add troubleshooting section for 502 protocol errors Key insight: Thruster provides HTTP/2 to end users through TLS termination, but the container must expose HTTP/1.1 to the load balancer. This is different from running Thruster in production with direct TLS termination where it would handle HTTP/2 end-to-end. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent eea187f commit 2a51d9a

File tree

3 files changed

+27
-10
lines changed

3 files changed

+27
-10
lines changed

.controlplane/readme.md

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,14 +147,20 @@ CMD ["bundle", "exec", "thrust", "bin/rails", "server"]
147147

148148
#### 2. Workload Port Protocol (`.controlplane/templates/rails.yml`)
149149

150-
The workload port must be configured for HTTP/2:
150+
The workload port should remain as HTTP/1.1:
151151

152152
```yaml
153153
ports:
154154
- number: 3000
155-
protocol: http2 # Must be http2, not http
155+
protocol: http # Keep as http, not http2
156156
```
157157
158+
**Important:** This may seem counter-intuitive, but here's why:
159+
- **Thruster handles HTTP/2** on the public-facing TLS connection
160+
- **Control Plane's load balancer** communicates with the container via HTTP/1.1
161+
- Setting `protocol: http2` causes a protocol mismatch and 502 errors
162+
- Thruster automatically provides HTTP/2 to end users through its TLS termination
163+
158164
### Important: Dockerfile vs Procfile
159165

160166
**On Heroku:** The `Procfile` defines how dynos start:
@@ -204,14 +210,18 @@ After deployment, verify HTTP/2 is working:
204210
- Incorrect CMD syntax in Dockerfile
205211
- Port mismatch (ensure Rails listens on 3000)
206212

207-
#### HTTP/2 not working (showing HTTP/1.1)
213+
#### Getting 502 errors after enabling HTTP/2
214+
215+
**Symptom:** Workload returns 502 Bad Gateway with "protocol error"
208216

209-
**Symptom:** Browser shows protocol as "http/1.1" instead of "h2"
217+
**Root Cause:** Setting `protocol: http2` in rails.yml causes a protocol mismatch
210218

211219
**Solution:**
212-
1. Verify `protocol: http2` in `.controlplane/templates/rails.yml`
220+
1. Change `protocol: http2` back to `protocol: http` in `.controlplane/templates/rails.yml`
213221
2. Apply the template: `cpflow apply-template rails -a <app-name>`
214-
3. Redeploy: `cpflow deploy-image -a <app-name>`
222+
3. The workload will immediately update (no redeploy needed)
223+
224+
**Why:** Thruster provides HTTP/2 to end users, but Control Plane's load balancer communicates with containers via HTTP/1.1. Setting the port protocol to `http2` tells the load balancer to expect HTTP/2 from the container, which Thruster doesn't provide on the backend.
215225

216226
#### Assets not loading or CORS errors
217227

.controlplane/templates/rails.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ spec:
1919
memory: 512Mi
2020
ports:
2121
- number: 3000
22-
protocol: http2
22+
protocol: http
23+
# Note: Keep as 'http' - Thruster handles HTTP/2 on the TLS frontend,
24+
# but the load balancer communicates with the container via HTTP/1.1
2325
defaultOptions:
2426
# Start out like this for "test apps"
2527
autoscaling:

docs/thruster.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,15 +157,20 @@ CMD ["bundle", "exec", "thrust", "bin/rails", "server"]
157157

158158
#### 2. Workload Port Configuration
159159

160-
The workload port must be set to HTTP/2 (`.controlplane/templates/rails.yml`):
160+
The workload port should remain as HTTP/1.1 (`.controlplane/templates/rails.yml`):
161161

162162
```yaml
163163
ports:
164164
- number: 3000
165-
protocol: http2 # Required for HTTP/2
165+
protocol: http # Keep as http, NOT http2
166166
```
167167
168-
**Important:** On Control Plane/Kubernetes, the `Dockerfile CMD` determines container startup, NOT the `Procfile`. This differs from Heroku where Procfile is used.
168+
**Important:** Keep the protocol as `http` (not `http2`) because:
169+
- Thruster handles HTTP/2 on the public-facing TLS connection
170+
- Control Plane's load balancer communicates with containers via HTTP/1.1
171+
- Setting `protocol: http2` causes 502 protocol errors
172+
173+
**Note:** On Control Plane/Kubernetes, the `Dockerfile CMD` determines container startup, NOT the `Procfile`. This differs from Heroku where Procfile is used.
169174

170175
#### Deployment Commands
171176

0 commit comments

Comments
 (0)