@@ -23,7 +23,7 @@ You can see the definition of Postgres and Redis in the `.controlplane/templates
2323
2424This repo uses the generated ` cpflow-* ` GitHub Actions wrappers. Keep the
2525generic behavior documented upstream in the
26- [ ` control-plane-flow ` CI automation guide] ( https://github.com/shakacode/control-plane-flow/blob/v5.1.1 /docs/ci-automation.md ) ;
26+ [ ` control-plane-flow ` CI automation guide] ( https://github.com/shakacode/control-plane-flow/blob/v5.2.0 /docs/ci-automation.md ) ;
2727this section only lists the values that are specific to this app.
2828
2929### Review Apps and Staging
@@ -124,10 +124,11 @@ The matching Control Plane resources are:
124124Bootstrap production the same way before the first promotion, using the
125125production org and production-only secret values. After bootstrap or any
126126template change, re-apply the persistent production templates so the ` rails `
127- and ` daily-task ` workloads keep the same secret-backed env names as staging:
127+ ` node-renderer ` , and ` daily-task ` workloads keep the same secret-backed env
128+ names as staging:
128129
129130``` sh
130- cpflow apply-template app postgres redis daily-task rails \
131+ cpflow apply-template app postgres redis daily-task node-renderer rails \
131132 -a react-webpack-rails-tutorial-production \
132133 --org shakacode-open-source-examples-production \
133134 --yes --add-app-identity
@@ -138,12 +139,13 @@ secrets:
138139
139140- ` SECRET_KEY_BASE `
140141- ` RENDERER_PASSWORD `
142+ - ` ROLLING_DEPLOY_TOKEN `
141143- ` REACT_ON_RAILS_PRO_LICENSE `
142144
143145Generate ` SECRET_KEY_BASE ` with ` openssl rand -hex 64 ` and
144- ` RENDERER_PASSWORD ` with ` openssl rand -hex 32 ` . For real production, prefer
145- managed Postgres and Redis services and update ` DATABASE_URL ` and ` REDIS_URL `
146- accordingly.
146+ ` RENDERER_PASSWORD ` and ` ROLLING_DEPLOY_TOKEN ` with ` openssl rand -hex 32 ` .
147+ For real production, prefer managed Postgres and Redis services and update
148+ ` DATABASE_URL ` and ` REDIS_URL ` accordingly.
147149
148150Review apps run pull request code, so anything mounted through
149151` cpln://secret/... ` can be read by that code after it starts. Keep the
@@ -283,9 +285,13 @@ Thruster is a small, fast HTTP/2 proxy designed for Ruby web applications. It pr
283285
284286To enable Thruster with HTTP/2 on Control Plane, two configuration changes are required:
285287
286- #### 1. Dockerfile CMD ( ` .controlplane/Dockerfile ` )
288+ #### 1. Container Startup Command
287289
288- The Dockerfile must use Thruster to start the Rails server:
290+ The Dockerfile ` CMD ` is the local and single-container fallback. Control Plane
291+ workload templates can override it with explicit ` args: ` ; this app does that for
292+ both ` rails ` and ` node-renderer ` .
293+
294+ The fallback command still uses Thruster to start the Rails server:
289295
290296``` dockerfile
291297# Use Thruster HTTP/2 proxy for optimized performance
@@ -294,9 +300,9 @@ CMD ["bundle", "exec", "thrust", "bin/rails", "server"]
294300
295301** Note:** Do NOT use ` --early-hints ` flag as Thruster handles this automatically.
296302
297- #### 2. Workload Port Protocol (` .controlplane/templates/rails.yml ` )
303+ #### 2. Workload Port Protocol (` .controlplane/templates/rails.yml ` and ` node-renderer.yml ` )
298304
299- The workload port should remain as HTTP/1.1:
305+ The Rails workload port should remain as HTTP/1.1:
300306
301307``` yaml
302308ports :
@@ -310,16 +316,25 @@ ports:
310316- Setting ` protocol: http2` causes a protocol mismatch and 502 errors
311317- Thruster automatically provides HTTP/2 to end users through its TLS termination
312318
319+ The separate `node-renderer` workload is different : React on Rails Pro's Node
320+ Renderer listens with cleartext HTTP/2 (h2c), so its workload port intentionally
321+ uses `protocol : http2`. Keep its probes as `tcpSocket` because HTTP/1.1-only
322+ health probes cannot speak to that listener.
323+
313324# ## Important: Dockerfile vs Procfile
314325
315326**On Heroku:** The `Procfile` defines how dynos start:
316327```
317328web: bundle exec thrust bin/rails server
318329```
319330
320- **On Control Plane/Kubernetes:** The `Dockerfile CMD` defines how containers start. The Procfile is ignored.
331+ **On Control Plane/Kubernetes:** workload `args:` define how `rails` and
332+ `node-renderer` start. The Dockerfile `CMD` is the fallback for local or
333+ single-container runs. The Procfile is ignored.
321334
322- This is a common source of confusion when migrating from Heroku. Always ensure your Dockerfile CMD matches your intended startup command.
335+ This is a common source of confusion when migrating from Heroku. For deployed
336+ workloads, update the matching template in `.controlplane/templates/`; keep the
337+ Dockerfile fallback aligned for local and single-container use.
323338
324339### Verifying HTTP/2 is Enabled
325340
@@ -567,17 +582,60 @@ The system uses Control Plane's infrastructure to manage these deployments, with
567582each review app getting its own resources as defined in the controlplane.yml
568583configuration.
569584
585+ ### Separate React on Rails renderer workload
586+
587+ Control Plane runs the React on Rails Pro Node Renderer as its own
588+ ` node-renderer ` workload. ` .controlplane/controlplane.yml ` includes
589+ ` node-renderer ` in ` app_workloads ` and sets ` deploy_order ` so
590+ ` cpflow deploy-image ` and ` cpflow promote-app-from-upstream ` deploy the
591+ renderer first, wait for it to become healthy, and then deploy ` rails ` plus
592+ ` daily-task ` .
593+
594+ The renderer workload uses the same application image as Rails, runs
595+ ` react_on_rails_pro:pre_seed_renderer_cache ` at container boot, and then starts
596+ ` yarn node-renderer ` . Rails gets ` RENDERER_URL ` from
597+ ` .controlplane/templates/app.yml ` and reaches the renderer at
598+ ` http://node-renderer.<app>.cpln.local:3800 ` .
599+
600+ ` ROLLING_DEPLOY_TOKEN ` lives in the app secret dictionary alongside
601+ ` RENDERER_PASSWORD ` . ` ROLLING_DEPLOY_PREVIOUS_URLS ` points at the app's
602+ Control Plane rolling-deploy endpoint so the boot seed can pull the draining
603+ bundle before Rails rolls.
604+
605+ ### Coordinating existing staging and production apps
606+
607+ For existing persistent apps, roll the topology change separately from the new
608+ React on Rails RC when possible:
609+
610+ 1 . Populate ` ROLLING_DEPLOY_TOKEN ` in the staging and production app secret
611+ dictionaries. Use the same value for Rails and the renderer within each app.
612+ 2 . Re-apply templates to staging first:
613+ ` cpflow apply-template app postgres redis daily-task node-renderer rails -a react-webpack-rails-tutorial-staging --org shakacode-open-source-examples-staging --yes --add-app-identity ` .
614+ 3 . Deploy staging with ` cpflow deploy-image -a react-webpack-rails-tutorial-staging --org shakacode-open-source-examples-staging ` .
615+ cpflow 5.2.0 honors ` deploy_order ` , so ` node-renderer ` deploys and waits
616+ before ` rails ` .
617+ 4 . After staging is healthy, re-apply the same template list to production.
618+ 5 . Promote production with the generated workflow. Production promotion also
619+ honors ` deploy_order ` , so the renderer rolls before Rails.
620+
621+ Do not apply the production template change until the production app secret
622+ dictionary has ` ROLLING_DEPLOY_TOKEN ` ; the app template references that secret
623+ for both Rails and the renderer.
624+
625+ React on Rails docs reference:
626+ < https://reactonrails.com/docs/pro/rolling-deploy-adapters/#deploy-the-renderer-before-rails >
627+
570628
571629### Updating Generated cpflow Workflows
572630
573631Keep the reusable-workflow mechanics in the upstream
574- [ ` control-plane-flow ` CI automation guide] ( https://github.com/shakacode/control-plane-flow/blob/v5.1.1 /docs/ci-automation.md ) .
632+ [ ` control-plane-flow ` CI automation guide] ( https://github.com/shakacode/control-plane-flow/blob/v5.2.0 /docs/ci-automation.md ) .
575633For this repo, the update loop is:
576634
5776351 . Update the bundled ` cpflow ` gem to the desired release.
5786362 . Refresh generated wrappers from that release with ` --staging-branch master ` .
5796373 . Keep generated refs on the same release tag as the bundled ` cpflow ` gem.
580- This branch pins refs to ` v5.1.1 ` , which includes upstream promotion
638+ This branch pins refs to ` v5.2.0 ` , which includes upstream promotion
581639 hardening and the release-runner timeout fix. Use a full commit SHA only for
582640 short-lived upstream testing and leave ` CPFLOW_VERSION ` unset in that case.
5836414 . Keep app names and GitHub settings aligned with ` .controlplane/controlplane.yml ` .
0 commit comments