@@ -323,8 +323,8 @@ <h1 id="advanced-deployments">⚙️ Advanced Deployments</h1>
323323< li > No way to test a new version while another is live (blue/green)</ li >
324324< li > No quick rollback once upgraded</ li >
325325</ ul >
326- < p > When your app is ready for production, you can enable a < strong > traffic- router</ strong > in
327- to eliminate downtime, enable blue/green testing and easy rollbacks .</ p >
326+ < p > When your app is ready for production, you can enable a traffic router to
327+ eliminate these issues .</ p >
328328< h2 id ="how-it-works "> 🧭 How It Works</ h2 >
329329< p > The traffic router is a lightweight proxy project (already included with
330330SuperStack) that sits in front of your app. Its responsibilities:</ p >
@@ -338,13 +338,13 @@ <h2 id="how-it-works">🧭 How It Works</h2>
338338 Proxy --> LiveApp["Live App"]
339339 NextApp["Next App"]
340340</ code > </ pre >
341- < p > In standard mode, the app exposes ports directly. In advanced mode, the < strong > proxy
342- owns the ports</ strong > , and apps connect to it internally over Docker networks .</ p >
341+ < p > Normally the app exposes ports directly, but in this advanced mode, the < strong > proxy
342+ owns the ports</ strong > , and apps connect to its Docker network .</ p >
343343< h2 id ="deployment-flow "> 🔄 Deployment Flow</ h2 >
344344< ol >
345- < li > Stop exposing ports in the app project — only the proxy will listen on < code > :80</ code >
346- and < code > :443</ code > .</ li >
347345< li > Enable the proxy project (included in the repository).</ li >
346+ < li > Stop exposing ports in the app — only the proxy will listen on < code > :80</ code > and
347+ < code > :443</ code > .</ li >
348348< li > For each deployment, bring up a new app stack (e.g. < code > app/<commit></ code > ),
349349 connected to the proxy’s network.</ li >
350350< li > Test the new app while the current one remains live.</ li >
@@ -354,14 +354,16 @@ <h2 id="deployment-flow">🔄 Deployment Flow</h2>
354354< h2 id ="1-start-the-proxy "> 🧱 1. Start the Proxy</ h2 >
355355< p > A < code > proxy</ code > project already exists in your SuperStack project.</ p >
356356< blockquote >
357- < p > For consistent environments, use the proxy in all environments including
357+ < p > For consistent environments, use the proxy in all environments, including
358358development.</ p >
359359</ blockquote >
360- < p > Start it:</ p >
361- < div class ="highlight "> < pre > < span > </ span > < code > docker< span class ="w "> </ span > compose< span class ="w "> </ span > up< span class ="w "> </ span > -d
360+ < p > Start the proxy:</ p >
361+ < div class ="highlight "> < pre > < span > </ span > < code > < span class ="nb "> cd</ span > < span class ="w "> </ span > proxy
362+ docker< span class ="w "> </ span > compose< span class ="w "> </ span > up< span class ="w "> </ span > -d
362363</ code > </ pre > </ div >
363364< h2 id ="2-adjust-the-application "> ⚙️ 2. Adjust the Application</ h2 >
364- < p > Remove the app's exposed ports and connect it to the proxy's network:</ p >
365+ < p > < strong > Remove the < code > ports:</ code > section from the app,</ strong > and connect it to the proxy's
366+ network by adding these lines:</ p >
365367< div class ="highlight "> < span class ="filename "> app/compose.yaml</ span > < pre > < span > </ span > < code > < span class ="nt "> services</ span > < span class ="p "> :</ span >
366368< span class ="w "> </ span > < span class ="nt "> caddy</ span > < span class ="p "> :</ span >
367369< span class ="w "> </ span > < span class ="nt "> build</ span > < span class ="p "> :</ span >
@@ -378,19 +380,21 @@ <h2 id="2-adjust-the-application">⚙️ 2. Adjust the Application</h2>
378380</ span > < span class ="hll "> < span class ="w "> </ span > < span class ="nt "> proxy_default</ span > < span class ="p "> :</ span >
379381</ span > < span class ="hll "> < span class ="w "> </ span > < span class ="nt "> external</ span > < span class ="p "> :</ span > < span class ="w "> </ span > < span class ="l l-Scalar l-Scalar-Plain "> true</ span >
380382</ span > </ code > </ pre > </ div >
383+ < p > You should also remove the < code > ports:</ code > and < code > CADDY_SITE_ADDRESS</ code > in
384+ < code > app/compose.override.yaml</ code > .</ p >
381385< p > What's Changed?</ p >
382386< ol >
383387< li > Exposed ports were removed.</ li >
384388< li > < code > CADDY_SITE_ADDRESS</ code > now listens internally on port < code > :80</ code > .</ li >
385389< li > The app joins the proxy's network so traffic can be routed to it.</ li >
386- < li > A container alias (< code > _caddy</ code > ) lets the proxy target this service reliably.</ li >
390+ < li > A container alias (< code > _caddy</ code > ) allows the proxy to target this service
391+ reliably.</ li >
387392</ ol >
388- < p > You can also remove the < code > CADDY_SITE_ADDRESS</ code > override in
389- < code > compose.override.yaml</ code > .</ p >
390393< p > Recreate the app's Caddy container:</ p >
391- < div class ="highlight "> < pre > < span > </ span > < code > docker< span class ="w "> </ span > compose< span class ="w "> </ span > up< span class ="w "> </ span > -d< span class ="w "> </ span > --force-recreate< span class ="w "> </ span > caddy
394+ < div class ="highlight "> < pre > < span > </ span > < code > < span class ="nb "> cd</ span > < span class ="w "> </ span > app
395+ docker< span class ="w "> </ span > compose< span class ="w "> </ span > up< span class ="w "> </ span > -d< span class ="w "> </ span > --force-recreate< span class ="w "> </ span > caddy
392396</ code > </ pre > </ div >
393- < p > Commit these changes – your app is now " proxy-ready" .</ p >
397+ < p > Commit these changes – your app is now proxy-ready.</ p >
394398< h2 id ="3-deploying "> 🚀 3. Deploying</ h2 >
395399< p > The proxy is deployed once (usually manually), and each app is deployed
396400separately into its own directory.</ p >
@@ -404,8 +408,8 @@ <h2 id="3-deploying">🚀 3. Deploying</h2>
404408 compose.yaml
405409 .env
406410</ code > </ pre > </ div >
407- < p > Before deploying, build and push your own proxy image by adding an image name
408- to the Compose file:</ p >
411+ < p > Before deploying, build and push your own proxy image by adding an < code > image: </ code >
412+ line to the Compose file:</ p >
409413< div class ="highlight "> < span class ="filename "> proxy/compose.yaml</ span > < pre > < span > </ span > < code > < span class ="nt "> services</ span > < span class ="p "> :</ span >
410414< span class ="w "> </ span > < span class ="nt "> caddy</ span > < span class ="p "> :</ span >
411415< span class ="w "> </ span > < span class ="nt "> build</ span > < span class ="p "> :</ span >
@@ -423,17 +427,21 @@ <h2 id="3-deploying">🚀 3. Deploying</h2>
423427< div class ="highlight "> < pre > < span > </ span > < code > scp< span class ="w "> </ span > proxy/compose.yaml< span class ="w "> </ span > app-backend:proxy/
424428</ code > </ pre > </ div >
425429< p > Start the proxy:</ p >
426- < p > docker compose up -d</ p >
430+ < div class ="highlight "> < pre > < span > </ span > < code > docker< span class ="w "> </ span > compose< span class ="w "> </ span > up< span class ="w "> </ span > -d
431+ </ code > </ pre > </ div >
427432< h2 id ="4-deploy-the-new-app-stack "> 🆕 4. Deploy the New App Stack</ h2 >
428433< p > Deploy your app into a new directory (e.g. < code > b/</ code > ):</ p >
434+ < div class ="highlight "> < pre > < span > </ span > < code > mkdir< span class ="w "> </ span > app/b
435+ </ code > </ pre > </ div >
429436< div class ="highlight "> < pre > < span > </ span > < code > scp< span class ="w "> </ span > compose.yaml< span class ="w "> </ span > yourserver:app/b/
430437</ code > </ pre > </ div >
431438< p > Start it on the server:</ p >
432439< div class ="highlight "> < pre > < span > </ span > < code > < span class ="nb "> cd</ span > < span class ="w "> </ span > app/b
433440docker< span class ="w "> </ span > compose< span class ="w "> </ span > up< span class ="w "> </ span > -d
434441</ code > </ pre > </ div >
435- < p > Optionally, verify it's healthy before switching traffic:</ p >
436- < div class ="highlight "> < pre > < span > </ span > < code > docker< span class ="w "> </ span > compose< span class ="w "> </ span > < span class ="nb "> exec</ span > < span class ="w "> </ span > -T< span class ="w "> </ span > caddy< span class ="w "> </ span > curl< span class ="w "> </ span > -fsS< span class ="w "> </ span > http://caddy:80/healthz
442+ < p > Optionally, verify the new app is healthy before switching traffic:</ p >
443+ < div class ="highlight "> < pre > < span > </ span > < code > $< span class ="w "> </ span > docker< span class ="w "> </ span > compose< span class ="w "> </ span > < span class ="nb "> exec</ span > < span class ="w "> </ span > -T< span class ="w "> </ span > caddy< span class ="w "> </ span > curl< span class ="w "> </ span > -fsS< span class ="w "> </ span > http://caddy:80/healthz
444+ OK
437445</ code > </ pre > </ div >
438446< h2 id ="5-flip-traffic "> 🔁 5. Flip Traffic</ h2 >
439447< div class ="highlight "> < pre > < span > </ span > < code > < span class ="nb "> cd</ span > < span class ="w "> </ span > proxy
@@ -442,6 +450,7 @@ <h2 id="5-flip-traffic">🔁 5. Flip Traffic</h2>
442450</ code > </ pre > </ div >
443451< p > Traffic now points to the new stack.</ p >
444452< h2 id ="github-actions-example "> ⚡ GitHub Actions Example</ h2 >
453+ < p > Use this Github Actions Workflow to automate deployments.</ p >
445454< details >
446455< summary > Show full workflow</ summary >
447456< div class ="highlight "> < span class ="filename "> .github/workflows/ci.yaml</ span > < pre > < span > </ span > < code > < span class ="nt "> name</ span > < span class ="p "> :</ span > < span class ="w "> </ span > < span class ="l l-Scalar l-Scalar-Plain "> Deploy</ span >
0 commit comments