<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Vibe Coding With Fred - RSS Feed]]></title><description><![CDATA[A developer blog - Build Anything With Vibe Coding! I mean - anything]]></description><link>https://vibecodingwithfred.com</link><generator>GatsbyJS</generator><lastBuildDate>Sun, 11 Jan 2026 17:52:49 GMT</lastBuildDate><atom:link href="https://vibecodingwithfred.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><item><title><![CDATA[Keep Cloudflare Containers Warm: Eliminate Cold Starts with a Healthcheck Endpoint]]></title><description><![CDATA[Cloudflare Containers are fast once they're running, but cold starts can add 5+ seconds to your first request. Here's how to keep them warm with a lightweight healthcheck endpoint and a scheduled Worker—no external services needed.]]></description><link>https://vibecodingwithfred.com/blog/cloudflare-container-warmup/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/cloudflare-container-warmup/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 23 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Last tested:&lt;/strong&gt; December 2025 | &lt;strong&gt;Platform:&lt;/strong&gt; Cloudflare Workers Containers | &lt;strong&gt;Languages:&lt;/strong&gt; Node.js, Python&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Cloudflare Workers Containers are impressive. You get a full container runtime—any language, any framework—replicated and distributed across Cloudflare&apos;s global network. Once warm, they respond with almost no latency. The problem is getting them warm in the first place.&lt;/p&gt;
&lt;p&gt;If you&apos;re running anything heavier than a basic web server, cold starts can hit 3-5 seconds or more. That&apos;s an eternity for your first user of the day, or after any quiet period. Unlike standard Workers which spin up in milliseconds, containers need to pull images, start runtimes, and initialize your application. There&apos;s no magic bullet to eliminate this entirely, but you can make cold starts rare enough that most users never experience them.&lt;/p&gt;
&lt;p&gt;The solution is the same pattern that&apos;s worked for AWS Lambda and GCP Cloud Functions for years: keep the container warm with scheduled pings.&lt;/p&gt;
&lt;h2 id=&quot;what-cold-starts-actually-cost-you&quot;&gt;What Cold Starts Actually Cost You&lt;/h2&gt;
&lt;p&gt;When a Cloudflare Container goes cold, the next request triggers a cascade of operations. The container image needs to be pulled (if not cached nearby). The runtime starts and your application boots. Any initialization code runs—database connections open, config files parse, models load into memory. Only then does your actual request handler run.&lt;/p&gt;
&lt;p&gt;For a simple Node.js server, this might add 1-2 seconds. For a Python application with heavy dependencies like image processing libraries, you can easily hit 5 seconds or more. One user on Reddit reported seeing &quot;up to 5 seconds before any upload packets are sent&quot; on their image processor container—and that was on one of the larger container sizes.&lt;/p&gt;
&lt;p&gt;The first-byte delay isn&apos;t just annoying. It kills perceived performance. Users abandon pages that don&apos;t respond within 3 seconds. APIs that timeout look broken. Your container might be incredibly fast once running, but none of that matters if the cold start already drove users away.&lt;/p&gt;
&lt;h2 id=&quot;the-healthcheck-endpoint-pattern&quot;&gt;The Healthcheck Endpoint Pattern&lt;/h2&gt;
&lt;p&gt;The fix is straightforward: add a lightweight endpoint that your container can respond to instantly, then ping it on a schedule from outside. This keeps at least one container instance warm and ready for real traffic.&lt;/p&gt;
&lt;p&gt;The critical rule for your healthcheck endpoint is that it must not initialize heavy dependencies. No image libraries, no database connections, no model loading, no cache warming. It should return immediately with minimal work—ideally just a 204 No Content response. If your healthcheck triggers the same initialization as your real endpoints, you&apos;ve defeated the entire purpose.&lt;/p&gt;
&lt;p&gt;Think of it as a separate code path that proves the container is running without actually doing anything useful. Real requests get the full initialization. Healthcheck requests get a fast &quot;yes I&apos;m alive&quot; and nothing more.&lt;/p&gt;
&lt;h2 id=&quot;nodejs-implementation&quot;&gt;Node.js Implementation&lt;/h2&gt;
&lt;p&gt;Here&apos;s a complete Node.js server with a proper healthcheck endpoint. Notice how the heavy initialization is guarded behind a lazy-loading flag that only triggers on real requests.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; http &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;node:http&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Heavy dependencies stay uninitialized until needed&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; sharp&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; pipelineReady &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;initializePipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pipelineReady&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// This is the slow part - only do it for real requests&lt;/span&gt;
  sharp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;sharp&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;default&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Any other expensive setup goes here&lt;/span&gt;
  pipelineReady &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Pipeline initialized&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; server &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createServer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Healthcheck: return immediately, skip all initialization&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;method &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GET&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/healthcheck&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;writeHead&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;204&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token string-property property&quot;&gt;&apos;cache-control&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;no-store&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string-property property&quot;&gt;&apos;content-type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;text/plain&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Real request: initialize dependencies if needed&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;initializePipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Your actual request handling goes here&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;method &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;POST&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/resize&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Process image with sharp...&lt;/span&gt;
    res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;writeHead&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-property property&quot;&gt;&apos;content-type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;writeHead&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;404&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-property property&quot;&gt;&apos;content-type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;text/plain&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Not found&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

server&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Don&apos;t do heavy work here - this runs on cold start&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Server listening on port &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The healthcheck path returns a 204 response in microseconds. It doesn&apos;t touch the &lt;code class=&quot;language-text&quot;&gt;sharp&lt;/code&gt; import or any other expensive dependencies. When a real request comes in on &lt;code class=&quot;language-text&quot;&gt;/resize&lt;/code&gt;, that&apos;s when &lt;code class=&quot;language-text&quot;&gt;initializePipeline()&lt;/code&gt; runs for the first time.&lt;/p&gt;
&lt;p&gt;If you&apos;re using Express, the pattern is the same but with Express routing:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; express &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; pipelineReady &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ensurePipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/healthcheck&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;pipelineReady&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Lazy-load heavy dependencies&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; sharp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;sharp&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;default&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;locals&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sharp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; sharp&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    pipelineReady &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ensurePipeline&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Healthcheck bypasses all middleware except the check above&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/healthcheck&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;204&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Real endpoints get the initialized pipeline&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/resize&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; sharp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;locals&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sharp&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Process with sharp...&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Listening on &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The middleware &lt;code class=&quot;language-text&quot;&gt;ensurePipeline&lt;/code&gt; checks if we&apos;re hitting healthcheck and skips initialization if so. Every other route gets the full dependency load. This keeps your healthcheck fast while ensuring real requests have everything they need.&lt;/p&gt;
&lt;h2 id=&quot;python-implementation&quot;&gt;Python Implementation&lt;/h2&gt;
&lt;p&gt;The same pattern works in Python. Here&apos;s a FastAPI implementation with lazy loading:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; fastapi &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; FastAPI&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Response
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; functools &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; lru_cache
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os

app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; FastAPI&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Heavy imports stay at module level but don&apos;t execute&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# The actual loading happens in get_processor()&lt;/span&gt;
_processor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get_processor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;global&lt;/span&gt; _processor
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; _processor &lt;span class=&quot;token keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# This is the slow part - heavy imports happen here&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; PIL &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Image
        &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; numpy &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; np
        _processor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;pil&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Image&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;np&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; np&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Processor initialized&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; _processor

&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/healthcheck&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;healthcheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Return immediately - no initialization&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Response&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;status_code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;204&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/resize&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;resize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Real request: initialize if needed&lt;/span&gt;
    proc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; get_processor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Use proc[&apos;pil&apos;] and proc[&apos;np&apos;] for image processing...&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;success&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; __name__ &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;__main__&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; uvicorn
    port &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;PORT&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    uvicorn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;run&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;app&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;0.0.0.0&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; port&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;get_processor()&lt;/code&gt; function uses a global flag to ensure expensive imports only happen once, and only when a real endpoint calls it. The healthcheck endpoint never triggers this initialization—it just returns 204 and exits.&lt;/p&gt;
&lt;p&gt;For Flask, the approach is identical:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; flask &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Flask&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Response
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os

app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Flask&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
_processor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get_processor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;global&lt;/span&gt; _processor
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; _processor &lt;span class=&quot;token keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; PIL &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Image
        &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; numpy &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; np
        _processor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;pil&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Image&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;np&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; np&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; _processor

&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/healthcheck&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;healthcheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Response&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;status&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;204&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/resize&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;resize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    proc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; get_processor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;success&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; __name__ &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;__main__&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    port &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;PORT&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;run&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;0.0.0.0&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; port&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Run with Gunicorn in production: &lt;code class=&quot;language-text&quot;&gt;gunicorn -b 0.0.0.0:${PORT:-8080} app:app&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;the-cron-worker-keeping-things-warm&quot;&gt;The Cron Worker: Keeping Things Warm&lt;/h2&gt;
&lt;p&gt;Your container has a healthcheck endpoint. Now you need something to ping it on a schedule. The cleanest solution is a Cloudflare Worker with a Cron Trigger—it stays entirely within Cloudflare&apos;s ecosystem and costs nothing on the free tier.&lt;/p&gt;
&lt;p&gt;Create a new Worker project for your warmer:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; container-warmer &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; container-warmer
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; init &lt;span class=&quot;token parameter variable&quot;&gt;-y&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Create &lt;code class=&quot;language-text&quot;&gt;wrangler.toml&lt;/code&gt; with your cron schedule:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token key property&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;container-warmer&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;src/index.ts&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;compatibility_date&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2025-12-01&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;triggers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;crons&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;*/5 * * * *&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;*/5 * * * *&lt;/code&gt; expression runs every 5 minutes. Adjust based on how warm you need the container—more frequent pings mean warmer containers but more Worker invocations.&lt;/p&gt;
&lt;p&gt;Create &lt;code class=&quot;language-text&quot;&gt;src/index.ts&lt;/code&gt; with the scheduled handler:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Env&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;CONTAINER_URL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;AUTH_TOKEN&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scheduled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;event&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ScheduledEvent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; env&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Env&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ctx&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ExecutionContext&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;waitUntil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pingContainer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pingContainer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;env&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Env&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; headers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Record&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string-property property&quot;&gt;&apos;user-agent&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;cloudflare-container-warmer/1.0&apos;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Optional: protect your healthcheck with a bearer token&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;AUTH_TOKEN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    headers&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;authorization&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;AUTH_TOKEN&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CONTAINER_URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      method&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GET&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      headers
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ok &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;status &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;204&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Container warmed successfully&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Warm ping returned status: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;status&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Warm ping failed: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;error&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Set your environment variables and deploy:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Set the container&apos;s healthcheck URL&lt;/span&gt;
npx wrangler secret put CONTAINER_URL
&lt;span class=&quot;token comment&quot;&gt;# Enter: https://your-container.your-subdomain.workers.dev/healthcheck&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Optional: set an auth token&lt;/span&gt;
npx wrangler secret put AUTH_TOKEN

&lt;span class=&quot;token comment&quot;&gt;# Deploy the warmer&lt;/span&gt;
npx wrangler deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The Worker will now ping your container every 5 minutes, keeping at least one instance warm and ready for traffic.&lt;/p&gt;
&lt;h2 id=&quot;protecting-your-healthcheck&quot;&gt;Protecting Your Healthcheck&lt;/h2&gt;
&lt;p&gt;Without protection, anyone can hit your healthcheck endpoint and keep your container running—which you pay for. If you want to lock it down, add a simple bearer token check:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// In your container&apos;s healthcheck handler&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/healthcheck&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; auth &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;authorization&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; expected &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEALTHCHECK_TOKEN&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEALTHCHECK_TOKEN&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; auth &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; expected&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;401&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;204&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Set the same token in both your container and your warmer Worker. External requests without the token get rejected, but your scheduled pings get through.&lt;/p&gt;
&lt;h2 id=&quot;what-warming-cannot-guarantee&quot;&gt;What Warming Cannot Guarantee&lt;/h2&gt;
&lt;p&gt;Scheduled pings reduce cold starts significantly, but they don&apos;t eliminate them completely. Cloudflare can still evict your container instance based on resource pressure or their own scaling logic. If traffic spikes and multiple instances spin up, only the ones receiving your warm pings stay hot—new instances still cold-start.&lt;/p&gt;
&lt;p&gt;There&apos;s also no hard SLA for &quot;always warm.&quot; Cloudflare optimizes for their global infrastructure, not your specific container&apos;s uptime. Think of warming as a best-effort strategy that works most of the time, not a guarantee.&lt;/p&gt;
&lt;p&gt;That said, in practice, a 5-minute ping interval keeps containers warm enough that cold starts become rare events rather than common ones. Most of your users will never experience them.&lt;/p&gt;
&lt;h2 id=&quot;recommended-intervals&quot;&gt;Recommended Intervals&lt;/h2&gt;
&lt;p&gt;The right ping interval depends on your tolerance for cold starts versus cost:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Every 2-3 minutes:&lt;/strong&gt; Very warm. Cold starts become extremely rare. Higher Worker invocation count.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Every 5 minutes:&lt;/strong&gt; The sweet spot for most applications. Container stays warm enough for consistent performance without excessive pings.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Every 10-15 minutes:&lt;/strong&gt; Mostly warm. You&apos;ll see occasional cold starts during quiet periods, but still far better than no warming at all.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Every 30+ minutes:&lt;/strong&gt; Minimal warming. Good if you just want to prevent the container from being evicted entirely, but cold starts will still happen regularly.&lt;/p&gt;
&lt;p&gt;Start at 5 minutes and adjust based on what you see in your logs. If users report slow first loads, shorten the interval. If your container is handling steady traffic anyway, you might not need warming at all.&lt;/p&gt;
&lt;h2 id=&quot;additional-performance-tactics&quot;&gt;Additional Performance Tactics&lt;/h2&gt;
&lt;p&gt;Warming helps, but you can reduce cold start pain even further with these optimizations:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Shrink your container image.&lt;/strong&gt; Smaller images pull faster. Use slim base images, remove dev dependencies, and clean up any files you don&apos;t need at runtime. Every megabyte matters.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Move initialization out of startup.&lt;/strong&gt; Don&apos;t load models, open database connections, or parse large config files in your container&apos;s entrypoint. Defer that work to the first real request, or better yet, to specific endpoints that need it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Preload only what&apos;s essential.&lt;/strong&gt; If you need to accept uploads, make sure your upload handler can start receiving bytes before your image processing pipeline is ready. Acknowledge the request first, process later.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Consider container size.&lt;/strong&gt; Cloudflare offers different container classes. Larger containers have more resources but may take slightly longer to provision. Test whether your specific workload benefits from upsizing.&lt;/p&gt;
&lt;p&gt;The goal is to make your container as lightweight as possible at startup, even if that means lazy-loading some functionality.&lt;/p&gt;
&lt;h2 id=&quot;putting-it-all-together&quot;&gt;Putting It All Together&lt;/h2&gt;
&lt;p&gt;Here&apos;s the complete workflow:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Add a &lt;code class=&quot;language-text&quot;&gt;/healthcheck&lt;/code&gt; endpoint to your container that returns 204 immediately without initializing heavy dependencies&lt;/li&gt;
&lt;li&gt;Deploy a Worker with a Cron Trigger that pings your healthcheck every 5 minutes&lt;/li&gt;
&lt;li&gt;Optionally protect the healthcheck with a bearer token so only your warmer can access it&lt;/li&gt;
&lt;li&gt;Monitor your container logs to verify pings are working and cold starts are decreasing&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The implementation takes about 20 minutes. The payoff is a container that feels fast for every user, not just the ones who happen to hit it while it&apos;s already warm.&lt;/p&gt;
&lt;p&gt;Cloudflare Containers aren&apos;t cheap compared to standard Workers, but they let you run anything—any language, any framework, any runtime. Keeping them warm ensures you actually get the performance you&apos;re paying for.&lt;/p&gt;
&lt;h2 id=&quot;frequently-asked-questions&quot;&gt;Frequently Asked Questions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Why not just use Cloudflare Workers instead of Containers?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Workers are faster and cheaper but limited to JavaScript/TypeScript with specific APIs. Containers let you run Python, Go, Rust, or any language in a full Linux environment. If your workload requires libraries or runtimes that Workers don&apos;t support, Containers are your only option on Cloudflare&apos;s edge.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does this work for multiple container instances?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Your warmer only pings one endpoint, which keeps one instance warm. If Cloudflare scales up to multiple instances under load, the new ones will cold-start. For most applications this is fine—steady traffic keeps additional instances warm naturally.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How much does the warmer Worker cost?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The warmer is a standard Worker, covered by the free tier (100,000 requests/day). Running every 5 minutes uses about 8,640 invocations per month—well within free limits.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I use an external uptime monitor instead?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Yes. Services like UptimeRobot, Better Uptime, or Pingdom can hit your healthcheck endpoint on a schedule. The downside is adding an external dependency when a Worker Cron Trigger does the same thing natively.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Related Guides:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/cloudflare-workers-deployment/&quot;&gt;Deploy to Cloudflare Workers&lt;/a&gt;&lt;/strong&gt; - Complete Workers deployment guide with custom domains&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/pages-to-workers-migration/&quot;&gt;Migrate from Pages to Workers&lt;/a&gt;&lt;/strong&gt; - Full migration walkthrough with zero-downtime scripts&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/hono-markdown-blog-workers/&quot;&gt;Build a Blog with Hono on Workers&lt;/a&gt;&lt;/strong&gt; - Fast, simple markdown blog on Workers&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Cloudflare Containersをウォームに保つ：ヘルスチェックエンドポイントでコールドスタートを排除]]></title><description><![CDATA[Cloudflare Containersは実行中は高速ですが、コールドスタートは最初のリクエストに5秒以上追加される可能性があります。軽量なヘルスチェックエンドポイントとスケジュールされたWorkerでウォームに保つ方法を紹介します。外部サービス不要です。]]></description><link>https://vibecodingwithfred.com/ja/blog/cloudflare-container-warmup/</link><guid isPermaLink="false">https://vibecodingwithfred.com/ja/blog/cloudflare-container-warmup/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 23 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;最終テスト日:&lt;/strong&gt; 2025年12月 | &lt;strong&gt;プラットフォーム:&lt;/strong&gt; Cloudflare Workers Containers | &lt;strong&gt;言語:&lt;/strong&gt; Node.js、Python&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Cloudflare Workers Containersは印象的です。完全なコンテナランタイム—任意の言語、任意のフレームワーク—がCloudflareのグローバルネットワーク全体に複製・分散されます。ウォーム状態になると、ほとんどレイテンシなしで応答します。問題は、最初にウォーム状態にすることです。&lt;/p&gt;
&lt;p&gt;基本的なWebサーバーより重いものを実行している場合、コールドスタートは3〜5秒以上になる可能性があります。これは、その日の最初のユーザーや、静かな期間の後の最初のリクエストにとっては永遠です。ミリ秒で起動する標準のWorkersとは異なり、コンテナはイメージをプル、ランタイムを起動し、アプリケーションを初期化する必要があります。これを完全に排除する魔法の弾丸はありませんが、コールドスタートをほとんどのユーザーが経験しないほど稀にすることはできます。&lt;/p&gt;
&lt;p&gt;解決策は、AWS LambdaやGCP Cloud Functionsで何年も機能してきたのと同じパターンです：スケジュールされたpingでコンテナをウォームに保ちます。&lt;/p&gt;
&lt;h2 id=&quot;コールドスタートの実際のコスト&quot;&gt;コールドスタートの実際のコスト&lt;/h2&gt;
&lt;p&gt;Cloudflare Containerがコールドになると、次のリクエストは一連の操作をトリガーします。コンテナイメージをプルする必要があります（近くにキャッシュされていない場合）。ランタイムが起動し、アプリケーションがブートします。初期化コードが実行されます—データベース接続がオープンし、設定ファイルが解析され、モデルがメモリにロードされます。その後ようやく実際のリクエストハンドラが実行されます。&lt;/p&gt;
&lt;p&gt;シンプルなNode.jsサーバーの場合、これは1〜2秒追加されるかもしれません。画像処理ライブラリなどの重い依存関係を持つPythonアプリケーションの場合、5秒以上になることも簡単です。Redditのあるユーザーは、画像プロセッサコンテナで「アップロードパケットが送信されるまで最大5秒」を報告していました—それも大きなコンテナサイズの一つでした。&lt;/p&gt;
&lt;p&gt;最初のバイト遅延は単に迷惑なだけではありません。知覚されるパフォーマンスを殺します。3秒以内に応答しないページはユーザーに放棄されます。タイムアウトするAPIは壊れているように見えます。コンテナは実行中は非常に高速かもしれませんが、コールドスタートがすでにユーザーを追い払っていたら、それは関係ありません。&lt;/p&gt;
&lt;h2 id=&quot;ヘルスチェックエンドポイントパターン&quot;&gt;ヘルスチェックエンドポイントパターン&lt;/h2&gt;
&lt;p&gt;修正は簡単です：コンテナが即座に応答できる軽量なエンドポイントを追加し、外部からスケジュールでpingします。これにより、少なくとも1つのコンテナインスタンスがウォームで実際のトラフィックに対応できる状態を保ちます。&lt;/p&gt;
&lt;p&gt;ヘルスチェックエンドポイントの重要なルールは、重い依存関係を初期化してはならないことです。画像ライブラリなし、データベース接続なし、モデルローディングなし、キャッシュウォーミングなし。最小限の作業で即座に返す必要があります—理想的には204 No Contentレスポンスだけです。ヘルスチェックが実際のエンドポイントと同じ初期化をトリガーすると、目的全体が台無しになります。&lt;/p&gt;
&lt;p&gt;コンテナが実行中であることを証明する別のコードパスと考えてください。実際のリクエストは完全な初期化を取得します。ヘルスチェックリクエストは高速な「はい、生きています」を取得し、それ以外は何もしません。&lt;/p&gt;
&lt;h2 id=&quot;nodejs実装&quot;&gt;Node.js実装&lt;/h2&gt;
&lt;p&gt;適切なヘルスチェックエンドポイントを持つ完全なNode.jsサーバーを示します。重い初期化が遅延ロードフラグの後ろでガードされ、実際のリクエストでのみトリガーされることに注目してください。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; http &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;node:http&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 重い依存関係は必要になるまで初期化されない&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; sharp&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; pipelineReady &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;initializePipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pipelineReady&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// これが遅い部分 - 実際のリクエストでのみ実行&lt;/span&gt;
  sharp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;sharp&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;default&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// 他の高コストなセットアップもここに&lt;/span&gt;
  pipelineReady &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Pipeline initialized&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; server &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createServer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ヘルスチェック：即座に返し、すべての初期化をスキップ&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;method &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GET&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/healthcheck&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;writeHead&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;204&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token string-property property&quot;&gt;&apos;cache-control&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;no-store&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string-property property&quot;&gt;&apos;content-type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;text/plain&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// 実際のリクエスト：必要に応じて依存関係を初期化&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;initializePipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// 実際のリクエスト処理はここに&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;method &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;POST&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/resize&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// sharpで画像を処理...&lt;/span&gt;
    res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;writeHead&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-property property&quot;&gt;&apos;content-type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;writeHead&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;404&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-property property&quot;&gt;&apos;content-type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;text/plain&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Not found&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

server&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ここで重い作業をしない - コールドスタート時に実行される&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Server listening on port &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ヘルスチェックパスはマイクロ秒で204レスポンスを返します。&lt;code class=&quot;language-text&quot;&gt;sharp&lt;/code&gt;インポートや他の高コストな依存関係には触れません。&lt;code class=&quot;language-text&quot;&gt;/resize&lt;/code&gt;で実際のリクエストが来たとき、そのときに初めて&lt;code class=&quot;language-text&quot;&gt;initializePipeline()&lt;/code&gt;が実行されます。&lt;/p&gt;
&lt;p&gt;Expressを使用している場合、パターンは同じですがExpressルーティングを使用します：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; express &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; pipelineReady &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ensurePipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/healthcheck&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;pipelineReady&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 重い依存関係を遅延ロード&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; sharp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;sharp&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;default&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;locals&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sharp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; sharp&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    pipelineReady &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ensurePipeline&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ヘルスチェックは上記のチェック以外のすべてのミドルウェアをバイパス&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/healthcheck&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;204&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 実際のエンドポイントは初期化されたパイプラインを取得&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/resize&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; sharp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;locals&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sharp&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// sharpで処理...&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Listening on &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ミドルウェア&lt;code class=&quot;language-text&quot;&gt;ensurePipeline&lt;/code&gt;はヘルスチェックにヒットしているかチェックし、そうであれば初期化をスキップします。他のすべてのルートは完全な依存関係ロードを取得します。これにより、ヘルスチェックは高速に保たれ、実際のリクエストは必要なすべてを持っています。&lt;/p&gt;
&lt;h2 id=&quot;python実装&quot;&gt;Python実装&lt;/h2&gt;
&lt;p&gt;同じパターンがPythonでも機能します。遅延ロードを持つFastAPI実装を示します：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; fastapi &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; FastAPI&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Response
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; functools &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; lru_cache
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os

app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; FastAPI&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 重いインポートはモジュールレベルに留まるが実行されない&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# 実際のロードはget_processor()で発生&lt;/span&gt;
_processor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get_processor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;global&lt;/span&gt; _processor
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; _processor &lt;span class=&quot;token keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# これが遅い部分 - 重いインポートはここで発生&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; PIL &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Image
        &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; numpy &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; np
        _processor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;pil&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Image&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;np&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; np&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Processor initialized&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; _processor

&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/healthcheck&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;healthcheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# 即座に返す - 初期化なし&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Response&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;status_code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;204&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/resize&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;resize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# 実際のリクエスト：必要に応じて初期化&lt;/span&gt;
    proc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; get_processor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# proc[&apos;pil&apos;]とproc[&apos;np&apos;]を画像処理に使用...&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;success&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; __name__ &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;__main__&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; uvicorn
    port &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;PORT&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    uvicorn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;run&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;app&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;0.0.0.0&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; port&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;get_processor()&lt;/code&gt;関数はグローバルフラグを使用して、高コストなインポートが一度だけ発生し、実際のエンドポイントが呼び出したときにのみ発生することを保証します。ヘルスチェックエンドポイントはこの初期化をトリガーしません—ただ204を返して終了します。&lt;/p&gt;
&lt;h2 id=&quot;cronワーカーウォームに保つ&quot;&gt;Cronワーカー：ウォームに保つ&lt;/h2&gt;
&lt;p&gt;コンテナにヘルスチェックエンドポイントがあります。次に、スケジュールでpingするものが必要です。最もクリーンな解決策は、Cron Triggerを持つCloudflare Workerです—Cloudflareのエコシステム内に完全に留まり、無料ティアでは何もコストがかかりません。&lt;/p&gt;
&lt;p&gt;ウォーマー用の新しいWorkerプロジェクトを作成します：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; container-warmer &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; container-warmer
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; init &lt;span class=&quot;token parameter variable&quot;&gt;-y&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;cronスケジュールを持つ&lt;code class=&quot;language-text&quot;&gt;wrangler.toml&lt;/code&gt;を作成します：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token key property&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;container-warmer&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;src/index.ts&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;compatibility_date&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2025-12-01&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;triggers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;crons&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;*/5 * * * *&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;*/5 * * * *&lt;/code&gt;式は5分ごとに実行されます。コンテナをどれだけウォームに保つ必要があるかに応じて調整します—より頻繁なpingはより暖かいコンテナを意味しますが、Workerの呼び出し回数も増えます。&lt;/p&gt;
&lt;p&gt;スケジュールされたハンドラを持つ&lt;code class=&quot;language-text&quot;&gt;src/index.ts&lt;/code&gt;を作成します：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Env&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;CONTAINER_URL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;AUTH_TOKEN&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scheduled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;event&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ScheduledEvent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; env&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Env&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ctx&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ExecutionContext&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;waitUntil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pingContainer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pingContainer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;env&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Env&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; headers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Record&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string-property property&quot;&gt;&apos;user-agent&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;cloudflare-container-warmer/1.0&apos;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// オプション：ヘルスチェックをベアラートークンで保護&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;AUTH_TOKEN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    headers&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;authorization&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;AUTH_TOKEN&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CONTAINER_URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      method&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GET&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      headers
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ok &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;status &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;204&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Container warmed successfully&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Warm ping returned status: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;status&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Warm ping failed: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;error&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;環境変数を設定してデプロイします：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# コンテナのヘルスチェックURLを設定&lt;/span&gt;
npx wrangler secret put CONTAINER_URL
&lt;span class=&quot;token comment&quot;&gt;# 入力: https://your-container.your-subdomain.workers.dev/healthcheck&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# オプション：認証トークンを設定&lt;/span&gt;
npx wrangler secret put AUTH_TOKEN

&lt;span class=&quot;token comment&quot;&gt;# ウォーマーをデプロイ&lt;/span&gt;
npx wrangler deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Workerは5分ごとにコンテナにpingを送り、少なくとも1つのインスタンスをウォームでトラフィック準備完了の状態に保ちます。&lt;/p&gt;
&lt;h2 id=&quot;推奨間隔&quot;&gt;推奨間隔&lt;/h2&gt;
&lt;p&gt;適切なping間隔は、コールドスタートに対する許容度とコストによって異なります：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2〜3分ごと:&lt;/strong&gt; 非常にウォーム。コールドスタートは極めて稀になります。Workerの呼び出し回数が多くなります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5分ごと:&lt;/strong&gt; ほとんどのアプリケーションにとってスイートスポット。コンテナは一貫したパフォーマンスのために十分ウォームに保たれ、過度なpingなしで済みます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;10〜15分ごと:&lt;/strong&gt; ほぼウォーム。静かな期間中に時折コールドスタートが見られますが、ウォーミングなしよりははるかに良いです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;30分以上ごと:&lt;/strong&gt; 最小限のウォーミング。コンテナが完全に退去されるのを防ぎたいだけなら良いですが、コールドスタートは定期的に発生します。&lt;/p&gt;
&lt;p&gt;5分から始めて、ログで見られることに基づいて調整してください。ユーザーが最初のロードが遅いと報告したら、間隔を短くします。コンテナがすでに安定したトラフィックを処理しているなら、ウォーミングは全く必要ないかもしれません。&lt;/p&gt;
&lt;h2 id=&quot;すべてをまとめる&quot;&gt;すべてをまとめる&lt;/h2&gt;
&lt;p&gt;完全なワークフローは以下の通りです：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;重い依存関係を初期化せずに即座に204を返す&lt;code class=&quot;language-text&quot;&gt;/healthcheck&lt;/code&gt;エンドポイントをコンテナに追加&lt;/li&gt;
&lt;li&gt;5分ごとにヘルスチェックにpingを送るCron Trigger付きのWorkerをデプロイ&lt;/li&gt;
&lt;li&gt;オプションでヘルスチェックをベアラートークンで保護し、ウォーマーのみがアクセスできるようにする&lt;/li&gt;
&lt;li&gt;コンテナログを監視してpingが機能し、コールドスタートが減少していることを確認&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;実装には約20分かかります。その見返りは、すでにウォームな状態でヒットしたユーザーだけでなく、すべてのユーザーにとって高速に感じるコンテナです。&lt;/p&gt;
&lt;p&gt;Cloudflare Containersは標準のWorkersと比較して安価ではありませんが、任意の言語、任意のフレームワーク、任意のランタイムで何でも実行できます。ウォームに保つことで、支払っているパフォーマンスを実際に得られることを保証します。&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Build a Markdown Blog with Hono on Cloudflare Workers]]></title><description><![CDATA[Gatsby and Next.js are overkill for most blogs. Here's how to build a fast, simple markdown-based blog using Hono that runs on Cloudflare Workers. No build step drama, no framework bloat, just markdown and TypeScript.]]></description><link>https://vibecodingwithfred.com/blog/hono-markdown-blog-workers/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/hono-markdown-blog-workers/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Mon, 22 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Last tested:&lt;/strong&gt; December 2025 | &lt;strong&gt;Hono:&lt;/strong&gt; 4.x | &lt;strong&gt;Node.js:&lt;/strong&gt; 20+ | &lt;strong&gt;Platform:&lt;/strong&gt; Cloudflare Workers&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I built this blog with Gatsby. It works. It&apos;s also 200+ dependencies, a 2-minute build, and breaks every time I update a plugin. For a simple markdown blog, that&apos;s absurd.&lt;/p&gt;
&lt;p&gt;If you&apos;re starting fresh in 2025, there&apos;s a better way. Hono is a tiny web framework that runs on Cloudflare Workers. Combine it with markdown files and you get a blog that deploys in seconds, costs nothing to host, and doesn&apos;t require you to debug webpack config at 2am.&lt;/p&gt;
&lt;p&gt;Here&apos;s everything you need to build one from scratch.&lt;/p&gt;
&lt;h2 id=&quot;what-were-building&quot;&gt;What We&apos;re Building&lt;/h2&gt;
&lt;p&gt;A markdown blog with:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Posts written in markdown with YAML frontmatter&lt;/li&gt;
&lt;li&gt;A list page showing all posts&lt;/li&gt;
&lt;li&gt;Individual post pages with full content&lt;/li&gt;
&lt;li&gt;Proper SEO tags and schema markup&lt;/li&gt;
&lt;li&gt;Deploy to Cloudflare Workers for free&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Total size when deployed: around 10KB plus your content. No client-side JavaScript required.&lt;/p&gt;
&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;Before you start, make sure you have Node.js 18 or higher installed, a Cloudflare account (free tier works), and basic familiarity with TypeScript. You&apos;ll also need the Wrangler CLI, which we&apos;ll install in a moment.&lt;/p&gt;
&lt;h2 id=&quot;project-structure&quot;&gt;Project Structure&lt;/h2&gt;
&lt;p&gt;Create your project folder and set up this structure:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;your-blog/
├── content/
│   └── blog/
│       ├── my-first-post.md
│       └── another-post.md
├── src/
│   ├── index.ts
│   ├── routes/
│   │   └── blog.ts
│   └── templates/
│       └── blog.ts
├── package.json
├── tsconfig.json
└── wrangler.toml&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;content/blog&lt;/code&gt; folder holds your markdown posts. The &lt;code class=&quot;language-text&quot;&gt;src&lt;/code&gt; folder contains the Hono application code. Simple.&lt;/p&gt;
&lt;h2 id=&quot;install-dependencies&quot;&gt;Install Dependencies&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; init &lt;span class=&quot;token parameter variable&quot;&gt;-y&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; hono marked
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-D&lt;/span&gt; @types/node typescript wrangler&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That&apos;s three production dependencies. Compare that to the 847 packages in a typical Gatsby project.&lt;/p&gt;
&lt;h2 id=&quot;how-markdown-posts-work&quot;&gt;How Markdown Posts Work&lt;/h2&gt;
&lt;p&gt;Each blog post is a markdown file with YAML frontmatter at the top. The frontmatter contains metadata like title, date, and description. Everything after the second &lt;code class=&quot;language-text&quot;&gt;---&lt;/code&gt; is the post content.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;markdown&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-markdown line-numbers&quot;&gt;&lt;code class=&quot;language-markdown&quot;&gt;&lt;span class=&quot;token front-matter-block&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token front-matter yaml language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; My First Blog Post
&lt;span class=&quot;token key atrule&quot;&gt;slug&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; my&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;first&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;post
&lt;span class=&quot;token key atrule&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token datetime number&quot;&gt;2024-12-22&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; A brief description for SEO and previews.
&lt;span class=&quot;token key atrule&quot;&gt;author&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Your Name
&lt;span class=&quot;token key atrule&quot;&gt;tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;javascript&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; tutorial&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;#&lt;/span&gt; My First Blog Post&lt;/span&gt;

Your markdown content goes here.

&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;##&lt;/span&gt; Subheading&lt;/span&gt;

More content with &lt;span class=&quot;token bold&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;token content&quot;&gt;bold&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;**&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;token italic&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token content&quot;&gt;italic&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt;&lt;/span&gt; text.

&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; Bullet points
&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; Work great

```javascript
// Code blocks too
console.log(&apos;Hello, world!&apos;);&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;
The frontmatter gets parsed into structured data. The markdown body gets converted to HTML. Together they form a complete blog post.

## The Blog Routes

Create `src/routes/blog.ts`. This file handles parsing markdown, storing posts, and defining the routes.

```typescript
import { Hono } from &apos;hono&apos;;
import { marked } from &apos;marked&apos;;

export interface BlogPost {
  slug: string;
  title: string;
  date: string;
  description: string;
  author?: string;
  tags?: string[];
  content: string;
  htmlContent?: string;
}

function parseFrontmatter(markdown: string): {
  frontmatter: Record&amp;lt;string, any&gt;;
  content: string;
} {
  const match = markdown.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);

  if (!match) {
    return { frontmatter: {}, content: markdown };
  }

  const [, frontmatterStr, content] = match;
  const frontmatter: Record&amp;lt;string, any&gt; = {};

  for (const line of frontmatterStr.split(&apos;\n&apos;)) {
    const colonIndex = line.indexOf(&apos;:&apos;);
    if (colonIndex &gt; 0) {
      const key = line.slice(0, colonIndex).trim();
      let value = line.slice(colonIndex + 1).trim();

      if (value.startsWith(&apos;[&apos;) &amp;amp;&amp;amp; value.endsWith(&apos;]&apos;)) {
        value = value.slice(1, -1).split(&apos;,&apos;).map(v =&gt; v.trim()) as any;
      }

      frontmatter[key] = value;
    }
  }

  return { frontmatter, content };
}&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;parseFrontmatter&lt;/code&gt; function is simple. It splits the file on the &lt;code class=&quot;language-text&quot;&gt;---&lt;/code&gt; markers, then parses the YAML-like frontmatter line by line. It handles arrays like &lt;code class=&quot;language-text&quot;&gt;[tag1, tag2]&lt;/code&gt; by splitting on commas. Nothing fancy, but it works for 95% of use cases.&lt;/p&gt;
&lt;h2 id=&quot;storing-posts&quot;&gt;Storing Posts&lt;/h2&gt;
&lt;p&gt;Cloudflare Workers can&apos;t read the filesystem at runtime. Your posts need to be embedded in the code at build time. Here&apos;s how:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;BLOG_POSTS&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Map&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; BlogPost&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;EMBEDDED_POSTS&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Record&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token string-property property&quot;&gt;&apos;my-first-post&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;---
title: My First Post
slug: my-first-post
date: 2024-12-22
description: This is my first blog post.
author: Your Name
tags: [intro]
---

# My First Post

Welcome to my blog!
&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Add more posts here&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;initializePosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;BLOG_POSTS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;slug&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; markdown&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt; Object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;entries&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;EMBEDDED_POSTS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; frontmatter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; content &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parseFrontmatter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;markdown&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token constant&quot;&gt;BLOG_POSTS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;slug&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      slug&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; frontmatter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;slug &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; slug&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      title&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; frontmatter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Untitled&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      date&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; frontmatter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;date &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toISOString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;T&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      description&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; frontmatter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;description &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      author&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; frontmatter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;author&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      tags&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; frontmatter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tags&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      content&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      htmlContent&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;marked&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Yes, embedding posts as strings in your code is ugly. But it works and it&apos;s simple. If you have many posts, I&apos;ll show you how to automate this with a build script later.&lt;/p&gt;
&lt;h2 id=&quot;getting-and-listing-posts&quot;&gt;Getting and Listing Posts&lt;/h2&gt;
&lt;p&gt;Add these helper functions and the Hono routes:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getAllPosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; BlogPost&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;initializePosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;BLOG_POSTS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;b&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;date&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;date&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getPost&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;slug&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; BlogPost &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;undefined&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;initializePosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;BLOG_POSTS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;slug&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; blog &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Hono&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

blog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; posts &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getAllPosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; getBlogListPage &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;../templates/blog&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBlogListPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;posts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

blog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/:slug&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; slug &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;param&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;slug&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; post &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getPost&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;slug&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;notFound&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; getBlogPostPage &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;../templates/blog&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBlogPostPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Two routes total. One for the list page at &lt;code class=&quot;language-text&quot;&gt;/blog&lt;/code&gt;, one for individual posts at &lt;code class=&quot;language-text&quot;&gt;/blog/my-post-slug&lt;/code&gt;. Hono makes this straightforward.&lt;/p&gt;
&lt;h2 id=&quot;html-templates&quot;&gt;HTML Templates&lt;/h2&gt;
&lt;p&gt;Create &lt;code class=&quot;language-text&quot;&gt;src/templates/blog.ts&lt;/code&gt; for the HTML templates. I&apos;m including complete templates with CSS so you have something that looks decent out of the box.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; BlogPost &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;../routes/blog&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;formatDate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dateStr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; date &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dateStr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLocaleDateString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;en-US&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    year&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;numeric&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    month&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;long&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    day&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;numeric&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getBlogListPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;posts&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; BlogPost&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; postCards &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; posts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;post &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;article class=&quot;post-card&quot;&gt;
      &amp;lt;a href=&quot;/blog/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;slug&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&gt;
        &amp;lt;h2&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/h2&gt;
        &amp;lt;time datetime=&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;date&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;formatDate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;date&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/time&gt;
        &amp;lt;p&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;description&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/p&gt;
        &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tags &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
          &amp;lt;div class=&quot;tags&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tags&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;tag&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;span class=&quot;tag&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;tag&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
          &amp;lt;/div&gt;
        &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
      &amp;lt;/a&gt;
    &amp;lt;/article&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;!DOCTYPE html&gt;
&amp;lt;html lang=&quot;en&quot;&gt;
&amp;lt;head&gt;
  &amp;lt;meta charset=&quot;UTF-8&quot;&gt;
  &amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
  &amp;lt;title&gt;Blog | Your Site&amp;lt;/title&gt;
  &amp;lt;meta name=&quot;description&quot; content=&quot;Read our latest articles and insights.&quot;&gt;
  &amp;lt;link rel=&quot;canonical&quot; href=&quot;https://yoursite.com/blog&quot;&gt;
  &amp;lt;style&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getStyles&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/style&gt;
&amp;lt;/head&gt;
&amp;lt;body&gt;
  &amp;lt;header&gt;
    &amp;lt;nav&gt;
      &amp;lt;a href=&quot;/&quot; class=&quot;logo&quot;&gt;Your Site&amp;lt;/a&gt;
      &amp;lt;a href=&quot;/blog&quot;&gt;Blog&amp;lt;/a&gt;
    &amp;lt;/nav&gt;
  &amp;lt;/header&gt;
  &amp;lt;main class=&quot;blog-list&quot;&gt;
    &amp;lt;h1&gt;Blog&amp;lt;/h1&gt;
    &amp;lt;div class=&quot;posts&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;postCards&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/div&gt;
  &amp;lt;/main&gt;
  &amp;lt;footer&gt;
    &amp;lt;p&gt;&amp;amp;copy; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getFullYear&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; Your Site&amp;lt;/p&gt;
  &amp;lt;/footer&gt;
&amp;lt;/body&gt;
&amp;lt;/html&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The single post template needs proper SEO tags. Search engines care about meta descriptions, canonical URLs, and Open Graph tags. The JSON-LD schema helps Google understand your content for rich snippets.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getBlogPostPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;post&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; BlogPost&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;!DOCTYPE html&gt;
&amp;lt;html lang=&quot;en&quot;&gt;
&amp;lt;head&gt;
  &amp;lt;meta charset=&quot;UTF-8&quot;&gt;
  &amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
  &amp;lt;title&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; | Your Site&amp;lt;/title&gt;
  &amp;lt;meta name=&quot;description&quot; content=&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;description&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&gt;
  &amp;lt;link rel=&quot;canonical&quot; href=&quot;https://yoursite.com/blog/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;slug&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&gt;

  &amp;lt;meta property=&quot;og:type&quot; content=&quot;article&quot;&gt;
  &amp;lt;meta property=&quot;og:title&quot; content=&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&gt;
  &amp;lt;meta property=&quot;og:description&quot; content=&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;description&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&gt;
  &amp;lt;meta property=&quot;og:url&quot; content=&quot;https://yoursite.com/blog/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;slug&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&gt;
  &amp;lt;meta property=&quot;article:published_time&quot; content=&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;date&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;author &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;meta property=&quot;article:author&quot; content=&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;author&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;

  &amp;lt;script type=&quot;application/ld+json&quot;&gt;
  {
    &quot;@context&quot;: &quot;https://schema.org&quot;,
    &quot;@type&quot;: &quot;BlogPosting&quot;,
    &quot;headline&quot;: &quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;,
    &quot;description&quot;: &quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;description&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;,
    &quot;datePublished&quot;: &quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;date&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;,
    &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;author &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;author&quot;: { &quot;@type&quot;: &quot;Person&quot;, &quot;name&quot;: &quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;author&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot; },&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &quot;url&quot;: &quot;https://yoursite.com/blog/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;slug&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;
  }
  &amp;lt;/script&gt;

  &amp;lt;style&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getStyles&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/style&gt;
&amp;lt;/head&gt;
&amp;lt;body&gt;
  &amp;lt;header&gt;
    &amp;lt;nav&gt;
      &amp;lt;a href=&quot;/&quot; class=&quot;logo&quot;&gt;Your Site&amp;lt;/a&gt;
      &amp;lt;a href=&quot;/blog&quot;&gt;Blog&amp;lt;/a&gt;
    &amp;lt;/nav&gt;
  &amp;lt;/header&gt;
  &amp;lt;main class=&quot;blog-post&quot;&gt;
    &amp;lt;article&gt;
      &amp;lt;header class=&quot;post-header&quot;&gt;
        &amp;lt;h1&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/h1&gt;
        &amp;lt;div class=&quot;post-meta&quot;&gt;
          &amp;lt;time datetime=&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;date&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;formatDate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;date&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/time&gt;
          &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;author &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;span class=&quot;author&quot;&gt;by &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;author&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
        &amp;lt;/div&gt;
        &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tags &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
          &amp;lt;div class=&quot;tags&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tags&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;tag&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;span class=&quot;tag&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;tag&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
          &amp;lt;/div&gt;
        &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
      &amp;lt;/header&gt;
      &amp;lt;div class=&quot;post-content&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;htmlContent&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/div&gt;
    &amp;lt;/article&gt;
    &amp;lt;nav class=&quot;post-nav&quot;&gt;
      &amp;lt;a href=&quot;/blog&quot;&gt;&amp;amp;larr; Back to Blog&amp;lt;/a&gt;
    &amp;lt;/nav&gt;
  &amp;lt;/main&gt;
  &amp;lt;footer&gt;
    &amp;lt;p&gt;&amp;amp;copy; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getFullYear&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; Your Site&amp;lt;/p&gt;
  &amp;lt;/footer&gt;
&amp;lt;/body&gt;
&amp;lt;/html&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;the-css&quot;&gt;The CSS&lt;/h2&gt;
&lt;p&gt;I&apos;m including complete styles so you don&apos;t deploy something ugly. Add this function to your templates file:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getStyles&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    * { margin: 0; padding: 0; box-sizing: border-box; }

    body {
      font-family: -apple-system, BlinkMacSystemFont, &apos;Segoe UI&apos;, Roboto, sans-serif;
      line-height: 1.6;
      color: #1a202c;
      background: #fafafa;
    }

    header {
      background: white;
      border-bottom: 1px solid #e2e8f0;
      padding: 1rem 2rem;
    }

    header nav {
      max-width: 800px;
      margin: 0 auto;
      display: flex;
      gap: 2rem;
      align-items: center;
    }

    header .logo {
      font-weight: 700;
      font-size: 1.25rem;
      color: #1a202c;
      text-decoration: none;
    }

    header a { color: #4a5568; text-decoration: none; }
    header a:hover { color: #2d3748; }

    main {
      max-width: 800px;
      margin: 0 auto;
      padding: 3rem 2rem;
    }

    .blog-list h1 { font-size: 2.5rem; margin-bottom: 2rem; }
    .posts { display: flex; flex-direction: column; gap: 1.5rem; }

    .post-card {
      background: white;
      border-radius: 8px;
      padding: 1.5rem;
      box-shadow: 0 1px 3px rgba(0,0,0,0.1);
      transition: box-shadow 0.2s;
    }

    .post-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
    .post-card a { text-decoration: none; color: inherit; }
    .post-card h2 { font-size: 1.5rem; margin-bottom: 0.5rem; color: #2d3748; }
    .post-card time { font-size: 0.875rem; color: #718096; }
    .post-card p { margin-top: 0.5rem; color: #4a5568; }

    .tags { display: flex; gap: 0.5rem; margin-top: 0.75rem; }
    .tag {
      font-size: 0.75rem;
      padding: 0.25rem 0.5rem;
      background: #edf2f7;
      color: #4a5568;
      border-radius: 4px;
    }

    .post-header {
      margin-bottom: 2rem;
      padding-bottom: 1.5rem;
      border-bottom: 1px solid #e2e8f0;
    }

    .post-header h1 { font-size: 2.5rem; line-height: 1.2; margin-bottom: 1rem; }
    .post-meta { font-size: 0.9rem; color: #718096; display: flex; gap: 1rem; }

    .post-content { font-size: 1.125rem; line-height: 1.8; }
    .post-content h2 { font-size: 1.75rem; margin-top: 2rem; margin-bottom: 1rem; }
    .post-content h3 { font-size: 1.375rem; margin-top: 2rem; margin-bottom: 1rem; }
    .post-content p { margin-bottom: 1.25rem; }
    .post-content ul, .post-content ol { margin-bottom: 1.25rem; padding-left: 1.5rem; }
    .post-content li { margin-bottom: 0.5rem; }
    .post-content a { color: #3182ce; }
    .post-content a:hover { text-decoration: underline; }

    .post-content code {
      font-family: &apos;SF Mono&apos;, Consolas, monospace;
      font-size: 0.9em;
      background: #f1f5f9;
      padding: 0.2em 0.4em;
      border-radius: 4px;
    }

    .post-content pre {
      background: #1e293b;
      color: #e2e8f0;
      padding: 1.25rem;
      border-radius: 8px;
      overflow-x: auto;
      margin-bottom: 1.25rem;
    }

    .post-content pre code { background: none; padding: 0; color: inherit; }

    .post-content blockquote {
      border-left: 4px solid #e2e8f0;
      padding-left: 1rem;
      margin: 1.25rem 0;
      font-style: italic;
      color: #4a5568;
    }

    .post-nav {
      margin-top: 3rem;
      padding-top: 1.5rem;
      border-top: 1px solid #e2e8f0;
    }

    .post-nav a { color: #3182ce; text-decoration: none; }
    .post-nav a:hover { text-decoration: underline; }

    footer { text-align: center; padding: 2rem; color: #718096; font-size: 0.875rem; }

    @media (max-width: 640px) {
      main { padding: 2rem 1rem; }
      .blog-list h1, .post-header h1 { font-size: 2rem; }
      .post-content { font-size: 1rem; }
    }
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;the-main-app&quot;&gt;The Main App&lt;/h2&gt;
&lt;p&gt;Create &lt;code class=&quot;language-text&quot;&gt;src/index.ts&lt;/code&gt; to wire everything together:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Hono &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;hono&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; blog &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./routes/blog&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Hono&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/blog&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; blog&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Welcome to my blog!&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; app&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That&apos;s the entire application entry point. Three lines of meaningful code.&lt;/p&gt;
&lt;h2 id=&quot;wrangler-configuration&quot;&gt;Wrangler Configuration&lt;/h2&gt;
&lt;p&gt;Create &lt;code class=&quot;language-text&quot;&gt;wrangler.toml&lt;/code&gt; in your project root:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token key property&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;your-blog&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;src/index.ts&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;compatibility_date&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2024-01-01&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;compatibility_flags&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;nodejs_compat&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;compatibility_date&lt;/code&gt; locks your Workers runtime version. The &lt;code class=&quot;language-text&quot;&gt;nodejs_compat&lt;/code&gt; flag enables Node.js compatibility mode so the &lt;code class=&quot;language-text&quot;&gt;marked&lt;/code&gt; package works correctly.&lt;/p&gt;
&lt;h2 id=&quot;deploy&quot;&gt;Deploy&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Local development&lt;/span&gt;
npx wrangler dev

&lt;span class=&quot;token comment&quot;&gt;# Deploy to Cloudflare&lt;/span&gt;
npx wrangler deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first deploy prompts you to log in to Cloudflare. After that, deployments take about 5 seconds. Your blog is live at &lt;code class=&quot;language-text&quot;&gt;your-blog.your-account.workers.dev&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;adding-new-posts&quot;&gt;Adding New Posts&lt;/h2&gt;
&lt;p&gt;Since Workers can&apos;t read files at runtime, you have three options for managing content.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Option 1: Embed posts in code&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The simplest approach. Just add more entries to &lt;code class=&quot;language-text&quot;&gt;EMBEDDED_POSTS&lt;/code&gt;. Good for small blogs with a few posts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Option 2: Build-time bundling&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Write a script that reads your markdown files and generates TypeScript. Create &lt;code class=&quot;language-text&quot;&gt;scripts/bundle-posts.ts&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; readdirSync&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; readFileSync&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; writeFileSync &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;fs&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; join &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;path&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; postsDir &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./content/blog&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; outputFile &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./src/generated/posts.ts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; files &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;readdirSync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;postsDir&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;endsWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;.md&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; posts&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Record&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; file &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt; files&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; slug &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;.md&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; content &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;readFileSync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;postsDir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; file&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;utf-8&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  posts&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;slug&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; content&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;writeFileSync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;outputFile&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;export const POSTS = &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;posts&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Bundled &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;files&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; posts&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Run it before deploying:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;npx tsx scripts/bundle-posts.ts &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; npx wrangler deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Option 3: Use R2 or KV&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;For truly dynamic content, store markdown in Cloudflare R2 or Workers KV. Your route handler fetches content at request time. See our &lt;a href=&quot;/tutorials/r2-media-manager/&quot;&gt;R2 Media Manager tutorial&lt;/a&gt; for a complete guide to uploading and serving files from R2.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;blog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/:slug&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; slug &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;param&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;slug&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; r2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;BLOG_BUCKET&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; object &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; r2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;posts/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;slug&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;.md&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;object&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;notFound&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; markdown &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; frontmatter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; content &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parseFrontmatter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;markdown&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; html &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;marked&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Render template...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This adds complexity but lets you update content without redeploying code. Good for high-volume blogs or multiple authors.&lt;/p&gt;
&lt;h2 id=&quot;optional-rss-feed&quot;&gt;Optional: RSS Feed&lt;/h2&gt;
&lt;p&gt;Every blog should have an RSS feed. Add this route:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;blog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/rss.xml&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; posts &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getAllPosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; items &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; posts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;post &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;item&gt;
      &amp;lt;title&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/title&gt;
      &amp;lt;link&gt;https://yoursite.com/blog/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;slug&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/link&gt;
      &amp;lt;description&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;description&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/description&gt;
      &amp;lt;pubDate&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;date&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toUTCString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/pubDate&gt;
      &amp;lt;guid&gt;https://yoursite.com/blog/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;slug&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/guid&gt;
    &amp;lt;/item&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; rss &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&amp;lt;rss version=&quot;2.0&quot;&gt;
  &amp;lt;channel&gt;
    &amp;lt;title&gt;Your Blog&amp;lt;/title&gt;
    &amp;lt;link&gt;https://yoursite.com/blog&amp;lt;/link&gt;
    &amp;lt;description&gt;Your blog description&amp;lt;/description&gt;
    &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;items&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
  &amp;lt;/channel&gt;
&amp;lt;/rss&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rss&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-property property&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/rss+xml&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;optional-sitemap&quot;&gt;Optional: Sitemap&lt;/h2&gt;
&lt;p&gt;Search engines appreciate sitemaps. Add another route:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;blog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/sitemap.xml&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; posts &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getAllPosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; urls &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; posts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;url&gt;
      &amp;lt;loc&gt;https://yoursite.com/blog/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;slug&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/loc&gt;
      &amp;lt;lastmod&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;date&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/lastmod&gt;
    &amp;lt;/url&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot;?&gt;
    &amp;lt;urlset xmlns=&quot;http://www.sitemaps.org/schemas/sitemap/0.9&quot;&gt;
      &amp;lt;url&gt;
        &amp;lt;loc&gt;https://yoursite.com/blog&amp;lt;/loc&gt;
      &amp;lt;/url&gt;
      &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;urls&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;/urlset&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-property property&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/xml&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;what-you-get&quot;&gt;What You Get&lt;/h2&gt;
&lt;p&gt;When you&apos;re done, you have a blog that:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Deploys in 5 seconds, not 2 minutes&lt;/li&gt;
&lt;li&gt;Runs on Cloudflare&apos;s global edge network for free&lt;/li&gt;
&lt;li&gt;Has no client-side JavaScript unless you add it&lt;/li&gt;
&lt;li&gt;Loads fast because there&apos;s nothing to load&lt;/li&gt;
&lt;li&gt;Uses markdown files you can edit in any text editor&lt;/li&gt;
&lt;li&gt;Has proper SEO with schema markup built in&lt;/li&gt;
&lt;li&gt;Costs $0 unless you get millions of requests&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The total code is around 300 lines of TypeScript. You can read and understand all of it in an afternoon.&lt;/p&gt;
&lt;h2 id=&quot;when-to-use-this-vs-gatsbynextjs&quot;&gt;When to Use This vs Gatsby/Next.js&lt;/h2&gt;
&lt;p&gt;Use Hono on Workers when you want a simple blog, you don&apos;t need client-side interactivity, you value deployment speed and simplicity, and you&apos;re tired of debugging build tools.&lt;/p&gt;
&lt;p&gt;Use Gatsby or Next.js when you need a complex site with many pages, you want plugins for image optimization and GraphQL, you need client-side React components, or you&apos;re already deep in that ecosystem.&lt;/p&gt;
&lt;p&gt;There&apos;s no shame in using a big framework when you need it. But for a blog that&apos;s mostly words and code snippets, 10KB of Hono beats 10MB of Gatsby every time.&lt;/p&gt;
&lt;h2 id=&quot;next-steps&quot;&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;Once you have the basics working, consider adding syntax highlighting with Prism.js, a dark mode toggle, comments using something like Giscus, full-text search with a client-side library, or analytics using a privacy-friendly service. If you add any forms—contact, newsletter, comments—learn &lt;a href=&quot;/blog/honeypot-spam-protection/&quot;&gt;how to protect them from spam bots with honeypots&lt;/a&gt; before you get flooded with fake submissions.&lt;/p&gt;
&lt;p&gt;But start simple. Get your words on the internet first. You can add features later.&lt;/p&gt;
&lt;h2 id=&quot;related-guides&quot;&gt;Related Guides&lt;/h2&gt;
&lt;p&gt;Ready to deploy your Hono blog? Check out these guides:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;/blog/cloudflare-workers-deployment/&quot;&gt;Deploy Your Static Site to Cloudflare Workers&lt;/a&gt;&lt;/strong&gt; covers the full deployment process including custom domains and GitHub Actions CI/CD.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;/blog/godaddy-to-cloudflare-dns/&quot;&gt;Move Your DNS from GoDaddy to Cloudflare&lt;/a&gt;&lt;/strong&gt; helps you get your domain on Cloudflare for better performance.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;/seo/seo-content-only-experiment/&quot;&gt;Content-Only SEO Experiment&lt;/a&gt;&lt;/strong&gt; follows a new site with zero backlinks to see if content alone can rank—relevant if you&apos;re building a blog to attract organic traffic.&lt;/p&gt;
&lt;p&gt;Questions about building with Hono? Drop a comment below. I&apos;m actively using this setup for side projects and can share more specific examples if there&apos;s interest.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Honeypots Still Work: 3 Ways to Stop Spam Signups Without CAPTCHAs]]></title><description><![CDATA[Bot farms from Russia and Netherlands were flooding my waitlist with fake signups. Here's how a simple two-part honeypot detection system stopped them cold—no CAPTCHAs, no third-party services, just clever HTML and timing.]]></description><link>https://vibecodingwithfred.com/blog/honeypot-spam-protection/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/honeypot-spam-protection/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Fri, 19 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;honeypots-still-work-3-ways-to-stop-spam-signups-without-captchas&quot;&gt;Honeypots Still Work: 3 Ways to Stop Spam Signups Without CAPTCHAs&lt;/h2&gt;
&lt;p&gt;Last week, I noticed something suspicious in my SEO Friend waitlist signups. Dozens of email addresses from disposable domains, all submitted within milliseconds of each other, originating from IP addresses in Russia and the Netherlands. Classic bot farm behavior.&lt;/p&gt;
&lt;p&gt;The obvious solution? Slap a CAPTCHA on the form. But CAPTCHAs are annoying. They frustrate real users, hurt conversion rates, and honestly—modern bots are getting pretty good at solving them anyway. I wanted something invisible to humans but deadly to bots.&lt;/p&gt;
&lt;p&gt;Enter the honeypot.&lt;/p&gt;
&lt;h2 id=&quot;what-is-a-honeypot&quot;&gt;What is a Honeypot?&lt;/h2&gt;
&lt;p&gt;A honeypot is a trap designed to catch automated systems by exploiting their predictable behavior. In web security, a form honeypot works on a simple principle: bots auto-fill every form field they find, while humans only fill the fields they can see.&lt;/p&gt;
&lt;p&gt;If you add a hidden field that humans can&apos;t see, and that field gets filled out—you&apos;ve caught a bot.&lt;/p&gt;
&lt;p&gt;It&apos;s an old technique, but it still works remarkably well in 2025. Combined with timing checks, you can stop the vast majority of spam signups without any user friction whatsoever.&lt;/p&gt;
&lt;h2 id=&quot;the-problem-bot-farm-signups&quot;&gt;The Problem: Bot Farm Signups&lt;/h2&gt;
&lt;p&gt;Before implementing my honeypot, here&apos;s what I was dealing with. IPs from data centers in Russia, Netherlands, and Germany were hitting my waitlist form. The submissions came in at inhuman speed—0.2 to 0.5 seconds after the page loaded. The email addresses were all from disposable domains like tempmail and guerrillamail. And they were filling out every single form field they could find, which would become their undoing.&lt;/p&gt;
&lt;p&gt;Why do bots do this? They&apos;re harvesting email systems—submitting forms to see if confirmation emails bounce back, validating that your email pipeline works. They&apos;re polluting databases with junk data to waste your time and email quota. They&apos;re testing email addresses for credential stuffing attacks later. Sometimes it&apos;s competitor sabotage—inflating your metrics with garbage data so you can&apos;t trust your numbers.&lt;/p&gt;
&lt;p&gt;The bots were coming from the same /24 IP blocks, submitting within fractions of a second, and using obvious throwaway emails. Perfect candidates for honeypot detection.&lt;/p&gt;
&lt;h2 id=&quot;example-1-the-hidden-field-trap&quot;&gt;Example 1: The Hidden Field Trap&lt;/h2&gt;
&lt;p&gt;This is the classic honeypot technique that&apos;s been stopping bots since the early 2000s. The concept is beautifully simple: add a form field that&apos;s invisible to humans but visible to bots. When a bot auto-fills every field on the page (which they always do), they&apos;ll fill your hidden field too—and you&apos;ve caught them.&lt;/p&gt;
&lt;p&gt;Here&apos;s the HTML you&apos;ll add to your form, right alongside your real email input:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;form&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;waitlist-form&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/api/signup&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;POST&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- The real field that humans fill out --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Email Address&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;required&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- The honeypot field - completely invisible to humans --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;website&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value css language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;-9999px&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;tabindex&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;-1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;autocomplete&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;aria-hidden&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Join Waitlist&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Every attribute on that honeypot field serves a specific purpose. The &lt;code class=&quot;language-text&quot;&gt;type=&quot;text&quot;&lt;/code&gt; makes it look like a normal text field to any bot parsing your HTML. The &lt;code class=&quot;language-text&quot;&gt;name=&quot;website&quot;&lt;/code&gt; is deliberately innocuous—bots are programmed to fill common fields like &quot;website&quot;, &quot;url&quot;, &quot;company&quot;, and &quot;phone&quot;, so using one of these names ensures they&apos;ll take the bait. Avoid obvious names like &quot;honeypot&quot; or &quot;trap&quot; because some sophisticated bots look for those patterns.&lt;/p&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;style=&quot;position:absolute;left:-9999px&quot;&lt;/code&gt; is the key to invisibility. By positioning the element 9999 pixels off the left side of the screen, no human will ever see it, but bots parsing the DOM will find it just fine. The &lt;code class=&quot;language-text&quot;&gt;tabindex=&quot;-1&quot;&lt;/code&gt; prevents keyboard users from accidentally tabbing into the field while navigating your form. The &lt;code class=&quot;language-text&quot;&gt;autocomplete=&quot;off&quot;&lt;/code&gt; stops browser autofill from touching it—you don&apos;t want Chrome helpfully filling your honeypot with a legitimate user&apos;s saved data. Finally, &lt;code class=&quot;language-text&quot;&gt;aria-hidden=&quot;true&quot;&lt;/code&gt; tells screen readers to ignore this field entirely, maintaining accessibility for visually impaired users.&lt;/p&gt;
&lt;p&gt;On the server side, the check is trivial. If the &lt;code class=&quot;language-text&quot;&gt;website&lt;/code&gt; field contains any value at all, you&apos;ve caught a bot:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/signup&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; website &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseBody&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// If the honeypot field has any value, a bot filled it&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;website&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Bot detected via honeypot:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Return fake success - the bot thinks it worked&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Thanks for signing up!&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Real human - process normally&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;saveToDatabase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Welcome!&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The critical detail here: return a fake success response instead of an error. If you return an error message, sophisticated bots might detect they&apos;ve been caught and try different approaches—maybe skipping fields, maybe using a different IP. By returning success, the bot&apos;s operator sees green checkmarks in their logs and moves on to easier targets. Your database stays clean, and they never know what hit them.&lt;/p&gt;
&lt;h2 id=&quot;example-2-the-timing-check&quot;&gt;Example 2: The Timing Check&lt;/h2&gt;
&lt;p&gt;Humans take time to read a page and fill out a form. Even the fastest typist needs several seconds to scan the form, click into the email field, type their address, and hit submit. A real person simply cannot load a page and submit a form in 300 milliseconds.&lt;/p&gt;
&lt;p&gt;Bots can. And they do, constantly.&lt;/p&gt;
&lt;p&gt;This honeypot technique measures the time between page load and form submission. Anything under 3 seconds is almost certainly automated.&lt;/p&gt;
&lt;p&gt;First, add a hidden field to your form that will store the page load timestamp:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;form&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;waitlist-form&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/api/signup&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;POST&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Email Address&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;required&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Timing check field - captures when the page loaded --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;hidden&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;loadedAtField&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Join Waitlist&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
  &lt;span class=&quot;token comment&quot;&gt;// As soon as the page loads, record the timestamp&lt;/span&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;loadedAtField&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When the page loads, JavaScript immediately sets the hidden field&apos;s value to the current Unix timestamp in milliseconds. This value gets submitted along with the rest of the form data. The user never sees it, never interacts with it—it&apos;s completely invisible.&lt;/p&gt;
&lt;p&gt;On the server, you compare the submission time to the load time:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/signup&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; loadedAt &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseBody&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Calculate how long the user took to submit&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; elapsed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Less than 3 seconds? No human types that fast.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elapsed &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Bot detected: submitted in &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;elapsed&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;ms&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token comment&quot;&gt;// Return rate limit error - slightly more believable&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Please wait a moment before submitting.&apos;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;429&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Took a reasonable amount of time - probably human&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;saveToDatabase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Welcome!&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I use 3 seconds (3000 milliseconds) as the threshold. In testing, I found that even fast users with autofill enabled take at least 4-5 seconds to submit. The slowest bots I caught were around 800 milliseconds. Three seconds gives comfortable margin for both.&lt;/p&gt;
&lt;p&gt;Why return a 429 (Too Many Requests) error for timing violations instead of fake success? Because timing violations might occasionally catch edge cases—like a user with an extremely fast connection who spam-clicks submit. A &quot;please wait&quot; message is more user-friendly than silently succeeding and not actually signing them up. You can also return fake success here if you prefer; both approaches work.&lt;/p&gt;
&lt;h2 id=&quot;example-3-the-complete-two-part-system&quot;&gt;Example 3: The Complete Two-Part System&lt;/h2&gt;
&lt;p&gt;In practice, you want both techniques working together. The hidden field catches bots that auto-fill forms. The timing check catches bots that try to be clever and skip hidden fields. Together, they form a nearly impenetrable barrier against automated submissions.&lt;/p&gt;
&lt;p&gt;Here&apos;s the complete implementation I&apos;m running on SEO Friend:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token doctype&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;token doctype-tag&quot;&gt;DOCTYPE&lt;/span&gt; &lt;span class=&quot;token name&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;html&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;en&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meta&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;charset&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;UTF-8&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Join the Waitlist&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;form&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;waitlist-form&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;form-group&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Email Address&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;required&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;placeholder&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;you@example.com&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- HONEYPOT 1: Hidden field trap --&gt;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Bots auto-fill this; humans never see it --&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;website&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value css language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;-9999px&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;tabindex&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;-1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;autocomplete&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;aria-hidden&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- HONEYPOT 2: Timing check --&gt;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Records page load time for speed validation --&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;hidden&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Join Waitlist&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Set the timestamp as soon as page loads&lt;/span&gt;
    document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;loadedAt&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;waitlist-form&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;submit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;preventDefault&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; formData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FormData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;target&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/signup&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;POST&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; formData
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;success&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Thanks for joining the waitlist!&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;error &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Something went wrong.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And the server-side handler that ties it all together:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Hono &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;hono&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Hono&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/signup&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; body &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseBody&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; email &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; website &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;website&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// Honeypot field&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; loadedAt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// Timing field&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Get IP for logging (Cloudflare provides this header)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; ip &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;cf-connecting-ip&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;unknown&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// CHECK 1: Hidden field honeypot&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// If this field has any value, a bot filled it&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;website&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;[BLOCKED] Honeypot triggered | IP: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;ip&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; | Email: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;email&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Fake success - bot doesn&apos;t know it failed&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Thanks for signing up!&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// CHECK 2: Timing validation&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// If form was submitted in under 3 seconds, it&apos;s automated&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; elapsed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elapsed &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;[BLOCKED] Too fast (&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;elapsed&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;ms) | IP: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;ip&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; | Email: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;email&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Please wait a moment before submitting.&apos;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;429&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// CHECK 3: Basic email validation&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;email &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;includes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;@&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Please enter a valid email.&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// PASSED ALL CHECKS - This is a real human&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;[SUCCESS] New signup | IP: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;ip&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; | Email: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;email&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Save to your database&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ip&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;signedUpAt&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toISOString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Welcome to the waitlist!&apos;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; app&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The logging is important. By tracking blocked attempts, you can see exactly how many bots you&apos;re catching and from where. In my first week, I logged over 200 honeypot triggers from IPs in the Netherlands and Russia. All of them thought they successfully signed up. None of them made it into my database.&lt;/p&gt;
&lt;h2 id=&quot;results&quot;&gt;Results&lt;/h2&gt;
&lt;p&gt;After implementing this two-part honeypot system, spam signups dropped from 20-50 per day to essentially zero. The bots are still trying—I see them in my server logs—but they all get caught and fed fake success responses. They think they&apos;re winning. My database stays clean.&lt;/p&gt;
&lt;p&gt;Real users haven&apos;t noticed anything. There&apos;s no CAPTCHA to solve, no friction added to the signup flow. They fill out their email, click submit, and they&apos;re done. The honeypot checks happen invisibly in the background.&lt;/p&gt;
&lt;p&gt;The implementation took about 30 minutes—most of that was setting up the logging so I could monitor what was being blocked. There&apos;s no ongoing maintenance, no monthly fees for anti-spam services, no API keys to manage.&lt;/p&gt;
&lt;p&gt;Sometimes the simplest solutions are the best ones. Honeypots have been around for decades because they work. In an age of increasingly sophisticated AI and machine learning, there&apos;s something satisfying about stopping bots with a hidden text field and a timestamp.&lt;/p&gt;
&lt;h2 id=&quot;frequently-asked-questions&quot;&gt;Frequently Asked Questions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Do honeypots work against all bots?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;No. Sophisticated bots specifically designed to bypass honeypots may skip hidden fields or add artificial delays. However, these are rare. The vast majority of bots are simple scrapers that auto-fill everything and submit immediately. Honeypots catch 95%+ of automated spam, which is usually enough to make your spam problem manageable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Will this break accessibility?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Not if implemented correctly. The &lt;code class=&quot;language-text&quot;&gt;aria-hidden=&quot;true&quot;&lt;/code&gt; attribute tells screen readers to ignore the honeypot field entirely, so visually impaired users won&apos;t be confused by a field they can&apos;t interact with. The &lt;code class=&quot;language-text&quot;&gt;tabindex=&quot;-1&quot;&lt;/code&gt; prevents keyboard users from tabbing into it. Users navigating with assistive technology will experience the form exactly as intended.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What if a legitimate user somehow fills the honeypot?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is nearly impossible with proper implementation. The field is positioned 9999 pixels off the left edge of the screen—users literally cannot see it or click into it. Browser autofill is disabled with &lt;code class=&quot;language-text&quot;&gt;autocomplete=&quot;off&quot;&lt;/code&gt;. In two weeks of production use with thousands of visitors, I&apos;ve had zero false positives.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Should I use CAPTCHA instead?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;CAPTCHAs add friction. Studies show they can reduce conversion rates by 3-8%. Users hate them—I hate them. Honeypots are invisible; users don&apos;t even know they exist. Start with honeypots. Only add CAPTCHAs if you&apos;re still getting significant spam after implementing proper honeypot protection, which is unlikely for most sites.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Les Honeypots fonctionnent encore : 3 facons d'arreter les inscriptions spam sans CAPTCHAs]]></title><description><![CDATA[Des fermes de bots de Russie et des Pays-Bas inondaient ma liste d'attente d'inscriptions fausses. Voici comment un simple systeme de detection honeypot en deux parties les a arretes net - pas de CAPTCHAs, pas de services tiers, juste du HTML astucieux et du timing.]]></description><link>https://vibecodingwithfred.com/fr/blog/honeypot-spam-protection/</link><guid isPermaLink="false">https://vibecodingwithfred.com/fr/blog/honeypot-spam-protection/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Fri, 19 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;les-honeypots-fonctionnent-encore--3-facons-darreter-les-inscriptions-spam-sans-captchas&quot;&gt;Les Honeypots fonctionnent encore : 3 facons d&apos;arreter les inscriptions spam sans CAPTCHAs&lt;/h2&gt;
&lt;p&gt;La semaine derniere, j&apos;ai remarque quelque chose de suspect dans les inscriptions a ma liste d&apos;attente SEO Friend. Des dizaines d&apos;adresses email de domaines jetables, toutes soumises en quelques millisecondes l&apos;une de l&apos;autre, provenant d&apos;adresses IP en Russie et aux Pays-Bas. Comportement classique de ferme de bots.&lt;/p&gt;
&lt;p&gt;La solution evidente ? Coller un CAPTCHA sur le formulaire. Mais les CAPTCHAs sont ennuyeux. Ils frustrent les vrais utilisateurs, nuisent aux taux de conversion, et honnetement - les bots modernes deviennent assez bons pour les resoudre de toute facon. Je voulais quelque chose d&apos;invisible pour les humains mais mortel pour les bots.&lt;/p&gt;
&lt;p&gt;Entrez le honeypot.&lt;/p&gt;
&lt;h2 id=&quot;quest-ce-quun-honeypot-&quot;&gt;Qu&apos;est-ce qu&apos;un Honeypot ?&lt;/h2&gt;
&lt;p&gt;Un honeypot est un piege concu pour attraper les systemes automatises en exploitant leur comportement previsible. En securite web, un honeypot de formulaire fonctionne sur un principe simple : les bots remplissent automatiquement chaque champ de formulaire qu&apos;ils trouvent, tandis que les humains ne remplissent que les champs qu&apos;ils peuvent voir.&lt;/p&gt;
&lt;p&gt;Si vous ajoutez un champ cache que les humains ne peuvent pas voir, et que ce champ est rempli - vous avez attrape un bot.&lt;/p&gt;
&lt;p&gt;C&apos;est une vieille technique, mais elle fonctionne encore remarquablement bien en 2025. Combinee avec des verifications de timing, vous pouvez arreter la grande majorite des inscriptions spam sans aucune friction utilisateur.&lt;/p&gt;
&lt;h2 id=&quot;le-probleme--les-inscriptions-de-fermes-de-bots&quot;&gt;Le probleme : Les inscriptions de fermes de bots&lt;/h2&gt;
&lt;p&gt;Avant d&apos;implementer mon honeypot, voici a quoi je faisais face. Des IPs de centres de donnees en Russie, aux Pays-Bas et en Allemagne frappaient mon formulaire de liste d&apos;attente. Les soumissions arrivaient a une vitesse inhumaine - 0.2 a 0.5 secondes apres le chargement de la page. Les adresses email etaient toutes de domaines jetables comme tempmail et guerrillamail. Et ils remplissaient chaque champ de formulaire qu&apos;ils pouvaient trouver, ce qui deviendrait leur perte.&lt;/p&gt;
&lt;p&gt;Pourquoi les bots font-ils ca ? Ils recoltent des systemes email - soumettant des formulaires pour voir si les emails de confirmation rebondissent, validant que votre pipeline email fonctionne. Ils polluent les bases de donnees avec des donnees inutiles pour gaspiller votre temps et votre quota d&apos;emails. Ils testent des adresses email pour des attaques de credential stuffing plus tard. Parfois c&apos;est du sabotage concurrent - gonflant vos metriques avec des donnees poubelles pour que vous ne puissiez pas faire confiance a vos chiffres.&lt;/p&gt;
&lt;p&gt;Les bots venaient des memes blocs IP /24, soumettaient en fractions de seconde et utilisaient des emails jetables evidents. Candidats parfaits pour la detection honeypot.&lt;/p&gt;
&lt;h2 id=&quot;exemple-1--le-piege-a-champ-cache&quot;&gt;Exemple 1 : Le piege a champ cache&lt;/h2&gt;
&lt;p&gt;C&apos;est la technique honeypot classique qui arrete les bots depuis le debut des annees 2000. Le concept est magnifiquement simple : ajoutez un champ de formulaire invisible aux humains mais visible aux bots. Quand un bot remplit automatiquement chaque champ de la page (ce qu&apos;ils font toujours), ils rempliront aussi votre champ cache - et vous les avez attrapes.&lt;/p&gt;
&lt;p&gt;Voici le HTML que vous ajouterez a votre formulaire, juste a cote de votre vrai champ email :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;form&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;waitlist-form&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/api/signup&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;POST&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Le vrai champ que les humains remplissent --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Adresse email&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;required&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Le champ honeypot - completement invisible aux humains --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;website&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value css language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;-9999px&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;tabindex&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;-1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;autocomplete&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;aria-hidden&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Rejoindre la liste d&apos;attente&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Chaque attribut sur ce champ honeypot sert un objectif specifique. Le &lt;code class=&quot;language-text&quot;&gt;type=&quot;text&quot;&lt;/code&gt; le fait ressembler a un champ de texte normal pour tout bot analysant votre HTML. Le &lt;code class=&quot;language-text&quot;&gt;name=&quot;website&quot;&lt;/code&gt; est deliberement anodin - les bots sont programmes pour remplir les champs courants comme &quot;website&quot;, &quot;url&quot;, &quot;company&quot; et &quot;phone&quot;, donc utiliser un de ces noms garantit qu&apos;ils mordront a l&apos;hamecon. Evitez les noms evidents comme &quot;honeypot&quot; ou &quot;trap&quot; parce que certains bots sophistiques cherchent ces patterns.&lt;/p&gt;
&lt;p&gt;Le &lt;code class=&quot;language-text&quot;&gt;style=&quot;position:absolute;left:-9999px&quot;&lt;/code&gt; est la cle de l&apos;invisibilite. En positionnant l&apos;element 9999 pixels a gauche de l&apos;ecran, aucun humain ne le verra jamais, mais les bots analysant le DOM le trouveront sans probleme. Le &lt;code class=&quot;language-text&quot;&gt;tabindex=&quot;-1&quot;&lt;/code&gt; empeche les utilisateurs clavier de tabber accidentellement dans le champ en naviguant votre formulaire. Le &lt;code class=&quot;language-text&quot;&gt;autocomplete=&quot;off&quot;&lt;/code&gt; empeche le remplissage automatique du navigateur de le toucher - vous ne voulez pas que Chrome remplisse utilement votre honeypot avec les donnees sauvegardees d&apos;un utilisateur legitime. Enfin, &lt;code class=&quot;language-text&quot;&gt;aria-hidden=&quot;true&quot;&lt;/code&gt; dit aux lecteurs d&apos;ecran d&apos;ignorer completement ce champ, maintenant l&apos;accessibilite pour les utilisateurs malvoyants.&lt;/p&gt;
&lt;p&gt;Cote serveur, la verification est triviale. Si le champ &lt;code class=&quot;language-text&quot;&gt;website&lt;/code&gt; contient une valeur quelconque, vous avez attrape un bot :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/signup&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; website &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseBody&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Si le champ honeypot a une valeur, un bot l&apos;a rempli&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;website&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Bot detecte via honeypot:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Retourne faux succes - le bot pense que ca a marche&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Merci de vous etre inscrit !&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Vrai humain - traiter normalement&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;saveToDatabase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Bienvenue !&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Le detail critique ici : retournez une fausse reponse de succes au lieu d&apos;une erreur. Si vous retournez un message d&apos;erreur, les bots sophistiques pourraient detecter qu&apos;ils ont ete attrapes et essayer differentes approches - peut-etre sauter des champs, peut-etre utiliser une IP differente. En retournant le succes, l&apos;operateur du bot voit des coches vertes dans ses logs et passe a des cibles plus faciles. Votre base de donnees reste propre, et ils ne savent jamais ce qui les a frappes.&lt;/p&gt;
&lt;h2 id=&quot;exemple-2--la-verification-de-timing&quot;&gt;Exemple 2 : La verification de timing&lt;/h2&gt;
&lt;p&gt;Les humains prennent du temps pour lire une page et remplir un formulaire. Meme le dactylographe le plus rapide a besoin de plusieurs secondes pour scanner le formulaire, cliquer dans le champ email, taper son adresse et cliquer sur soumettre. Une vraie personne ne peut tout simplement pas charger une page et soumettre un formulaire en 300 millisecondes.&lt;/p&gt;
&lt;p&gt;Les bots peuvent. Et ils le font, constamment.&lt;/p&gt;
&lt;p&gt;Cette technique honeypot mesure le temps entre le chargement de la page et la soumission du formulaire. Tout ce qui est sous 3 secondes est presque certainement automatise.&lt;/p&gt;
&lt;p&gt;D&apos;abord, ajoutez un champ cache a votre formulaire qui stockera l&apos;horodatage de chargement de page :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;form&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;waitlist-form&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/api/signup&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;POST&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Adresse email&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;required&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Champ de verification de timing - capture quand la page a charge --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;hidden&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;loadedAtField&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Rejoindre la liste d&apos;attente&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Des que la page charge, enregistre l&apos;horodatage&lt;/span&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;loadedAtField&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Quand la page charge, JavaScript definit immediatement la valeur du champ cache a l&apos;horodatage Unix actuel en millisecondes. Cette valeur est soumise avec le reste des donnees du formulaire. L&apos;utilisateur ne la voit jamais, n&apos;interagit jamais avec - c&apos;est completement invisible.&lt;/p&gt;
&lt;p&gt;Cote serveur, vous comparez le temps de soumission au temps de chargement :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/signup&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; loadedAt &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseBody&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Calcule combien de temps l&apos;utilisateur a mis pour soumettre&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; elapsed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Moins de 3 secondes ? Aucun humain ne tape aussi vite.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elapsed &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Bot detecte: soumis en &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;elapsed&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;ms&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token comment&quot;&gt;// Retourne erreur de rate limit - legerement plus credible&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Veuillez attendre un moment avant de soumettre.&apos;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;429&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// A pris un temps raisonnable - probablement humain&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;saveToDatabase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Bienvenue !&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;J&apos;utilise 3 secondes (3000 millisecondes) comme seuil. En testant, j&apos;ai trouve que meme les utilisateurs rapides avec le remplissage automatique active prennent au moins 4-5 secondes pour soumettre. Les bots les plus lents que j&apos;ai attrapes etaient autour de 800 millisecondes. Trois secondes donne une marge confortable pour les deux.&lt;/p&gt;
&lt;p&gt;Pourquoi retourner une erreur 429 (Too Many Requests) pour les violations de timing au lieu d&apos;un faux succes ? Parce que les violations de timing pourraient occasionnellement attraper des cas limites - comme un utilisateur avec une connexion extremement rapide qui spam-clique soumettre. Un message &quot;veuillez attendre&quot; est plus convivial que de reussir silencieusement sans vraiment les inscrire. Vous pouvez aussi retourner un faux succes ici si vous preferez ; les deux approches fonctionnent.&lt;/p&gt;
&lt;h2 id=&quot;exemple-3--le-systeme-complet-en-deux-parties&quot;&gt;Exemple 3 : Le systeme complet en deux parties&lt;/h2&gt;
&lt;p&gt;En pratique, vous voulez les deux techniques travaillant ensemble. Le champ cache attrape les bots qui remplissent automatiquement les formulaires. La verification de timing attrape les bots qui essaient d&apos;etre malins et sautent les champs caches. Ensemble, ils forment une barriere presque impenetrable contre les soumissions automatisees.&lt;/p&gt;
&lt;p&gt;Voici l&apos;implementation complete que j&apos;utilise sur SEO Friend :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token doctype&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;token doctype-tag&quot;&gt;DOCTYPE&lt;/span&gt; &lt;span class=&quot;token name&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;html&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;fr&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meta&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;charset&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;UTF-8&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Rejoindre la liste d&apos;attente&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;form&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;waitlist-form&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;form-group&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Adresse email&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;required&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;placeholder&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;vous@exemple.com&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- HONEYPOT 1: Piege a champ cache --&gt;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Les bots remplissent ceci ; les humains ne le voient jamais --&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;website&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value css language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;-9999px&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;tabindex&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;-1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;autocomplete&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;aria-hidden&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- HONEYPOT 2: Verification de timing --&gt;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Enregistre le temps de chargement de page pour validation de vitesse --&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;hidden&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Rejoindre la liste d&apos;attente&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Definir l&apos;horodatage des que la page charge&lt;/span&gt;
    document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;loadedAt&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;waitlist-form&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;submit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;preventDefault&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; formData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FormData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;target&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/signup&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;POST&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; formData
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;success&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Merci d\&apos;avoir rejoint la liste d\&apos;attente !&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;error &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Quelque chose s\&apos;est mal passe.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Et le handler cote serveur qui lie tout ensemble :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Hono &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;hono&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Hono&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/signup&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; body &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseBody&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; email &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; website &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;website&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// Champ Honeypot&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; loadedAt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// Champ de timing&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Obtenir IP pour le logging (Cloudflare fournit cet header)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; ip &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;cf-connecting-ip&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;unknown&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// VERIFICATION 1: Honeypot de champ cache&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Si ce champ a une valeur, un bot l&apos;a rempli&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;website&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;[BLOQUE] Honeypot declenche | IP: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;ip&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; | Email: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;email&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Faux succes - le bot ne sait pas qu&apos;il a echoue&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Merci de vous etre inscrit !&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// VERIFICATION 2: Validation de timing&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Si le formulaire a ete soumis en moins de 3 secondes, c&apos;est automatise&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; elapsed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elapsed &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;[BLOQUE] Trop rapide (&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;elapsed&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;ms) | IP: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;ip&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; | Email: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;email&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Veuillez attendre un moment avant de soumettre.&apos;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;429&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// VERIFICATION 3: Validation email basique&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;email &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;includes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;@&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Veuillez entrer un email valide.&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// TOUTES LES VERIFICATIONS PASSEES - C&apos;est un vrai humain&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;[SUCCES] Nouvelle inscription | IP: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;ip&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; | Email: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;email&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Sauvegarder dans votre base de donnees&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ip&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;signedUpAt&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toISOString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Bienvenue dans la liste d\&apos;attente !&apos;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; app&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Le logging est important. En suivant les tentatives bloquees, vous pouvez voir exactement combien de bots vous attrapez et d&apos;ou. Dans ma premiere semaine, j&apos;ai logue plus de 200 declenchements honeypot depuis des IPs aux Pays-Bas et en Russie. Tous pensaient qu&apos;ils s&apos;etaient inscrits avec succes. Aucun n&apos;a atteint ma base de donnees.&lt;/p&gt;
&lt;h2 id=&quot;resultats&quot;&gt;Resultats&lt;/h2&gt;
&lt;p&gt;Apres avoir implemente ce systeme honeypot en deux parties, les inscriptions spam sont passees de 20-50 par jour a essentiellement zero. Les bots essaient toujours - je les vois dans mes logs serveur - mais ils sont tous attrapes et nourris de fausses reponses de succes. Ils pensent qu&apos;ils gagnent. Ma base de donnees reste propre.&lt;/p&gt;
&lt;p&gt;Les vrais utilisateurs n&apos;ont rien remarque. Il n&apos;y a pas de CAPTCHA a resoudre, pas de friction ajoutee au flux d&apos;inscription. Ils remplissent leur email, cliquent soumettre, et c&apos;est fait. Les verifications honeypot se passent invisiblement en arriere-plan.&lt;/p&gt;
&lt;p&gt;L&apos;implementation a pris environ 30 minutes - la plupart de ce temps a ete pour configurer le logging pour que je puisse surveiller ce qui etait bloque. Il n&apos;y a pas de maintenance continue, pas de frais mensuels pour des services anti-spam, pas de cles API a gerer.&lt;/p&gt;
&lt;p&gt;Parfois les solutions les plus simples sont les meilleures. Les honeypots existent depuis des decennies parce qu&apos;ils fonctionnent. A une epoque d&apos;IA et de machine learning de plus en plus sophistiques, il y a quelque chose de satisfaisant a arreter des bots avec un champ de texte cache et un horodatage.&lt;/p&gt;
&lt;h2 id=&quot;questions-frequentes&quot;&gt;Questions frequentes&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Les honeypots fonctionnent-ils contre tous les bots ?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Non. Les bots sophistiques specifiquement concus pour contourner les honeypots peuvent sauter les champs caches ou ajouter des delais artificiels. Cependant, ceux-ci sont rares. La grande majorite des bots sont de simples scrapers qui remplissent tout automatiquement et soumettent immediatement. Les honeypots attrapent 95%+ du spam automatise, ce qui est generalement suffisant pour rendre votre probleme de spam gerable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cela va-t-il casser l&apos;accessibilite ?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Pas si c&apos;est implemente correctement. L&apos;attribut &lt;code class=&quot;language-text&quot;&gt;aria-hidden=&quot;true&quot;&lt;/code&gt; dit aux lecteurs d&apos;ecran d&apos;ignorer completement le champ honeypot, donc les utilisateurs malvoyants ne seront pas confus par un champ avec lequel ils ne peuvent pas interagir. Le &lt;code class=&quot;language-text&quot;&gt;tabindex=&quot;-1&quot;&lt;/code&gt; empeche les utilisateurs clavier de tabber dedans. Les utilisateurs naviguant avec des technologies d&apos;assistance vivront le formulaire exactement comme prevu.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Que se passe-t-il si un utilisateur legitime remplit le honeypot d&apos;une facon ou d&apos;une autre ?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;C&apos;est presque impossible avec une implementation correcte. Le champ est positionne 9999 pixels au-dela du bord gauche de l&apos;ecran - les utilisateurs ne peuvent litteralement pas le voir ou cliquer dedans. Le remplissage automatique du navigateur est desactive avec &lt;code class=&quot;language-text&quot;&gt;autocomplete=&quot;off&quot;&lt;/code&gt;. En deux semaines d&apos;utilisation en production avec des milliers de visiteurs, j&apos;ai eu zero faux positifs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Devrais-je utiliser un CAPTCHA a la place ?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Les CAPTCHAs ajoutent de la friction. Les etudes montrent qu&apos;ils peuvent reduire les taux de conversion de 3-8%. Les utilisateurs les detestent - je les deteste. Les honeypots sont invisibles ; les utilisateurs ne savent meme pas qu&apos;ils existent. Commencez avec les honeypots. N&apos;ajoutez des CAPTCHAs que si vous recevez encore du spam significatif apres avoir implemente une protection honeypot correcte, ce qui est peu probable pour la plupart des sites.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[허니팟은 여전히 효과적: CAPTCHA 없이 스팸 가입을 막는 3가지 방법]]></title><description><![CDATA[러시아와 네덜란드의 봇 팜이 제 대기자 명단에 가짜 가입을 쏟아붓고 있었습니다. 간단한 2단계 허니팟 탐지 시스템으로 그들을 완전히 막은 방법을 소개합니다—CAPTCHA도, 타사 서비스도 없이, 영리한 HTML과 타이밍만으로.]]></description><link>https://vibecodingwithfred.com/ko/blog/honeypot-spam-protection/</link><guid isPermaLink="false">https://vibecodingwithfred.com/ko/blog/honeypot-spam-protection/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Fri, 19 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;허니팟은-여전히-효과적-captcha-없이-스팸-가입을-막는-3가지-방법&quot;&gt;허니팟은 여전히 효과적: CAPTCHA 없이 스팸 가입을 막는 3가지 방법&lt;/h2&gt;
&lt;p&gt;지난주, SEO Friend 대기자 명단 가입에서 의심스러운 것을 발견했습니다. 일회용 도메인에서 수십 개의 이메일 주소가 서로 몇 밀리초 간격으로 제출되었고, 러시아와 네덜란드의 IP 주소에서 발생했습니다. 전형적인 봇 팜 행동입니다.&lt;/p&gt;
&lt;p&gt;명백한 해결책은? 폼에 CAPTCHA를 붙이는 것입니다. 하지만 CAPTCHA는 짜증납니다. 실제 사용자를 좌절시키고, 전환율을 떨어뜨리며, 솔직히—현대 봇들은 어쨌든 꽤 잘 풀고 있습니다. 저는 인간에게는 보이지 않지만 봇에게는 치명적인 것을 원했습니다.&lt;/p&gt;
&lt;p&gt;허니팟의 등장입니다.&lt;/p&gt;
&lt;h2 id=&quot;허니팟이란&quot;&gt;허니팟이란?&lt;/h2&gt;
&lt;p&gt;허니팟은 예측 가능한 행동을 악용하여 자동화된 시스템을 잡도록 설계된 함정입니다. 웹 보안에서 폼 허니팟은 간단한 원칙으로 작동합니다: 봇은 찾는 모든 폼 필드를 자동 채우지만, 인간은 볼 수 있는 필드만 채웁니다.&lt;/p&gt;
&lt;p&gt;인간이 볼 수 없는 숨겨진 필드를 추가하고 그 필드가 채워지면—봇을 잡은 것입니다.&lt;/p&gt;
&lt;p&gt;오래된 기술이지만 2025년에도 여전히 놀라울 정도로 잘 작동합니다. 타이밍 검사와 결합하면 사용자 마찰 없이 대부분의 스팸 가입을 막을 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;문제-봇-팜-가입&quot;&gt;문제: 봇 팜 가입&lt;/h2&gt;
&lt;p&gt;허니팟을 구현하기 전, 제가 다루던 상황입니다. 러시아, 네덜란드, 독일의 데이터 센터에서 온 IP들이 제 대기자 명단 폼을 공격했습니다. 제출은 비인간적인 속도로 들어왔습니다—페이지 로드 후 0.2에서 0.5초. 이메일 주소는 모두 tempmail과 guerrillamail 같은 일회용 도메인에서 왔습니다. 그리고 찾을 수 있는 모든 폼 필드를 채우고 있었는데, 이것이 그들의 패망이 됩니다.&lt;/p&gt;
&lt;p&gt;봇들이 왜 이러는 걸까요? 이메일 시스템을 수확하고 있습니다—확인 이메일이 반송되는지 보기 위해 폼을 제출하고, 이메일 파이프라인이 작동하는지 확인합니다. 시간과 이메일 할당량을 낭비하게 하려고 정크 데이터로 데이터베이스를 오염시킵니다. 나중에 크리덴셜 스터핑 공격을 위해 이메일 주소를 테스트합니다. 때로는 경쟁자 방해입니다—숫자를 신뢰할 수 없도록 쓰레기 데이터로 메트릭을 부풀립니다.&lt;/p&gt;
&lt;p&gt;봇들은 같은 /24 IP 블록에서 오고, 몇 분의 1초 만에 제출하며, 명백한 일회용 이메일을 사용했습니다. 허니팟 탐지에 완벽한 후보들입니다.&lt;/p&gt;
&lt;h2 id=&quot;예시-1-숨겨진-필드-함정&quot;&gt;예시 1: 숨겨진 필드 함정&lt;/h2&gt;
&lt;p&gt;이것은 2000년대 초반부터 봇을 막아온 고전적인 허니팟 기술입니다. 개념은 아름답게 간단합니다: 인간에게는 보이지 않지만 봇에게는 보이는 폼 필드를 추가합니다. 봇이 페이지의 모든 필드를 자동 채울 때(항상 그렇듯이) 숨겨진 필드도 채웁니다—그리고 그들을 잡았습니다.&lt;/p&gt;
&lt;p&gt;실제 이메일 입력과 함께 폼에 추가할 HTML입니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;form&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;waitlist-form&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/api/signup&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;POST&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- 인간이 채우는 실제 필드 --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;이메일 주소&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;required&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- 허니팟 필드 - 인간에게 완전히 보이지 않음 --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;website&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value css language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;-9999px&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;tabindex&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;-1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;autocomplete&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;aria-hidden&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;대기자 명단 가입&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;서버 측에서 검사는 간단합니다. &lt;code class=&quot;language-text&quot;&gt;website&lt;/code&gt; 필드에 값이 있으면 봇을 잡은 것입니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/signup&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; website &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseBody&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// 허니팟 필드에 값이 있으면 봇이 채운 것&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;website&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;허니팟으로 봇 감지:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// 가짜 성공 반환 - 봇은 작동했다고 생각함&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;가입해 주셔서 감사합니다!&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// 실제 인간 - 정상적으로 처리&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;saveToDatabase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;환영합니다!&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;여기서 중요한 세부 사항: 오류 대신 가짜 성공 응답을 반환합니다. 오류 메시지를 반환하면 정교한 봇이 잡혔다는 것을 감지하고 다른 접근 방식을 시도할 수 있습니다—필드를 건너뛰거나 다른 IP를 사용하는 등. 성공을 반환하면 봇 운영자는 로그에서 녹색 체크 표시를 보고 더 쉬운 대상으로 이동합니다. 데이터베이스는 깨끗하게 유지되고 그들은 무슨 일이 일어났는지 절대 모릅니다.&lt;/p&gt;
&lt;h2 id=&quot;예시-2-타이밍-검사&quot;&gt;예시 2: 타이밍 검사&lt;/h2&gt;
&lt;p&gt;인간은 페이지를 읽고 폼을 채우는 데 시간이 걸립니다. 가장 빠른 타이피스트도 폼을 스캔하고, 이메일 필드를 클릭하고, 주소를 입력하고, 제출을 누르는 데 몇 초가 필요합니다. 실제 사람은 페이지를 로드하고 300밀리초 만에 폼을 제출할 수 없습니다.&lt;/p&gt;
&lt;p&gt;봇은 할 수 있습니다. 그리고 끊임없이 합니다.&lt;/p&gt;
&lt;p&gt;이 허니팟 기술은 페이지 로드와 폼 제출 사이의 시간을 측정합니다. 3초 미만은 거의 확실히 자동화입니다.&lt;/p&gt;
&lt;p&gt;먼저, 페이지 로드 타임스탬프를 저장할 숨겨진 필드를 폼에 추가합니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;form&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;waitlist-form&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/api/signup&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;POST&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;이메일 주소&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;required&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- 타이밍 검사 필드 - 페이지 로드 시간 캡처 --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;hidden&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;loadedAtField&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;대기자 명단 가입&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
  &lt;span class=&quot;token comment&quot;&gt;// 페이지가 로드되자마자 타임스탬프 기록&lt;/span&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;loadedAtField&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;서버에서 제출 시간과 로드 시간을 비교합니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/signup&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; loadedAt &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseBody&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// 사용자가 제출하는 데 걸린 시간 계산&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; elapsed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// 3초 미만? 인간은 그렇게 빨리 타이핑하지 않습니다.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elapsed &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;봇 감지: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;elapsed&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;ms 만에 제출&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token comment&quot;&gt;// 속도 제한 오류 반환 - 약간 더 그럴듯함&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;제출하기 전에 잠시 기다려 주세요.&apos;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;429&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// 합리적인 시간이 걸림 - 아마 인간&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;saveToDatabase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;환영합니다!&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;임계값으로 3초(3000밀리초)를 사용합니다. 테스트에서 자동 채우기가 활성화된 빠른 사용자도 최소 4-5초가 걸렸습니다. 제가 잡은 가장 느린 봇은 약 800밀리초였습니다. 3초는 둘 다에 편안한 마진을 제공합니다.&lt;/p&gt;
&lt;h2 id=&quot;예시-3-완전한-2단계-시스템&quot;&gt;예시 3: 완전한 2단계 시스템&lt;/h2&gt;
&lt;p&gt;실제로는 두 기술이 함께 작동하기를 원합니다. 숨겨진 필드는 폼을 자동 채우는 봇을 잡습니다. 타이밍 검사는 숨겨진 필드를 건너뛰려고 영리하게 행동하는 봇을 잡습니다. 함께하면 자동화된 제출에 대해 거의 뚫을 수 없는 장벽을 형성합니다.&lt;/p&gt;
&lt;p&gt;SEO Friend에서 실행 중인 완전한 구현입니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token doctype&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;token doctype-tag&quot;&gt;DOCTYPE&lt;/span&gt; &lt;span class=&quot;token name&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;html&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;ko&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meta&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;charset&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;UTF-8&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;대기자 명단 가입&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;form&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;waitlist-form&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;form-group&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;이메일 주소&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;required&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;placeholder&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;you@example.com&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- 허니팟 1: 숨겨진 필드 함정 --&gt;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- 봇은 이것을 자동 채움; 인간은 절대 보지 못함 --&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;website&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value css language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;-9999px&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;tabindex&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;-1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;autocomplete&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;aria-hidden&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- 허니팟 2: 타이밍 검사 --&gt;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- 속도 검증을 위해 페이지 로드 시간 기록 --&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;hidden&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;대기자 명단 가입&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 페이지 로드 즉시 타임스탬프 설정&lt;/span&gt;
    document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;loadedAt&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;waitlist-form&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;submit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;preventDefault&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; formData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FormData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;target&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/signup&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;POST&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; formData
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;success&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;대기자 명단에 가입해 주셔서 감사합니다!&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;error &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;문제가 발생했습니다.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;결과&quot;&gt;결과&lt;/h2&gt;
&lt;p&gt;이 2단계 허니팟 시스템을 구현한 후, 스팸 가입이 하루 20-50개에서 사실상 0으로 떨어졌습니다. 봇들은 여전히 시도하고 있습니다—서버 로그에서 볼 수 있습니다—하지만 모두 잡혀서 가짜 성공 응답을 받습니다. 그들은 이기고 있다고 생각합니다. 제 데이터베이스는 깨끗하게 유지됩니다.&lt;/p&gt;
&lt;p&gt;실제 사용자는 아무것도 눈치채지 못했습니다. 풀어야 할 CAPTCHA도, 가입 흐름에 추가된 마찰도 없습니다. 이메일을 입력하고 제출을 클릭하면 끝입니다. 허니팟 검사는 백그라운드에서 보이지 않게 발생합니다.&lt;/p&gt;
&lt;p&gt;구현하는 데 약 30분이 걸렸습니다—대부분 무엇이 차단되는지 모니터링할 수 있도록 로깅을 설정하는 데 사용했습니다. 지속적인 유지 보수도 없고, 스팸 방지 서비스에 대한 월 비용도 없고, 관리할 API 키도 없습니다.&lt;/p&gt;
&lt;p&gt;때로는 가장 간단한 해결책이 최고입니다. 허니팟은 작동하기 때문에 수십 년 동안 존재해 왔습니다. 점점 더 정교해지는 AI와 머신 러닝의 시대에, 숨겨진 텍스트 필드와 타임스탬프로 봇을 막는 것에는 만족스러운 무언가가 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;자주-묻는-질문&quot;&gt;자주 묻는 질문&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;허니팟은 모든 봇에 효과가 있나요?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;아니요. 허니팟을 우회하도록 특별히 설계된 정교한 봇은 숨겨진 필드를 건너뛰거나 인위적인 지연을 추가할 수 있습니다. 그러나 이것은 드뭅니다. 대부분의 봇은 모든 것을 자동 채우고 즉시 제출하는 단순한 스크레이퍼입니다. 허니팟은 자동화된 스팸의 95% 이상을 잡으며, 이는 대개 스팸 문제를 관리 가능하게 만드는 데 충분합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;이것이 접근성을 깨뜨릴까요?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;올바르게 구현하면 아닙니다. &lt;code class=&quot;language-text&quot;&gt;aria-hidden=&quot;true&quot;&lt;/code&gt; 속성은 스크린 리더에게 허니팟 필드를 완전히 무시하라고 알려주므로, 시각 장애인 사용자는 상호 작용할 수 없는 필드로 혼란스러워하지 않습니다. &lt;code class=&quot;language-text&quot;&gt;tabindex=&quot;-1&quot;&lt;/code&gt;은 키보드 사용자가 탭으로 들어가는 것을 방지합니다. 보조 기술로 탐색하는 사용자는 의도한 대로 정확히 폼을 경험합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;합법적인 사용자가 허니팟을 채우면 어떻게 되나요?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;올바른 구현으로는 거의 불가능합니다. 필드는 화면 왼쪽 가장자리에서 9999 픽셀 떨어져 위치합니다—사용자는 문자 그대로 그것을 보거나 클릭할 수 없습니다. 브라우저 자동 채우기는 &lt;code class=&quot;language-text&quot;&gt;autocomplete=&quot;off&quot;&lt;/code&gt;로 비활성화됩니다. 수천 명의 방문자와 2주간의 프로덕션 사용에서 오탐이 전혀 없었습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;대신 CAPTCHA를 사용해야 할까요?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;CAPTCHA는 마찰을 추가합니다. 연구에 따르면 전환율을 3-8% 줄일 수 있습니다. 사용자는 싫어합니다—저도 싫어합니다. 허니팟은 보이지 않습니다; 사용자는 존재하는지도 모릅니다. 허니팟으로 시작하세요. 적절한 허니팟 보호를 구현한 후에도 여전히 심각한 스팸이 발생하는 경우에만 CAPTCHA를 추가하세요. 대부분의 사이트에서는 그럴 가능성이 낮습니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Honeypots Werken Nog Steeds: 3 Manieren om Spam-aanmeldingen te Stoppen Zonder CAPTCHAs]]></title><description><![CDATA[Botfarms uit Rusland en Nederland overspoelden mijn wachtlijst met nep-aanmeldingen. Zo stopte een eenvoudig tweedelig honeypot-detectiesysteem ze—geen CAPTCHAs, geen externe diensten, gewoon slimme HTML en timing.]]></description><link>https://vibecodingwithfred.com/nl/blog/honeypot-spam-protection/</link><guid isPermaLink="false">https://vibecodingwithfred.com/nl/blog/honeypot-spam-protection/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Fri, 19 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;honeypots-werken-nog-steeds-3-manieren-om-spam-aanmeldingen-te-stoppen-zonder-captchas&quot;&gt;Honeypots Werken Nog Steeds: 3 Manieren om Spam-aanmeldingen te Stoppen Zonder CAPTCHAs&lt;/h2&gt;
&lt;p&gt;Vorige week viel me iets verdachts op in mijn SEO Friend wachtlijst-aanmeldingen. Tientallen e-mailadressen van wegwerp-domeinen, allemaal ingediend binnen milliseconden van elkaar, afkomstig van IP-adressen in Rusland en Nederland. Klassiek botfarm-gedrag.&lt;/p&gt;
&lt;p&gt;De voor de hand liggende oplossing? Plak een CAPTCHA op het formulier. Maar CAPTCHAs zijn irritant. Ze frustreren echte gebruikers, schaden conversieratio&apos;s en eerlijk gezegd—moderne bots worden behoorlijk goed in het oplossen ervan. Ik wilde iets dat onzichtbaar is voor mensen maar dodelijk voor bots.&lt;/p&gt;
&lt;p&gt;Maak kennis met de honeypot.&lt;/p&gt;
&lt;h2 id=&quot;wat-is-een-honeypot&quot;&gt;Wat is een Honeypot?&lt;/h2&gt;
&lt;p&gt;Een honeypot is een val ontworpen om geautomatiseerde systemen te vangen door hun voorspelbare gedrag uit te buiten. In webbeveiliging werkt een formulier-honeypot op een eenvoudig principe: bots vullen automatisch elk formulierveld dat ze vinden in, terwijl mensen alleen de velden invullen die ze kunnen zien.&lt;/p&gt;
&lt;p&gt;Als je een verborgen veld toevoegt dat mensen niet kunnen zien, en dat veld wordt ingevuld—heb je een bot gevangen.&lt;/p&gt;
&lt;p&gt;Het is een oude techniek, maar het werkt nog steeds opmerkelijk goed in 2025. Gecombineerd met timingcontroles kun je de overgrote meerderheid van spam-aanmeldingen stoppen zonder enige gebruikersfrictie.&lt;/p&gt;
&lt;h2 id=&quot;het-probleem-botfarm-aanmeldingen&quot;&gt;Het Probleem: Botfarm-aanmeldingen&lt;/h2&gt;
&lt;p&gt;Voordat ik mijn honeypot implementeerde, had ik dit te maken. IP&apos;s van datacenters in Rusland, Nederland en Duitsland raakten mijn wachtlijstformulier. De inzendingen kwamen binnen op onmenselijke snelheid—0,2 tot 0,5 seconden nadat de pagina laadde. De e-mailadressen waren allemaal van wegwerp-domeinen zoals tempmail en guerrillamail. En ze vulden elk formulierveld in dat ze konden vinden, wat hun ondergang zou worden.&lt;/p&gt;
&lt;p&gt;Waarom doen bots dit? Ze oogsten e-mailsystemen—formulieren indienen om te zien of bevestigingsmails terugstuiteren, valideren dat je e-mailpijplijn werkt. Ze vervuilen databases met rommeldata om je tijd en e-mailquota te verspillen. Ze testen e-mailadressen voor credential stuffing-aanvallen later. Soms is het concurrent-sabotage—je metrics opblazen met afvaldata zodat je je cijfers niet kunt vertrouwen.&lt;/p&gt;
&lt;p&gt;De bots kwamen van dezelfde /24 IP-blokken, dienden in binnen fracties van seconden en gebruikten duidelijke wegwerp-e-mails. Perfecte kandidaten voor honeypot-detectie.&lt;/p&gt;
&lt;h2 id=&quot;voorbeeld-1-de-verborgen-veldval&quot;&gt;Voorbeeld 1: De Verborgen Veldval&lt;/h2&gt;
&lt;p&gt;Dit is de klassieke honeypot-techniek die bots stopt sinds de vroege jaren 2000. Het concept is prachtig eenvoudig: voeg een formulierveld toe dat onzichtbaar is voor mensen maar zichtbaar voor bots. Wanneer een bot elk veld op de pagina automatisch invult (wat ze altijd doen), vullen ze ook je verborgen veld in—en je hebt ze gevangen.&lt;/p&gt;
&lt;p&gt;Hier is de HTML die je aan je formulier toevoegt, direct naast je echte e-mailinvoer:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;form&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;waitlist-form&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/api/signup&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;POST&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Het echte veld dat mensen invullen --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;E-mailadres&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;required&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Het honeypot-veld - volledig onzichtbaar voor mensen --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;website&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value css language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;-9999px&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;tabindex&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;-1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;autocomplete&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;aria-hidden&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Aanmelden voor Wachtlijst&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Elk attribuut op dat honeypot-veld dient een specifiek doel. De &lt;code class=&quot;language-text&quot;&gt;type=&quot;text&quot;&lt;/code&gt; laat het eruitzien als een normaal tekstveld voor elke bot die je HTML parset. De &lt;code class=&quot;language-text&quot;&gt;name=&quot;website&quot;&lt;/code&gt; is opzettelijk onopvallend—bots zijn geprogrammeerd om veelvoorkomende velden in te vullen zoals &quot;website&quot;, &quot;url&quot;, &quot;company&quot; en &quot;phone&quot;, dus het gebruiken van een van deze namen zorgt ervoor dat ze het aas nemen. Vermijd voor de hand liggende namen zoals &quot;honeypot&quot; of &quot;trap&quot; omdat sommige geavanceerde bots naar die patronen zoeken.&lt;/p&gt;
&lt;p&gt;De &lt;code class=&quot;language-text&quot;&gt;style=&quot;position:absolute;left:-9999px&quot;&lt;/code&gt; is de sleutel tot onzichtbaarheid. Door het element 9999 pixels buiten de linkerkant van het scherm te positioneren, zal geen mens het ooit zien, maar bots die de DOM parsen vinden het prima. De &lt;code class=&quot;language-text&quot;&gt;tabindex=&quot;-1&quot;&lt;/code&gt; voorkomt dat toetsenbordgebruikers per ongeluk in het veld tabben tijdens het navigeren door je formulier. De &lt;code class=&quot;language-text&quot;&gt;autocomplete=&quot;off&quot;&lt;/code&gt; stopt browser-autofill om het aan te raken—je wilt niet dat Chrome behulpzaam je honeypot invult met de opgeslagen gegevens van een legitieme gebruiker. Ten slotte vertelt &lt;code class=&quot;language-text&quot;&gt;aria-hidden=&quot;true&quot;&lt;/code&gt; schermlezers om dit veld volledig te negeren, waardoor toegankelijkheid voor visueel gehandicapte gebruikers behouden blijft.&lt;/p&gt;
&lt;p&gt;Aan de serverzijde is de controle triviaal. Als het &lt;code class=&quot;language-text&quot;&gt;website&lt;/code&gt;-veld enige waarde bevat, heb je een bot gevangen:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/signup&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; website &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseBody&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Als het honeypot-veld enige waarde heeft, heeft een bot het ingevuld&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;website&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Bot gedetecteerd via honeypot:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Retourneer nep succes - de bot denkt dat het werkte&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Bedankt voor je aanmelding!&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Echte mens - verwerk normaal&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;saveToDatabase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Welkom!&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Het kritieke detail hier: retourneer een nep-succesrespons in plaats van een fout. Als je een foutbericht retourneert, kunnen geavanceerde bots detecteren dat ze gepakt zijn en andere benaderingen proberen—misschien velden overslaan, misschien een ander IP gebruiken. Door succes te retourneren, ziet de operator van de bot groene vinkjes in hun logs en gaat verder naar makkelijkere doelwitten. Je database blijft schoon en ze weten nooit wat ze raakte.&lt;/p&gt;
&lt;h2 id=&quot;voorbeeld-2-de-timingcontrole&quot;&gt;Voorbeeld 2: De Timingcontrole&lt;/h2&gt;
&lt;p&gt;Mensen hebben tijd nodig om een pagina te lezen en een formulier in te vullen. Zelfs de snelste typer heeft meerdere seconden nodig om het formulier te scannen, in het e-mailveld te klikken, hun adres te typen en op verzenden te drukken. Een echt persoon kan simpelweg geen pagina laden en een formulier indienen in 300 milliseconden.&lt;/p&gt;
&lt;p&gt;Bots kunnen dat wel. En dat doen ze, constant.&lt;/p&gt;
&lt;p&gt;Deze honeypot-techniek meet de tijd tussen paginalading en formulierinzending. Alles onder de 3 seconden is bijna zeker geautomatiseerd.&lt;/p&gt;
&lt;p&gt;Voeg eerst een verborgen veld toe aan je formulier dat de laadtijdstempel opslaat:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;form&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;waitlist-form&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/api/signup&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;POST&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;E-mailadres&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;required&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Timingcontroleveld - legt vast wanneer de pagina laadde --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;hidden&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;loadedAtField&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Aanmelden voor Wachtlijst&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Zodra de pagina laadt, leg de tijdstempel vast&lt;/span&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;loadedAtField&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Wanneer de pagina laadt, stelt JavaScript onmiddellijk de waarde van het verborgen veld in op de huidige Unix-tijdstempel in milliseconden. Deze waarde wordt ingediend samen met de rest van de formuliergegevens. De gebruiker ziet het nooit, interacteert er nooit mee—het is volledig onzichtbaar.&lt;/p&gt;
&lt;p&gt;Op de server vergelijk je de inzendtijd met de laadtijd:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/signup&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; loadedAt &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseBody&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Bereken hoe lang de gebruiker erover deed om in te dienen&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; elapsed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Minder dan 3 seconden? Geen mens typt zo snel.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elapsed &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Bot gedetecteerd: ingediend in &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;elapsed&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;ms&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token comment&quot;&gt;// Retourneer rate limit-fout - iets geloofwaardiger&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Wacht even voordat je indient.&apos;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;429&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Deed er redelijk lang over - waarschijnlijk mens&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;saveToDatabase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Welkom!&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ik gebruik 3 seconden (3000 milliseconden) als drempel. In tests ontdekte ik dat zelfs snelle gebruikers met autofill ingeschakeld minstens 4-5 seconden nodig hebben om in te dienen. De langzaamste bots die ik ving waren rond de 800 milliseconden. Drie seconden geeft comfortabele marge voor beide.&lt;/p&gt;
&lt;h2 id=&quot;voorbeeld-3-het-complete-tweedelige-systeem&quot;&gt;Voorbeeld 3: Het Complete Tweedelige Systeem&lt;/h2&gt;
&lt;p&gt;In de praktijk wil je beide technieken samenwerken. Het verborgen veld vangt bots die formulieren automatisch invullen. De timingcontrole vangt bots die proberen slim te zijn en verborgen velden overslaan. Samen vormen ze een bijna ondoordringbare barrière tegen geautomatiseerde inzendingen.&lt;/p&gt;
&lt;h2 id=&quot;resultaten&quot;&gt;Resultaten&lt;/h2&gt;
&lt;p&gt;Na het implementeren van dit tweedelige honeypot-systeem daalde spam-aanmeldingen van 20-50 per dag naar vrijwel nul. De bots proberen het nog steeds—ik zie ze in mijn serverlogs—maar ze worden allemaal gevangen en krijgen nep-succesresponsen. Ze denken dat ze winnen. Mijn database blijft schoon.&lt;/p&gt;
&lt;p&gt;Echte gebruikers hebben niets gemerkt. Er is geen CAPTCHA om op te lossen, geen frictie toegevoegd aan de aanmeldflow. Ze vullen hun e-mail in, klikken op verzenden en ze zijn klaar. De honeypot-controles gebeuren onzichtbaar op de achtergrond.&lt;/p&gt;
&lt;p&gt;De implementatie duurde ongeveer 30 minuten—het meeste daarvan was het opzetten van logging zodat ik kon monitoren wat werd geblokkeerd. Er is geen lopend onderhoud, geen maandelijkse kosten voor anti-spamservices, geen API-sleutels om te beheren.&lt;/p&gt;
&lt;p&gt;Soms zijn de eenvoudigste oplossingen de beste. Honeypots bestaan al decennia omdat ze werken. In een tijdperk van steeds geavanceerdere AI en machine learning, is er iets bevredigends aan het stoppen van bots met een verborgen tekstveld en een tijdstempel.&lt;/p&gt;
&lt;h2 id=&quot;veelgestelde-vragen&quot;&gt;Veelgestelde Vragen&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Werken honeypots tegen alle bots?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Nee. Geavanceerde bots die specifiek zijn ontworpen om honeypots te omzeilen, kunnen verborgen velden overslaan of kunstmatige vertragingen toevoegen. Echter, deze zijn zeldzaam. De overgrote meerderheid van bots zijn eenvoudige scrapers die alles automatisch invullen en direct indienen. Honeypots vangen 95%+ van geautomatiseerde spam, wat meestal genoeg is om je spamprobleem beheersbaar te maken.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Breekt dit de toegankelijkheid?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Niet als het correct is geïmplementeerd. Het &lt;code class=&quot;language-text&quot;&gt;aria-hidden=&quot;true&quot;&lt;/code&gt; attribuut vertelt schermlezers om het honeypot-veld volledig te negeren, zodat visueel gehandicapte gebruikers niet verward raken door een veld waarmee ze niet kunnen interacteren. De &lt;code class=&quot;language-text&quot;&gt;tabindex=&quot;-1&quot;&lt;/code&gt; voorkomt dat toetsenbordgebruikers erin tabben. Gebruikers die navigeren met ondersteunende technologie ervaren het formulier precies zoals bedoeld.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wat als een legitieme gebruiker op de een of andere manier de honeypot invult?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Dit is bijna onmogelijk met correcte implementatie. Het veld is 9999 pixels buiten de linkerkant van het scherm gepositioneerd—gebruikers kunnen het letterlijk niet zien of erin klikken. Browser-autofill is uitgeschakeld met &lt;code class=&quot;language-text&quot;&gt;autocomplete=&quot;off&quot;&lt;/code&gt;. In twee weken productiegebruik met duizenden bezoekers heb ik nul false positives gehad.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Moet ik in plaats daarvan CAPTCHA gebruiken?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;CAPTCHAs voegen frictie toe. Studies tonen aan dat ze conversieratio&apos;s met 3-8% kunnen verminderen. Gebruikers haten ze—ik haat ze. Honeypots zijn onzichtbaar; gebruikers weten niet eens dat ze bestaan. Begin met honeypots. Voeg alleen CAPTCHAs toe als je nog steeds significante spam krijgt na het implementeren van juiste honeypot-bescherming, wat onwaarschijnlijk is voor de meeste sites.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Honeypots Ainda Funcionam: 3 Formas de Parar Spam em Cadastros Sem CAPTCHAs]]></title><description><![CDATA[Bot farms da Russia e Holanda estavam inundando minha lista de espera com cadastros falsos. Eis como um sistema simples de deteccao honeypot de duas partes os parou de vez—sem CAPTCHAs, sem servicos de terceiros, apenas HTML inteligente e timing.]]></description><link>https://vibecodingwithfred.com/pt/blog/honeypot-spam-protection/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pt/blog/honeypot-spam-protection/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Fri, 19 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;honeypots-ainda-funcionam-3-formas-de-parar-spam-em-cadastros-sem-captchas&quot;&gt;Honeypots Ainda Funcionam: 3 Formas de Parar Spam em Cadastros Sem CAPTCHAs&lt;/h2&gt;
&lt;p&gt;Semana passada, notei algo suspeito nos cadastros da minha lista de espera do SEO Friend. Dezenas de enderecos de email de dominios descartaveis, todos enviados em milissegundos um do outro, originando de enderecos IP na Russia e Holanda. Comportamento classico de bot farm.&lt;/p&gt;
&lt;p&gt;A solucao obvia? Colocar um CAPTCHA no formulario. Mas CAPTCHAs sao irritantes. Eles frustram usuarios reais, prejudicam taxas de conversao e honestamente—bots modernos estao ficando bem bons em resolve-los de qualquer forma. Eu queria algo invisivel para humanos mas mortal para bots.&lt;/p&gt;
&lt;p&gt;Entre o honeypot.&lt;/p&gt;
&lt;h2 id=&quot;o-que-e-um-honeypot&quot;&gt;O Que e um Honeypot?&lt;/h2&gt;
&lt;p&gt;Um honeypot e uma armadilha projetada para capturar sistemas automatizados explorando seu comportamento previsivel. Em seguranca web, um honeypot de formulario funciona em um principio simples: bots preenchem automaticamente todos os campos de formulario que encontram, enquanto humanos so preenchem os campos que podem ver.&lt;/p&gt;
&lt;p&gt;Se voce adicionar um campo oculto que humanos nao podem ver, e esse campo for preenchido—voce pegou um bot.&lt;/p&gt;
&lt;p&gt;E uma tecnica antiga, mas ainda funciona notavelmente bem em 2025. Combinada com verificacoes de timing, voce pode parar a vasta maioria de cadastros spam sem nenhuma friccao para o usuario.&lt;/p&gt;
&lt;h2 id=&quot;o-problema-cadastros-de-bot-farm&quot;&gt;O Problema: Cadastros de Bot Farm&lt;/h2&gt;
&lt;p&gt;Antes de implementar meu honeypot, aqui esta o que eu estava enfrentando. IPs de data centers na Russia, Holanda e Alemanha estavam atingindo meu formulario de lista de espera. Os envios vinham em velocidade inumana—0.2 a 0.5 segundos apos a pagina carregar. Os enderecos de email eram todos de dominios descartaveis como tempmail e guerrillamail. E eles estavam preenchendo todos os campos de formulario que podiam encontrar, o que seria sua ruina.&lt;/p&gt;
&lt;p&gt;Por que bots fazem isso? Eles estao colhendo sistemas de email—enviando formularios para ver se emails de confirmacao voltam, validando que seu pipeline de email funciona. Eles estao poluindo bancos de dados com dados lixo para desperdicar seu tempo e cota de email. Eles estao testando enderecos de email para ataques de credential stuffing depois. As vezes e sabotagem de concorrentes—inflando suas metricas com dados lixo para que voce nao possa confiar nos seus numeros.&lt;/p&gt;
&lt;p&gt;Os bots vinham dos mesmos blocos de IP /24, enviando em fracoes de segundo e usando emails descartaveis obvios. Candidatos perfeitos para deteccao honeypot.&lt;/p&gt;
&lt;h2 id=&quot;exemplo-1-a-armadilha-de-campo-oculto&quot;&gt;Exemplo 1: A Armadilha de Campo Oculto&lt;/h2&gt;
&lt;p&gt;Esta e a tecnica classica de honeypot que tem parado bots desde o inicio dos anos 2000. O conceito e lindamente simples: adicione um campo de formulario que e invisivel para humanos mas visivel para bots. Quando um bot preenche automaticamente todos os campos na pagina (o que eles sempre fazem), eles preencherao seu campo oculto tambem—e voce os pegou.&lt;/p&gt;
&lt;p&gt;Aqui esta o HTML que voce adicionara ao seu formulario, junto com seu campo de email real:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;form&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;waitlist-form&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/api/signup&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;POST&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- O campo real que humanos preenchem --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Endereco de Email&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;required&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- O campo honeypot - completamente invisivel para humanos --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;website&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value css language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;-9999px&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;tabindex&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;-1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;autocomplete&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;aria-hidden&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Entrar na Lista&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Cada atributo naquele campo honeypot serve um proposito especifico. O &lt;code class=&quot;language-text&quot;&gt;type=&quot;text&quot;&lt;/code&gt; faz parecer um campo de texto normal para qualquer bot parseando seu HTML. O &lt;code class=&quot;language-text&quot;&gt;name=&quot;website&quot;&lt;/code&gt; e deliberadamente inofensivo—bots sao programados para preencher campos comuns como &quot;website&quot;, &quot;url&quot;, &quot;company&quot; e &quot;phone&quot;, entao usar um desses nomes garante que eles mordam a isca. Evite nomes obvios como &quot;honeypot&quot; ou &quot;trap&quot; porque alguns bots sofisticados procuram esses padroes.&lt;/p&gt;
&lt;p&gt;O &lt;code class=&quot;language-text&quot;&gt;style=&quot;position:absolute;left:-9999px&quot;&lt;/code&gt; e a chave para a invisibilidade. Posicionando o elemento 9999 pixels para fora do lado esquerdo da tela, nenhum humano jamais o vera, mas bots parseando o DOM o encontrarao numa boa. O &lt;code class=&quot;language-text&quot;&gt;tabindex=&quot;-1&quot;&lt;/code&gt; impede usuarios de teclado de acidentalmente navegar para o campo ao percorrer seu formulario. O &lt;code class=&quot;language-text&quot;&gt;autocomplete=&quot;off&quot;&lt;/code&gt; para o preenchimento automatico do navegador de toca-lo—voce nao quer o Chrome preenchendo seu honeypot com dados salvos de um usuario legitimo. Finalmente, &lt;code class=&quot;language-text&quot;&gt;aria-hidden=&quot;true&quot;&lt;/code&gt; diz aos leitores de tela para ignorar este campo completamente, mantendo acessibilidade para usuarios com deficiencia visual.&lt;/p&gt;
&lt;p&gt;No servidor, a verificacao e trivial. Se o campo &lt;code class=&quot;language-text&quot;&gt;website&lt;/code&gt; contem qualquer valor, voce pegou um bot:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/signup&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; website &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseBody&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Se o campo honeypot tem qualquer valor, um bot preencheu&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;website&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Bot detectado via honeypot:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Retorna sucesso falso - o bot acha que funcionou&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Obrigado por se cadastrar!&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Humano real - processa normalmente&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;saveToDatabase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Bem-vindo!&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;O detalhe critico aqui: retorne uma resposta de sucesso falso em vez de um erro. Se voce retornar uma mensagem de erro, bots sofisticados podem detectar que foram pegos e tentar abordagens diferentes—talvez pulando campos, talvez usando um IP diferente. Retornando sucesso, o operador do bot ve checkmarks verdes nos logs e segue para alvos mais faceis. Seu banco de dados fica limpo, e eles nunca sabem o que os atingiu.&lt;/p&gt;
&lt;h2 id=&quot;exemplo-2-a-verificacao-de-timing&quot;&gt;Exemplo 2: A Verificacao de Timing&lt;/h2&gt;
&lt;p&gt;Humanos levam tempo para ler uma pagina e preencher um formulario. Ate o digitador mais rapido precisa de varios segundos para escanear o formulario, clicar no campo de email, digitar seu endereco e clicar em enviar. Uma pessoa real simplesmente nao pode carregar uma pagina e enviar um formulario em 300 milissegundos.&lt;/p&gt;
&lt;p&gt;Bots podem. E fazem, constantemente.&lt;/p&gt;
&lt;p&gt;Esta tecnica honeypot mede o tempo entre carregamento da pagina e envio do formulario. Qualquer coisa abaixo de 3 segundos e quase certamente automatizado.&lt;/p&gt;
&lt;p&gt;Primeiro, adicione um campo oculto ao seu formulario que armazenara o timestamp de carregamento da pagina:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;form&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;waitlist-form&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/api/signup&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;POST&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Endereco de Email&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;required&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Campo de verificacao de timing - captura quando a pagina carregou --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;hidden&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;loadedAtField&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Entrar na Lista&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Assim que a pagina carrega, registra o timestamp&lt;/span&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;loadedAtField&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Quando a pagina carrega, JavaScript imediatamente define o valor do campo oculto para o timestamp Unix atual em milissegundos. Este valor e enviado junto com o resto dos dados do formulario. O usuario nunca o ve, nunca interage com ele—e completamente invisivel.&lt;/p&gt;
&lt;p&gt;No servidor, voce compara o tempo de envio com o tempo de carregamento:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/signup&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; loadedAt &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseBody&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Calcula quanto tempo o usuario levou para enviar&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; elapsed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Menos de 3 segundos? Nenhum humano digita tao rapido.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elapsed &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Bot detectado: enviou em &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;elapsed&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;ms&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token comment&quot;&gt;// Retorna erro de rate limit - um pouco mais plausivel&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Por favor espere um momento antes de enviar.&apos;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;429&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Levou um tempo razoavel - provavelmente humano&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;saveToDatabase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Bem-vindo!&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Uso 3 segundos (3000 milissegundos) como limite. Em testes, descobri que mesmo usuarios rapidos com preenchimento automatico habilitado levam pelo menos 4-5 segundos para enviar. Os bots mais lentos que peguei estavam em torno de 800 milissegundos. Tres segundos da margem confortavel para ambos.&lt;/p&gt;
&lt;h2 id=&quot;exemplo-3-o-sistema-completo-de-duas-partes&quot;&gt;Exemplo 3: O Sistema Completo de Duas Partes&lt;/h2&gt;
&lt;p&gt;Na pratica, voce quer ambas as tecnicas funcionando juntas. O campo oculto pega bots que preenchem formularios automaticamente. A verificacao de timing pega bots que tentam ser espertos e pulam campos ocultos. Juntos, formam uma barreira quase impenetravel contra envios automatizados.&lt;/p&gt;
&lt;p&gt;Aqui esta a implementacao completa que estou rodando no SEO Friend:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token doctype&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;token doctype-tag&quot;&gt;DOCTYPE&lt;/span&gt; &lt;span class=&quot;token name&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;html&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;pt&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meta&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;charset&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;UTF-8&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Entre na Lista de Espera&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;form&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;waitlist-form&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;form-group&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Endereco de Email&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;required&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;placeholder&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;voce@exemplo.com&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- HONEYPOT 1: Armadilha de campo oculto --&gt;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Bots preenchem isso automaticamente; humanos nunca veem --&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;website&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value css language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;-9999px&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;tabindex&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;-1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;autocomplete&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;aria-hidden&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- HONEYPOT 2: Verificacao de timing --&gt;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Registra tempo de carregamento da pagina para validacao de velocidade --&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;hidden&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;loadedAt&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Entrar na Lista&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Define o timestamp assim que a pagina carrega&lt;/span&gt;
    document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;loadedAt&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;waitlist-form&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;submit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;preventDefault&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; formData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FormData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;target&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/signup&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;POST&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; formData
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;success&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Obrigado por entrar na lista de espera!&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;error &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Algo deu errado.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;resultados&quot;&gt;Resultados&lt;/h2&gt;
&lt;p&gt;Apos implementar este sistema honeypot de duas partes, cadastros spam cairam de 20-50 por dia para essencialmente zero. Os bots ainda estao tentando—eu os vejo nos logs do servidor—mas todos sao pegos e alimentados com respostas de sucesso falso. Eles acham que estao vencendo. Meu banco de dados fica limpo.&lt;/p&gt;
&lt;p&gt;Usuarios reais nao notaram nada. Nao ha CAPTCHA para resolver, nenhuma friccao adicionada ao fluxo de cadastro. Eles preenchem o email, clicam em enviar e pronto. As verificacoes honeypot acontecem invisivelmente em segundo plano.&lt;/p&gt;
&lt;p&gt;A implementacao levou cerca de 30 minutos—a maior parte foi configurando o logging para que eu pudesse monitorar o que estava sendo bloqueado. Nao ha manutencao continua, nenhuma taxa mensal para servicos anti-spam, nenhuma chave de API para gerenciar.&lt;/p&gt;
&lt;p&gt;As vezes as solucoes mais simples sao as melhores. Honeypots existem ha decadas porque funcionam. Em uma era de IA e machine learning cada vez mais sofisticados, ha algo satisfatorio em parar bots com um campo de texto oculto e um timestamp.&lt;/p&gt;
&lt;h2 id=&quot;perguntas-frequentes&quot;&gt;Perguntas Frequentes&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Honeypots funcionam contra todos os bots?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Nao. Bots sofisticados projetados especificamente para contornar honeypots podem pular campos ocultos ou adicionar delays artificiais. Porem, esses sao raros. A vasta maioria dos bots sao scrapers simples que preenchem tudo automaticamente e enviam imediatamente. Honeypots pegam 95%+ do spam automatizado, o que geralmente e suficiente para tornar seu problema de spam gerenciavel.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Isso vai quebrar acessibilidade?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Nao se implementado corretamente. O atributo &lt;code class=&quot;language-text&quot;&gt;aria-hidden=&quot;true&quot;&lt;/code&gt; diz aos leitores de tela para ignorar o campo honeypot completamente, entao usuarios com deficiencia visual nao serao confundidos por um campo com o qual nao podem interagir. O &lt;code class=&quot;language-text&quot;&gt;tabindex=&quot;-1&quot;&lt;/code&gt; impede usuarios de teclado de navegar para ele. Usuarios navegando com tecnologia assistiva vao experimentar o formulario exatamente como pretendido.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;E se um usuario legitimo de alguma forma preencher o honeypot?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Isso e quase impossivel com implementacao adequada. O campo esta posicionado 9999 pixels para fora da borda esquerda da tela—usuarios literalmente nao podem ve-lo ou clicar nele. Preenchimento automatico do navegador esta desabilitado com &lt;code class=&quot;language-text&quot;&gt;autocomplete=&quot;off&quot;&lt;/code&gt;. Em duas semanas de uso em producao com milhares de visitantes, tive zero falsos positivos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Devo usar CAPTCHA em vez disso?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;CAPTCHAs adicionam friccao. Estudos mostram que podem reduzir taxas de conversao em 3-8%. Usuarios odeiam—eu odeio. Honeypots sao invisiveis; usuarios nem sabem que existem. Comece com honeypots. So adicione CAPTCHAs se voce ainda estiver recebendo spam significativo apos implementar protecao honeypot adequada, o que e improvavel para a maioria dos sites.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[GDPR Compliant Cookie Banner: 2KB CDN Solution for Any Website]]></title><description><![CDATA[How to add a lightweight, legally compliant cookie consent banner to any website using smallest-cookie-banner - a 2KB library that loads from CDN with zero dependencies.]]></description><link>https://vibecodingwithfred.com/blog/gdpr-cookie-banner-cdn/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/gdpr-cookie-banner-cdn/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 13 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Library:&lt;/strong&gt; smallest-cookie-banner | &lt;strong&gt;Size:&lt;/strong&gt; ~2KB gzipped | &lt;strong&gt;License:&lt;/strong&gt; MIT&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;the-problem-with-cookie-consent&quot;&gt;The Problem with Cookie Consent&lt;/h2&gt;
&lt;p&gt;Every website that uses analytics, advertising, or tracking needs user consent in the EU under GDPR. Most cookie consent solutions are bloated - OneTrust clocks in at 100KB+, and even simpler solutions like cookieconsent hit 25KB. That&apos;s larger than many entire websites need to be.&lt;/p&gt;
&lt;p&gt;When you&apos;re building a fast, performant site, adding a 100KB consent manager defeats the purpose. You need something that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Loads instantly (no impact on Core Web Vitals)&lt;/li&gt;
&lt;li&gt;Works without a build step (CDN-loadable)&lt;/li&gt;
&lt;li&gt;Handles GDPR compliance correctly&lt;/li&gt;
&lt;li&gt;Doesn&apos;t require a SaaS subscription&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;enter-smallest-cookie-banner&quot;&gt;Enter smallest-cookie-banner&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/DreadfulCode/smallest-cookie-banner&quot;&gt;smallest-cookie-banner&lt;/a&gt; is a ~2KB gzipped library that handles cookie consent properly. It&apos;s MIT licensed, has zero dependencies, and loads from unpkg CDN.&lt;/p&gt;
&lt;p&gt;Key features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Geo-aware&lt;/strong&gt;: Auto-detects EU users via timezone for GDPR&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Implied consent&lt;/strong&gt;: Auto-accepts in regions where it&apos;s legal (USA, Asia)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WCAG 2.1 AA accessible&lt;/strong&gt;: Keyboard navigation, screen readers, 44px touch targets&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fully customizable&lt;/strong&gt;: Every string, style, and behavior can be configured&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;quick-installation-cdn&quot;&gt;Quick Installation (CDN)&lt;/h2&gt;
&lt;p&gt;The simplest setup - just two script tags:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Set config before loading --&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
  window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CookieBannerConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;We use cookies for analytics.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;acceptText&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Accept&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;rejectText&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Decline&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function-variable function&quot;&gt;onAccept&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// Load your analytics here&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;User accepted cookies&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function-variable function&quot;&gt;onReject&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// Disable tracking&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;User rejected cookies&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Load the library --&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;https://cdn.jsdelivr.net/npm/smallest-cookie-banner@2.1.2/dist/cookie-banner.min.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That&apos;s it. The banner appears for EU users with Accept/Decline buttons. Non-EU users get a simpler &quot;OK&quot; button with implied consent.&lt;/p&gt;
&lt;h2 id=&quot;configuration-options&quot;&gt;Configuration Options&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CookieBannerConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Text (fully customizable for i18n)&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;We use cookies to enhance your experience.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;acceptText&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Accept&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;rejectText&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Decline&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Behavior&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;days&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;365&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;              &lt;span class=&quot;token comment&quot;&gt;// Cookie expiry&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;forceEU&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;          &lt;span class=&quot;token comment&quot;&gt;// Force EU mode (show Accept/Decline everywhere)&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;autoAcceptDelay&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// Auto-accept after 5s for non-EU (0 to disable)&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;cookieName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ck&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;       &lt;span class=&quot;token comment&quot;&gt;// Custom cookie name&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;cookieDomain&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.example.com&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// For subdomains&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Callbacks&lt;/span&gt;
  &lt;span class=&quot;token function-variable function&quot;&gt;onAccept&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* Load analytics */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token function-variable function&quot;&gt;onReject&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* Disable tracking */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Styling&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;css&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;#ckb { background: #333; }&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// Additional CSS&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;border-radius: 8px;&apos;&lt;/span&gt;        &lt;span class=&quot;token comment&quot;&gt;// Inline styles&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;toast-style-corner-banner&quot;&gt;Toast-Style Corner Banner&lt;/h2&gt;
&lt;p&gt;Want a modern toast notification instead of a full-width bar? Add custom CSS:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CookieBannerConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;We use cookies for analytics.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;acceptText&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Accept&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;rejectText&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Decline&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;forceEU&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;css&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    #ckb {
      bottom: 20px !important;
      right: 20px !important;
      left: auto !important;
      width: 320px;
      border-radius: 12px;
      flex-direction: column;
      text-align: center;
      box-shadow: 0 4px 20px rgba(0,0,0,0.3);
    }
    #ckb p { min-width: auto; }
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;integrating-with-google-analytics&quot;&gt;Integrating with Google Analytics&lt;/h2&gt;
&lt;p&gt;The key to GDPR compliance is only loading tracking scripts AFTER consent:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CookieBannerConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;We use cookies for analytics.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;acceptText&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Accept&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;rejectText&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Decline&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;forceEU&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token function-variable function&quot;&gt;onAccept&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Only load GA after user accepts&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;script[src*=&quot;googletagmanager.com/gtag/js&quot;]&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; s &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;script&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;async &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;src &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;head&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;appendChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dataLayer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dataLayer &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;gtag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;dataLayer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;arguments&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;gtag &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; gtag&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;gtag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;gtag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;config&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;G-XXXXXXXXXX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token function-variable function&quot;&gt;onReject&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Disable GA if user rejects&lt;/span&gt;
    window&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;ga-disable-G-XXXXXXXXXX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;gatsbyreact-integration&quot;&gt;Gatsby/React Integration&lt;/h2&gt;
&lt;p&gt;For Gatsby sites, add the banner via &lt;code class=&quot;language-text&quot;&gt;gatsby-ssr.js&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; React &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;react&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

exports&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onRenderBody&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; setPostBodyComponents &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;setPostBodyComponents&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Config must come before script&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;script
      key&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;cookie-banner-config&quot;&lt;/span&gt;
      dangerouslySetInnerHTML&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;__html&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
          window.CookieBannerConfig = {
            msg: &apos;We use cookies for analytics.&apos;,
            acceptText: &apos;Accept&apos;,
            rejectText: &apos;Decline&apos;,
            forceEU: true,
            onAccept: function() {
              // Load GA
            },
            onReject: function() {
              window[&apos;ga-disable-G-XXXXXXXXXX&apos;] = true;
            }
          };
        &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;script
      key&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;cookie-banner-script&quot;&lt;/span&gt;
      src&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://cdn.jsdelivr.net/npm/smallest-cookie-banner@2.1.2/dist/cookie-banner.min.js&quot;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: Set the config BEFORE loading the script. The library auto-initializes when it detects &lt;code class=&quot;language-text&quot;&gt;window.CookieBannerConfig&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;common-gotchas&quot;&gt;Common Gotchas&lt;/h2&gt;
&lt;h3 id=&quot;double-banner-issue&quot;&gt;Double Banner Issue&lt;/h3&gt;
&lt;p&gt;If you see two banners, you&apos;re likely:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Setting config AND calling &lt;code class=&quot;language-text&quot;&gt;createCookieBanner()&lt;/code&gt; manually&lt;/li&gt;
&lt;li&gt;Loading the script twice&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The library auto-initializes when config exists. Don&apos;t call &lt;code class=&quot;language-text&quot;&gt;createCookieBanner()&lt;/code&gt; unless you&apos;re not setting &lt;code class=&quot;language-text&quot;&gt;window.CookieBannerConfig&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;banner-not-showing&quot;&gt;Banner Not Showing&lt;/h3&gt;
&lt;p&gt;If the banner doesn&apos;t appear:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Check if a &lt;code class=&quot;language-text&quot;&gt;ck&lt;/code&gt; cookie already exists (user already consented)&lt;/li&gt;
&lt;li&gt;Non-EU users get auto-accepted silently - use &lt;code class=&quot;language-text&quot;&gt;forceEU: true&lt;/code&gt; to test&lt;/li&gt;
&lt;li&gt;Clear cookies: &lt;code class=&quot;language-text&quot;&gt;document.cookie = &quot;ck=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;&quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;checking-consent-status&quot;&gt;Checking Consent Status&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// After banner loads, check consent:&lt;/span&gt;
CookieBanner&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ok    &lt;span class=&quot;token comment&quot;&gt;// true (accepted), false (rejected), null (no decision)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Programmatic control:&lt;/span&gt;
CookieBanner&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;yes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// Accept&lt;/span&gt;
CookieBanner&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;no&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;     &lt;span class=&quot;token comment&quot;&gt;// Reject&lt;/span&gt;
CookieBanner&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// Clear and reload page&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;npm-installation-alternative&quot;&gt;npm Installation (Alternative)&lt;/h2&gt;
&lt;p&gt;If you prefer npm over CDN:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; smallest-cookie-banner&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;smallest-cookie-banner&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Set config in useEffect (React) or mounted (Vue)&lt;/span&gt;
window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CookieBannerConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;We use cookies.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token function-variable function&quot;&gt;onAccept&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;loadAnalytics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;size-comparison&quot;&gt;Size Comparison&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;smallest-cookie-banner&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~2KB&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cookie-consent&lt;/td&gt;
&lt;td&gt;~15KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cookieconsent&lt;/td&gt;
&lt;td&gt;~25KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tarteaucitron&lt;/td&gt;
&lt;td&gt;~45KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OneTrust&lt;/td&gt;
&lt;td&gt;~100KB+&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;legal-compliance&quot;&gt;Legal Compliance&lt;/h2&gt;
&lt;p&gt;The library handles these regulations:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Region&lt;/th&gt;
&lt;th&gt;Law&lt;/th&gt;
&lt;th&gt;Behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;EU&lt;/td&gt;
&lt;td&gt;GDPR&lt;/td&gt;
&lt;td&gt;Shows Accept + Reject buttons&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UK&lt;/td&gt;
&lt;td&gt;UK GDPR&lt;/td&gt;
&lt;td&gt;Shows Accept + Reject buttons&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;California&lt;/td&gt;
&lt;td&gt;CCPA&lt;/td&gt;
&lt;td&gt;Shows OK button (implied consent)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brazil&lt;/td&gt;
&lt;td&gt;LGPD&lt;/td&gt;
&lt;td&gt;Shows Accept + Reject buttons&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rest of World&lt;/td&gt;
&lt;td&gt;Various&lt;/td&gt;
&lt;td&gt;Shows OK button (implied consent)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The geo-detection uses timezone offset, which is reliable for determining EU vs non-EU without any external API calls.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;smallest-cookie-banner solves cookie consent without the bloat. At 2KB, it&apos;s smaller than most favicons. It loads from CDN, requires no build step, and handles GDPR compliance correctly.&lt;/p&gt;
&lt;p&gt;For most sites, the CDN approach shown here is the simplest path to compliance. Set your config, load the script, and you&apos;re done.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/DreadfulCode/smallest-cookie-banner&quot;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dreadfulcode.github.io/smallest-cookie-banner/&quot;&gt;Live Configurator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/smallest-cookie-banner&quot;&gt;npm Package&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[10 Ways to Move Your Lovable Website to Free Hosting]]></title><description><![CDATA[Follow step-by-step instructions to export your Lovable project and move your website to free hosting platforms including Cloudflare Pages, Vercel, and Firebase with minimal downtime.]]></description><link>https://vibecodingwithfred.com/blog/3-ways-to-move-lovable-website/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/3-ways-to-move-lovable-website/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Fri, 05 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;10-ways-to-move-your-lovable-website-to-free-hosting&quot;&gt;10 Ways to Move Your Lovable Website to Free Hosting&lt;/h2&gt;
&lt;p&gt;If you&apos;ve built a website using Lovable&apos;s AI platform, you might be looking for alternatives to &lt;strong&gt;Lovable hosting&lt;/strong&gt;—especially given the recent issues with Lovable 2.0. Whether you&apos;re looking to migrate due to reliability concerns, need more control over your deployment, or simply want to explore other options, this complete migration guide shows you how to move your Lovable project to enterprise-grade hosting platforms—all for free.&lt;/p&gt;
&lt;p&gt;In this comprehensive guide, I&apos;ll walk you through &lt;strong&gt;10 hosting options&lt;/strong&gt; for your Lovable-generated website: Cloudflare Workers, Firebase Hosting, Vercel, Netlify, GitHub Pages, Render, Railway, Fly.io, AWS Amplify, and DigitalOcean. Most offer generous free tiers—though some have changed their pricing in 2025 (I&apos;ve noted the changes throughout).&lt;/p&gt;
&lt;h2 id=&quot;table-of-contents-10-free-lovable-hosting-alternatives&quot;&gt;Table of Contents: 10 Free Lovable Hosting Alternatives&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Getting Started:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#how-to-export-your-lovable-project&quot;&gt;How to Export Your Lovable Project&lt;/a&gt; – Step-by-step export instructions&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#why-move-away-from-lovable-hosting&quot;&gt;Why Move Away from Lovable Hosting?&lt;/a&gt; – Benefits of migration&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#benefits-of-using-free-hosting-platforms&quot;&gt;Benefits of Free Hosting Platforms&lt;/a&gt; – What you gain&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;The 10 Free Hosting Options:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#option-1-cloudflare-workers&quot;&gt;Cloudflare Workers&lt;/a&gt; – Best for edge computing, unlimited bandwidth&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#option-2-firebase-hosting&quot;&gt;Firebase Hosting&lt;/a&gt; – Best for Google/Firebase ecosystem&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#option-3-vercel&quot;&gt;Vercel&lt;/a&gt; – Best developer experience, easiest setup&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#option-4-netlify&quot;&gt;Netlify&lt;/a&gt; – Best for instant deploys and rollbacks&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#option-5-github-pages&quot;&gt;GitHub Pages&lt;/a&gt; – Best for simple sites, zero config&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#option-6-render&quot;&gt;Render&lt;/a&gt; – Best for modern app development&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#option-7-railway&quot;&gt;Railway&lt;/a&gt; – Best for apps needing databases&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#option-8-flyio&quot;&gt;Fly.io&lt;/a&gt; – Best for global edge deployment ⚠️ (no free tier)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#option-9-aws-amplify&quot;&gt;AWS Amplify&lt;/a&gt; – Best for AWS ecosystem integration&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#option-10-digitalocean-app-platform&quot;&gt;DigitalOcean App Platform&lt;/a&gt; – Best for DO users&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Guides &amp;#x26; Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#comparing-all-10-options&quot;&gt;Comparing All 10 Options&lt;/a&gt; – Feature comparison table&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#website-migration-checklist&quot;&gt;Website Migration Checklist&lt;/a&gt; – Pre, during, and post-migration tasks&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#migrating-without-downtime&quot;&gt;Migrating Without Downtime&lt;/a&gt; – Zero-downtime DNS cutover&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#dns-configuration-guide&quot;&gt;DNS Configuration Guide&lt;/a&gt; – A records, CNAMEs, and troubleshooting&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#troubleshooting-common-migration-issues&quot;&gt;Troubleshooting Common Issues&lt;/a&gt; – Build failures, routing, env vars&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;how-to-export-your-lovable-project&quot;&gt;How to Export Your Lovable Project&lt;/h2&gt;
&lt;p&gt;Before you can migrate to any hosting platform, you need to &lt;strong&gt;export your Lovable project&lt;/strong&gt;. Here&apos;s the complete process:&lt;/p&gt;
&lt;h3 id=&quot;step-by-step-export-instructions&quot;&gt;Step-by-Step Export Instructions&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Open your Lovable project&lt;/strong&gt; in the Lovable dashboard&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Navigate to project settings&lt;/strong&gt; (gear icon or menu)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Look for &quot;Export&quot; or &quot;Download&quot;&lt;/strong&gt; option in the project menu&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Select &quot;Download as ZIP&quot;&lt;/strong&gt; to get all your project files&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Extract the ZIP file&lt;/strong&gt; to a local folder on your computer&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;whats-included-in-your-export&quot;&gt;What&apos;s Included in Your Export&lt;/h3&gt;
&lt;p&gt;When you export a Lovable project, you typically receive:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Source code&lt;/strong&gt;: React/TypeScript files with all your components&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configuration files&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;vite.config.js&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Static assets&lt;/strong&gt;: Images, fonts, and other media&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Styling&lt;/strong&gt;: CSS files or Tailwind configuration&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dependencies list&lt;/strong&gt;: Everything needed to rebuild the project&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;verifying-your-export&quot;&gt;Verifying Your Export&lt;/h3&gt;
&lt;p&gt;After exporting, test that your project runs locally:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Navigate to your exported project&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; your-lovable-project

&lt;span class=&quot;token comment&quot;&gt;# Install dependencies&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Start the development server&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run dev&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If your project runs locally, you&apos;re ready to deploy to any of the hosting platforms below.&lt;/p&gt;
&lt;h2 id=&quot;why-move-away-from-lovable-hosting&quot;&gt;Why Move Away from Lovable Hosting?&lt;/h2&gt;
&lt;p&gt;Before diving into the alternatives, let&apos;s consider why you might want to move:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;More reliable infrastructure&lt;/strong&gt;: Enterprise-grade hosting platforms with global CDNs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Better performance&lt;/strong&gt;: Faster load times and improved user experience&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Custom domains&lt;/strong&gt;: Easy setup with free SSL certificates&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Advanced features&lt;/strong&gt;: Analytics, A/B testing, and more sophisticated deployment options&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Independence&lt;/strong&gt;: Protection from Lovable platform changes or outages&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;benefits-of-using-free-hosting-platforms&quot;&gt;Benefits of Using Free Hosting Platforms&lt;/h2&gt;
&lt;p&gt;Migrating from &lt;strong&gt;Lovable hosting&lt;/strong&gt; to dedicated platforms like Cloudflare, Vercel, or Firebase gives you significant advantages:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Benefit&lt;/th&gt;
&lt;th&gt;What You Get&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Global CDN&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Your site loads fast worldwide from 200+ edge locations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;99.99% Uptime&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Enterprise-grade reliability vs. startup infrastructure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Free SSL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Automatic HTTPS with zero configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Unlimited Scaling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Handle traffic spikes without manual intervention&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Version Control&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Git-based deployments with rollback capability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Preview Deployments&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Test changes on unique URLs before going live&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Analytics&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Built-in traffic and performance monitoring&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Custom Domains&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Use your own domain with simple DNS setup&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;These platforms serve billions of requests daily for companies like Shopify, The Washington Post, and Discord—all available on their free tiers for your Lovable project.&lt;/p&gt;
&lt;h2 id=&quot;option-1-cloudflare-workers&quot;&gt;Option 1: Cloudflare Workers&lt;/h2&gt;
&lt;p&gt;Cloudflare Workers is an excellent choice for hosting static and dynamic websites with edge computing capabilities and a generous free tier.&lt;/p&gt;
&lt;h3 id=&quot;what-you-get-for-free&quot;&gt;What You Get for Free:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;100,000 requests per day&lt;/li&gt;
&lt;li&gt;Unlimited bandwidth&lt;/li&gt;
&lt;li&gt;Sub-millisecond global response times&lt;/li&gt;
&lt;li&gt;Custom domains with free SSL&lt;/li&gt;
&lt;li&gt;Global CDN across 300+ locations&lt;/li&gt;
&lt;li&gt;Built-in KV storage (1GB free)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;migration-steps&quot;&gt;Migration Steps:&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Export your Lovable project&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In Lovable, go to your project settings&lt;/li&gt;
&lt;li&gt;Click on &quot;Export&quot; or &quot;Download&quot; (usually found in the project menu)&lt;/li&gt;
&lt;li&gt;Select &quot;Download as ZIP&quot; to get all your project files&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install Wrangler CLI&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Install Wrangler globally&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; wrangler

&lt;span class=&quot;token comment&quot;&gt;# Login to Cloudflare&lt;/span&gt;
wrangler login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Initialize your Workers project&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Navigate to your project directory&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; your-lovable-project

&lt;span class=&quot;token comment&quot;&gt;# Build your static files&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build

&lt;span class=&quot;token comment&quot;&gt;# Create wrangler.toml configuration&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; wrangler.toml &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;EOF
name = &quot;my-lovable-site&quot;
main = &quot;src/index.js&quot;
compatibility_date = &quot;2024-01-01&quot;

[site]
bucket = &quot;./dist&quot;  # or ./build depending on your setup
EOF&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create a Worker script to serve your site&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; src
&lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; src/index.js &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;EOF&apos;
import { getAssetFromKV } from &apos;@cloudflare/kv-asset-handler&apos;

export default {
  async fetch(request, env, ctx) {
    try {
      return await getAssetFromKV(
        {
          request,
          waitUntil: ctx.waitUntil.bind(ctx),
        },
        {
          ASSET_NAMESPACE: env.__STATIC_CONTENT,
          ASSET_MANIFEST: __STATIC_CONTENT_MANIFEST,
        }
      )
    } catch (e) {
      return new Response(&apos;Not found&apos;, { status: 404 })
    }
  },
}
EOF&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install dependencies and deploy&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Install the KV asset handler&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; @cloudflare/kv-asset-handler

&lt;span class=&quot;token comment&quot;&gt;# Deploy to Cloudflare Workers&lt;/span&gt;
wrangler deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Set up your custom domain&lt;/strong&gt; (optional):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In your Cloudflare dashboard, go to Workers &amp;#x26; Pages&lt;/li&gt;
&lt;li&gt;Select your Worker&lt;/li&gt;
&lt;li&gt;Go to &quot;Settings&quot; &gt; &quot;Domains &amp;#x26; Routes&quot;&lt;/li&gt;
&lt;li&gt;Click &quot;Add Custom Domain&quot;&lt;/li&gt;
&lt;li&gt;Follow the instructions to add and verify your domain&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;real-world-example&quot;&gt;Real-world Example:&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// wrangler.toml - Configuration for your Lovable site&lt;/span&gt;
name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;my-lovable-app&quot;&lt;/span&gt;
main &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;src/index.js&quot;&lt;/span&gt;
compatibility_date &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2024-01-01&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;site&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
bucket &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;./dist&quot;&lt;/span&gt;

# Optional&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Add environment variables
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;vars&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token constant&quot;&gt;API_URL&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://api.example.com&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;option-2-firebase-hosting&quot;&gt;Option 2: Firebase Hosting&lt;/h2&gt;
&lt;p&gt;Firebase Hosting is Google&apos;s solution for hosting web applications and static content, with excellent performance and integration with other Firebase services.&lt;/p&gt;
&lt;h3 id=&quot;what-you-get-for-free-1&quot;&gt;What You Get for Free:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;10GB storage&lt;/li&gt;
&lt;li&gt;360MB/day data transfer&lt;/li&gt;
&lt;li&gt;Custom domains with free SSL&lt;/li&gt;
&lt;li&gt;Global CDN&lt;/li&gt;
&lt;li&gt;Easy integration with Firebase Authentication and other Firebase services&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;migration-steps-1&quot;&gt;Migration Steps:&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Export your Lovable project&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In Lovable, go to your project settings&lt;/li&gt;
&lt;li&gt;Click on &quot;Export&quot; or &quot;Download&quot; (usually found in the project menu)&lt;/li&gt;
&lt;li&gt;Select &quot;Download as ZIP&quot; to get all your project files&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Set up a Git repository&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Initialize a new Git repository&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init

&lt;span class=&quot;token comment&quot;&gt;# Add all files&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Commit the files&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial commit from Lovable export&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Create a new repository on GitHub/GitLab and push&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; origin &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;your-repository-url&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;New to Git? See our &lt;a href=&quot;/blog/everyday-git-commands/&quot;&gt;8 essential Git commands guide&lt;/a&gt; for a quick refresher.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Set up Firebase&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a &lt;a href=&quot;https://firebase.google.com/&quot;&gt;Firebase account&lt;/a&gt; if you don&apos;t have one&lt;/li&gt;
&lt;li&gt;Create a new Firebase project&lt;/li&gt;
&lt;li&gt;Install Firebase CLI:
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; firebase-tools&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Initialize Firebase in your project&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Login to Firebase&lt;/span&gt;
firebase login

&lt;span class=&quot;token comment&quot;&gt;# Initialize Firebase in your project directory&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; your-lovable-project
firebase init&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Select &quot;Hosting&quot; when prompted&lt;/li&gt;
&lt;li&gt;Choose your Firebase project&lt;/li&gt;
&lt;li&gt;Specify your public directory (usually &lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt;, or &lt;code class=&quot;language-text&quot;&gt;public&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Configure as a single-page app if applicable&lt;/li&gt;
&lt;li&gt;Set up GitHub Actions for automatic deployment (optional)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deploy your site&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Build your project if needed&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build

&lt;span class=&quot;token comment&quot;&gt;# Deploy to Firebase&lt;/span&gt;
firebase deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Set up your custom domain&lt;/strong&gt; (optional):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In the Firebase console, go to Hosting&lt;/li&gt;
&lt;li&gt;Click &quot;Add custom domain&quot;&lt;/li&gt;
&lt;li&gt;Follow the instructions to verify and connect your domain&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;handling-dynamic-content&quot;&gt;Handling Dynamic Content:&lt;/h3&gt;
&lt;p&gt;If your Lovable app uses backend functionality, you can use Firebase Functions:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Example of a simple Firebase function&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; functions &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;firebase-functions&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

exports&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;helloWorld &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; functions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;https&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onRequest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hello from Firebase Functions!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;option-3-vercel&quot;&gt;Option 3: Vercel&lt;/h2&gt;
&lt;p&gt;Vercel is known for its excellent developer experience and is the company behind Next.js. For a complete beginner&apos;s guide, see our &lt;a href=&quot;/blog/getting-started-vercel/&quot;&gt;Getting Started with Vercel&lt;/a&gt; tutorial.&lt;/p&gt;
&lt;h3 id=&quot;what-you-get-for-free-2&quot;&gt;What You Get for Free:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Unlimited static sites&lt;/li&gt;
&lt;li&gt;100GB bandwidth per month&lt;/li&gt;
&lt;li&gt;Custom domains with free SSL&lt;/li&gt;
&lt;li&gt;Global CDN&lt;/li&gt;
&lt;li&gt;Preview deployments for each Git branch&lt;/li&gt;
&lt;li&gt;Serverless functions&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;migration-steps-2&quot;&gt;Migration Steps:&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Export your Lovable project&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In Lovable, go to your project settings&lt;/li&gt;
&lt;li&gt;Click on &quot;Export&quot; or &quot;Download&quot; (usually found in the project menu)&lt;/li&gt;
&lt;li&gt;Select &quot;Download as ZIP&quot; to get all your project files&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Set up a Git repository&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Initialize a new Git repository&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init

&lt;span class=&quot;token comment&quot;&gt;# Add all files&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Commit the files&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial commit from Lovable export&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Create a new repository on GitHub/GitLab and push&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; origin &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;your-repository-url&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deploy to Vercel&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sign up for a &lt;a href=&quot;https://vercel.com/signup&quot;&gt;Vercel account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Install the Vercel CLI:
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; vercel&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Deploy your project:
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; your-lovable-project
vercel&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Alternatively, connect your GitHub repository through the Vercel dashboard&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Configure build settings&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vercel will auto-detect most frameworks&lt;/li&gt;
&lt;li&gt;For custom configurations, create a &lt;code class=&quot;language-text&quot;&gt;vercel.json&lt;/code&gt; file:
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-json line-numbers&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;builds&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;build/**&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;use&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;@vercel/static&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;routes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/(.*)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;dest&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/build/$1&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Set up your custom domain&lt;/strong&gt; (optional):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In your Vercel project, go to &quot;Settings&quot; &gt; &quot;Domains&quot;&lt;/li&gt;
&lt;li&gt;Add your domain and follow the verification instructions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;serverless-functions-example&quot;&gt;Serverless Functions Example:&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// api/hello.js - A simple Vercel serverless function&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Hello from Vercel Serverless Functions!&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;option-4-netlify&quot;&gt;Option 4: Netlify&lt;/h2&gt;
&lt;p&gt;Netlify is beloved by developers for its instant deployments, instant rollbacks, and phenomenal developer experience.&lt;/p&gt;
&lt;h3 id=&quot;what-you-get-for-free-3&quot;&gt;What You Get for Free:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;100GB bandwidth per month&lt;/li&gt;
&lt;li&gt;20 builds per month (credit-based system as of Sept 2025)&lt;/li&gt;
&lt;li&gt;Unlimited personal and commercial projects&lt;/li&gt;
&lt;li&gt;Automatic HTTPS with custom domains&lt;/li&gt;
&lt;li&gt;Instant rollbacks and deploy previews&lt;/li&gt;
&lt;li&gt;Serverless functions (125,000 requests/month)&lt;/li&gt;
&lt;li&gt;Form handling and split testing&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note (December 2025):&lt;/strong&gt; Netlify moved to a credit-based pricing model. Free tier now includes 20 builds/month. Frequent deployers may need to upgrade or consider alternatives like Cloudflare or Vercel.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;migration-steps-3&quot;&gt;Migration Steps:&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Export your Lovable project&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In Lovable, go to your project settings&lt;/li&gt;
&lt;li&gt;Click &quot;Export&quot; or &quot;Download&quot;&lt;/li&gt;
&lt;li&gt;Download as ZIP&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Set up Git repository&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Extract and navigate to your project&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; your-lovable-project

&lt;span class=&quot;token comment&quot;&gt;# Initialize git&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial commit from Lovable&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Push to GitHub/GitLab&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; origin &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;your-repo-url&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deploy to Netlify&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sign up at &lt;a href=&quot;https://app.netlify.com/signup&quot;&gt;Netlify&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Click &quot;Add new site&quot; &gt; &quot;Import an existing project&quot;&lt;/li&gt;
&lt;li&gt;Connect your Git provider (GitHub, GitLab, Bitbucket)&lt;/li&gt;
&lt;li&gt;Select your repository&lt;/li&gt;
&lt;li&gt;Configure build settings:
&lt;ul&gt;
&lt;li&gt;Build command: &lt;code class=&quot;language-text&quot;&gt;npm run build&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Publish directory: &lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click &quot;Deploy site&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Configure custom domain&lt;/strong&gt; (optional):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In site settings, go to &quot;Domain management&quot;&lt;/li&gt;
&lt;li&gt;Click &quot;Add custom domain&quot;&lt;/li&gt;
&lt;li&gt;Follow DNS configuration instructions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;netlify-specific-features&quot;&gt;Netlify-Specific Features:&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# netlify.toml - Advanced configuration&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;command&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;npm run build&quot;&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;publish&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;dist&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;redirects&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/*&quot;&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/index.html&quot;&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/*&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;headers.values&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token key property&quot;&gt;X-Frame-Options&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;DENY&quot;&lt;/span&gt;
    &lt;span class=&quot;token key property&quot;&gt;X-XSS-Protection&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1; mode=block&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;option-5-github-pages&quot;&gt;Option 5: GitHub Pages&lt;/h2&gt;
&lt;p&gt;GitHub Pages is the simplest option if your code is already on GitHub—zero configuration needed for basic sites.&lt;/p&gt;
&lt;h3 id=&quot;what-you-get-for-free-4&quot;&gt;What You Get for Free:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;1GB storage&lt;/li&gt;
&lt;li&gt;100GB bandwidth per month&lt;/li&gt;
&lt;li&gt;Free &lt;code class=&quot;language-text&quot;&gt;username.github.io&lt;/code&gt; subdomain&lt;/li&gt;
&lt;li&gt;Custom domain support with HTTPS&lt;/li&gt;
&lt;li&gt;Built-in Jekyll support (or use any static site generator)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;migration-steps-4&quot;&gt;Migration Steps:&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Export and push to GitHub&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Initialize and push to GitHub&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial commit&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Create repo on GitHub, then:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; origin https://github.com/username/repo-name.git
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enable GitHub Pages&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go to your repository settings&lt;/li&gt;
&lt;li&gt;Scroll to &quot;Pages&quot; section&lt;/li&gt;
&lt;li&gt;Under &quot;Source&quot;, select your branch (usually &lt;code class=&quot;language-text&quot;&gt;main&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Select folder: &lt;code class=&quot;language-text&quot;&gt;/root&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;/docs&lt;/code&gt; (where your built files are)&lt;/li&gt;
&lt;li&gt;Click &quot;Save&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;For build step sites&lt;/strong&gt; (React, Vue, etc):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Install gh-pages package&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; --save-dev gh-pages&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-json line-numbers&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Add to package.json&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;homepage&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://username.github.io/repo-name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;predeploy&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;npm run build&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;deploy&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;gh-pages -d build&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Deploy&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Custom domain&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add a &lt;code class=&quot;language-text&quot;&gt;CNAME&lt;/code&gt; file to your repo root with your domain&lt;/li&gt;
&lt;li&gt;Configure DNS with your domain registrar&lt;/li&gt;
&lt;li&gt;Enable &quot;Enforce HTTPS&quot; in GitHub Pages settings&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;option-6-render&quot;&gt;Option 6: Render&lt;/h2&gt;
&lt;p&gt;Render combines simplicity with power—great for static sites and apps with backends.&lt;/p&gt;
&lt;h3 id=&quot;what-you-get-for-free-5&quot;&gt;What You Get for Free:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Unlimited static sites&lt;/li&gt;
&lt;li&gt;100GB bandwidth per month&lt;/li&gt;
&lt;li&gt;Global CDN&lt;/li&gt;
&lt;li&gt;Automatic HTTPS&lt;/li&gt;
&lt;li&gt;Custom domains&lt;/li&gt;
&lt;li&gt;Continuous deployment from Git&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;migration-steps-5&quot;&gt;Migration Steps:&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Export and push to Git&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial Lovable export&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deploy to Render&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sign up at &lt;a href=&quot;https://render.com&quot;&gt;Render&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Click &quot;New&quot; &gt; &quot;Static Site&quot;&lt;/li&gt;
&lt;li&gt;Connect your Git provider&lt;/li&gt;
&lt;li&gt;Select your repository&lt;/li&gt;
&lt;li&gt;Configure:
&lt;ul&gt;
&lt;li&gt;Build Command: &lt;code class=&quot;language-text&quot;&gt;npm run build&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Publish Directory: &lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click &quot;Create Static Site&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Custom domain&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In your site dashboard, go to &quot;Settings&quot;&lt;/li&gt;
&lt;li&gt;Add custom domain&lt;/li&gt;
&lt;li&gt;Configure DNS as instructed&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;render-configuration&quot;&gt;Render Configuration:&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# render.yaml - Infrastructure as code&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; web
    &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; my&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;lovable&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;site
    &lt;span class=&quot;token key atrule&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; static
    &lt;span class=&quot;token key atrule&quot;&gt;buildCommand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm run build
    &lt;span class=&quot;token key atrule&quot;&gt;staticPublishPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; dist
    &lt;span class=&quot;token key atrule&quot;&gt;routes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; rewrite
        &lt;span class=&quot;token key atrule&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /*
        &lt;span class=&quot;token key atrule&quot;&gt;destination&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /index.html&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;option-7-railway&quot;&gt;Option 7: Railway&lt;/h2&gt;
&lt;p&gt;Railway shines when you need databases, cron jobs, or multiple services—perfect for apps that grew beyond static.&lt;/p&gt;
&lt;h3 id=&quot;what-you-get-for-free-6&quot;&gt;What You Get for Free:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;One-time $5 trial credit (expires after 30 days)&lt;/li&gt;
&lt;li&gt;After trial: $1/month free credit on Hobby plan ($5/month subscription)&lt;/li&gt;
&lt;li&gt;One-click PostgreSQL, MySQL, Redis&lt;/li&gt;
&lt;li&gt;Automatic HTTPS&lt;/li&gt;
&lt;li&gt;Preview deployments&lt;/li&gt;
&lt;li&gt;Environment variables&lt;/li&gt;
&lt;li&gt;Multiple services per project&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note (December 2025):&lt;/strong&gt; Railway changed their pricing model. New users get a one-time $5 trial that expires after 30 days. After that, the Hobby plan costs $5/month but includes $1/month in free usage credits. Best suited for apps that need databases or backend services.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;migration-steps-6&quot;&gt;Migration Steps:&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install Railway CLI&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @railway/cli
railway login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Initialize project&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; your-lovable-project
railway init&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Configure for static site&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Add to package.json&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;build&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;vite build&quot;&lt;/span&gt;,
    &lt;span class=&quot;token string&quot;&gt;&quot;serve&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;npx serve -s dist -l 3000&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deploy&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;railway up&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Custom domain&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In Railway dashboard, go to your service&lt;/li&gt;
&lt;li&gt;Click &quot;Settings&quot; &gt; &quot;Domains&quot;&lt;/li&gt;
&lt;li&gt;Add custom domain and configure DNS&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;railway-with-database-example&quot;&gt;Railway with Database Example:&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// If your Lovable app needs a database&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Railway makes it dead simple&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Add PostgreSQL service in Railway dashboard&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Railway automatically provides DATABASE_URL&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Pool &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;pg&apos;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pool &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;connectionString&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DATABASE_URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;ssl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;rejectUnauthorized&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;option-8-flyio&quot;&gt;Option 8: Fly.io&lt;/h2&gt;
&lt;p&gt;Fly.io runs your app on servers close to your users—true edge deployment with impressive global performance.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Important (December 2025):&lt;/strong&gt; Fly.io has discontinued their free tier for new users. New accounts now receive only a 2-hour trial. However, if you created an account before the change, your free allowances may still apply. Consider Cloudflare Workers or Render for free edge hosting instead.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;what-you-get-triallegacy-free-tier&quot;&gt;What You Get (Trial/Legacy Free Tier):&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;2-hour trial for new users&lt;/li&gt;
&lt;li&gt;Legacy accounts: 3 shared-cpu VMs with 256MB RAM each&lt;/li&gt;
&lt;li&gt;Legacy accounts: 160GB outbound data transfer&lt;/li&gt;
&lt;li&gt;Automatic HTTPS&lt;/li&gt;
&lt;li&gt;Global edge network (30+ regions)&lt;/li&gt;
&lt;li&gt;Built-in load balancing&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;migration-steps-7&quot;&gt;Migration Steps:&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install flyctl CLI&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# macOS/Linux&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Windows&lt;/span&gt;
iwr https://fly.io/install.ps1 &lt;span class=&quot;token parameter variable&quot;&gt;-useb&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; iex&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sign up and authenticate&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;fly auth signup
&lt;span class=&quot;token comment&quot;&gt;# or&lt;/span&gt;
fly auth login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Initialize your app&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; your-lovable-project
fly launch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Follow the prompts to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Choose app name&lt;/li&gt;
&lt;li&gt;Select region&lt;/li&gt;
&lt;li&gt;Skip PostgreSQL (unless needed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Configure static site&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;dockerfile&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-dockerfile line-numbers&quot;&gt;&lt;code class=&quot;language-dockerfile&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Dockerfile (created by fly launch, modify as needed)&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; node:18-alpine &lt;span class=&quot;token keyword&quot;&gt;AS&lt;/span&gt; builder&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;WORKDIR&lt;/span&gt; /app&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; package*.json ./&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; npm install&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; . .&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; npm run build&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; nginx:alpine&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; &lt;span class=&quot;token options&quot;&gt;&lt;span class=&quot;token property&quot;&gt;--from&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;builder&lt;/span&gt;&lt;/span&gt; /app/dist /usr/share/nginx/html&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; nginx.conf /etc/nginx/nginx.conf&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;EXPOSE&lt;/span&gt; 8080&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;CMD&lt;/span&gt; [&lt;span class=&quot;token string&quot;&gt;&quot;nginx&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;-g&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;daemon off;&quot;&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;nginx&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-nginx line-numbers&quot;&gt;&lt;code class=&quot;language-nginx&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# nginx.conf&lt;/span&gt;
&lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;events&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;worker_connections&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;http&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;include&lt;/span&gt; /etc/nginx/mime.types&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;server&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;root&lt;/span&gt; /usr/share/nginx/html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;index&lt;/span&gt; index.html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;location&lt;/span&gt; /&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;try_files&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$uri&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$uri&lt;/span&gt;/ /index.html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deploy&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;fly deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Custom domain&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;fly certs create yourdomain.com
fly certs show yourdomain.com&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;option-9-aws-amplify&quot;&gt;Option 9: AWS Amplify&lt;/h2&gt;
&lt;p&gt;If you&apos;re in the AWS ecosystem or need AWS service integrations, Amplify is your best bet.&lt;/p&gt;
&lt;h3 id=&quot;what-you-get-for-free-7&quot;&gt;What You Get for Free:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;1,000 build minutes per month&lt;/li&gt;
&lt;li&gt;1GB served per month (data transfer out)&lt;/li&gt;
&lt;li&gt;5GB storage&lt;/li&gt;
&lt;li&gt;Custom domains with HTTPS&lt;/li&gt;
&lt;li&gt;Password-protected branches&lt;/li&gt;
&lt;li&gt;Integration with AWS services&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; AWS Amplify&apos;s free tier is more limited than some alternatives—1GB served monthly may not be enough for high-traffic sites. Best for AWS ecosystem users or low-traffic applications.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;migration-steps-8&quot;&gt;Migration Steps:&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Export your project&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Standard Git setup&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Lovable export&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deploy via Amplify Console&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Open &lt;a href=&quot;https://console.aws.amazon.com/amplify/&quot;&gt;AWS Amplify Console&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Click &quot;New app&quot; &gt; &quot;Host web app&quot;&lt;/li&gt;
&lt;li&gt;Connect your Git provider&lt;/li&gt;
&lt;li&gt;Select repository and branch&lt;/li&gt;
&lt;li&gt;Configure build settings:
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;frontend&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;phases&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;preBuild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;commands&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; npm install
    &lt;span class=&quot;token key atrule&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;commands&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; npm run build
  &lt;span class=&quot;token key atrule&quot;&gt;artifacts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;baseDirectory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; dist
    &lt;span class=&quot;token key atrule&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;**/*&apos;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; node_modules/&lt;span class=&quot;token important&quot;&gt;**/*&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Click &quot;Save and deploy&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Custom domain&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In app settings, choose &quot;Domain management&quot;&lt;/li&gt;
&lt;li&gt;Add domain&lt;/li&gt;
&lt;li&gt;Follow Route 53 or external DNS configuration&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;aws-integration-example&quot;&gt;AWS Integration Example:&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Easy integration with AWS services&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Amplify&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;API&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;aws-amplify&apos;&lt;/span&gt;

Amplify&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;configure&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;API&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;endpoints&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;MyAPI&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;endpoint&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;REACT_APP_API_URL&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;option-10-digitalocean-app-platform&quot;&gt;Option 10: DigitalOcean App Platform&lt;/h2&gt;
&lt;p&gt;DigitalOcean brings its reliable infrastructure to a modern PaaS experience—great if you&apos;re familiar with DO.&lt;/p&gt;
&lt;h3 id=&quot;what-you-get-for-free-8&quot;&gt;What You Get for Free:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;3 static sites&lt;/li&gt;
&lt;li&gt;1GB outbound bandwidth per app/month&lt;/li&gt;
&lt;li&gt;Automatic HTTPS&lt;/li&gt;
&lt;li&gt;Custom domains&lt;/li&gt;
&lt;li&gt;GitHub/GitLab integration&lt;/li&gt;
&lt;li&gt;Easy scaling path to paid tiers&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; DigitalOcean&apos;s free tier has limited bandwidth (1GB per app). For high-traffic static sites, consider Cloudflare Workers, Vercel, or Netlify which offer 100GB+ free bandwidth.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;migration-steps-9&quot;&gt;Migration Steps:&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Push to Git&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Lovable project&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create App&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Log into &lt;a href=&quot;https://cloud.digitalocean.com&quot;&gt;DigitalOcean&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Click &quot;Create&quot; &gt; &quot;Apps&quot;&lt;/li&gt;
&lt;li&gt;Connect your Git source&lt;/li&gt;
&lt;li&gt;Select repository and branch&lt;/li&gt;
&lt;li&gt;DigitalOcean auto-detects build settings&lt;/li&gt;
&lt;li&gt;Modify if needed:
&lt;ul&gt;
&lt;li&gt;Build Command: &lt;code class=&quot;language-text&quot;&gt;npm run build&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Output Directory: &lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click &quot;Next&quot; through review&lt;/li&gt;
&lt;li&gt;Launch app&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Custom domain&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In app settings, go to &quot;Settings&quot; tab&lt;/li&gt;
&lt;li&gt;Click &quot;Domains&quot;&lt;/li&gt;
&lt;li&gt;Add your domain&lt;/li&gt;
&lt;li&gt;Update DNS records as shown&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;app-platform-configuration&quot;&gt;App Platform Configuration:&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# .do/app.yaml - Optional: commit this for consistent deploys&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; my&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;lovable&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;site
&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; web
    &lt;span class=&quot;token key atrule&quot;&gt;github&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;repo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; username/repo&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;name
      &lt;span class=&quot;token key atrule&quot;&gt;branch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; main
      &lt;span class=&quot;token key atrule&quot;&gt;deploy_on_push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;build_command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm run build
    &lt;span class=&quot;token key atrule&quot;&gt;output_dir&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; dist
    &lt;span class=&quot;token key atrule&quot;&gt;routes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /
    &lt;span class=&quot;token key atrule&quot;&gt;static_sites&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; site
        &lt;span class=&quot;token key atrule&quot;&gt;build_command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm run build
        &lt;span class=&quot;token key atrule&quot;&gt;output_dir&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; dist&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;comparing-all-10-options&quot;&gt;Comparing All 10 Options&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;th&gt;Free Bandwidth&lt;/th&gt;
&lt;th&gt;Custom Domain&lt;/th&gt;
&lt;th&gt;Serverless&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cloudflare Workers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Edge computing&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅ (Built-in)&lt;/td&gt;
&lt;td&gt;Best overall free tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Firebase Hosting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Firebase ecosystem&lt;/td&gt;
&lt;td&gt;360MB/day&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅ (Cloud Functions)&lt;/td&gt;
&lt;td&gt;Great for Google integration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vercel&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Best DX, Next.js&lt;/td&gt;
&lt;td&gt;100GB/month&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Easiest setup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Netlify&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Instant deploys&lt;/td&gt;
&lt;td&gt;100GB/month&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅ (125k/mo)&lt;/td&gt;
&lt;td&gt;20 builds/month limit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub Pages&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Simple sites&lt;/td&gt;
&lt;td&gt;100GB/month&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;No build step support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Render&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Modern apps&lt;/td&gt;
&lt;td&gt;100GB/month&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅ (paid)&lt;/td&gt;
&lt;td&gt;Good scaling path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Railway&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Backend needs&lt;/td&gt;
&lt;td&gt;Trial only&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;$5 one-time trial credit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Fly.io&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Global edge&lt;/td&gt;
&lt;td&gt;Legacy only&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;No free tier for new users&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AWS Amplify&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AWS ecosystem&lt;/td&gt;
&lt;td&gt;1GB/month&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Limited bandwidth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DigitalOcean&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;DO users&lt;/td&gt;
&lt;td&gt;1GB/app&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅ (paid)&lt;/td&gt;
&lt;td&gt;Limited bandwidth&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;which-platform-should-you-choose&quot;&gt;Which Platform Should You Choose?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Choose Cloudflare Workers if&lt;/strong&gt;: You want unlimited bandwidth and true edge computing with 100,000 free requests/day.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Choose Firebase if&lt;/strong&gt;: You need deep integration with Firebase Auth, Firestore, or other Google services.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Choose Vercel if&lt;/strong&gt;: You want the easiest setup with the best developer experience—perfect for beginners.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Choose Netlify if&lt;/strong&gt;: You want instant deploys, rollbacks, and built-in form handling.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Choose GitHub Pages if&lt;/strong&gt;: Your code is already on GitHub and you want zero-configuration hosting.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Choose Render if&lt;/strong&gt;: You want a modern, clean interface with room to grow into backend services.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Choose Railway if&lt;/strong&gt;: You need databases, cron jobs, or multiple interconnected services.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Choose Fly.io if&lt;/strong&gt;: Global performance matters and you want your app running close to users worldwide. &lt;strong&gt;Note:&lt;/strong&gt; Free tier discontinued for new users—consider Cloudflare Workers instead.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Choose AWS Amplify if&lt;/strong&gt;: You&apos;re already using AWS services or need enterprise-grade AWS integration.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Choose DigitalOcean if&lt;/strong&gt;: You&apos;re familiar with DO and want a reliable PaaS from a trusted provider.&lt;/p&gt;
&lt;h2 id=&quot;website-migration-checklist&quot;&gt;Website Migration Checklist&lt;/h2&gt;
&lt;p&gt;Before you start migrating your Lovable website, use this checklist to ensure a smooth transition:&lt;/p&gt;
&lt;h3 id=&quot;pre-migration&quot;&gt;Pre-Migration&lt;/h3&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Export your complete Lovable project&lt;/strong&gt; (Download as ZIP from project settings)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Document current functionality&lt;/strong&gt; (List all features, API integrations, database connections)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Identify dependencies&lt;/strong&gt; (Note all external services, APIs, and third-party integrations)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Backup your data&lt;/strong&gt; (Export any databases or user-generated content)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;List environment variables&lt;/strong&gt; (Document all API keys and configuration)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Review custom domain settings&lt;/strong&gt; (Note your current DNS configuration)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Test locally&lt;/strong&gt; (Ensure your exported project runs on your local machine)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;during-migration&quot;&gt;During Migration&lt;/h3&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Set up Git repository&lt;/strong&gt; (Initialize version control for your code)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Choose hosting platform&lt;/strong&gt; (Cloudflare, Vercel, or Firebase based on needs)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Configure build settings&lt;/strong&gt; (Set build command and output directory)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Add environment variables&lt;/strong&gt; (Securely add API keys to hosting platform)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Deploy to staging&lt;/strong&gt; (Test on temporary URL before going live)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Test all functionality&lt;/strong&gt; (Verify forms, API calls, authentication work)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Check performance&lt;/strong&gt; (Use Lighthouse or similar tools)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;post-migration&quot;&gt;Post-Migration&lt;/h3&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Update DNS records&lt;/strong&gt; (Point domain to new hosting)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Verify SSL certificate&lt;/strong&gt; (Ensure HTTPS is working)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Test from multiple devices&lt;/strong&gt; (Check mobile, tablet, desktop)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Update analytics&lt;/strong&gt; (Reconnect Google Analytics or other tracking)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Monitor for errors&lt;/strong&gt; (Check hosting dashboard for 404s or errors)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Inform users&lt;/strong&gt; (If applicable, notify users of any changes)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;Keep old hosting active&lt;/strong&gt; (Maintain for 7-14 days as backup)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;migrating-without-downtime&quot;&gt;Migrating Without Downtime&lt;/h2&gt;
&lt;p&gt;One of the biggest concerns when moving hosting providers is avoiding downtime. Here&apos;s how to achieve a zero-downtime migration:&lt;/p&gt;
&lt;h3 id=&quot;the-dns-cutover-strategy&quot;&gt;The DNS Cutover Strategy&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deploy to new hosting first&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Set up your site on Cloudflare/Vercel/Firebase completely&lt;/li&gt;
&lt;li&gt;Test thoroughly using the temporary URL (e.g., &lt;code class=&quot;language-text&quot;&gt;your-site.vercel.app&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Don&apos;t change DNS yet&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Lower your TTL (Time To Live)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In your current DNS provider, reduce TTL to 300 seconds (5 minutes)&lt;/li&gt;
&lt;li&gt;Wait 24-48 hours for this to propagate globally&lt;/li&gt;
&lt;li&gt;This ensures fast DNS updates when you switch&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Prepare DNS records&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Document exact DNS records from new hosting platform&lt;/li&gt;
&lt;li&gt;For Cloudflare/Vercel: Usually A or CNAME records&lt;/li&gt;
&lt;li&gt;Have these ready to paste immediately&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The switch (takes 2-5 minutes)&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Example DNS records for Vercel&lt;/span&gt;
Type: A
Name: @
Value: &lt;span class=&quot;token number&quot;&gt;76.76&lt;/span&gt;.21.21

Type: CNAME
Name: www
Value: cname.vercel-dns.com&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Update DNS records at your registrar&lt;/li&gt;
&lt;li&gt;Change from old hosting to new hosting IPs/CNAMEs&lt;/li&gt;
&lt;li&gt;Both sites are running, so no downtime occurs&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Monitor the propagation&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;a href=&quot;https://whatsmydns.net&quot;&gt;whatsmydns.net&lt;/a&gt; to check global propagation&lt;/li&gt;
&lt;li&gt;Most users will see new site within 5-30 minutes&lt;/li&gt;
&lt;li&gt;Full global propagation takes 24-48 hours&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Verify everything works&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Test site from different locations/networks&lt;/li&gt;
&lt;li&gt;Check SSL certificate is active&lt;/li&gt;
&lt;li&gt;Verify all pages and features work&lt;/li&gt;
&lt;li&gt;Monitor error logs on new hosting&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;rollback-plan&quot;&gt;Rollback Plan&lt;/h3&gt;
&lt;p&gt;If something goes wrong:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Keep old hosting active&lt;/strong&gt; for at least 7 days after migration&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Revert DNS records&lt;/strong&gt; to old hosting immediately if needed&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Document the issue&lt;/strong&gt; before attempting another migration&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fix problems&lt;/strong&gt; on new hosting while old site runs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Try again&lt;/strong&gt; when ready&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;testing-without-affecting-live-site&quot;&gt;Testing Without Affecting Live Site&lt;/h3&gt;
&lt;p&gt;You can test your new hosting before switching DNS:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Edit your local hosts file (requires admin/sudo)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# macOS/Linux: /etc/hosts&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Windows: C:\Windows\System32\drivers\etc\hosts&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Add this line (replace with your new hosting IP)&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;76.76&lt;/span&gt;.21.21 yourdomain.com&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This makes only your computer see the new hosting, perfect for testing.&lt;/p&gt;
&lt;h2 id=&quot;dns-configuration-guide&quot;&gt;DNS Configuration Guide&lt;/h2&gt;
&lt;p&gt;Understanding DNS is crucial for a successful migration. Here&apos;s what you need to know:&lt;/p&gt;
&lt;h3 id=&quot;common-dns-record-types&quot;&gt;Common DNS Record Types&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;A Record&lt;/strong&gt; - Points your domain to an IPv4 address&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Type: A
Name: @
Value: 76.76.21.21
TTL: 3600&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;AAAA Record&lt;/strong&gt; - Points your domain to an IPv6 address&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Type: AAAA
Name: @
Value: 2606:4700:3033::6815:2b52
TTL: 3600&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;CNAME Record&lt;/strong&gt; - Points your subdomain to another domain&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Type: CNAME
Name: www
Value: cname.vercel-dns.com
TTL: 3600&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;platform-specific-dns-settings&quot;&gt;Platform-Specific DNS Settings&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare Workers:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use Cloudflare&apos;s nameservers for full integration&lt;/li&gt;
&lt;li&gt;A record: Provided in Workers dashboard&lt;/li&gt;
&lt;li&gt;Automatic SSL/DDoS protection&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Vercel:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A record: &lt;code class=&quot;language-text&quot;&gt;76.76.21.21&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;CNAME for www: &lt;code class=&quot;language-text&quot;&gt;cname.vercel-dns.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Automatic SSL provisioning&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Firebase:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A record: Provided in Firebase console&lt;/li&gt;
&lt;li&gt;TXT record for domain verification&lt;/li&gt;
&lt;li&gt;Automatic SSL within 24 hours&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;troubleshooting-dns-issues&quot;&gt;Troubleshooting DNS Issues&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; &quot;DNS not updating&quot;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Clear your DNS cache, wait for TTL expiration, check global propagation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; &quot;SSL certificate error&quot;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Wait 24 hours for certificate provisioning, verify DNS points to correct IP&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; &quot;Some users see old site, some see new&quot;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Normal during propagation, wait 48 hours for full global update&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;troubleshooting-common-migration-issues&quot;&gt;Troubleshooting Common Migration Issues&lt;/h2&gt;
&lt;p&gt;Beyond DNS problems, here are the most frequent issues when migrating from &lt;strong&gt;Lovable hosting&lt;/strong&gt; and how to fix them:&lt;/p&gt;
&lt;h3 id=&quot;build-failures&quot;&gt;Build Failures&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; &quot;npm run build&quot; fails with dependency errors&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Error: Cannot find module &apos;react-scripts&apos;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Run &lt;code class=&quot;language-text&quot;&gt;npm install&lt;/code&gt; first, check your Node.js version matches project requirements (usually Node 18+)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Build fails with TypeScript errors&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Run &lt;code class=&quot;language-text&quot;&gt;npm run build -- --no-strict&lt;/code&gt; or fix the TypeScript errors shown in the output&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Out of memory during build&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Add &lt;code class=&quot;language-text&quot;&gt;NODE_OPTIONS=--max-old-space-size=4096&lt;/code&gt; before your build command&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;routing-issues-404-errors&quot;&gt;Routing Issues (404 Errors)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Pages work on homepage but show 404 on refresh&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Configure your hosting for single-page app (SPA) routing:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For &lt;strong&gt;Vercel&lt;/strong&gt;, add to &lt;code class=&quot;language-text&quot;&gt;vercel.json&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-json line-numbers&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;rewrites&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;source&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/(.*)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;destination&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/index.html&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For &lt;strong&gt;Cloudflare Workers&lt;/strong&gt;, ensure your worker handles all routes returning &lt;code class=&quot;language-text&quot;&gt;index.html&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For &lt;strong&gt;Firebase&lt;/strong&gt;, set &lt;code class=&quot;language-text&quot;&gt;&quot;rewrites&quot;&lt;/code&gt; in &lt;code class=&quot;language-text&quot;&gt;firebase.json&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-json line-numbers&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;hosting&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;rewrites&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;source&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;**&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;destination&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/index.html&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;environment-variables-not-working&quot;&gt;Environment Variables Not Working&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; API calls fail after migration (worked in Lovable)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Add environment variables to your hosting platform&apos;s dashboard, not just &lt;code class=&quot;language-text&quot;&gt;.env&lt;/code&gt; files&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Environment variables undefined in browser&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Prefix variables with &lt;code class=&quot;language-text&quot;&gt;VITE_&lt;/code&gt; for Vite projects or &lt;code class=&quot;language-text&quot;&gt;REACT_APP_&lt;/code&gt; for Create React App&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;images-and-assets-not-loading&quot;&gt;Images and Assets Not Loading&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Images show broken/missing after deployment&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Check that asset paths are relative (&lt;code class=&quot;language-text&quot;&gt;./images/&lt;/code&gt;) not absolute (&lt;code class=&quot;language-text&quot;&gt;/images/&lt;/code&gt;), or use the public folder correctly&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Fonts not loading (CORS error)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Host fonts locally or ensure your CDN allows cross-origin requests&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;performance-issues-after-migration&quot;&gt;Performance Issues After Migration&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Site slower than on Lovable hosting&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Enable CDN/edge caching in your hosting dashboard, optimize images, enable compression&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;handling-lovable-specific-features&quot;&gt;Handling Lovable-Specific Features&lt;/h2&gt;
&lt;h3 id=&quot;api-integrations&quot;&gt;API Integrations&lt;/h3&gt;
&lt;p&gt;If your Lovable app uses API integrations, you will need to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Identify API endpoints&lt;/strong&gt;: Look through your code for fetch/axios calls&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Secure API keys&lt;/strong&gt;: Move API keys to environment variables&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Create serverless functions&lt;/strong&gt;: For any backend logic&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Example of moving an API call to a serverless function:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Before (client-side)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;fetchData&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;https://api.example.com/data&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-property property&quot;&gt;&apos;Authorization&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Bearer YOUR_API_KEY&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// After (serverless function)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// api/getData.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; axios &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;axios&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; axios&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;https://api.example.com/data&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-property property&quot;&gt;&apos;Authorization&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;API_KEY&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Failed to fetch data&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;database-connections&quot;&gt;Database Connections&lt;/h3&gt;
&lt;p&gt;If your Lovable app uses a database:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;For Firebase: Use Firestore or Realtime Database&lt;/li&gt;
&lt;li&gt;For Cloudflare Workers: Connect to external databases directly from your Worker, or use Cloudflare D1 for serverless SQL&lt;/li&gt;
&lt;li&gt;For Vercel: Use serverless functions to connect to your database&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;conclusion-take-control-of-your-lovable-hosting&quot;&gt;Conclusion: Take Control of Your Lovable Hosting&lt;/h2&gt;
&lt;p&gt;Moving your Lovable website from &lt;strong&gt;Lovable hosting&lt;/strong&gt; to a dedicated hosting platform gives you more control, better performance, and protection from platform-specific issues. Most options in this guide offer generous free tiers—though some have changed their pricing in 2025 (noted below).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;My recommendations (Updated December 2025):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Easiest setup:&lt;/strong&gt; Vercel or Netlify for instant deploys and best developer experience&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Best performance:&lt;/strong&gt; Cloudflare Workers (100,000 free requests/day, unlimited bandwidth)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Backend needs:&lt;/strong&gt; Railway (trial) or Firebase for apps requiring databases&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AWS ecosystem:&lt;/strong&gt; AWS Amplify if you&apos;re already using AWS services (limited free bandwidth)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub users:&lt;/strong&gt; GitHub Pages for zero-configuration hosting&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Modern simplicity:&lt;/strong&gt; Render for static sites with room to grow&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Important changes in 2025:&lt;/strong&gt; Fly.io no longer offers a free tier for new users. Railway changed to a one-time $5 trial credit. AWS Amplify and DigitalOcean have limited free bandwidth (1GB/month). For the best truly free hosting, stick with &lt;strong&gt;Cloudflare Workers&lt;/strong&gt;, &lt;strong&gt;Vercel&lt;/strong&gt;, &lt;strong&gt;Netlify&lt;/strong&gt;, or &lt;strong&gt;Render&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;learn-to-build-static-sites-from-scratch&quot;&gt;Learn to Build Static Sites from Scratch&lt;/h2&gt;
&lt;p&gt;Want to understand what&apos;s happening under the hood? Build your own static website with vanilla JavaScript:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-scratch/&quot;&gt;Build a Blog from Scratch&lt;/a&gt;&lt;/strong&gt; - Master web fundamentals with pure HTML, CSS, and JavaScript&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-scratch/&quot;&gt;Build a Portfolio from Scratch&lt;/a&gt;&lt;/strong&gt; - Create a professional site without frameworks&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-scratch/&quot;&gt;Build E-Commerce from Scratch&lt;/a&gt;&lt;/strong&gt; - Learn shopping cart logic with vanilla JavaScript&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each tutorial teaches core web development skills that transfer to any framework or platform—including understanding exactly what tools like Lovable generate for you.&lt;/p&gt;
&lt;h2 id=&quot;automate-your-deployments&quot;&gt;Automate Your Deployments&lt;/h2&gt;
&lt;p&gt;Once you&apos;ve moved your site to a new host, take automation further:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/deploy-claude-code-cloudflare/&quot;&gt;Deploy Claude Code to Cloudflare Workers&lt;/a&gt;&lt;/strong&gt; - Set up AI-assisted coding workflows that run on Cloudflare&apos;s edge network&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;related-lovable-guides&quot;&gt;Related Lovable Guides&lt;/h2&gt;
&lt;p&gt;Before migrating, make sure you understand your options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/lovable-credits-complete-guide/&quot;&gt;Complete Lovable Credits Guide&lt;/a&gt;&lt;/strong&gt; - Understand how credits work and avoid wasting them during migration&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website/&quot;&gt;Deploy Lovable to Vercel&lt;/a&gt;&lt;/strong&gt; - Step-by-step Vercel deployment with automatic Git sync&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/export-lovable-to-github-complete/&quot;&gt;Export Lovable to GitHub&lt;/a&gt;&lt;/strong&gt; - Get your code into version control first&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/lovable-from-hero-to-zero/&quot;&gt;Lovable 2.0: From Hero to Zero&lt;/a&gt;&lt;/strong&gt; - Why users are leaving and what went wrong&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;frequently-asked-questions&quot;&gt;Frequently Asked Questions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Does Lovable host my website for free?&lt;/strong&gt;
Yes, &lt;strong&gt;Lovable hosting&lt;/strong&gt; is free, but many developers migrate to platforms like Cloudflare, Firebase, or Vercel for better performance, reliability, and more control over deployments.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I move my Lovable website to another hosting provider?&lt;/strong&gt;
Absolutely. You can easily migrate from &lt;strong&gt;Lovable hosting&lt;/strong&gt; by exporting your project as a ZIP file, which you can then deploy to any hosting platform that supports Node.js applications.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where should I host my Lovable website?&lt;/strong&gt;
For most use cases, we recommend Cloudflare Workers (unlimited bandwidth), Vercel (best developer experience), or Firebase (excellent backend integration). All three offer generous free tiers and are excellent alternatives to &lt;strong&gt;Lovable hosting&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I export my Lovable project?&lt;/strong&gt;
In Lovable, go to your project settings, click &quot;Export&quot; or &quot;Download&quot; from the project menu, and select &quot;Download as ZIP&quot; to get all your project files.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Will my Lovable app work on other hosting platforms?&lt;/strong&gt;
Yes! Lovable generates standard React/TypeScript applications that are compatible with any hosting platform that supports static sites or Node.js applications.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How to Deploy Claude AI and Codex Code on Cloudflare Edge with SSL and Unblock Tips]]></title><description><![CDATA[Learn how to deploy Claude AI and Codex applications on Cloudflare Edge with free hosting, automatic SSL setup, global CDN, and tips to unblock apps for smooth access.]]></description><link>https://vibecodingwithfred.com/blog/deploy-claude-code-cloudflare/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/deploy-claude-code-cloudflare/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Fri, 05 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Last tested:&lt;/strong&gt; November 2025 | &lt;strong&gt;Node.js:&lt;/strong&gt; v18.x/v20.x | &lt;strong&gt;Cloudflare Dashboard:&lt;/strong&gt; Current version | &lt;strong&gt;Wrangler CLI:&lt;/strong&gt; v3.x&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Building apps with &lt;strong&gt;Claude Code&lt;/strong&gt; or &lt;strong&gt;OpenAI Codex&lt;/strong&gt; is powerful, but deploying them shouldn&apos;t be a headache. Whether you&apos;ve generated a React frontend with Claude Code, built an API with Codex, or created a full-stack app using AI-assisted development, &lt;strong&gt;Cloudflare Pages&lt;/strong&gt; and &lt;strong&gt;Cloudflare Workers&lt;/strong&gt; offer an excellent hosting platform—fast, free (generous tier), and globally distributed.&lt;/p&gt;
&lt;p&gt;This guide walks you through deploying AI-generated projects to Cloudflare&apos;s edge network, from static sites to dynamic APIs. You&apos;ll learn how to set up Cloudflare Pages for frontend hosting, use Cloudflare Workers for backend logic, secure your API keys, and troubleshoot common deployment issues.&lt;/p&gt;
&lt;h2 id=&quot;who-this-guide-is-for&quot;&gt;Who This Guide Is For&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;This guide is for you if:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You&apos;ve built something with Claude Code, Codex, or Copilot and need to deploy it&lt;/li&gt;
&lt;li&gt;You want free, fast hosting with a generous free tier&lt;/li&gt;
&lt;li&gt;You&apos;re looking for an alternative to Vercel/Netlify with better performance&lt;/li&gt;
&lt;li&gt;You need to deploy both frontend and API endpoints&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;You&apos;ll need:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A project built with any AI coding tool (React, Vue, vanilla JS, etc.)&lt;/li&gt;
&lt;li&gt;Basic Git knowledge&lt;/li&gt;
&lt;li&gt;A Cloudflare account (free)&lt;/li&gt;
&lt;li&gt;Node.js installed locally&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;What you&apos;ll learn:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Deploy static sites to Cloudflare Pages in under 10 minutes&lt;/li&gt;
&lt;li&gt;Set up edge functions with Workers for API endpoints&lt;/li&gt;
&lt;li&gt;Properly secure API keys and environment variables&lt;/li&gt;
&lt;li&gt;Fix common deployment errors that AI code generators create&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;why-deploy-ai-generated-projects-on-cloudflare&quot;&gt;Why Deploy AI-Generated Projects on Cloudflare&lt;/h2&gt;
&lt;p&gt;Cloudflare isn&apos;t just another hosting platform—it&apos;s a global edge network that runs your code in 300+ cities worldwide. For AI-generated projects, this matters.&lt;/p&gt;
&lt;h3 id=&quot;edge-performance-and-global-routing-for-ai-apps&quot;&gt;Edge Performance and Global Routing for AI Apps&lt;/h3&gt;
&lt;p&gt;When you deploy to &lt;strong&gt;Cloudflare Pages&lt;/strong&gt; or &lt;strong&gt;Cloudflare Workers&lt;/strong&gt;, your application runs on Cloudflare&apos;s edge network, which means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Sub-50ms response times&lt;/strong&gt; globally (your code runs close to users)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automatic DDoS protection&lt;/strong&gt; and security (built into every deployment)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zero cold starts&lt;/strong&gt; for Pages (instant responses)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Minimal cold starts&lt;/strong&gt; for Workers (typically &amp;#x3C;10ms)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Performance metrics from my production deployments:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TTFB (Time to First Byte):&lt;/strong&gt; AWS us-east: 180ms → Cloudflare: 35ms (5x faster)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Global latency:&lt;/strong&gt; 95th percentile under 50ms from any continent&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build times:&lt;/strong&gt; Vercel: 2-3 minutes → Cloudflare: 45 seconds&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Monthly costs:&lt;/strong&gt; AWS: $47/month → Cloudflare: $0 (free tier handles 500K requests/day)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For AI-powered apps that might call Claude, OpenAI, or other APIs, reducing latency on the hosting side means your users spend less time waiting overall.&lt;/p&gt;
&lt;h3 id=&quot;free-tier-limits-and-scalability-for-claudecodex-projects&quot;&gt;Free Tier Limits and Scalability for Claude/Codex Projects&lt;/h3&gt;
&lt;p&gt;Both Cloudflare Pages and Workers offer generous free tiers:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare Pages&lt;/strong&gt; (Free):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Unlimited sites and requests&lt;/li&gt;
&lt;li&gt;500 builds per month&lt;/li&gt;
&lt;li&gt;25 MiB file size limit per deployment&lt;/li&gt;
&lt;li&gt;20,000 files per deployment&lt;/li&gt;
&lt;li&gt;Automatic HTTPS and CDN&lt;/li&gt;
&lt;li&gt;Unlimited bandwidth&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare Workers&lt;/strong&gt; (Free):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;100,000 requests per day&lt;/li&gt;
&lt;li&gt;10ms CPU time per request&lt;/li&gt;
&lt;li&gt;128MB memory&lt;/li&gt;
&lt;li&gt;1GB KV storage (key-value store)&lt;/li&gt;
&lt;li&gt;Automatic HTTPS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For most personal projects and MVPs, you&apos;ll never hit these limits. Even production apps can run for free.&lt;/p&gt;
&lt;h3 id=&quot;comparison-cloudflare-vs-vercel-vs-netlify&quot;&gt;Comparison: Cloudflare vs Vercel vs Netlify&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Cloudflare Pages&lt;/th&gt;
&lt;th&gt;Cloudflare Workers&lt;/th&gt;
&lt;th&gt;Vercel&lt;/th&gt;
&lt;th&gt;Netlify&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Free Requests&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;100,000/day&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Free Bandwidth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;100GB/mo&lt;/td&gt;
&lt;td&gt;100GB/mo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Free Builds&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;500/mo&lt;/td&gt;
&lt;td&gt;N/A (local builds)&lt;/td&gt;
&lt;td&gt;6,000 min/mo&lt;/td&gt;
&lt;td&gt;300 min/mo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Edge Functions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ (native)&lt;/td&gt;
&lt;td&gt;✅ (limited)&lt;/td&gt;
&lt;td&gt;✅ (limited)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Global CDN&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ 300+ cities&lt;/td&gt;
&lt;td&gt;✅ 300+ cities&lt;/td&gt;
&lt;td&gt;✅ 70+ regions&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cold Starts&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;&amp;#x3C;10ms&lt;/td&gt;
&lt;td&gt;~50-200ms&lt;/td&gt;
&lt;td&gt;~50-300ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;KV Storage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ 1GB free&lt;/td&gt;
&lt;td&gt;✅ (paid)&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;WebSocket Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ (Durable Objects)&lt;/td&gt;
&lt;td&gt;✅ (limited)&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best For&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Static AI frontends&lt;/td&gt;
&lt;td&gt;AI APIs, backends&lt;/td&gt;
&lt;td&gt;Full-stack&lt;/td&gt;
&lt;td&gt;Jamstack&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Verdict&lt;/strong&gt;: For static sites built with Claude Code or Codex, &lt;strong&gt;Cloudflare Pages&lt;/strong&gt; is unbeatable (unlimited requests/bandwidth). For AI APIs or backend logic, &lt;strong&gt;Cloudflare Workers&lt;/strong&gt; offers better performance than Vercel/Netlify edge functions.&lt;/p&gt;
&lt;p&gt;Want more hosting comparisons? Check out our guides on &lt;a href=&quot;/blog/3-ways-to-move-lovable-website&quot;&gt;deploying to Vercel, Firebase, and more&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;preparing-your-claude-or-codex-project&quot;&gt;Preparing Your Claude or Codex Project&lt;/h2&gt;
&lt;p&gt;Before deploying, you need to organize your AI-generated code for Cloudflare.&lt;/p&gt;
&lt;h3 id=&quot;exporting-code-safely-from-claude-or-codex&quot;&gt;Exporting Code Safely from Claude or Codex&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;From Claude Code&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If using Claude.ai&apos;s code generation, copy your code into local files&lt;/li&gt;
&lt;li&gt;Organize into a standard project structure:
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;my-project/
├── src/
├── public/
├── package.json
├── vite.config.js (or equivalent)
└── README.md&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Ensure you have a &lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt; with build scripts&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;From OpenAI Codex&lt;/strong&gt; (via GitHub Copilot, ChatGPT, or API):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Save generated code to your local development environment&lt;/li&gt;
&lt;li&gt;Verify all dependencies are in &lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Test locally before deploying:
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run dev&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;From ChatGPT Code Interpreter&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download generated files as a ZIP&lt;/li&gt;
&lt;li&gt;Extract and organize into a proper project structure&lt;/li&gt;
&lt;li&gt;Add missing config files (&lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt;, build configs)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;organizing-your-repo-for-cloudflare-pages&quot;&gt;Organizing Your Repo for Cloudflare Pages&lt;/h3&gt;
&lt;p&gt;Cloudflare Pages expects a standard build output. Common frameworks and their outputs:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework&lt;/th&gt;
&lt;th&gt;Build Command&lt;/th&gt;
&lt;th&gt;Output Directory&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vite&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;npm run build&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;React (CRA)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;npm run build&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Next.js&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;next build &amp;amp;&amp;amp; next export&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;out&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vue&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;npm run build&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Svelte/SvelteKit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;npm run build&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Astro&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;npm run build&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Plain HTML/JS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;.&lt;/code&gt; (root)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Make sure your AI-generated project follows one of these patterns. If Claude or Codex generated custom build scripts, verify they work:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Test your build locally&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build

&lt;span class=&quot;token comment&quot;&gt;# Verify output directory exists&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-la&lt;/span&gt; dist/  &lt;span class=&quot;token comment&quot;&gt;# or build/, out/, etc.&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;adding-environment-variables-for-api-keys-and-secrets&quot;&gt;Adding Environment Variables for API Keys and Secrets&lt;/h3&gt;
&lt;p&gt;AI apps often need API keys (for Claude, OpenAI, databases, etc.). &lt;strong&gt;Never commit these to Git&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Create a &lt;code class=&quot;language-text&quot;&gt;.env.local&lt;/code&gt; file (gitignored):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# .env.local&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;VITE_CLAUDE_API_KEY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;sk-ant-&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.
&lt;span class=&quot;token assign-left variable&quot;&gt;VITE_OPENAI_API_KEY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;sk-&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.
&lt;span class=&quot;token assign-left variable&quot;&gt;VITE_SUPABASE_URL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;https://&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.
&lt;span class=&quot;token assign-left variable&quot;&gt;VITE_SUPABASE_ANON_KEY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;eyJ&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For Vite projects, use &lt;code class=&quot;language-text&quot;&gt;VITE_&lt;/code&gt; prefix. For Next.js, use &lt;code class=&quot;language-text&quot;&gt;NEXT_PUBLIC_&lt;/code&gt; prefix.&lt;/p&gt;
&lt;p&gt;In your code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Access environment variables&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; apiKey &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VITE_CLAUDE_API_KEY&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Vite&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// or&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; apiKey &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;NEXT_PUBLIC_OPENAI_API_KEY&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Next.js&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Add &lt;code class=&quot;language-text&quot;&gt;.env.local&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;.gitignore&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;.env.local&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; .gitignore&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You&apos;ll add these as Cloudflare environment variables later.&lt;/p&gt;
&lt;h2 id=&quot;deploying-to-cloudflare-pages&quot;&gt;Deploying to Cloudflare Pages&lt;/h2&gt;
&lt;p&gt;Cloudflare Pages is the easiest way to deploy static sites and frameworks. It&apos;s ideal for frontends generated by Claude Code or Codex.&lt;/p&gt;
&lt;h3 id=&quot;connect-your-github-repository&quot;&gt;Connect Your GitHub Repository&lt;/h3&gt;
&lt;p&gt;First, push your code to GitHub:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Initialize Git if not already done&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init

&lt;span class=&quot;token comment&quot;&gt;# Add all files&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Commit&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial commit: Claude Code generated project&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Create a new repository on GitHub, then:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; origin https://github.com/YOUR-USERNAME/YOUR-REPO.git
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch &lt;span class=&quot;token parameter variable&quot;&gt;-M&lt;/span&gt; main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now connect to Cloudflare:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Log in to &lt;a href=&quot;https://dash.cloudflare.com&quot;&gt;Cloudflare Dashboard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&quot;Workers &amp;#x26; Pages&quot;&lt;/strong&gt; in the left sidebar&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&quot;Create application&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Select the &lt;strong&gt;&quot;Pages&quot;&lt;/strong&gt; tab&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&quot;Connect to Git&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Authorize Cloudflare to access your GitHub account&lt;/li&gt;
&lt;li&gt;Select your repository&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&quot;Begin setup&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;configure-build-settings-for-static-or-framework-projects&quot;&gt;Configure Build Settings for Static or Framework Projects&lt;/h3&gt;
&lt;p&gt;Cloudflare will try to auto-detect your framework. Verify or manually set:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For Vite projects&lt;/strong&gt; (common with Claude Code):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Framework preset&lt;/strong&gt;: Vite&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build command&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;npm run build&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build output directory&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;For React (Create React App)&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Framework preset&lt;/strong&gt;: Create React App&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build command&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;npm run build&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build output directory&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;For Next.js&lt;/strong&gt; (static export):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Framework preset&lt;/strong&gt;: Next.js (Static HTML Export)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build command&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;npx next build &amp;amp;&amp;amp; npx next export&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build output directory&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;out&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;For plain HTML/CSS/JS&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Framework preset&lt;/strong&gt;: None&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build command&lt;/strong&gt;: Leave blank&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build output directory&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;.&lt;/code&gt; (or the folder containing &lt;code class=&quot;language-text&quot;&gt;index.html&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Environment variables&lt;/strong&gt;:
Add your API keys here (these replace &lt;code class=&quot;language-text&quot;&gt;.env.local&lt;/code&gt;):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Scroll to &lt;strong&gt;&quot;Environment variables&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&quot;Add variable&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Add each variable:
&lt;ul&gt;
&lt;li&gt;Variable name: &lt;code class=&quot;language-text&quot;&gt;VITE_CLAUDE_API_KEY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Value: &lt;code class=&quot;language-text&quot;&gt;sk-ant-...&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Set for both &lt;strong&gt;&quot;Production&quot;&lt;/strong&gt; and &lt;strong&gt;&quot;Preview&quot;&lt;/strong&gt; environments&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Click &lt;strong&gt;&quot;Save and Deploy&quot;&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;common-issues-missing-build-output-or-wrong-path&quot;&gt;Common Issues: Missing Build Output or Wrong Path&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Build fails with &quot;No index.html found&quot;&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Verify your &lt;strong&gt;build output directory&lt;/strong&gt; is correct&lt;/li&gt;
&lt;li&gt;Check the build logs: does &lt;code class=&quot;language-text&quot;&gt;npm run build&lt;/code&gt; succeed?&lt;/li&gt;
&lt;li&gt;Common mistakes:
&lt;ul&gt;
&lt;li&gt;Set &lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt; when it should be &lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Set &lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt; when it should be &lt;code class=&quot;language-text&quot;&gt;out&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Check your build config file:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# For Vite, check vite.config.js&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Look for:&lt;/span&gt;
build: &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  outDir: &lt;span class=&quot;token string&quot;&gt;&apos;dist&apos;&lt;/span&gt;  // &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;-- This is your output directory
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Build succeeds but site shows blank page&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Check browser console for errors (F12)&lt;/li&gt;
&lt;li&gt;Common issue: Base URL mismatch&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For Vite, if deploying to a subdirectory, set base in &lt;code class=&quot;language-text&quot;&gt;vite.config.js&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// Use &apos;/&apos; for root domain or subdomain&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Environment variables not working&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Verify variable names match exactly (case-sensitive)&lt;/li&gt;
&lt;li&gt;For Vite: Must start with &lt;code class=&quot;language-text&quot;&gt;VITE_&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;For Next.js: Must start with &lt;code class=&quot;language-text&quot;&gt;NEXT_PUBLIC_&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Redeploy after adding variables (Cloudflare requires rebuild)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;preview-deployments--continuous-updates&quot;&gt;Preview Deployments &amp;#x26; Continuous Updates&lt;/h3&gt;
&lt;p&gt;Every time you push to your &lt;code class=&quot;language-text&quot;&gt;main&lt;/code&gt; branch, Cloudflare automatically rebuilds and deploys.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For feature branches&lt;/strong&gt; (e.g., &lt;code class=&quot;language-text&quot;&gt;dev&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;staging&lt;/code&gt;):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Push to a non-main branch:
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout &lt;span class=&quot;token parameter variable&quot;&gt;-b&lt;/span&gt; new-feature
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push origin new-feature&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Cloudflare creates a &lt;strong&gt;preview deployment&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Get a unique URL like &lt;code class=&quot;language-text&quot;&gt;abc123.your-project.pages.dev&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Test before merging to main&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Disable automatic deployments&lt;/strong&gt;:
In Pages settings &gt; Builds &amp;#x26; deployments &gt; Disable &quot;Automatic git deployments&quot; if you want manual control.&lt;/p&gt;
&lt;h2 id=&quot;adding-logic-with-cloudflare-workers&quot;&gt;Adding Logic with Cloudflare Workers&lt;/h2&gt;
&lt;p&gt;For AI apps that need backend APIs, authentication, or server-side logic, Cloudflare Workers run JavaScript/TypeScript at the edge.&lt;/p&gt;
&lt;h3 id=&quot;using-wrangler-cli-for-local-testing-and-deploys&quot;&gt;Using Wrangler CLI for Local Testing and Deploys&lt;/h3&gt;
&lt;p&gt;Install Wrangler (Cloudflare&apos;s CLI):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Install globally&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; wrangler

&lt;span class=&quot;token comment&quot;&gt;# Verify installation&lt;/span&gt;
wrangler &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Log in to Cloudflare&lt;/span&gt;
wrangler login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Create a new Worker:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Create a new Worker project&lt;/span&gt;
wrangler init my-ai-api

&lt;span class=&quot;token comment&quot;&gt;# Choose options:&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# - Would you like to use TypeScript? Yes&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# - Would you like to create a Worker? Yes&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# - Would you like to install dependencies? Yes&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This creates:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;my-ai-api/
├── src/
│   └── index.ts
├── wrangler.toml
└── package.json&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;running-ai-apis-at-the-edge-claude-codex-or-gpt-endpoints&quot;&gt;Running AI APIs at the Edge (Claude, Codex, or GPT Endpoints)&lt;/h3&gt;
&lt;p&gt;Here&apos;s how to build an AI API endpoint using Cloudflare Workers:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example: Claude API proxy&lt;/strong&gt; (&lt;code class=&quot;language-text&quot;&gt;src/index.ts&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Env&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;CLAUDE_API_KEY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; env&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Env&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Response&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// CORS headers&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; corsHeaders &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token string-property property&quot;&gt;&apos;Access-Control-Allow-Origin&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;*&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string-property property&quot;&gt;&apos;Access-Control-Allow-Methods&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GET, POST, OPTIONS&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string-property property&quot;&gt;&apos;Access-Control-Allow-Headers&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Handle CORS preflight&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;method &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;OPTIONS&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; headers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; corsHeaders &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Only allow POST&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;method &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;POST&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Method not allowed&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; status&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;405&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; prompt &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

      &lt;span class=&quot;token comment&quot;&gt;// Call Claude API&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;https://api.anthropic.com/v1/messages&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        method&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;POST&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        headers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token string-property property&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token string-property property&quot;&gt;&apos;x-api-key&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CLAUDE_API_KEY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token string-property property&quot;&gt;&apos;anthropic-version&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;2023-06-01&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        body&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          model&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;claude-3-5-sonnet-20241022&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          max_tokens&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          messages&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; role&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;user&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; content&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; prompt &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        headers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;corsHeaders&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string-property property&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; error&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        status&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        headers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;corsHeaders&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string-property property&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Add your API key to Wrangler&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Set a secret (never commit this)&lt;/span&gt;
wrangler secret put CLAUDE_API_KEY
&lt;span class=&quot;token comment&quot;&gt;# Paste your Claude API key when prompted&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Test locally&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;wrangler dev&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This starts a local server at &lt;code class=&quot;language-text&quot;&gt;http://localhost:8787&lt;/code&gt;. Test with curl:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; POST http://localhost:8787 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{&quot;prompt&quot;: &quot;Hello Claude!&quot;}&apos;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Deploy to Cloudflare&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;wrangler deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Your Worker is now live at &lt;code class=&quot;language-text&quot;&gt;https://my-ai-api.YOUR-SUBDOMAIN.workers.dev&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;combining-pages--workers-for-hybrid-apps&quot;&gt;Combining Pages + Workers for Hybrid Apps&lt;/h3&gt;
&lt;p&gt;You can use Cloudflare Pages for your frontend and Workers for your backend API.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Architecture&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Frontend (Pages): your-app.pages.dev
Backend (Worker): api.your-app.workers.dev&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;In your frontend code&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Call your Worker from Pages&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;https://api.your-app.workers.dev&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;POST&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-property property&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;prompt&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; userInput &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Better: Use Pages Functions&lt;/strong&gt; (Workers built into Pages):&lt;/p&gt;
&lt;p&gt;Cloudflare Pages can run Workers functions directly:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a &lt;code class=&quot;language-text&quot;&gt;functions&lt;/code&gt; directory in your Pages project:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;my-project/
├── src/
├── public/
├── functions/
│   └── api/
│       └── chat.ts
└── package.json&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add your function (&lt;code class=&quot;language-text&quot;&gt;functions/api/chat.ts&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;onRequestPost&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; env &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; context
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; prompt &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;https://api.anthropic.com/v1/messages&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    method&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;POST&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    headers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token string-property property&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string-property property&quot;&gt;&apos;x-api-key&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CLAUDE_API_KEY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string-property property&quot;&gt;&apos;anthropic-version&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;2023-06-01&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    body&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      model&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;claude-3-5-sonnet-20241022&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      max_tokens&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      messages&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; role&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;user&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; content&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; prompt &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; response
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Call from your frontend:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// No CORS issues - same domain&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/chat&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;POST&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-property property&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;prompt&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; userInput &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Pages Functions run on the same domain, so no CORS issues.&lt;/p&gt;
&lt;h3 id=&quot;using-kv--d1-for-caching-or-persistent-storage&quot;&gt;Using KV / D1 for Caching or Persistent Storage&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare KV&lt;/strong&gt; (Key-Value store) is excellent for caching AI responses:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Env&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;CACHE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; KVNamespace
  &lt;span class=&quot;token constant&quot;&gt;CLAUDE_API_KEY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; env&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Env&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Response&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; prompt &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Check cache first&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cached &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CACHE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;prompt&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cached&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cached&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        headers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-property property&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Call Claude API&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;https://api.anthropic.com/v1/messages&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// ... Claude API call&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Cache for 1 hour (3600 seconds)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CACHE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;prompt&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; expirationTtl&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      headers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-property property&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Create a KV namespace&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Create KV namespace&lt;/span&gt;
wrangler kv:namespace create CACHE

&lt;span class=&quot;token comment&quot;&gt;# Add to wrangler.toml&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;kv_namespaces&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
binding &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;CACHE&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;your-namespace-id&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare D1&lt;/strong&gt; (SQL database) for persistent data:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Create D1 database&lt;/span&gt;
wrangler d1 create my-database

&lt;span class=&quot;token comment&quot;&gt;# Add to wrangler.toml&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;d1_databases&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
binding &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;DB&quot;&lt;/span&gt;
database_name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;my-database&quot;&lt;/span&gt;
database_id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;your-database-id&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Use in your Worker:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Query D1&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; results &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;prepare&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&apos;SELECT * FROM conversations WHERE user_id = ?&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;userId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;custom-domains-ssl-and-security-with-cloudflare&quot;&gt;Custom Domains, SSL, and Security with Cloudflare&lt;/h2&gt;
&lt;h3 id=&quot;mapping-your-domain-to-cloudflare-pages&quot;&gt;Mapping Your Domain to Cloudflare Pages&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;If your domain is on Cloudflare DNS&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In your Pages project, click &lt;strong&gt;&quot;Custom domains&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&quot;Set up a custom domain&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Enter your domain (e.g., &lt;code class=&quot;language-text&quot;&gt;myapp.com&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;www.myapp.com&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Cloudflare automatically creates DNS records&lt;/li&gt;
&lt;li&gt;SSL is enabled immediately&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;If your domain is NOT on Cloudflare&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Add custom domain in Pages settings&lt;/li&gt;
&lt;li&gt;Cloudflare shows you DNS records to add:
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;CNAME&lt;/code&gt;: &lt;code class=&quot;language-text&quot;&gt;www&lt;/code&gt; → &lt;code class=&quot;language-text&quot;&gt;your-project.pages.dev&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Go to your domain registrar (GoDaddy, Namecheap, etc.)&lt;/li&gt;
&lt;li&gt;Add the CNAME record&lt;/li&gt;
&lt;li&gt;Wait for DNS propagation (5 minutes to 24 hours)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Pro tip&lt;/strong&gt;: Transfer your domain to Cloudflare Registrar for at-cost pricing (no markup) and instant DNS updates.&lt;/p&gt;
&lt;h3 id=&quot;enforcing-https-and-zero-trust-edge-rules&quot;&gt;Enforcing HTTPS and Zero-Trust Edge Rules&lt;/h3&gt;
&lt;p&gt;Cloudflare Pages automatically enforces HTTPS. For Workers, add:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Request&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Response&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Redirect HTTP to HTTPS&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; url &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token constant&quot;&gt;URL&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;protocol &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;redirect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;https://&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;host&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pathname&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;301&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Your Worker logic&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Hello World&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Add security headers&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; securityHeaders &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token string-property property&quot;&gt;&apos;X-Frame-Options&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;DENY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string-property property&quot;&gt;&apos;X-Content-Type-Options&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;nosniff&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string-property property&quot;&gt;&apos;Referrer-Policy&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;strict-origin-when-cross-origin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string-property property&quot;&gt;&apos;Permissions-Policy&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;geolocation=(), microphone=(), camera=()&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string-property property&quot;&gt;&apos;Content-Security-Policy&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;default-src &apos;self&apos;; script-src &apos;self&apos; &apos;unsafe-inline&apos;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; headers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; securityHeaders &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;protecting-claude--codex-api-keys-and-tokens&quot;&gt;Protecting Claude / Codex API Keys and Tokens&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Never expose API keys in frontend code&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// ❌ BAD - Exposed to users&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; apiKey &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;sk-ant-...&apos;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ✅ GOOD - Use Workers as a proxy&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/chat&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;POST&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; prompt &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Use Cloudflare secrets for sensitive data&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# For Workers&lt;/span&gt;
wrangler secret put CLAUDE_API_KEY

&lt;span class=&quot;token comment&quot;&gt;# For Pages Functions&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Add in Cloudflare Dashboard: Pages &gt; Settings &gt; Environment variables&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Check &quot;Encrypt&quot; for sensitive values&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Rate limiting&lt;/strong&gt; to prevent API abuse:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Simple rate limiting with KV&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; clientIP &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;CF-Connecting-IP&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; rateLimitKey &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;ratelimit:&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;clientIP&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; requests &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CACHE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rateLimitKey&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;requests &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;requests&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Rate limit exceeded&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; status&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;429&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CACHE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rateLimitKey&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;requests &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;0&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  expirationTtl&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 10 requests per minute&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;troubleshooting-common-deployment-issues-with-cloudflare&quot;&gt;Troubleshooting Common Deployment Issues with Cloudflare&lt;/h2&gt;
&lt;h3 id=&quot;build-logs-show-missing-build-command&quot;&gt;Build Logs Show &quot;Missing Build Command&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Error&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;Build failed: No build command specified&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cause&lt;/strong&gt;: Cloudflare doesn&apos;t know how to build your project&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Verify &lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt; has a &lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt; script:
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-json line-numbers&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;build&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;vite build&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;In Pages settings, explicitly set build command: &lt;code class=&quot;language-text&quot;&gt;npm run build&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;If using a different package manager:
&lt;ul&gt;
&lt;li&gt;Yarn: &lt;code class=&quot;language-text&quot;&gt;yarn build&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;pnpm: &lt;code class=&quot;language-text&quot;&gt;pnpm build&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;wrangler-publish-fails-with-authentication-error&quot;&gt;Wrangler Publish Fails with Authentication Error&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Error&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;Error: Not authenticated. Please run &apos;wrangler login&apos;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Log out and log back in&lt;/span&gt;
wrangler &lt;span class=&quot;token builtin class-name&quot;&gt;logout&lt;/span&gt;
wrangler login

&lt;span class=&quot;token comment&quot;&gt;# Verify authentication&lt;/span&gt;
wrangler &lt;span class=&quot;token function&quot;&gt;whoami&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;For CI/CD&lt;/strong&gt; (GitHub Actions), use API tokens:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create API token: Cloudflare Dashboard &gt; My Profile &gt; API Tokens&lt;/li&gt;
&lt;li&gt;Use &quot;Edit Cloudflare Workers&quot; template&lt;/li&gt;
&lt;li&gt;Add to GitHub secrets as &lt;code class=&quot;language-text&quot;&gt;CLOUDFLARE_API_TOKEN&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;environment-variables-not-applied-in-production&quot;&gt;Environment Variables Not Applied in Production&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Code works locally but fails in production&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Common mistakes&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Forgot to redeploy after adding variables&lt;/strong&gt;: Cloudflare requires a rebuild&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Solution: Make a dummy commit and push, or click &quot;Retry deployment&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Variable name mismatch&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Local: &lt;code class=&quot;language-text&quot;&gt;VITE_API_KEY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Cloudflare: &lt;code class=&quot;language-text&quot;&gt;API_KEY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Solution: Names must match exactly (case-sensitive)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Wrong environment&lt;/strong&gt; (Production vs Preview):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Solution: Add variables to both environments in Pages settings&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Accessing in wrong way&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// ❌ Wrong - Won&apos;t work in Workers&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; key &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;API_KEY&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ✅ Correct - Use env binding&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; env&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; key &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;API_KEY&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;cors-errors-between-pages-and-workers&quot;&gt;CORS Errors Between Pages and Workers&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Error&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;Access to fetch at &apos;https://api.workers.dev&apos; from origin &apos;https://pages.dev&apos; has been blocked by CORS policy&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Add CORS headers to your Worker:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; corsHeaders &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token string-property property&quot;&gt;&apos;Access-Control-Allow-Origin&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;*&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Or specify your Pages domain&lt;/span&gt;
  &lt;span class=&quot;token string-property property&quot;&gt;&apos;Access-Control-Allow-Methods&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GET, POST, OPTIONS&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string-property property&quot;&gt;&apos;Access-Control-Allow-Headers&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Content-Type, Authorization&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Request&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Response&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Handle preflight&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;method &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;OPTIONS&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; headers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; corsHeaders &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Hello&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Add CORS headers to all responses&lt;/span&gt;
    Object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;entries&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;corsHeaders&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; response
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Better solution&lt;/strong&gt;: Use Pages Functions (same domain, no CORS issues).&lt;/p&gt;
&lt;h2 id=&quot;automating-your-workflow-with-cloudflare&quot;&gt;Automating Your Workflow with Cloudflare&lt;/h2&gt;
&lt;h3 id=&quot;github-actions-cicd-with-wrangler&quot;&gt;GitHub Actions CI/CD with Wrangler&lt;/h3&gt;
&lt;p&gt;Automatically deploy your Worker on every push:&lt;/p&gt;
&lt;p&gt;Create &lt;code class=&quot;language-text&quot;&gt;.github/workflows/deploy.yml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deploy to Cloudflare Workers

&lt;span class=&quot;token key atrule&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;branches&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; main

&lt;span class=&quot;token key atrule&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;deploy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ubuntu&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;latest
    &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deploy
    &lt;span class=&quot;token key atrule&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/checkout@v3

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Setup Node.js
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/setup&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;node@v3
        &lt;span class=&quot;token key atrule&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;node-version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;18&apos;&lt;/span&gt;

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Install dependencies
        &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm install

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deploy to Cloudflare Workers
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cloudflare/wrangler&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;action@v3
        &lt;span class=&quot;token key atrule&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;apiToken&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; secrets.CLOUDFLARE_API_TOKEN &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Setup&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create Cloudflare API token (Dashboard &gt; My Profile &gt; API Tokens)&lt;/li&gt;
&lt;li&gt;Add to GitHub repo: Settings &gt; Secrets &gt; New repository secret&lt;/li&gt;
&lt;li&gt;Name it &lt;code class=&quot;language-text&quot;&gt;CLOUDFLARE_API_TOKEN&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Push to main branch → auto-deploy&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;automating-claude--cloudflare-pipeline&quot;&gt;Automating Claude → Cloudflare Pipeline&lt;/h3&gt;
&lt;p&gt;Full automation from code generation to deployment:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; AI&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;Generated Code Deploy

&lt;span class=&quot;token key atrule&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;branches&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; main

&lt;span class=&quot;token key atrule&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;build-and-deploy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ubuntu&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;latest
    &lt;span class=&quot;token key atrule&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/checkout@v3

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Setup Node.js
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/setup&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;node@v3
        &lt;span class=&quot;token key atrule&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;node-version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;18&apos;&lt;/span&gt;

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Install dependencies
        &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm ci

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Build project
        &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm run build

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deploy to Cloudflare Pages
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cloudflare/pages&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;action@v1
        &lt;span class=&quot;token key atrule&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;apiToken&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; secrets.CLOUDFLARE_API_TOKEN &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;accountId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; secrets.CLOUDFLARE_ACCOUNT_ID &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;projectName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; my&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;ai&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;project
          &lt;span class=&quot;token key atrule&quot;&gt;directory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; dist
          &lt;span class=&quot;token key atrule&quot;&gt;gitHubToken&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; secrets.GITHUB_TOKEN &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;scheduling-worker-cron-triggers&quot;&gt;Scheduling Worker Cron Triggers&lt;/h3&gt;
&lt;p&gt;Run Workers on a schedule (great for AI-powered tasks):&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In &lt;code class=&quot;language-text&quot;&gt;wrangler.toml&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;triggers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;crons&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0 */6 * * *&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# Every 6 hours&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;In your Worker&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scheduled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;event&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ScheduledEvent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; env&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Env&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Run AI task every 6 hours&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; prompt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Summarize the day&apos;s news&quot;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;https://api.anthropic.com/v1/messages&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      method&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;POST&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      headers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string-property property&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string-property property&quot;&gt;&apos;x-api-key&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CLAUDE_API_KEY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string-property property&quot;&gt;&apos;anthropic-version&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;2023-06-01&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      body&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        model&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;claude-3-5-sonnet-20241022&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        max_tokens&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        messages&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; role&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;user&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; content&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; prompt &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Store result in KV&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CACHE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;daily-summary&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;faqs&quot;&gt;FAQs&lt;/h2&gt;
&lt;h3 id=&quot;can-i-host-claude-code-projects-for-free-on-cloudflare&quot;&gt;Can I host Claude Code projects for free on Cloudflare?&lt;/h3&gt;
&lt;p&gt;Yes! Cloudflare Pages offers unlimited sites and requests for free. The free tier includes 500 builds per month, which is more than enough for personal projects and MVPs. Most Claude Code-generated frontends fit well within the free tier.&lt;/p&gt;
&lt;h3 id=&quot;is-cloudflare-pages-good-for-dynamic-codex-generated-apps&quot;&gt;Is Cloudflare Pages good for dynamic Codex-generated apps?&lt;/h3&gt;
&lt;p&gt;Cloudflare Pages works well for static sites and frameworks with static builds (React, Vue, Svelte, etc.). For dynamic apps with server-side logic, combine Pages (frontend) with Workers (backend API). Workers run JavaScript/TypeScript at the edge and can handle API calls, database queries, and authentication.&lt;/p&gt;
&lt;h3 id=&quot;how-do-i-connect-my-claude-code-backend-api-to-cloudflare-workers&quot;&gt;How do I connect my Claude Code backend API to Cloudflare Workers?&lt;/h3&gt;
&lt;p&gt;If Claude generated a backend API (Node.js/Express), you have two options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Rewrite for Workers&lt;/strong&gt;: Adapt your API to Cloudflare Workers (use &lt;code class=&quot;language-text&quot;&gt;fetch&lt;/code&gt; handlers instead of Express routes)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deploy elsewhere&lt;/strong&gt;: Keep your backend on a traditional platform (Railway, Render) and use Workers as a proxy or for edge functions only&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For most use cases, option 1 gives better performance (edge deployment).&lt;/p&gt;
&lt;h3 id=&quot;how-to-fix-wrangler-cli-authentication-errors&quot;&gt;How to fix Wrangler CLI authentication errors?&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Log out and back in&lt;/span&gt;
wrangler &lt;span class=&quot;token builtin class-name&quot;&gt;logout&lt;/span&gt;
wrangler login

&lt;span class=&quot;token comment&quot;&gt;# If still failing, manually set API token&lt;/span&gt;
wrangler login --api-token YOUR_API_TOKEN

&lt;span class=&quot;token comment&quot;&gt;# Verify it works&lt;/span&gt;
wrangler &lt;span class=&quot;token function&quot;&gt;whoami&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For CI/CD, use API tokens (not OAuth) in environment variables.&lt;/p&gt;
&lt;h3 id=&quot;can-cloudflare-host-python-or-node-ai-apps&quot;&gt;Can Cloudflare host Python or Node AI apps?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Python&lt;/strong&gt;: Not directly. Cloudflare Workers run JavaScript/TypeScript/Rust/C/C++ (compiled to WebAssembly). For Python AI apps, deploy to Railway, Render, or Fly.io instead.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Node.js&lt;/strong&gt;: Yes, but Workers use a subset of Node.js APIs. Standard Node modules won&apos;t work. Use Workers-compatible libraries or rewrite for the Workers runtime. See &lt;a href=&quot;https://developers.cloudflare.com/workers/runtime-apis/&quot;&gt;Cloudflare Workers runtime docs&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Deploying AI-generated projects to Cloudflare gives you enterprise-grade performance for free. Whether you built with Claude Code, OpenAI Codex, or GitHub Copilot, Cloudflare Pages and Workers offer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Lightning-fast edge deployment&lt;/strong&gt; (300+ global locations)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generous free tiers&lt;/strong&gt; (unlimited requests for Pages, 100k/day for Workers)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automatic HTTPS&lt;/strong&gt; and security&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Easy Git integration&lt;/strong&gt; (push to deploy)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Advanced features&lt;/strong&gt; (KV storage, D1 databases, cron triggers)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Quick recommendations&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Frontend only?&lt;/strong&gt; Use Cloudflare Pages&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Need backend APIs?&lt;/strong&gt; Add Cloudflare Workers or use Pages Functions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Caching AI responses?&lt;/strong&gt; Use KV storage&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Database needed?&lt;/strong&gt; Use D1 (SQL) or connect to external databases&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For more deployment guides, check out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;Complete Guide: Deploying Lovable Projects to Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website&quot;&gt;10 Ways to Move Your Website to Free Hosting&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Have questions about deploying your specific AI project? Drop a comment below!&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;article-updates&quot;&gt;Article Updates&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;November 2025:&lt;/strong&gt; SEO optimization and updated keywords for Claude AI and Cloudflare edge deployment&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;October 2025:&lt;/strong&gt; Updated for Wrangler v3 and latest Cloudflare Dashboard UI&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;October 2025:&lt;/strong&gt; Added performance metrics from production deployments&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;October 2025:&lt;/strong&gt; Added &quot;Who This Is For&quot; section and clearer prerequisites&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;October 2025:&lt;/strong&gt; Verified all code examples with Node.js 18.x and 20.x&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Further reading&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/pages/&quot;&gt;Cloudflare Pages Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/workers/&quot;&gt;Cloudflare Workers Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.anthropic.com/&quot;&gt;Anthropic Claude API Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://platform.openai.com/docs/&quot;&gt;OpenAI API Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[8 Common Git Commands You Will Use Daily: Switch, Checkout, and Pull Rebase Explained]]></title><description><![CDATA[Learn the 8 Git commands developers use every day, including how to use git switch vs checkout and why git pull --rebase keeps your commit history clean for smoother workflows.]]></description><link>https://vibecodingwithfred.com/blog/everyday-git-commands/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/everyday-git-commands/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Fri, 05 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Git is powerful, but it has a reputation for being complicated. It includes hundreds of commands and flags, yet most developers only rely on a small set of them every day. If you learn the eight commands in this guide, you can work confidently in almost any Git project without needing to memorize the rest.&lt;/p&gt;
&lt;h2 id=&quot;the-8-essential-commands&quot;&gt;The 8 Essential Commands&lt;/h2&gt;
&lt;h3 id=&quot;1-git-status&quot;&gt;1. git status&lt;/h3&gt;
&lt;p&gt;Use this to check the state of your workspace. It shows which files have changed, which files are staged, which branch you are on, and whether your branch is ahead or behind the remote. This command is your main dashboard.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; status&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-git-add-&quot;&gt;2. git add .&lt;/h3&gt;
&lt;p&gt;This stages your changes so they are ready to be committed. The dot means &quot;add everything that changed&quot;. You can also stage individual files if you prefer to be more selective.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Or stage specific files:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; src/index.js&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-git-commit--m-&quot;&gt;3. git commit -m &quot;&quot;&lt;/h3&gt;
&lt;p&gt;A commit creates a snapshot of your work. The message inside the quotes should describe why the change was made. Good commit messages save time later when reviewing history or debugging issues.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Add user authentication flow&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-git-pull---rebase&quot;&gt;4. git pull --rebase&lt;/h3&gt;
&lt;p&gt;This updates your local branch with the latest changes from the remote. The &lt;code class=&quot;language-text&quot;&gt;--rebase&lt;/code&gt; flag keeps your commit history clean by replaying your commits on top of the newest upstream commits. This avoids unnecessary merge commits and reduces conflict noise.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; pull &lt;span class=&quot;token parameter variable&quot;&gt;--rebase&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Why rebase?&lt;/strong&gt; Without it, you get merge commits every time you pull, cluttering your history with &quot;Merge branch &apos;main&apos; into main&quot; messages.&lt;/p&gt;
&lt;h3 id=&quot;5-git-push&quot;&gt;5. git push&lt;/h3&gt;
&lt;p&gt;This uploads your commits to GitHub, GitLab, or any other remote. Pushing saves your work to the server, backs it up, and makes it available for pull requests and team collaboration.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push
&lt;span class=&quot;token comment&quot;&gt;# First push on a new branch:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin feature/my-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;6-git-switch-branch&quot;&gt;6. git switch &amp;#x3C;branch&gt;&lt;/h3&gt;
&lt;p&gt;This is the modern way to switch to another branch. It is simple, clear, and cannot accidentally modify your files.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If the branch does not exist yet, create it with:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch &lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt; new-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;7-git-merge-branch&quot;&gt;7. git merge &amp;#x3C;branch&gt;&lt;/h3&gt;
&lt;p&gt;This merges the specified branch into the branch you are currently on. The correct order is to switch into the branch you want to update first, then merge another branch into it.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; merge feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;8-git-checkout--&quot;&gt;8. git checkout -&lt;/h3&gt;
&lt;p&gt;This returns you to the previous branch along with its working state. It is an extremely useful shortcut and one of the only modern uses of &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; that is still recommended.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout -
&lt;span class=&quot;token comment&quot;&gt;# Equivalent to &quot;cd -&quot; for branches&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;quick-reference&quot;&gt;Quick Reference&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show workspace state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git add .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stage all changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git commit -m &quot;msg&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git pull --rebase&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Update from remote (clean history)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Upload commits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Change branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git merge &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Merge branch into current&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Return to previous branch&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;modern-git-switch-vs-checkout&quot;&gt;Modern Git: Switch vs Checkout&lt;/h2&gt;
&lt;p&gt;Since Git 2.23, things have become even simpler. Git introduced two new commands, &lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;git restore&lt;/code&gt;, to separate branch switching from file restoration. This change makes the intent of each command clear, especially for new developers. The old &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; command was overloaded and tried to do too many unrelated things.&lt;/p&gt;
&lt;p&gt;Here is the simple rule set for modern Git usage:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Changes branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns to previous branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Should NOT be used for switching branches (except the dash shortcut)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;wrapping-up&quot;&gt;Wrapping Up&lt;/h2&gt;
&lt;p&gt;If you master these eight commands, you will be effective in almost every daily Git workflow without needing any advanced knowledge. The key insight is using &lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt; for branches and reserving &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; only for the dash shortcut.&lt;/p&gt;
&lt;p&gt;For everything else—rebasing, cherry-picking, bisecting—you can look it up when you need it. These eight commands cover 95% of what you&apos;ll do every day.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[8 haeufige Git-Befehle, die Sie taeglich verwenden werden: Switch, Checkout und Pull Rebase erklaert]]></title><description><![CDATA[Lernen Sie die 8 Git-Befehle, die Entwickler jeden Tag verwenden, einschliesslich der Verwendung von git switch vs checkout und warum git pull --rebase Ihre Commit-Historie sauber haelt.]]></description><link>https://vibecodingwithfred.com/de/blog/everyday-git-commands/</link><guid isPermaLink="false">https://vibecodingwithfred.com/de/blog/everyday-git-commands/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Fri, 05 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Git ist maechtig, hat aber den Ruf, kompliziert zu sein. Es beinhaltet Hunderte von Befehlen und Flags, doch die meisten Entwickler verlassen sich jeden Tag nur auf eine kleine Auswahl davon. Wenn Sie die acht Befehle in dieser Anleitung lernen, koennen Sie selbstbewusst in fast jedem Git-Projekt arbeiten, ohne den Rest auswendig lernen zu muessen.&lt;/p&gt;
&lt;h2 id=&quot;die-8-essentiellen-befehle&quot;&gt;Die 8 essentiellen Befehle&lt;/h2&gt;
&lt;h3 id=&quot;1-git-status&quot;&gt;1. git status&lt;/h3&gt;
&lt;p&gt;Verwenden Sie diesen Befehl, um den Zustand Ihres Arbeitsbereichs zu pruefen. Er zeigt, welche Dateien sich geaendert haben, welche Dateien gestaged sind, auf welchem Branch Sie sich befinden und ob Ihr Branch vor oder hinter dem Remote liegt. Dieser Befehl ist Ihr Haupt-Dashboard.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; status&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-git-add-&quot;&gt;2. git add .&lt;/h3&gt;
&lt;p&gt;Dies staged Ihre Aenderungen, damit sie bereit zum Committen sind. Der Punkt bedeutet &quot;alles hinzufuegen, was sich geaendert hat&quot;. Sie koennen auch einzelne Dateien stagen, wenn Sie selektiver sein moechten.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Oder spezifische Dateien stagen:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; src/index.js&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-git-commit--m-&quot;&gt;3. git commit -m &quot;&quot;&lt;/h3&gt;
&lt;p&gt;Ein Commit erstellt einen Schnappschuss Ihrer Arbeit. Die Nachricht in den Anfuehrungszeichen sollte beschreiben, warum die Aenderung gemacht wurde. Gute Commit-Nachrichten sparen spaeter Zeit beim Ueberpruefen der Historie oder beim Debuggen von Problemen.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Benutzerauthentifizierungs-Flow hinzufuegen&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-git-pull---rebase&quot;&gt;4. git pull --rebase&lt;/h3&gt;
&lt;p&gt;Dies aktualisiert Ihren lokalen Branch mit den neuesten Aenderungen vom Remote. Das &lt;code class=&quot;language-text&quot;&gt;--rebase&lt;/code&gt;-Flag haelt Ihre Commit-Historie sauber, indem Ihre Commits auf die neuesten Upstream-Commits aufgesetzt werden. Dies vermeidet unnoetige Merge-Commits und reduziert Konflikt-Rauschen.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; pull &lt;span class=&quot;token parameter variable&quot;&gt;--rebase&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Warum rebase?&lt;/strong&gt; Ohne es bekommen Sie bei jedem Pull Merge-Commits, die Ihre Historie mit &quot;Merge branch &apos;main&apos; into main&quot;-Nachrichten ueberladen.&lt;/p&gt;
&lt;h3 id=&quot;5-git-push&quot;&gt;5. git push&lt;/h3&gt;
&lt;p&gt;Dies laedt Ihre Commits zu GitHub, GitLab oder einem anderen Remote hoch. Pushen speichert Ihre Arbeit auf dem Server, sichert sie und macht sie fuer Pull Requests und Team-Zusammenarbeit verfuegbar.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push
&lt;span class=&quot;token comment&quot;&gt;# Erster Push auf einem neuen Branch:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin feature/mein-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;6-git-switch-branch&quot;&gt;6. git switch &amp;#x3C;branch&gt;&lt;/h3&gt;
&lt;p&gt;Dies ist die moderne Art, zu einem anderen Branch zu wechseln. Es ist einfach, klar und kann nicht versehentlich Ihre Dateien modifizieren.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Wenn der Branch noch nicht existiert, erstellen Sie ihn mit:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch &lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt; neuer-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;7-git-merge-branch&quot;&gt;7. git merge &amp;#x3C;branch&gt;&lt;/h3&gt;
&lt;p&gt;Dies merged den angegebenen Branch in den Branch, auf dem Sie sich gerade befinden. Die richtige Reihenfolge ist, zuerst in den Branch zu wechseln, den Sie aktualisieren moechten, und dann einen anderen Branch hinein zu mergen.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; merge feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;8-git-checkout--&quot;&gt;8. git checkout -&lt;/h3&gt;
&lt;p&gt;Dies bringt Sie zum vorherigen Branch zusammen mit seinem Arbeitszustand zurueck. Es ist eine extrem nuetzliche Abkuerzung und eine der wenigen modernen Verwendungen von &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt;, die noch empfohlen wird.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout -
&lt;span class=&quot;token comment&quot;&gt;# Entspricht &quot;cd -&quot; fuer Branches&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;kurzreferenz&quot;&gt;Kurzreferenz&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Befehl&lt;/th&gt;
&lt;th&gt;Was er tut&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Workspace-Zustand anzeigen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git add .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Alle Aenderungen stagen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git commit -m &quot;msg&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Einen Commit erstellen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git pull --rebase&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Vom Remote aktualisieren (saubere Historie)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Commits hochladen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Branches wechseln&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git merge &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Branch in aktuellen mergen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Zum vorherigen Branch zurueckkehren&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;modernes-git-switch-vs-checkout&quot;&gt;Modernes Git: Switch vs Checkout&lt;/h2&gt;
&lt;p&gt;Seit Git 2.23 sind die Dinge noch einfacher geworden. Git fuehrte zwei neue Befehle ein, &lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt; und &lt;code class=&quot;language-text&quot;&gt;git restore&lt;/code&gt;, um Branch-Wechsel von Datei-Wiederherstellung zu trennen. Diese Aenderung macht die Absicht jedes Befehls klar, besonders fuer neue Entwickler. Der alte &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt;-Befehl war ueberladen und versuchte, zu viele unzusammenhaengende Dinge zu tun.&lt;/p&gt;
&lt;p&gt;Hier ist das einfache Regelset fuer moderne Git-Nutzung:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Befehl&lt;/th&gt;
&lt;th&gt;Zweck&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Wechselt Branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Kehrt zum vorherigen Branch zurueck&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sollte NICHT fuer Branch-Wechsel verwendet werden (ausser der Strich-Abkuerzung)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;zusammenfassung&quot;&gt;Zusammenfassung&lt;/h2&gt;
&lt;p&gt;Wenn Sie diese acht Befehle beherrschen, werden Sie in fast jedem taeglichen Git-Workflow effektiv sein, ohne fortgeschrittenes Wissen zu benoetigen. Die wichtigste Erkenntnis ist, &lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt; fuer Branches zu verwenden und &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; nur fuer die Strich-Abkuerzung zu reservieren.&lt;/p&gt;
&lt;p&gt;Fuer alles andere - Rebasing, Cherry-Picking, Bisecting - koennen Sie es nachschlagen, wenn Sie es brauchen. Diese acht Befehle decken 95% von dem ab, was Sie jeden Tag tun werden.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[8 Comandi Git Comuni Che Userai Ogni Giorno: Switch, Checkout e Pull Rebase Spiegati]]></title><description><![CDATA[Impara gli 8 comandi Git che gli sviluppatori usano ogni giorno, incluso come usare git switch vs checkout e perche git pull --rebase mantiene la cronologia dei commit pulita per workflow piu fluidi.]]></description><link>https://vibecodingwithfred.com/it/blog/everyday-git-commands/</link><guid isPermaLink="false">https://vibecodingwithfred.com/it/blog/everyday-git-commands/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Fri, 05 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Git e potente, ma ha la reputazione di essere complicato. Include centinaia di comandi e flag, eppure la maggior parte degli sviluppatori si affida solo a un piccolo set di essi ogni giorno. Se impari gli otto comandi in questa guida, puoi lavorare con sicurezza in quasi ogni progetto Git senza dover memorizzare il resto.&lt;/p&gt;
&lt;h2 id=&quot;gli-8-comandi-essenziali&quot;&gt;Gli 8 Comandi Essenziali&lt;/h2&gt;
&lt;h3 id=&quot;1-git-status&quot;&gt;1. git status&lt;/h3&gt;
&lt;p&gt;Usa questo per controllare lo stato del tuo workspace. Mostra quali file sono cambiati, quali file sono in staging, su quale branch sei, e se il tuo branch e avanti o indietro rispetto al remote. Questo comando e la tua dashboard principale.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; status&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-git-add-&quot;&gt;2. git add .&lt;/h3&gt;
&lt;p&gt;Questo mette in staging le tue modifiche in modo che siano pronte per essere committate. Il punto significa &quot;aggiungi tutto quello che e cambiato&quot;. Puoi anche mettere in staging file individuali se preferisci essere piu selettivo.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Oppure metti in staging file specifici:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; src/index.js&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-git-commit--m-&quot;&gt;3. git commit -m &quot;&quot;&lt;/h3&gt;
&lt;p&gt;Un commit crea uno snapshot del tuo lavoro. Il messaggio dentro le virgolette dovrebbe descrivere perche la modifica e stata fatta. Buoni messaggi di commit risparmiano tempo dopo quando rivedi la cronologia o fai debug di problemi.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Add user authentication flow&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-git-pull---rebase&quot;&gt;4. git pull --rebase&lt;/h3&gt;
&lt;p&gt;Questo aggiorna il tuo branch locale con le ultime modifiche dal remote. Il flag &lt;code class=&quot;language-text&quot;&gt;--rebase&lt;/code&gt; mantiene la cronologia dei commit pulita riproducendo i tuoi commit sopra i commit upstream piu recenti. Questo evita commit di merge non necessari e riduce il rumore dei conflitti.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; pull &lt;span class=&quot;token parameter variable&quot;&gt;--rebase&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Perche rebase?&lt;/strong&gt; Senza di esso, ottieni commit di merge ogni volta che fai pull, riempiendo la tua cronologia con messaggi &quot;Merge branch &apos;main&apos; into main&quot;.&lt;/p&gt;
&lt;h3 id=&quot;5-git-push&quot;&gt;5. git push&lt;/h3&gt;
&lt;p&gt;Questo carica i tuoi commit su GitHub, GitLab o qualsiasi altro remote. Il push salva il tuo lavoro sul server, ne fa il backup e lo rende disponibile per pull request e collaborazione di team.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push
&lt;span class=&quot;token comment&quot;&gt;# Primo push su un nuovo branch:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin feature/my-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;6-git-switch-branch&quot;&gt;6. git switch &amp;#x3C;branch&gt;&lt;/h3&gt;
&lt;p&gt;Questo e il modo moderno per passare a un altro branch. E semplice, chiaro e non puo accidentalmente modificare i tuoi file.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Se il branch non esiste ancora, crealo con:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch &lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt; new-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;7-git-merge-branch&quot;&gt;7. git merge &amp;#x3C;branch&gt;&lt;/h3&gt;
&lt;p&gt;Questo unisce il branch specificato nel branch su cui sei attualmente. L&apos;ordine corretto e passare prima al branch che vuoi aggiornare, poi unire un altro branch in esso.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; merge feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;8-git-checkout--&quot;&gt;8. git checkout -&lt;/h3&gt;
&lt;p&gt;Questo ti riporta al branch precedente insieme al suo stato di lavoro. E una scorciatoia estremamente utile e uno dei soli usi moderni di &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; che e ancora raccomandato.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout -
&lt;span class=&quot;token comment&quot;&gt;# Equivalente a &quot;cd -&quot; per i branch&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;riferimento-rapido&quot;&gt;Riferimento Rapido&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Comando&lt;/th&gt;
&lt;th&gt;Cosa Fa&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Mostra stato workspace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git add .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Metti in staging tutte le modifiche&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git commit -m &quot;msg&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Crea un commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git pull --rebase&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Aggiorna dal remote (cronologia pulita)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Carica commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cambia branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git merge &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unisci branch nel corrente&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Torna al branch precedente&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;git-moderno-switch-vs-checkout&quot;&gt;Git Moderno: Switch vs Checkout&lt;/h2&gt;
&lt;p&gt;Da Git 2.23, le cose sono diventate ancora piu semplici. Git ha introdotto due nuovi comandi, &lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt; e &lt;code class=&quot;language-text&quot;&gt;git restore&lt;/code&gt;, per separare il cambio di branch dal ripristino dei file. Questo cambiamento rende chiaro l&apos;intento di ogni comando, specialmente per i nuovi sviluppatori. Il vecchio comando &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; era sovraccarico e cercava di fare troppe cose non correlate.&lt;/p&gt;
&lt;p&gt;Ecco il set di regole semplice per l&apos;uso moderno di Git:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Comando&lt;/th&gt;
&lt;th&gt;Scopo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cambia branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Torna al branch precedente&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;NON dovrebbe essere usato per cambiare branch (eccetto la scorciatoia con trattino)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;conclusione&quot;&gt;Conclusione&lt;/h2&gt;
&lt;p&gt;Se padroneggi questi otto comandi, sarai efficace in quasi ogni workflow Git quotidiano senza bisogno di conoscenze avanzate. L&apos;intuizione chiave e usare &lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt; per i branch e riservare &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; solo per la scorciatoia con trattino.&lt;/p&gt;
&lt;p&gt;Per tutto il resto - rebasing, cherry-picking, bisecting - puoi cercarlo quando ne hai bisogno. Questi otto comandi coprono il 95% di quello che farai ogni giorno.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[8 commandes Git courantes que vous utiliserez quotidiennement : Switch, Checkout et Pull Rebase expliques]]></title><description><![CDATA[Apprenez les 8 commandes Git que les developpeurs utilisent chaque jour, incluant comment utiliser git switch vs checkout et pourquoi git pull --rebase garde votre historique de commits propre pour des workflows plus fluides.]]></description><link>https://vibecodingwithfred.com/fr/blog/everyday-git-commands/</link><guid isPermaLink="false">https://vibecodingwithfred.com/fr/blog/everyday-git-commands/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Fri, 05 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Git est puissant, mais il a la reputation d&apos;etre complique. Il inclut des centaines de commandes et d&apos;options, pourtant la plupart des developpeurs ne s&apos;appuient que sur un petit ensemble d&apos;entre elles chaque jour. Si vous apprenez les huit commandes de ce guide, vous pouvez travailler en confiance dans presque n&apos;importe quel projet Git sans avoir besoin de memoriser le reste.&lt;/p&gt;
&lt;h2 id=&quot;les-8-commandes-essentielles&quot;&gt;Les 8 commandes essentielles&lt;/h2&gt;
&lt;h3 id=&quot;1-git-status&quot;&gt;1. git status&lt;/h3&gt;
&lt;p&gt;Utilisez ceci pour verifier l&apos;etat de votre espace de travail. Ca montre quels fichiers ont change, quels fichiers sont stages, sur quelle branche vous etes et si votre branche est en avance ou en retard par rapport au remote. Cette commande est votre tableau de bord principal.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; status&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-git-add-&quot;&gt;2. git add .&lt;/h3&gt;
&lt;p&gt;Ceci stage vos changements pour qu&apos;ils soient prets a etre commites. Le point signifie &quot;ajouter tout ce qui a change&quot;. Vous pouvez aussi stager des fichiers individuels si vous preferez etre plus selectif.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Ou stager des fichiers specifiques :&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; src/index.js&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-git-commit--m-&quot;&gt;3. git commit -m &quot;&quot;&lt;/h3&gt;
&lt;p&gt;Un commit cree un instantane de votre travail. Le message entre guillemets doit decrire pourquoi le changement a ete fait. De bons messages de commit font gagner du temps plus tard lors de la revue de l&apos;historique ou du debogage de problemes.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Add user authentication flow&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-git-pull---rebase&quot;&gt;4. git pull --rebase&lt;/h3&gt;
&lt;p&gt;Ceci met a jour votre branche locale avec les derniers changements du remote. L&apos;option &lt;code class=&quot;language-text&quot;&gt;--rebase&lt;/code&gt; garde votre historique de commits propre en rejouant vos commits au-dessus des commits upstream les plus recents. Cela evite les commits de merge inutiles et reduit le bruit des conflits.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; pull &lt;span class=&quot;token parameter variable&quot;&gt;--rebase&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Pourquoi rebase ?&lt;/strong&gt; Sans lui, vous obtenez des commits de merge a chaque fois que vous pull, encombrant votre historique avec des messages &quot;Merge branch &apos;main&apos; into main&quot;.&lt;/p&gt;
&lt;h3 id=&quot;5-git-push&quot;&gt;5. git push&lt;/h3&gt;
&lt;p&gt;Ceci telecharge vos commits vers GitHub, GitLab ou tout autre remote. Pusher sauvegarde votre travail sur le serveur, le sauvegarde et le rend disponible pour les pull requests et la collaboration d&apos;equipe.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push
&lt;span class=&quot;token comment&quot;&gt;# Premier push sur une nouvelle branche :&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin feature/my-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;6-git-switch-branch&quot;&gt;6. git switch &amp;#x3C;branch&gt;&lt;/h3&gt;
&lt;p&gt;C&apos;est la facon moderne de passer a une autre branche. C&apos;est simple, clair et ne peut pas accidentellement modifier vos fichiers.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Si la branche n&apos;existe pas encore, creez-la avec :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch &lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt; new-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;7-git-merge-branch&quot;&gt;7. git merge &amp;#x3C;branch&gt;&lt;/h3&gt;
&lt;p&gt;Ceci fusionne la branche specifiee dans la branche sur laquelle vous etes actuellement. L&apos;ordre correct est de d&apos;abord passer dans la branche que vous voulez mettre a jour, puis fusionner une autre branche dedans.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; merge feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;8-git-checkout--&quot;&gt;8. git checkout -&lt;/h3&gt;
&lt;p&gt;Ceci vous ramene a la branche precedente avec son etat de travail. C&apos;est un raccourci extremement utile et l&apos;une des seules utilisations modernes de &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; qui est encore recommandee.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout -
&lt;span class=&quot;token comment&quot;&gt;# Equivalent a &quot;cd -&quot; pour les branches&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;reference-rapide&quot;&gt;Reference rapide&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Commande&lt;/th&gt;
&lt;th&gt;Ce qu&apos;elle fait&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Montre l&apos;etat de l&apos;espace de travail&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git add .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stage tous les changements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git commit -m &quot;msg&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cree un commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git pull --rebase&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Met a jour depuis le remote (historique propre)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Telecharge les commits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Change de branche&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git merge &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fusionne une branche dans la courante&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Retourne a la branche precedente&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;git-moderne--switch-vs-checkout&quot;&gt;Git moderne : Switch vs Checkout&lt;/h2&gt;
&lt;p&gt;Depuis Git 2.23, les choses sont devenues encore plus simples. Git a introduit deux nouvelles commandes, &lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt; et &lt;code class=&quot;language-text&quot;&gt;git restore&lt;/code&gt;, pour separer le changement de branche de la restauration de fichiers. Ce changement rend l&apos;intention de chaque commande claire, surtout pour les nouveaux developpeurs. L&apos;ancienne commande &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; etait surchargee et essayait de faire trop de choses sans rapport.&lt;/p&gt;
&lt;p&gt;Voici l&apos;ensemble de regles simples pour l&apos;utilisation moderne de Git :&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Commande&lt;/th&gt;
&lt;th&gt;Objectif&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Change de branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Retourne a la branche precedente&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ne devrait PAS etre utilise pour changer de branches (sauf le raccourci tiret)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Si vous maitrisez ces huit commandes, vous serez efficace dans presque tous les workflows Git quotidiens sans avoir besoin de connaissances avancees. L&apos;idee cle est d&apos;utiliser &lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt; pour les branches et de reserver &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; uniquement pour le raccourci tiret.&lt;/p&gt;
&lt;p&gt;Pour tout le reste - rebasing, cherry-picking, bisecting - vous pouvez le chercher quand vous en avez besoin. Ces huit commandes couvrent 95% de ce que vous ferez chaque jour.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[毎日使う8つのGitコマンド：Switch、Checkout、Pull Rebaseを解説]]></title><description><![CDATA[開発者が毎日使う8つのGitコマンドを学びましょう。git switchとcheckoutの使い分け、git pull --rebaseがコミット履歴をクリーンに保つ理由も解説します。]]></description><link>https://vibecodingwithfred.com/ja/blog/everyday-git-commands/</link><guid isPermaLink="false">https://vibecodingwithfred.com/ja/blog/everyday-git-commands/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Fri, 05 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Gitは強力ですが、複雑だという評判があります。数百のコマンドやフラグがありますが、ほとんどの開発者は毎日ごく一部しか使いません。このガイドの8つのコマンドを学べば、残りを暗記する必要なく、ほぼすべてのGitプロジェクトで自信を持って作業できます。&lt;/p&gt;
&lt;h2 id=&quot;8つの必須コマンド&quot;&gt;8つの必須コマンド&lt;/h2&gt;
&lt;h3 id=&quot;1-git-status&quot;&gt;1. git status&lt;/h3&gt;
&lt;p&gt;ワークスペースの状態を確認するために使います。どのファイルが変更されたか、どのファイルがステージングされているか、どのブランチにいるか、ブランチがリモートより先か後ろかを表示します。このコマンドがメインのダッシュボードです。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; status&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-git-add-&quot;&gt;2. git add .&lt;/h3&gt;
&lt;p&gt;変更をステージングしてコミット準備完了にします。ドットは「変更されたすべてを追加」を意味します。より選択的にしたい場合は個別のファイルをステージングすることもできます。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# または特定のファイルをステージング：&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; src/index.js&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-git-commit--m-&quot;&gt;3. git commit -m &quot;&quot;&lt;/h3&gt;
&lt;p&gt;コミットは作業のスナップショットを作成します。引用符内のメッセージは変更が行われた理由を説明する必要があります。良いコミットメッセージは、後で履歴をレビューしたり問題をデバッグしたりするときに時間を節約します。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Add user authentication flow&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-git-pull---rebase&quot;&gt;4. git pull --rebase&lt;/h3&gt;
&lt;p&gt;リモートからの最新の変更でローカルブランチを更新します。&lt;code class=&quot;language-text&quot;&gt;--rebase&lt;/code&gt;フラグは、最新のアップストリームコミットの上にコミットをリプレイすることで、コミット履歴をクリーンに保ちます。これにより不要なマージコミットが避けられ、コンフリクトのノイズが減ります。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; pull &lt;span class=&quot;token parameter variable&quot;&gt;--rebase&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;なぜrebaseなのか？&lt;/strong&gt; これがないと、プルするたびにマージコミットが発生し、「Merge branch &apos;main&apos; into main」というメッセージで履歴が散らかります。&lt;/p&gt;
&lt;h3 id=&quot;5-git-push&quot;&gt;5. git push&lt;/h3&gt;
&lt;p&gt;コミットをGitHub、GitLab、または他のリモートにアップロードします。プッシュすると作業がサーバーに保存され、バックアップされ、プルリクエストやチームコラボレーションで利用可能になります。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push
&lt;span class=&quot;token comment&quot;&gt;# 新しいブランチでの最初のプッシュ：&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin feature/my-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;6-git-switch-branch&quot;&gt;6. git switch &amp;#x3C;branch&gt;&lt;/h3&gt;
&lt;p&gt;別のブランチに切り替える現代的な方法です。シンプルで明確で、誤ってファイルを変更することがありません。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ブランチがまだ存在しない場合は、以下で作成します：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch &lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt; new-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;7-git-merge-branch&quot;&gt;7. git merge &amp;#x3C;branch&gt;&lt;/h3&gt;
&lt;p&gt;指定されたブランチを現在のブランチにマージします。正しい順序は、まず更新したいブランチに切り替えてから、別のブランチをマージすることです。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; merge feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;8-git-checkout--&quot;&gt;8. git checkout -&lt;/h3&gt;
&lt;p&gt;作業状態とともに前のブランチに戻ります。非常に便利なショートカットで、まだ推奨される&lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt;の数少ない現代的な使用法の一つです。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout -
&lt;span class=&quot;token comment&quot;&gt;# ブランチ用の &quot;cd -&quot; と同等&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;クイックリファレンス&quot;&gt;クイックリファレンス&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;コマンド&lt;/th&gt;
&lt;th&gt;機能&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ワークスペースの状態を表示&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git add .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;すべての変更をステージング&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git commit -m &quot;msg&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;コミットを作成&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git pull --rebase&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;リモートから更新（クリーンな履歴）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;コミットをアップロード&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ブランチを変更&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git merge &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ブランチを現在にマージ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;前のブランチに戻る&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;モダンなgitswitch-vs-checkout&quot;&gt;モダンなGit：Switch vs Checkout&lt;/h2&gt;
&lt;p&gt;Git 2.23以降、さらにシンプルになりました。Gitはブランチの切り替えとファイルの復元を分離するために、&lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt;と&lt;code class=&quot;language-text&quot;&gt;git restore&lt;/code&gt;という2つの新しいコマンドを導入しました。この変更により、特に新しい開発者にとって各コマンドの意図が明確になります。古い&lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt;コマンドはオーバーロードされており、無関係なことをあまりにも多く行おうとしていました。&lt;/p&gt;
&lt;p&gt;モダンなGit使用のシンプルなルールセットは以下の通りです：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;コマンド&lt;/th&gt;
&lt;th&gt;目的&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ブランチを変更&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;前のブランチに戻る&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ブランチの切り替えには使用すべきでない（ダッシュショートカットを除く）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;まとめ&quot;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;これらの8つのコマンドをマスターすれば、高度な知識がなくてもほぼすべての日常的なGitワークフローで効果的に作業できます。重要な洞察は、ブランチには&lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt;を使用し、&lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt;はダッシュショートカットのみに予約することです。&lt;/p&gt;
&lt;p&gt;それ以外のこと—リベース、チェリーピック、バイセクト—は必要なときに調べればいいのです。これらの8つのコマンドは、毎日行うことの95%をカバーします。&lt;/p&gt;</content:encoded></item><item><title><![CDATA[매일 사용하게 될 8가지 핵심 Git 명령어: Switch, Checkout, Pull Rebase 완벽 가이드]]></title><description><![CDATA[개발자들이 매일 사용하는 8가지 Git 명령어를 배워보세요. git switch vs checkout 사용법과 git pull --rebase가 커밋 히스토리를 깔끔하게 유지하는 이유를 설명합니다.]]></description><link>https://vibecodingwithfred.com/ko/blog/everyday-git-commands/</link><guid isPermaLink="false">https://vibecodingwithfred.com/ko/blog/everyday-git-commands/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Fri, 05 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Git은 강력하지만 복잡하다는 평판이 있습니다. 수백 개의 명령어와 플래그가 있지만, 대부분의 개발자는 매일 소수의 명령어만 사용합니다. 이 가이드의 8가지 명령어를 배우면 나머지를 외우지 않고도 거의 모든 Git 프로젝트에서 자신 있게 작업할 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;8가지-필수-명령어&quot;&gt;8가지 필수 명령어&lt;/h2&gt;
&lt;h3 id=&quot;1-git-status&quot;&gt;1. git status&lt;/h3&gt;
&lt;p&gt;작업 영역의 상태를 확인하는 데 사용합니다. 어떤 파일이 변경되었는지, 어떤 파일이 스테이징되었는지, 어떤 브랜치에 있는지, 브랜치가 리모트보다 앞서 있는지 뒤처져 있는지 보여줍니다. 이 명령어는 메인 대시보드입니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; status&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-git-add-&quot;&gt;2. git add .&lt;/h3&gt;
&lt;p&gt;변경 사항을 스테이징하여 커밋할 준비를 합니다. 점은 &quot;변경된 모든 것을 추가&quot;를 의미합니다. 더 선택적으로 하고 싶다면 개별 파일을 스테이징할 수도 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# 또는 특정 파일 스테이징:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; src/index.js&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-git-commit--m-&quot;&gt;3. git commit -m &quot;&quot;&lt;/h3&gt;
&lt;p&gt;커밋은 작업의 스냅샷을 만듭니다. 따옴표 안의 메시지는 변경이 왜 이루어졌는지 설명해야 합니다. 좋은 커밋 메시지는 나중에 히스토리를 검토하거나 문제를 디버깅할 때 시간을 절약합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Add user authentication flow&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-git-pull---rebase&quot;&gt;4. git pull --rebase&lt;/h3&gt;
&lt;p&gt;리모트에서 최신 변경 사항으로 로컬 브랜치를 업데이트합니다. &lt;code class=&quot;language-text&quot;&gt;--rebase&lt;/code&gt; 플래그는 최신 업스트림 커밋 위에 커밋을 다시 적용하여 커밋 히스토리를 깔끔하게 유지합니다. 이렇게 하면 불필요한 머지 커밋을 피하고 충돌 노이즈를 줄입니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; pull &lt;span class=&quot;token parameter variable&quot;&gt;--rebase&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;왜 rebase인가?&lt;/strong&gt; 이것 없이는 pull할 때마다 머지 커밋이 생겨 히스토리가 &quot;Merge branch &apos;main&apos; into main&quot; 메시지로 어수선해집니다.&lt;/p&gt;
&lt;h3 id=&quot;5-git-push&quot;&gt;5. git push&lt;/h3&gt;
&lt;p&gt;커밋을 GitHub, GitLab 또는 다른 리모트에 업로드합니다. Push는 작업을 서버에 저장하고 백업하며 풀 리퀘스트와 팀 협업에 사용할 수 있게 합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push
&lt;span class=&quot;token comment&quot;&gt;# 새 브랜치의 첫 push:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin feature/my-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;6-git-switch-branch&quot;&gt;6. git switch &amp;#x3C;branch&gt;&lt;/h3&gt;
&lt;p&gt;다른 브랜치로 전환하는 현대적인 방법입니다. 간단하고 명확하며 실수로 파일을 수정할 수 없습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;브랜치가 아직 없다면 다음으로 생성합니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch &lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt; new-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;7-git-merge-branch&quot;&gt;7. git merge &amp;#x3C;branch&gt;&lt;/h3&gt;
&lt;p&gt;지정된 브랜치를 현재 있는 브랜치로 병합합니다. 올바른 순서는 먼저 업데이트하려는 브랜치로 전환한 다음 다른 브랜치를 병합하는 것입니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; merge feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;8-git-checkout--&quot;&gt;8. git checkout -&lt;/h3&gt;
&lt;p&gt;작업 상태와 함께 이전 브랜치로 돌아갑니다. 매우 유용한 단축키이며 여전히 권장되는 &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt;의 유일한 현대적 사용법 중 하나입니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout -
&lt;span class=&quot;token comment&quot;&gt;# 브랜치의 &quot;cd -&quot;와 동일&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;빠른-참조&quot;&gt;빠른 참조&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;명령어&lt;/th&gt;
&lt;th&gt;하는 일&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;작업 영역 상태 표시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git add .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;모든 변경 사항 스테이징&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git commit -m &quot;msg&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;커밋 생성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git pull --rebase&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;리모트에서 업데이트 (깔끔한 히스토리)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;커밋 업로드&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;브랜치 변경&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git merge &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;브랜치를 현재로 병합&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;이전 브랜치로 돌아가기&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;현대-git-switch-vs-checkout&quot;&gt;현대 Git: Switch vs Checkout&lt;/h2&gt;
&lt;p&gt;Git 2.23부터 상황이 더 간단해졌습니다. Git은 브랜치 전환과 파일 복원을 분리하기 위해 &lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt;와 &lt;code class=&quot;language-text&quot;&gt;git restore&lt;/code&gt;라는 두 가지 새 명령어를 도입했습니다. 이 변경으로 각 명령어의 의도가 명확해졌으며, 특히 새로운 개발자에게 유용합니다. 이전의 &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; 명령어는 과부하되어 관련 없는 여러 작업을 수행하려 했습니다.&lt;/p&gt;
&lt;p&gt;다음은 현대 Git 사용을 위한 간단한 규칙 세트입니다:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;명령어&lt;/th&gt;
&lt;th&gt;목적&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;브랜치 변경&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;이전 브랜치로 돌아가기&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;브랜치 전환에 사용해서는 안 됨 (대시 단축키 제외)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;마무리&quot;&gt;마무리&lt;/h2&gt;
&lt;p&gt;이 8가지 명령어를 마스터하면 고급 지식 없이도 거의 모든 일상적인 Git 워크플로우에서 효과적으로 작업할 수 있습니다. 핵심 통찰은 브랜치에는 &lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt;를 사용하고 &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt;은 대시 단축키에만 사용하는 것입니다.&lt;/p&gt;
&lt;p&gt;그 외의 모든 것—리베이싱, 체리피킹, 바이섹팅—은 필요할 때 찾아볼 수 있습니다. 이 8가지 명령어가 매일 하는 일의 95%를 커버합니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[8 Veelgebruikte Git Commando's Die Je Dagelijks Zult Gebruiken: Switch, Checkout en Pull Rebase Uitgelegd]]></title><description><![CDATA[Leer de 8 Git commando's die ontwikkelaars elke dag gebruiken, inclusief hoe je git switch vs checkout gebruikt en waarom git pull --rebase je commit-geschiedenis schoon houdt voor soepelere workflows.]]></description><link>https://vibecodingwithfred.com/nl/blog/everyday-git-commands/</link><guid isPermaLink="false">https://vibecodingwithfred.com/nl/blog/everyday-git-commands/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Fri, 05 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Git is krachtig, maar het heeft de reputatie ingewikkeld te zijn. Het bevat honderden commando&apos;s en flags, maar de meeste ontwikkelaars vertrouwen dagelijks slechts op een kleine set. Als je de acht commando&apos;s in deze handleiding leert, kun je met vertrouwen werken in bijna elk Git-project zonder de rest te hoeven onthouden.&lt;/p&gt;
&lt;h2 id=&quot;de-8-essentiele-commandos&quot;&gt;De 8 Essentiële Commando&apos;s&lt;/h2&gt;
&lt;h3 id=&quot;1-git-status&quot;&gt;1. git status&lt;/h3&gt;
&lt;p&gt;Gebruik dit om de staat van je werkruimte te controleren. Het toont welke bestanden zijn gewijzigd, welke bestanden zijn gestaged, op welke branch je zit en of je branch voor of achter de remote loopt. Dit commando is je hoofddashboard.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; status&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-git-add-&quot;&gt;2. git add .&lt;/h3&gt;
&lt;p&gt;Dit staged je wijzigingen zodat ze klaar zijn om te worden gecommit. De punt betekent &quot;voeg alles toe dat is gewijzigd&quot;. Je kunt ook individuele bestanden stagen als je selectiever wilt zijn.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Of stage specifieke bestanden:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; src/index.js&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-git-commit--m-&quot;&gt;3. git commit -m &quot;&quot;&lt;/h3&gt;
&lt;p&gt;Een commit maakt een snapshot van je werk. Het bericht tussen de aanhalingstekens moet beschrijven waarom de wijziging is gemaakt. Goede commit-berichten besparen later tijd bij het reviewen van geschiedenis of het debuggen van problemen.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Voeg gebruikersauthenticatie flow toe&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-git-pull---rebase&quot;&gt;4. git pull --rebase&lt;/h3&gt;
&lt;p&gt;Dit werkt je lokale branch bij met de laatste wijzigingen van de remote. De &lt;code class=&quot;language-text&quot;&gt;--rebase&lt;/code&gt; flag houdt je commit-geschiedenis schoon door je commits opnieuw af te spelen bovenop de nieuwste upstream commits. Dit vermijdt onnodige merge commits en vermindert conflictruis.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; pull &lt;span class=&quot;token parameter variable&quot;&gt;--rebase&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Waarom rebase?&lt;/strong&gt; Zonder krijg je elke keer dat je pullt merge commits, waardoor je geschiedenis vol komt te staan met &quot;Merge branch &apos;main&apos; into main&quot; berichten.&lt;/p&gt;
&lt;h3 id=&quot;5-git-push&quot;&gt;5. git push&lt;/h3&gt;
&lt;p&gt;Dit uploadt je commits naar GitHub, GitLab of een andere remote. Pushen slaat je werk op naar de server, maakt een backup en maakt het beschikbaar voor pull requests en teamsamenwerking.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push
&lt;span class=&quot;token comment&quot;&gt;# Eerste push op een nieuwe branch:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin feature/my-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;6-git-switch-branch&quot;&gt;6. git switch &amp;#x3C;branch&gt;&lt;/h3&gt;
&lt;p&gt;Dit is de moderne manier om naar een andere branch te wisselen. Het is simpel, duidelijk en kan niet per ongeluk je bestanden wijzigen.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Als de branch nog niet bestaat, maak hem aan met:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch &lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt; new-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;7-git-merge-branch&quot;&gt;7. git merge &amp;#x3C;branch&gt;&lt;/h3&gt;
&lt;p&gt;Dit merged de opgegeven branch in de branch waar je momenteel op zit. De juiste volgorde is om eerst te wisselen naar de branch die je wilt bijwerken, en dan een andere branch erin te mergen.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; merge feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;8-git-checkout--&quot;&gt;8. git checkout -&lt;/h3&gt;
&lt;p&gt;Dit brengt je terug naar de vorige branch samen met de werkstaat ervan. Het is een extreem nuttige sneltoets en een van de enige moderne toepassingen van &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; die nog steeds wordt aanbevolen.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout -
&lt;span class=&quot;token comment&quot;&gt;# Equivalent aan &quot;cd -&quot; voor branches&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;snelle-referentie&quot;&gt;Snelle Referentie&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Commando&lt;/th&gt;
&lt;th&gt;Wat Het Doet&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Toon werkruimtestaat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git add .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stage alle wijzigingen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git commit -m &quot;msg&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Maak een commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git pull --rebase&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Update van remote (schone geschiedenis)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Upload commits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Wissel van branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git merge &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Merge branch in huidige&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Keer terug naar vorige branch&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;modern-git-switch-vs-checkout&quot;&gt;Modern Git: Switch vs Checkout&lt;/h2&gt;
&lt;p&gt;Sinds Git 2.23 zijn de dingen nog eenvoudiger geworden. Git introduceerde twee nieuwe commando&apos;s, &lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt; en &lt;code class=&quot;language-text&quot;&gt;git restore&lt;/code&gt;, om branch-wisselen te scheiden van bestandsherstel. Deze verandering maakt de intentie van elk commando duidelijk, vooral voor nieuwe ontwikkelaars. Het oude &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; commando was overbelast en probeerde te veel ongerelateerde dingen te doen.&lt;/p&gt;
&lt;p&gt;Hier is de simpele regelset voor modern Git-gebruik:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Commando&lt;/th&gt;
&lt;th&gt;Doel&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Wisselt van branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Keert terug naar vorige branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Moet NIET worden gebruikt voor branch-wisselen (behalve de streepje-sneltoets)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;afronden&quot;&gt;Afronden&lt;/h2&gt;
&lt;p&gt;Als je deze acht commando&apos;s beheerst, zul je effectief zijn in bijna elke dagelijkse Git-workflow zonder geavanceerde kennis nodig te hebben. Het belangrijkste inzicht is &lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt; gebruiken voor branches en &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; alleen reserveren voor de streepje-sneltoets.&lt;/p&gt;
&lt;p&gt;Voor al het andere—rebasing, cherry-picking, bisecting—kun je het opzoeken wanneer je het nodig hebt. Deze acht commando&apos;s dekken 95% van wat je elke dag zult doen.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[10 sposobow na przeniesienie strony Lovable na darmowy hosting]]></title><description><![CDATA[Postepuj krok po kroku zeby wyeksportowac projekt Lovable i przeniesc strone na darmowe platformy hostingowe w tym Cloudflare Pages, Vercel i Firebase z minimalnym przestojem.]]></description><link>https://vibecodingwithfred.com/pl/blog/3-ways-to-move-lovable-website/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pl/blog/3-ways-to-move-lovable-website/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Fri, 05 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;10-sposobow-na-przeniesienie-strony-lovable-na-darmowy-hosting&quot;&gt;10 sposobow na przeniesienie strony Lovable na darmowy hosting&lt;/h2&gt;
&lt;p&gt;Jesli zbudowales strone uzywajac platformy Lovable AI, mozesz szukac alternatyw dla hostingu Lovable - szczegolnie biorac pod uwage ostatnie problemy z Lovable 2.0. Niezaleznie czy chcesz migrowac z powodu obaw o niezawodnosc, potrzebujesz wiekszej kontroli nad wdrozeniem czy po prostu chcesz poznac inne opcje, ten kompletny przewodnik pokazuje jak przeniesc projekt Lovable na platformy hostingowe klasy enterprise - wszystko za darmo.&lt;/p&gt;
&lt;h2 id=&quot;jak-wyeksportowac-projekt-lovable&quot;&gt;Jak wyeksportowac projekt Lovable&lt;/h2&gt;
&lt;p&gt;Zanim bedziesz mogl migrowac na jakakolwiek platforme hostingowa, musisz wyeksportowac projekt Lovable:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Otworz projekt Lovable&lt;/strong&gt; w dashboardzie Lovable&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Przejdz do ustawien projektu&lt;/strong&gt; (ikona zebatki lub menu)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Szukaj opcji &quot;Export&quot; lub &quot;Download&quot;&lt;/strong&gt; w menu projektu&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wybierz &quot;Download as ZIP&quot;&lt;/strong&gt; zeby pobrac wszystkie pliki projektu&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rozpakuj plik ZIP&lt;/strong&gt; do lokalnego folderu na komputerze&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;co-jest-wlaczone-w-eksporcie&quot;&gt;Co jest wlaczone w eksporcie&lt;/h3&gt;
&lt;p&gt;Gdy eksportujesz projekt Lovable, zwykle otrzymujesz:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Kod zrodlowy&lt;/strong&gt;: pliki React/TypeScript ze wszystkimi komponentami&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pliki konfiguracyjne&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;vite.config.js&lt;/code&gt;, itp.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zasoby statyczne&lt;/strong&gt;: obrazy, czcionki i inne media&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stylizacja&lt;/strong&gt;: pliki CSS lub konfiguracja Tailwind&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lista zaleznosci&lt;/strong&gt;: wszystko potrzebne do przebudowania projektu&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;10-darmowych-alternatyw-hostingu-lovable&quot;&gt;10 darmowych alternatyw hostingu Lovable&lt;/h2&gt;
&lt;h3 id=&quot;opcja-1-cloudflare-workers&quot;&gt;Opcja 1: Cloudflare Workers&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;100 000 zapytan dziennie&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nieograniczony transfer&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Globalne czasy odpowiedzi ponizej milisekundy&lt;/li&gt;
&lt;li&gt;Wlasne domeny z darmowym SSL&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;opcja-2-firebase-hosting&quot;&gt;Opcja 2: Firebase Hosting&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;10GB storage&lt;/li&gt;
&lt;li&gt;360MB/dzien transferu danych&lt;/li&gt;
&lt;li&gt;Wlasne domeny z darmowym SSL&lt;/li&gt;
&lt;li&gt;Latwa integracja z innymi uslugami Firebase&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;opcja-3-vercel&quot;&gt;Opcja 3: Vercel&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Nieograniczone statyczne strony&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;100GB transferu miesiecznie&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Wlasne domeny z darmowym SSL&lt;/li&gt;
&lt;li&gt;Preview deployments dla kazdej galezi Git&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;opcja-4-netlify&quot;&gt;Opcja 4: Netlify&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;100GB transferu miesiecznie&lt;/li&gt;
&lt;li&gt;20 buildow miesiecznie (system oparty na kredytach od wrzesnia 2025)&lt;/li&gt;
&lt;li&gt;Nieograniczone osobiste i komercyjne projekty&lt;/li&gt;
&lt;li&gt;Automatyczne HTTPS z wlasnymi domenami&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;opcja-5-github-pages&quot;&gt;Opcja 5: GitHub Pages&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;1GB storage&lt;/li&gt;
&lt;li&gt;100GB transferu miesiecznie&lt;/li&gt;
&lt;li&gt;Darmowa subdomena &lt;code class=&quot;language-text&quot;&gt;username.github.io&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Wlasne domeny z HTTPS&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;opcja-6-render&quot;&gt;Opcja 6: Render&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Nieograniczone statyczne strony&lt;/li&gt;
&lt;li&gt;100GB transferu miesiecznie&lt;/li&gt;
&lt;li&gt;Globalne CDN&lt;/li&gt;
&lt;li&gt;Automatyczne HTTPS&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;opcja-7-railway&quot;&gt;Opcja 7: Railway&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Jednorazowy kredyt testowy 5$ (wygasa po 30 dniach)&lt;/li&gt;
&lt;li&gt;Jednym kliknieciem PostgreSQL, MySQL, Redis&lt;/li&gt;
&lt;li&gt;Automatyczne HTTPS&lt;/li&gt;
&lt;li&gt;Preview deployments&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;opcja-8-flyio&quot;&gt;Opcja 8: Fly.io&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Wazne:&lt;/strong&gt; Fly.io zaprzestal darmowego tieru dla nowych uzytkownikow. Rozwaz Cloudflare Workers lub Render zamiast tego.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;opcja-9-aws-amplify&quot;&gt;Opcja 9: AWS Amplify&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;1000 minut budowania miesiecznie&lt;/li&gt;
&lt;li&gt;1GB serwowane miesiecznie&lt;/li&gt;
&lt;li&gt;5GB storage&lt;/li&gt;
&lt;li&gt;Wlasne domeny z HTTPS&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;opcja-10-digitalocean-app-platform&quot;&gt;Opcja 10: DigitalOcean App Platform&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;3 statyczne strony&lt;/li&gt;
&lt;li&gt;1GB wychodzacego transferu na aplikacje/miesiac&lt;/li&gt;
&lt;li&gt;Automatyczne HTTPS&lt;/li&gt;
&lt;li&gt;Wlasne domeny&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;porownanie-wszystkich-10-opcji&quot;&gt;Porownanie wszystkich 10 opcji&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platforma&lt;/th&gt;
&lt;th&gt;Najlepsza dla&lt;/th&gt;
&lt;th&gt;Darmowy transfer&lt;/th&gt;
&lt;th&gt;Wlasna domena&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cloudflare Workers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Edge computing&lt;/td&gt;
&lt;td&gt;Nieograniczony&lt;/td&gt;
&lt;td&gt;Tak&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Firebase Hosting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ekosystem Firebase&lt;/td&gt;
&lt;td&gt;360MB/dzien&lt;/td&gt;
&lt;td&gt;Tak&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vercel&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Najlepsze DX, Next.js&lt;/td&gt;
&lt;td&gt;100GB/miesiac&lt;/td&gt;
&lt;td&gt;Tak&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Netlify&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Natychmiastowe wdrozenia&lt;/td&gt;
&lt;td&gt;100GB/miesiac&lt;/td&gt;
&lt;td&gt;Tak&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub Pages&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Proste strony&lt;/td&gt;
&lt;td&gt;100GB/miesiac&lt;/td&gt;
&lt;td&gt;Tak&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Render&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Nowoczesne aplikacje&lt;/td&gt;
&lt;td&gt;100GB/miesiac&lt;/td&gt;
&lt;td&gt;Tak&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Railway&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Potrzeby backendowe&lt;/td&gt;
&lt;td&gt;Tylko trial&lt;/td&gt;
&lt;td&gt;Tak&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Fly.io&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Globalny edge&lt;/td&gt;
&lt;td&gt;Tylko legacy&lt;/td&gt;
&lt;td&gt;Tak&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AWS Amplify&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ekosystem AWS&lt;/td&gt;
&lt;td&gt;1GB/miesiac&lt;/td&gt;
&lt;td&gt;Tak&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DigitalOcean&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Uzytkownicy DO&lt;/td&gt;
&lt;td&gt;1GB/aplikacje&lt;/td&gt;
&lt;td&gt;Tak&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;ktora-platforme-wybrac&quot;&gt;Ktora platforme wybrac?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Wybierz Cloudflare Workers jesli&lt;/strong&gt;: Chcesz nieograniczonego transferu i prawdziwego edge computing z 100 000 darmowych zapytan dziennie.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wybierz Firebase jesli&lt;/strong&gt;: Potrzebujesz glebokiej integracji z Firebase Auth, Firestore lub innymi uslugami Google.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wybierz Vercel jesli&lt;/strong&gt;: Chcesz najlatwiejszej konfiguracji z najlepszym doswiadczeniem developerskim - idealne dla poczatkujacych.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wybierz Netlify jesli&lt;/strong&gt;: Chcesz natychmiastowych wdrozen, rollbackow i wbudowanej obslugi formularzy.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wybierz GitHub Pages jesli&lt;/strong&gt;: Twoj kod jest juz na GitHub i chcesz hostingu bez konfiguracji.&lt;/p&gt;
&lt;h2 id=&quot;migracja-bez-przestoju&quot;&gt;Migracja bez przestoju&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Najpierw wdroz na nowy hosting&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Skonfiguruj strone na Cloudflare/Vercel/Firebase calkowicie&lt;/li&gt;
&lt;li&gt;Dokładnie przetestuj uzywajac tymczasowego URL&lt;/li&gt;
&lt;li&gt;Jeszcze nie zmieniaj DNS&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Zmniejsz TTL&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Zmniejsz TTL do 300 sekund (5 minut)&lt;/li&gt;
&lt;li&gt;Poczekaj 24-48 godzin na propagacje&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Przelaczenie (zajmuje 2-5 minut)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Zaktualizuj rekordy DNS u rejestratora&lt;/li&gt;
&lt;li&gt;Zmien ze starego hostingu na nowe IP/CNAME&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Monitoruj propagacje&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Uzyj whatsmydns.net do sprawdzenia globalnej propagacji&lt;/li&gt;
&lt;li&gt;Pelna globalna propagacja zajmuje 24-48 godzin&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;podsumowanie&quot;&gt;Podsumowanie&lt;/h2&gt;
&lt;p&gt;Przeniesienie strony Lovable z hostingu Lovable na dedykowana platforme daje wiecej kontroli, lepsza wydajnosc i ochrone przed problemami specyficznymi dla platformy.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Moje rekomendacje (zaktualizowane grudzien 2025):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Najlatwiejsza konfiguracja:&lt;/strong&gt; Vercel lub Netlify&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Najlepsza wydajnosc:&lt;/strong&gt; Cloudflare Workers (100 000 darmowych zapytan dziennie)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Potrzeby backendowe:&lt;/strong&gt; Railway (trial) lub Firebase&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ekosystem AWS:&lt;/strong&gt; AWS Amplify&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Uzytkownicy GitHub:&lt;/strong&gt; GitHub Pages&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Wazne zmiany w 2025:&lt;/strong&gt; Fly.io nie oferuje juz darmowego tieru dla nowych uzytkownikow. Railway zmienil na jednorazowy kredyt testowy 5$. Dla najlepszego prawdziwie darmowego hostingu trzymaj sie &lt;strong&gt;Cloudflare Workers&lt;/strong&gt;, &lt;strong&gt;Vercel&lt;/strong&gt;, &lt;strong&gt;Netlify&lt;/strong&gt; lub &lt;strong&gt;Render&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[8 typowych polecen Git ktorych uzywasz codziennie: Switch, Checkout i Pull Rebase wyjasnione]]></title><description><![CDATA[Poznaj 8 polecen Git ktorych programisci uzywaja kazdego dnia, w tym jak uzywac git switch vs checkout i dlaczego git pull --rebase utrzymuje historie commitow czysta dla plynniejszych workflow.]]></description><link>https://vibecodingwithfred.com/pl/blog/everyday-git-commands/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pl/blog/everyday-git-commands/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Fri, 05 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Git jest potezny, ale ma reputacje skomplikowanego narzedzia. Zawiera setki polecen i flag, ale wiekszosc programistow polega tylko na malym ich zestawie kazdego dnia. Jesli nauczysz sie osmiu polecen z tego przewodnika, mozesz pewnie pracowac w prawie kazdym projekcie Git bez koniecznosci zapamietywania reszty.&lt;/p&gt;
&lt;h2 id=&quot;8-niezbednych-polecen&quot;&gt;8 niezbednych polecen&lt;/h2&gt;
&lt;h3 id=&quot;1-git-status&quot;&gt;1. git status&lt;/h3&gt;
&lt;p&gt;Uzywaj tego do sprawdzania stanu workspace. Pokazuje ktore pliki sie zmienily, ktore pliki sa staged, na ktorej jestes galezi i czy twoja galaz jest do przodu czy do tylu wzgledem remote. To polecenie to twoj glowny dashboard.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; status&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-git-add-&quot;&gt;2. git add .&lt;/h3&gt;
&lt;p&gt;To staguje twoje zmiany zeby byly gotowe do commitowania. Kropka oznacza &quot;dodaj wszystko co sie zmienilo&quot;. Mozesz tez stagowac pojedyncze pliki jesli wolisz byc bardziej selektywny.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Lub staguj konkretne pliki:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; src/index.js&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-git-commit--m-&quot;&gt;3. git commit -m &quot;&quot;&lt;/h3&gt;
&lt;p&gt;Commit tworzy snapshot twojej pracy. Wiadomosc w cudzyslowach powinna opisywac dlaczego zmiana zostala wprowadzona. Dobre wiadomosci commitow oszczedzaja czas pozniej przy przegladaniu historii lub debugowaniu problemow.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Add user authentication flow&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-git-pull---rebase&quot;&gt;4. git pull --rebase&lt;/h3&gt;
&lt;p&gt;To aktualizuje twoja lokalna galaz najnowszymi zmianami z remote. Flaga &lt;code class=&quot;language-text&quot;&gt;--rebase&lt;/code&gt; utrzymuje historie commitow czysta przez ponowne odtworzenie twoich commitow na szczycie najnowszych commitow upstream. To unika niepotrzebnych merge commitow i redukuje szum konfliktow.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; pull &lt;span class=&quot;token parameter variable&quot;&gt;--rebase&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Dlaczego rebase?&lt;/strong&gt; Bez tego dostajesz merge commity za kazdym razem gdy robisz pull, zasmiecajac historie wiadomosciami &quot;Merge branch &apos;main&apos; into main&quot;.&lt;/p&gt;
&lt;h3 id=&quot;5-git-push&quot;&gt;5. git push&lt;/h3&gt;
&lt;p&gt;To uploaduje twoje commity na GitHub, GitLab lub kazde inne remote. Pushowanie zapisuje twoja prace na serwerze, tworzy jej backup i udostepnia ja dla pull requestow i wspolpracy zespolowej.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push
&lt;span class=&quot;token comment&quot;&gt;# Pierwszy push na nowej galezi:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin feature/my-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;6-git-switch-branch&quot;&gt;6. git switch &lt;branch&gt;&lt;/h3&gt;
&lt;p&gt;To nowoczesny sposob na przelaczanie na inna galaz. Jest prosty, jasny i nie moze przypadkowo zmodyfikowac twoich plikow.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Jesli galaz jeszcze nie istnieje, utworz ja:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch &lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt; new-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;7-git-merge-branch&quot;&gt;7. git merge &lt;branch&gt;&lt;/h3&gt;
&lt;p&gt;To laczy okreslona galaz z galazia na ktorej obecnie jestes. Poprawna kolejnosc to najpierw przelacz sie na galaz ktora chcesz zaktualizowac, potem merge inna galaz do niej.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; merge feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;8-git-checkout--&quot;&gt;8. git checkout -&lt;/h3&gt;
&lt;p&gt;To zwraca cie do poprzedniej galezi wraz z jej stanem roboczym. To niezwykle uzyteczny skrot i jedno z niewielu nowoczesnych uzyc &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; ktore jest nadal zalecane.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout -
&lt;span class=&quot;token comment&quot;&gt;# Odpowiednik &quot;cd -&quot; dla galezi&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;szybka-referencja&quot;&gt;Szybka referencja&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Polecenie&lt;/th&gt;
&lt;th&gt;Co robi&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pokaz stan workspace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git add .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Staguj wszystkie zmiany&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git commit -m &quot;msg&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Utworz commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git pull --rebase&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Zaktualizuj z remote (czysta historia)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Uploaduj commity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Zmien galaz&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git merge &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Polacz galaz z aktualna&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Wroc do poprzedniej galezi&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;nowoczesny-git-switch-vs-checkout&quot;&gt;Nowoczesny Git: Switch vs Checkout&lt;/h2&gt;
&lt;p&gt;Od Git 2.23 sprawy staly sie jeszcze prostsze. Git wprowadzil dwa nowe polecenia, &lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt; i &lt;code class=&quot;language-text&quot;&gt;git restore&lt;/code&gt;, zeby rozdzielic przelaczanie galezi od przywracania plikow. Ta zmiana sprawia ze intencja kazdego polecenia jest jasna, szczegolnie dla nowych programistow. Stare polecenie &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; bylo przeladowane i probowalo robic zbyt wiele niepowiazanych rzeczy.&lt;/p&gt;
&lt;p&gt;Oto prosta regula dla nowoczesnego uzycia Git:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Polecenie&lt;/th&gt;
&lt;th&gt;Cel&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Zmienia galezi&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Wraca do poprzedniej galezi&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;NIE powinno byc uzywane do przelaczania galezi (poza skrotem z kreska)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;podsumowanie&quot;&gt;Podsumowanie&lt;/h2&gt;
&lt;p&gt;Jesli opanujesz te osiem polecen, bedziesz skuteczny w prawie kazdym codziennym workflow Git bez zadnej zaawansowanej wiedzy. Kluczowe spostrzezenie to uzywanie &lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt; dla galezi i rezerwowanie &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; tylko dla skrotu z kreska.&lt;/p&gt;
&lt;p&gt;Dla wszystkiego innego - rebasowania, cherry-pickingu, bisectingu - mozesz to sprawdzic gdy tego potrzebujesz. Te osiem polecen pokrywa 95% tego co robisz kazdego dnia.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[8 Comandos Git Comuns Que Voce Usara Diariamente: Switch, Checkout e Pull Rebase Explicados]]></title><description><![CDATA[Aprenda os 8 comandos Git que desenvolvedores usam todos os dias, incluindo como usar git switch vs checkout e por que git pull --rebase mantem seu historico de commits limpo para fluxos de trabalho mais suaves.]]></description><link>https://vibecodingwithfred.com/pt/blog/everyday-git-commands/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pt/blog/everyday-git-commands/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Fri, 05 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Git e poderoso, mas tem fama de ser complicado. Inclui centenas de comandos e flags, mas a maioria dos desenvolvedores so depende de um pequeno conjunto deles todos os dias. Se voce aprender os oito comandos neste guia, pode trabalhar com confianca em quase qualquer projeto Git sem precisar memorizar o resto.&lt;/p&gt;
&lt;h2 id=&quot;os-8-comandos-essenciais&quot;&gt;Os 8 Comandos Essenciais&lt;/h2&gt;
&lt;h3 id=&quot;1-git-status&quot;&gt;1. git status&lt;/h3&gt;
&lt;p&gt;Use isso para verificar o estado do seu workspace. Mostra quais arquivos mudaram, quais arquivos estao em stage, em qual branch voce esta e se seu branch esta a frente ou atras do remoto. Este comando e seu dashboard principal.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; status&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-git-add-&quot;&gt;2. git add .&lt;/h3&gt;
&lt;p&gt;Isso coloca suas mudancas em stage para que estejam prontas para serem commitadas. O ponto significa &quot;adicionar tudo que mudou&quot;. Voce tambem pode colocar arquivos individuais em stage se preferir ser mais seletivo.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Ou coloque arquivos especificos em stage:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; src/index.js&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-git-commit--m-&quot;&gt;3. git commit -m &quot;&quot;&lt;/h3&gt;
&lt;p&gt;Um commit cria um snapshot do seu trabalho. A mensagem dentro das aspas deve descrever por que a mudanca foi feita. Boas mensagens de commit economizam tempo depois ao revisar historico ou debugar problemas.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Add user authentication flow&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-git-pull---rebase&quot;&gt;4. git pull --rebase&lt;/h3&gt;
&lt;p&gt;Isso atualiza seu branch local com as ultimas mudancas do remoto. A flag &lt;code class=&quot;language-text&quot;&gt;--rebase&lt;/code&gt; mantem seu historico de commits limpo replayando seus commits em cima dos commits upstream mais novos. Isso evita commits de merge desnecessarios e reduz ruido de conflitos.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; pull &lt;span class=&quot;token parameter variable&quot;&gt;--rebase&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Por que rebase?&lt;/strong&gt; Sem ele, voce recebe commits de merge toda vez que faz pull, enchendo seu historico com mensagens &quot;Merge branch &apos;main&apos; into main&quot;.&lt;/p&gt;
&lt;h3 id=&quot;5-git-push&quot;&gt;5. git push&lt;/h3&gt;
&lt;p&gt;Isso faz upload dos seus commits para GitHub, GitLab ou qualquer outro remoto. Push salva seu trabalho no servidor, faz backup e o disponibiliza para pull requests e colaboracao em equipe.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push
&lt;span class=&quot;token comment&quot;&gt;# Primeiro push em um novo branch:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin feature/my-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;6-git-switch-branch&quot;&gt;6. git switch &amp;#x3C;branch&gt;&lt;/h3&gt;
&lt;p&gt;Esta e a forma moderna de mudar para outro branch. E simples, claro e nao pode modificar acidentalmente seus arquivos.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Se o branch ainda nao existe, crie-o com:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch &lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt; new-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;7-git-merge-branch&quot;&gt;7. git merge &amp;#x3C;branch&gt;&lt;/h3&gt;
&lt;p&gt;Isso faz merge do branch especificado no branch em que voce esta atualmente. A ordem correta e primeiro mudar para o branch que voce quer atualizar, depois fazer merge de outro branch nele.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; merge feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;8-git-checkout--&quot;&gt;8. git checkout -&lt;/h3&gt;
&lt;p&gt;Isso te retorna ao branch anterior junto com seu estado de trabalho. E um atalho extremamente util e um dos unicos usos modernos do &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; que ainda e recomendado.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout -
&lt;span class=&quot;token comment&quot;&gt;# Equivalente a &quot;cd -&quot; para branches&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;referencia-rapida&quot;&gt;Referencia Rapida&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Comando&lt;/th&gt;
&lt;th&gt;O Que Faz&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Mostra estado do workspace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git add .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Coloca todas as mudancas em stage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git commit -m &quot;msg&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cria um commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git pull --rebase&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Atualiza do remoto (historico limpo)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Faz upload dos commits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Muda de branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git merge &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Faz merge de branch no atual&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Retorna ao branch anterior&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;git-moderno-switch-vs-checkout&quot;&gt;Git Moderno: Switch vs Checkout&lt;/h2&gt;
&lt;p&gt;Desde o Git 2.23, as coisas ficaram ainda mais simples. Git introduziu dois novos comandos, &lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt; e &lt;code class=&quot;language-text&quot;&gt;git restore&lt;/code&gt;, para separar troca de branch de restauracao de arquivo. Essa mudanca torna a intencao de cada comando clara, especialmente para novos desenvolvedores. O antigo comando &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; era sobrecarregado e tentava fazer muitas coisas nao relacionadas.&lt;/p&gt;
&lt;p&gt;Aqui esta o conjunto simples de regras para uso moderno do Git:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Comando&lt;/th&gt;
&lt;th&gt;Proposito&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Muda branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Retorna ao branch anterior&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;NAO deve ser usado para trocar branches (exceto o atalho com traco)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;finalizando&quot;&gt;Finalizando&lt;/h2&gt;
&lt;p&gt;Se voce dominar esses oito comandos, sera eficaz em quase todo fluxo de trabalho Git diario sem precisar de nenhum conhecimento avancado. O insight chave e usar &lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt; para branches e reservar &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; apenas para o atalho com traco.&lt;/p&gt;
&lt;p&gt;Para todo o resto—rebasing, cherry-picking, bisecting—voce pode pesquisar quando precisar. Esses oito comandos cobrem 95% do que voce fara todos os dias.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[8 个日常必用的 Git 命令：Switch、Checkout 和 Pull Rebase 详解]]></title><description><![CDATA[学习开发者每天使用的 8 个 Git 命令，包括如何使用 git switch vs checkout，以及为什么 git pull --rebase 能保持提交历史整洁以实现更顺畅的工作流。]]></description><link>https://vibecodingwithfred.com/zh/blog/everyday-git-commands/</link><guid isPermaLink="false">https://vibecodingwithfred.com/zh/blog/everyday-git-commands/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Fri, 05 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Git 很强大，但它有复杂的名声。它包含数百个命令和标志，但大多数开发者每天只依赖一小部分。如果你学会本指南中的八个命令，你可以在几乎任何 Git 项目中自信地工作，无需记住其余的。&lt;/p&gt;
&lt;h2 id=&quot;8-个基本命令&quot;&gt;8 个基本命令&lt;/h2&gt;
&lt;h3 id=&quot;1-git-status&quot;&gt;1. git status&lt;/h3&gt;
&lt;p&gt;使用它来检查你工作区的状态。它显示哪些文件已更改、哪些文件已暂存、你在哪个分支上，以及你的分支是否领先或落后于远程。这个命令是你的主要仪表板。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; status&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-git-add-&quot;&gt;2. git add .&lt;/h3&gt;
&lt;p&gt;这会暂存你的更改，使它们准备好提交。点号表示&quot;添加所有更改的内容&quot;。如果你更喜欢更有选择性，你也可以暂存单个文件。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# 或暂存特定文件：&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; src/index.js&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-git-commit--m-&quot;&gt;3. git commit -m &quot;&quot;&lt;/h3&gt;
&lt;p&gt;提交会创建你工作的快照。引号内的消息应描述为什么进行了更改。好的提交消息在以后审查历史或调试问题时节省时间。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Add user authentication flow&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-git-pull---rebase&quot;&gt;4. git pull --rebase&lt;/h3&gt;
&lt;p&gt;这会使用远程的最新更改更新你的本地分支。&lt;code class=&quot;language-text&quot;&gt;--rebase&lt;/code&gt; 标志通过将你的提交重新播放到最新的上游提交之上来保持提交历史整洁。这避免了不必要的合并提交并减少了冲突噪音。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; pull &lt;span class=&quot;token parameter variable&quot;&gt;--rebase&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;为什么用 rebase？&lt;/strong&gt; 没有它，每次拉取时你都会得到合并提交，用&quot;Merge branch &apos;main&apos; into main&quot;消息弄乱你的历史。&lt;/p&gt;
&lt;h3 id=&quot;5-git-push&quot;&gt;5. git push&lt;/h3&gt;
&lt;p&gt;这会将你的提交上传到 GitHub、GitLab 或任何其他远程。推送会将你的工作保存到服务器、备份它，并使其可用于拉取请求和团队协作。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push
&lt;span class=&quot;token comment&quot;&gt;# 新分支的第一次推送：&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin feature/my-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;6-git-switch-branch&quot;&gt;6. git switch &amp;#x3C;branch&gt;&lt;/h3&gt;
&lt;p&gt;这是切换到另一个分支的现代方式。它简单、清晰，不会意外修改你的文件。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果分支不存在，创建它：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch &lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt; new-branch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;7-git-merge-branch&quot;&gt;7. git merge &amp;#x3C;branch&gt;&lt;/h3&gt;
&lt;p&gt;这会将指定的分支合并到你当前所在的分支。正确的顺序是首先切换到你想更新的分支，然后将另一个分支合并到其中。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; switch main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; merge feature/login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;8-git-checkout--&quot;&gt;8. git checkout -&lt;/h3&gt;
&lt;p&gt;这会返回到上一个分支及其工作状态。这是一个非常有用的快捷方式，也是 &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; 仍然推荐的为数不多的现代用法之一。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout -
&lt;span class=&quot;token comment&quot;&gt;# 等同于分支的 &quot;cd -&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;快速参考&quot;&gt;快速参考&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;显示工作区状态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git add .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;暂存所有更改&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git commit -m &quot;msg&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;创建提交&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git pull --rebase&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从远程更新（干净历史）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;上传提交&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;切换分支&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git merge &amp;lt;branch&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;将分支合并到当前分支&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回上一个分支&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;现代-gitswitch-vs-checkout&quot;&gt;现代 Git：Switch vs Checkout&lt;/h2&gt;
&lt;p&gt;从 Git 2.23 开始，事情变得更简单了。Git 引入了两个新命令 &lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt; 和 &lt;code class=&quot;language-text&quot;&gt;git restore&lt;/code&gt;，将分支切换与文件恢复分开。这一变化使每个命令的意图清晰，特别是对新开发者而言。旧的 &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; 命令过于臃肿，试图做太多不相关的事情。&lt;/p&gt;
&lt;p&gt;这是现代 Git 使用的简单规则集：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;切换分支&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout -&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回上一个分支&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;不应该用于切换分支（除了短横线快捷方式）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;总结&quot;&gt;总结&lt;/h2&gt;
&lt;p&gt;如果你掌握这八个命令，你将在几乎每个日常 Git 工作流中都很有效，无需任何高级知识。关键见解是使用 &lt;code class=&quot;language-text&quot;&gt;git switch&lt;/code&gt; 用于分支，保留 &lt;code class=&quot;language-text&quot;&gt;git checkout&lt;/code&gt; 仅用于短横线快捷方式。&lt;/p&gt;
&lt;p&gt;对于其他一切——变基、挑选提交、二分法——你需要时可以查找。这八个命令涵盖了你每天 95% 的工作。&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Claude Code Installation Guide: Using irm Script, npm Setup, and https://claude.ai/install.ps1 Script]]></title><description><![CDATA[Step-by-step Claude Code CLI IDE setup, installation, and uninstallation of the native binary, npm and troubleshooting with claude doctor.]]></description><link>https://vibecodingwithfred.com/blog/claude-code-installation-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/claude-code-installation-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 26 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Claude Code is my go-to command-line tool for AI-assisted coding. Whether you&apos;re on Windows, macOS, or Linux, installation is straightforward with multiple options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Native Binary&lt;/strong&gt; (Recommended): &lt;code class=&quot;language-text&quot;&gt;curl -fsSL https://claude.ai/install.sh | bash&lt;/code&gt; for Linux/macOS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Windows PowerShell&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;irm https://claude.ai/install.ps1 | iex&lt;/code&gt; for Windows users&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;npm Global Install&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;npm install -g @anthropic-ai/claude-code&lt;/code&gt; for Node.js environments&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This guide covers each installation method in detail, plus troubleshooting with the &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; command to diagnose and fix common issues.&lt;/p&gt;
&lt;h2 id=&quot;recommended-native-binary&quot;&gt;Recommended: Native Binary&lt;/h2&gt;
&lt;p&gt;As of 2025, there are several runtims Claude is available in, including node.js and bun.js. Anthropic recommends using the native binary installation. This method avoids package manager conflicts, and is the most stable.&lt;/p&gt;
&lt;h3 id=&quot;installing-the-native-binary&quot;&gt;Installing the Native Binary&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Run the installation script:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reload your shell configuration:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token comment&quot;&gt;# or for zsh users:&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.zshrc&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Verify the installation:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;
claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That&apos;s it! Claude Code should now be installed at &lt;code class=&quot;language-text&quot;&gt;~/.claude/bin/claude&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;~/.local/bin/claude&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;troubleshooting-fixing-broken-installations&quot;&gt;Troubleshooting: Fixing Broken Installations&lt;/h2&gt;
&lt;p&gt;If you&apos;re experiencing issues with Claude Code such as segmentation fault errors, you likely have a mixed or outdated installation. If you have been using Claude since the start like I have, you may have a node.js or bun.js versions installed, too. Here&apos;s how to fix that:&lt;/p&gt;
&lt;h3 id=&quot;diagnose-your-current-installation-with-claude-doctor&quot;&gt;Diagnose Your Current Installation with claude doctor&lt;/h3&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; command is your first stop for troubleshooting. It analyzes your installation and reports potential issues.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;what-claude-doctor-checks&quot;&gt;What claude doctor Checks&lt;/h4&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; command inspects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Installation method&lt;/strong&gt;: Native binary, npm, Bun, or Homebrew&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Version information&lt;/strong&gt;: Current version and update status&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Auto-update capability&lt;/strong&gt;: Whether updates can be applied&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Search functionality&lt;/strong&gt;: If ripgrep is properly bundled/installed&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Path configuration&lt;/strong&gt;: Whether Claude is in your PATH correctly&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Execution path&lt;/strong&gt;: The actual binary being run&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;common-problematic-outputs&quot;&gt;Common Problematic Outputs&lt;/h4&gt;
&lt;p&gt;Watch for these warning signs in &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; output:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;unknown (2.0.0)&lt;/code&gt; - Version detection failed, likely mixed installation&lt;/li&gt;
&lt;li&gt;Mixed paths between Bun, npm, and Node.js&lt;/li&gt;
&lt;li&gt;Invocation path different from execution path&lt;/li&gt;
&lt;li&gt;Auto-updates disabled or failing&lt;/li&gt;
&lt;li&gt;Search status showing errors&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also check for multiple installations that may conflict:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;which&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; claude&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;need-to-uninstall-or-remove-claude-code-️&quot;&gt;Need to Uninstall or Remove Claude Code? 🗑️&lt;/h3&gt;
&lt;p&gt;If you need to completely remove Claude Code—whether to fix a broken installation, switch installation methods, or clean up mixed versions—I&apos;ve written a complete uninstall guide covering every platform and installation method.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;/blog/uninstall-claude-code/&quot;&gt;→ Complete Uninstall Guide: Remove Claude Code from Windows, macOS &amp;#x26; Linux 🗑️&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The guide covers removing npm installations (including nvm cleanup), Homebrew uninstalls, native binary removal, Bun installations, Windows PowerShell cleanup, and complete config/cache removal. After following the uninstall guide, come back here to reinstall with the native binary.&lt;/p&gt;
&lt;h3 id=&quot;fresh-native-binary-installation&quot;&gt;Fresh Native Binary Installation&lt;/h3&gt;
&lt;p&gt;Install (or reinstall) the native binary:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;verify-the-fix&quot;&gt;Verify the Fix&lt;/h3&gt;
&lt;p&gt;After installation, verify everything is working:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Check version&lt;/span&gt;
claude &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Run diagnostics&lt;/span&gt;
claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A healthy installation should show:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Version: native (2.0.x or higher)&lt;/li&gt;
&lt;li&gt;Config install method: native&lt;/li&gt;
&lt;li&gt;Auto-updates: enabled&lt;/li&gt;
&lt;li&gt;Search: OK (bundled)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;alternative-installation-methods&quot;&gt;Alternative Installation Methods&lt;/h2&gt;
&lt;p&gt;While the native binary is recommended, here are other options:&lt;/p&gt;
&lt;h3 id=&quot;npm-installation-npm-install--g-anthropic-aiclaude-code&quot;&gt;npm Installation: npm install -g @anthropic-ai/claude-code&lt;/h3&gt;
&lt;p&gt;If you prefer using npm (Node Package Manager), you can install Claude Code globally. This method requires Node.js 18 or higher.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;what-npm-install--g-does&quot;&gt;What npm install -g Does&lt;/h4&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;-g&lt;/code&gt; flag installs the package globally, making &lt;code class=&quot;language-text&quot;&gt;claude&lt;/code&gt; available as a command anywhere in your terminal. The package &lt;code class=&quot;language-text&quot;&gt;@anthropic-ai/claude-code&lt;/code&gt; is the official npm package maintained by Anthropic.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Benefits of npm installation:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Familiar workflow for Node.js developers&lt;/li&gt;
&lt;li&gt;Easy to manage alongside other global packages&lt;/li&gt;
&lt;li&gt;Works well in containerized/CI environments&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Drawbacks:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Requires Node.js runtime&lt;/li&gt;
&lt;li&gt;May conflict with other package managers (Bun, pnpm)&lt;/li&gt;
&lt;li&gt;Updates require manual &lt;code class=&quot;language-text&quot;&gt;npm update -g @anthropic-ai/claude-code&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; Never use &lt;code class=&quot;language-text&quot;&gt;sudo npm install -g&lt;/code&gt; as this causes permission issues. If you get EACCES errors, fix your npm permissions instead.&lt;/p&gt;
&lt;h3 id=&quot;specific-version-installation&quot;&gt;Specific Version Installation&lt;/h3&gt;
&lt;p&gt;To install a specific version of the native binary:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Install latest version&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; latest

&lt;span class=&quot;token comment&quot;&gt;# Install specific version&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.0&lt;/span&gt;.22&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;platform-specific-instructions&quot;&gt;Platform-Specific Instructions&lt;/h2&gt;
&lt;h3 id=&quot;macos-with-homebrew&quot;&gt;macOS with Homebrew&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note: Homebrew installations auto-update independently of the brew directory.&lt;/p&gt;
&lt;h3 id=&quot;windows-using-irm-httpsclaudeaiinstallps1--iex&quot;&gt;Windows: Using irm &lt;a href=&quot;https://claude.ai/install.ps1&quot;&gt;https://claude.ai/install.ps1&lt;/a&gt; | iex&lt;/h3&gt;
&lt;p&gt;For Windows users, you have three options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;WSL (Recommended)&lt;/strong&gt;: Install WSL and follow the Linux instructions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Git Bash&lt;/strong&gt;: Use the native installer with Git Bash&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PowerShell&lt;/strong&gt; (Native Windows):
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;powershell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-powershell line-numbers&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;irm&lt;/span&gt; https:&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;claude&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ai/install&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ps1 &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;iex&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;understanding-the-irm-command&quot;&gt;Understanding the irm Command&lt;/h4&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;irm&lt;/code&gt; command is PowerShell&apos;s &lt;strong&gt;Invoke-RestMethod&lt;/strong&gt;, which downloads content from a URL. Here&apos;s what the command does:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;irm https://claude.ai/install.ps1&lt;/code&gt; - Downloads the installation script from Anthropic&apos;s servers&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;| iex&lt;/code&gt; - Pipes the script to &lt;strong&gt;Invoke-Expression&lt;/strong&gt;, which executes it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;https://claude.ai/install.ps1&lt;/code&gt; script handles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Detecting your Windows architecture (x64, ARM64)&lt;/li&gt;
&lt;li&gt;Downloading the appropriate Claude Code binary&lt;/li&gt;
&lt;li&gt;Installing to your user directory&lt;/li&gt;
&lt;li&gt;Adding Claude to your PATH environment variable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Security Note:&lt;/strong&gt; Always verify you&apos;re downloading from the official &lt;code class=&quot;language-text&quot;&gt;claude.ai&lt;/code&gt; domain before running installation scripts.&lt;/p&gt;
&lt;h3 id=&quot;alpine-linux&quot;&gt;Alpine Linux&lt;/h3&gt;
&lt;p&gt;Alpine and other musl-based distributions need additional dependencies:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;apk &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; libgcc libstdc++ ripgrep
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;USE_BUILTIN_RIPGREP&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;post-installation-setup&quot;&gt;Post-Installation Setup&lt;/h2&gt;
&lt;h3 id=&quot;authentication&quot;&gt;Authentication&lt;/h3&gt;
&lt;p&gt;After installation, authenticate Claude Code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You&apos;ll be prompted to choose your authentication method:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Claude Console&lt;/strong&gt; (default): For API access with billing at console.anthropic.com&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude Pro/Max&lt;/strong&gt;: If you have a Claude subscription&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enterprise&lt;/strong&gt;: For AWS Bedrock or Google Vertex AI deployments&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;basic-usage&quot;&gt;Basic Usage&lt;/h3&gt;
&lt;p&gt;Start using Claude Code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Navigate to your project&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; /path/to/your/project

&lt;span class=&quot;token comment&quot;&gt;# Start Claude Code&lt;/span&gt;
claude

&lt;span class=&quot;token comment&quot;&gt;# Get help&lt;/span&gt;
claude &lt;span class=&quot;token builtin class-name&quot;&gt;help&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Inside a session, use slash commands&lt;/span&gt;
/help    &lt;span class=&quot;token comment&quot;&gt;# Show available commands&lt;/span&gt;
/clear   &lt;span class=&quot;token comment&quot;&gt;# Clear conversation&lt;/span&gt;
/exit    &lt;span class=&quot;token comment&quot;&gt;# Exit Claude Code&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;managing-updates&quot;&gt;Managing Updates&lt;/h2&gt;
&lt;h3 id=&quot;auto-updates&quot;&gt;Auto-Updates&lt;/h3&gt;
&lt;p&gt;Claude Code automatically updates by default. Updates are checked on startup and applied in the background.&lt;/p&gt;
&lt;h3 id=&quot;how-to-update-claude-code&quot;&gt;How to update Claude Code&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude update&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;
Add this to your `.bashrc` or `.zshrc` to make it permanent.

## Common Issues and Solutions

### Issue: &quot;Insufficient permissions to install update&quot;

This typically happens with npm/Bun installations. Solution: Switch to native binary installation.

### Issue: &quot;command not found: claude&quot;

The PATH wasn&apos;t updated. Add to your shell configuration:

```bash
echo &apos;export PATH=&quot;$HOME/.local/bin:$PATH&quot;&apos; &gt;&gt; ~/.bashrc
source ~/.bashrc&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;issue-installmethod-is-native-but-claude-command-not-found&quot;&gt;Issue: &quot;installmethod is native, but claude command not found&quot;&lt;/h3&gt;
&lt;p&gt;This error from &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; means the native binary installed successfully, but your shell can&apos;t find it. The binary exists but isn&apos;t in your PATH.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fix 1: Add Claude to PATH manually&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Check where Claude was installed&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt; ~/.claude/bin/claude &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt; ~/.local/bin/claude

&lt;span class=&quot;token comment&quot;&gt;# Add the correct path to your shell config&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export PATH=&quot;$HOME/.claude/bin:$HOME/.local/bin:$PATH&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For zsh users, replace &lt;code class=&quot;language-text&quot;&gt;.bashrc&lt;/code&gt; with &lt;code class=&quot;language-text&quot;&gt;.zshrc&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fix 2: Reinstall with fresh shell&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Remove and reinstall&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-rf&lt;/span&gt; ~/.claude
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Open a NEW terminal window (don&apos;t just source)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Fix 3: Check for conflicting installations&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# See all claude binaries on your system&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;which&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; claude
&lt;span class=&quot;token builtin class-name&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; claude

&lt;span class=&quot;token comment&quot;&gt;# Remove any non-native versions first (see cleanup steps above)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After fixing, verify with:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;
claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You should see &lt;code class=&quot;language-text&quot;&gt;Config install method: native&lt;/code&gt; with no PATH warnings.&lt;/p&gt;
&lt;h3 id=&quot;issue-search-functionality-not-working&quot;&gt;Issue: Search functionality not working&lt;/h3&gt;
&lt;p&gt;Usually fixed by the native installation, but if persisting:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Install ripgrep manually&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;apt-get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; ripgrep  &lt;span class=&quot;token comment&quot;&gt;# Ubuntu/Debian&lt;/span&gt;
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; ripgrep          &lt;span class=&quot;token comment&quot;&gt;# macOS&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;best-practices&quot;&gt;Best Practices&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Always use the native binary&lt;/strong&gt; unless you have specific requirements&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Avoid sudo&lt;/strong&gt; with any installation method&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keep auto-updates enabled&lt;/strong&gt; for security and features&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Run &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt;&lt;/strong&gt; after any installation or update&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Clean up old installations&lt;/strong&gt; before installing new versions&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Remember: when in doubt, remove everything and start fresh with the native binary. It&apos;s the simplest, fastest, and most reliable way to run Claude Code.&lt;/p&gt;
&lt;h2 id=&quot;related-reading&quot;&gt;Related Reading&lt;/h2&gt;
&lt;p&gt;Now that you have Claude Code installed, put it to work:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Build a Shopping Cart with Flask&lt;/a&gt;&lt;/strong&gt; - A hands-on tutorial where you can use Claude Code to build a complete e-commerce backend with Python and Flask&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/everyday-git-commands/&quot;&gt;8 Common Git Commands You&apos;ll Use Daily&lt;/a&gt;&lt;/strong&gt; - Master the essential Git commands you&apos;ll need when working with Claude Code on any project&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/deploy-claude-code-cloudflare/&quot;&gt;Deploy Claude Code to Cloudflare Workers&lt;/a&gt;&lt;/strong&gt; - Run Claude Code in a serverless environment for automated coding workflows&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/ultimate-vibe-coding-guide/&quot;&gt;The Ultimate Vibe Coding Guide&lt;/a&gt;&lt;/strong&gt; - Learn how to get the most out of AI-assisted development with Claude&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;quick-reference&quot;&gt;Quick Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Install&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;curl -fsSL https://claude.ai/install.sh | bash&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Check version&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude --version&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Diagnose&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Update&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude update&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Start&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Help&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude help&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Lovable Refund: From Hero to Zero with 2.0 Issues]]></title><description><![CDATA[Explore why Lovable 2.0 turned from hero to zero, including refund policies, user complaints, and support challenges to help you navigate the platform's recent issues.]]></description><link>https://vibecodingwithfred.com/blog/lovable-from-hero-to-zero/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/lovable-from-hero-to-zero/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 26 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Remember when Lovable was the darling of the AI development world? Their intuitive interface and reliable performance made them a go-to platform for developers of all skill levels. Unfortunately, that reputation has taken a dramatic nosedive since the release of &lt;strong&gt;Lovable 2.0&lt;/strong&gt;, with users across Reddit and other platforms voicing their frustrations about the update.&lt;/p&gt;
&lt;h2 id=&quot;the-golden-era-of-10&quot;&gt;The Golden Era of 1.0&lt;/h2&gt;
&lt;p&gt;Before diving into the current issues, let&apos;s remember what made Lovable special:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Intuitive UI&lt;/strong&gt;: Users frequently praised the clean, animated interface that made development enjoyable&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reliable Performance&lt;/strong&gt;: Projects worked consistently with minimal debugging required&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fair Credit System&lt;/strong&gt;: Users understood what they were paying for and how credits were being used&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Responsive Support&lt;/strong&gt;: Issues were addressed promptly, with clear communication&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One user reminisced: &quot;I absolutely loved 1.0 UI design. Great animations. Cool ideas. Unique UI creations. I was super impressed and using Lovable for all my projects.&quot;&lt;/p&gt;
&lt;h2 id=&quot;the-lovable-20-update-what-went-wrong&quot;&gt;The Lovable 2.0 Update: What Went Wrong?&lt;/h2&gt;
&lt;p&gt;The release of &lt;strong&gt;Lovable 2.0&lt;/strong&gt; in early 2025 brought a complete redesign of the platform. While promising enhanced capabilities, users are experiencing numerous critical issues:&lt;/p&gt;
&lt;h3 id=&quot;1-mysterious-credit-consumption&quot;&gt;1. Mysterious Credit Consumption&lt;/h3&gt;
&lt;p&gt;Users report credits disappearing without explanation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;I put myself into chat mode, asked a couple of questions and made a manual edit to one word... suddenly I&apos;m down to 3/5 daily credits?!? I asked Lovable to investigate and it couldn&apos;t even tell me what the credits were used for!&quot; - u/neuralgroov2&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Another user shared: &quot;I was paying for a scale 1 subscription when this new update hit... At the time I still had 360 credits that I had already paid for, and after I canceled / downgraded my subscription, I had only 5. Are you for real, Lovable?&quot;&lt;/p&gt;
&lt;h3 id=&quot;2-ui-regression&quot;&gt;2. UI Regression&lt;/h3&gt;
&lt;p&gt;The new interface has been almost universally panned:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;2.0 UI Design is awful. Please roll back!! All the sudden 2.0 rolls out and I&apos;m using the same descriptive prompts that were creating beautiful UI art in 1.0 and now in 2.0 it&apos;s poo poo. Bland boring no animation ugly cookie cutter terrible UI ideas that seem like you rolled back to early 2000s for UI design.&quot; - u/digitalml&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;3-broken-functionality&quot;&gt;3. Broken Functionality&lt;/h3&gt;
&lt;p&gt;Many users report that the update has broken previously working applications:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;After giving up on Lovable for the last two days (after upping to the $100 tier just prior to the upgrade and not having heard back from their overwhelmed support staff in days), I decided to dip my toe back in... It didn&apos;t do anything I asked it to. It added two login links in the header, and removed all the home page content with 20 cards that 404&apos;d.&quot; - u/who_am_i_to_say_so&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Another user shared: &quot;I&apos;ve spent over 20 credits trying to fix a code that results in my app being frozen on a &apos;loading page&apos;. The AI seems to confidently believe it&apos;s fixed however it&apos;s not, keep going back in circles.&quot;&lt;/p&gt;
&lt;h3 id=&quot;4-overwhelmed-support&quot;&gt;4. Overwhelmed Support&lt;/h3&gt;
&lt;p&gt;Customer support appears to be completely overwhelmed by the volume of issues:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;I tried contacting your &apos;support&apos; and received a message saying it&apos;s only available to paying users.&quot; - u/AI_4U&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Even paying users report waiting days for responses: &quot;After upping to the $100 tier just prior to the upgrade and not having heard back from their overwhelmed support staff in days...&quot;&lt;/p&gt;
&lt;h3 id=&quot;5-seo-promises-vs-reality&quot;&gt;5. SEO Promises vs. Reality&lt;/h3&gt;
&lt;p&gt;Multiple users have pointed out discrepancies between what Lovable promises and what it delivers:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Why do they talk about SEO when their apps are CSR and have no SEO-ability?&quot; - u/VisionaryOS&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This has led to third-party developers creating tools to address Lovable&apos;s shortcomings, with one user announcing: &quot;I Built a tool to help you in your Lovable projects and prevent them from turning into spaghetti.&quot;&lt;/p&gt;
&lt;h2 id=&quot;community-response&quot;&gt;Community Response&lt;/h2&gt;
&lt;p&gt;The community response has been swift and severe. Many users are calling for Lovable to roll back to version 1.0:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;This is not a threat but consider this a warning. This is how companies (start ups) die or get cancelled. If you do not roll back to 1.0 and refund back lost credits so that we can fix the apps your upgraded platform has destroyed... you will have no option but to face cancel action.&quot; - u/r4g3z29&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Others are demanding refunds:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Lovable; you need to refund some of these credits, do something, address the issues. I think fair is fair; there needs to be come kind of refund back in terms of credits, 2.Slow isn&apos;t working right and its not just a handful of us.&quot; - u/Horror_Brother67&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;code-quality-concerns&quot;&gt;Code Quality Concerns&lt;/h2&gt;
&lt;p&gt;Some users have even taken to analyzing the code quality of Lovable-generated applications, with concerning results:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;I gave my github project to grok and I was like..... wow. Security Grade: 4/10, Testing Grade: 2/10&quot; - u/adreportcard&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This suggests that beyond the interface and credit issues, there may be fundamental problems with the code Lovable 2.0 is generating.&lt;/p&gt;
&lt;h2 id=&quot;is-there-hope-for-lovable-20&quot;&gt;Is There Hope for Lovable 2.0?&lt;/h2&gt;
&lt;p&gt;While some users are still finding success with &lt;strong&gt;Lovable 2.0&lt;/strong&gt;, the overwhelming sentiment is negative. One user shared a system prompt they created to try to improve performance:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;I&apos;ve been using it for a week, and it seems to reduce stubbornness and unwanted code rewrites. While Lovable itself has recently made changes to only rewrite necessary lines, it hasn&apos;t been consistent.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This suggests that with significant workarounds, users might be able to salvage some functionality, but it&apos;s a far cry from the seamless experience promised.&lt;/p&gt;
&lt;h2 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;/h2&gt;
&lt;p&gt;The Lovable 2.0 debacle offers several important lessons for both users and companies:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Test thoroughly before major releases&lt;/strong&gt;: The volume and severity of issues suggest inadequate testing&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Maintain transparent communication&lt;/strong&gt;: Many users cite lack of clear information about what&apos;s happening&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consider phased rollouts&lt;/strong&gt;: A gradual transition might have prevented the shock of sudden changes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Have adequate support ready&lt;/strong&gt;: Support systems should scale with anticipated issues&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Provide rollback options&lt;/strong&gt;: When things go wrong, users need a way to return to what worked&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;whats-your-experience&quot;&gt;What&apos;s Your Experience?&lt;/h2&gt;
&lt;p&gt;Have you used Lovable before and after the 2.0 update? Share your experiences in the comments below. And if you&apos;ve found good alternatives with better support, I&apos;d love to hear about them!&lt;/p&gt;
&lt;p&gt;As one user aptly put it: &quot;This 2.0 update really is the worst update I have ever seen.&quot; For a platform that once showed so much promise, that&apos;s a devastating fall from grace.&lt;/p&gt;
&lt;h2 id=&quot;what-should-you-do-if-youre-affected-by-lovable-20&quot;&gt;What Should You Do If You&apos;re Affected by Lovable 2.0?&lt;/h2&gt;
&lt;p&gt;If you&apos;re experiencing issues with &lt;strong&gt;Lovable 2.0&lt;/strong&gt;, here are your options:&lt;/p&gt;
&lt;h3 id=&quot;option-1-migrate-to-external-hosting&quot;&gt;Option 1: Migrate to External Hosting&lt;/h3&gt;
&lt;p&gt;Export your Lovable project and host it elsewhere for better reliability:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;Move to Cloudflare&lt;/a&gt; - Best performance and unlimited requests&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website/&quot;&gt;Move to Vercel&lt;/a&gt; - Easiest setup with automatic deployments&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website&quot;&gt;10 Free Hosting Options&lt;/a&gt; - Complete guide to all free hosting platforms&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Migrating gives you full control over your codebase and removes dependency on Lovable&apos;s platform issues.&lt;/p&gt;
&lt;h3 id=&quot;option-2-export-and-continue-development-locally&quot;&gt;Option 2: Export and Continue Development Locally&lt;/h3&gt;
&lt;p&gt;Download your project code and continue development in VS Code with full control over your codebase. This lets you:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix issues Lovable can&apos;t resolve&lt;/li&gt;
&lt;li&gt;Improve code quality and security&lt;/li&gt;
&lt;li&gt;Add custom features without credit limits&lt;/li&gt;
&lt;li&gt;Work offline without platform dependencies&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;option-3-wait-for-fixes&quot;&gt;Option 3: Wait for Fixes&lt;/h3&gt;
&lt;p&gt;Monitor the Lovable community and support channels for updates and bug fixes. However, given the scale of reported issues, this may take considerable time.&lt;/p&gt;
&lt;h3 id=&quot;how-to-export-your-lovable-project&quot;&gt;How to Export Your Lovable Project&lt;/h3&gt;
&lt;p&gt;Regardless of which path you choose, exporting your project ensures you&apos;re not locked in and have full ownership of your work:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;In Lovable&lt;/strong&gt;: Click menu icon → Export → Download as ZIP&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Extract&lt;/strong&gt; the ZIP file to access your complete codebase&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Push to Git&lt;/strong&gt; for version control and deployment&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deploy anywhere&lt;/strong&gt;: Your code works on any platform that supports React&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;See our &lt;a href=&quot;/blog/export-lovable-to-github-complete/&quot;&gt;complete GitHub export guide&lt;/a&gt; for step-by-step instructions.&lt;/p&gt;
&lt;h2 id=&quot;understanding-lovable-credits&quot;&gt;Understanding Lovable Credits&lt;/h2&gt;
&lt;p&gt;Before you leave, make sure you understand &lt;a href=&quot;/blog/lovable-credits-complete-guide/&quot;&gt;how Lovable credits work&lt;/a&gt;—many users have reported unexpected credit consumption with 2.0, and knowing the system helps you avoid wasting credits during your final exports.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Claude Code Installationsanleitung: irm-Script, npm-Setup und https://claude.ai/install.ps1 Script]]></title><description><![CDATA[Schritt-fuer-Schritt Claude Code CLI IDE Setup, Installation und Deinstallation der nativen Binary, npm und Fehlerbehebung mit claude doctor.]]></description><link>https://vibecodingwithfred.com/de/blog/claude-code-installation-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/de/blog/claude-code-installation-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 26 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;einfuehrung&quot;&gt;Einfuehrung&lt;/h2&gt;
&lt;p&gt;Claude Code ist mein bevorzugtes Kommandozeilen-Tool fuer KI-unterstuetztes Coding. Ob Sie unter Windows, macOS oder Linux arbeiten, die Installation ist unkompliziert mit mehreren Optionen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Native Binary&lt;/strong&gt; (Empfohlen): &lt;code class=&quot;language-text&quot;&gt;curl -fsSL https://claude.ai/install.sh | bash&lt;/code&gt; fuer Linux/macOS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Windows PowerShell&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;irm https://claude.ai/install.ps1 | iex&lt;/code&gt; fuer Windows-Nutzer&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;npm Global Install&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;npm install -g @anthropic-ai/claude-code&lt;/code&gt; fuer Node.js-Umgebungen&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Diese Anleitung behandelt jede Installationsmethode im Detail, plus Fehlerbehebung mit dem &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt;-Befehl zur Diagnose und Behebung haeufiger Probleme.&lt;/p&gt;
&lt;h2 id=&quot;empfohlen-native-binary&quot;&gt;Empfohlen: Native Binary&lt;/h2&gt;
&lt;p&gt;Stand 2025 gibt es mehrere Laufzeitumgebungen, in denen Claude verfuegbar ist, einschliesslich Node.js und Bun.js. Anthropic empfiehlt die Verwendung der nativen Binary-Installation. Diese Methode vermeidet Paketmanager-Konflikte und ist am stabilsten.&lt;/p&gt;
&lt;h3 id=&quot;native-binary-installieren&quot;&gt;Native Binary installieren&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Installations-Script ausfuehren:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Shell-Konfiguration neu laden:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token comment&quot;&gt;# oder fuer zsh-Nutzer:&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.zshrc&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Installation verifizieren:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;
claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Das ist alles! Claude Code sollte jetzt unter &lt;code class=&quot;language-text&quot;&gt;~/.claude/bin/claude&lt;/code&gt; oder &lt;code class=&quot;language-text&quot;&gt;~/.local/bin/claude&lt;/code&gt; installiert sein.&lt;/p&gt;
&lt;h2 id=&quot;fehlerbehebung-kaputte-installationen-reparieren&quot;&gt;Fehlerbehebung: Kaputte Installationen reparieren&lt;/h2&gt;
&lt;p&gt;Wenn Sie Probleme mit Claude Code erleben, wie Segmentation-Fault-Fehler, haben Sie wahrscheinlich eine gemischte oder veraltete Installation. Wenn Sie Claude wie ich von Anfang an nutzen, haben Sie moeglicherweise auch Node.js- oder Bun.js-Versionen installiert. So beheben Sie das:&lt;/p&gt;
&lt;h3 id=&quot;aktuelle-installation-mit-claude-doctor-diagnostizieren&quot;&gt;Aktuelle Installation mit claude doctor diagnostizieren&lt;/h3&gt;
&lt;p&gt;Der &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt;-Befehl ist Ihre erste Anlaufstelle fuer die Fehlerbehebung. Er analysiert Ihre Installation und meldet potenzielle Probleme.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;was-claude-doctor-prueft&quot;&gt;Was claude doctor prueft&lt;/h4&gt;
&lt;p&gt;Der &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt;-Befehl inspiziert:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Installationsmethode&lt;/strong&gt;: Native Binary, npm, Bun oder Homebrew&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Versionsinformationen&lt;/strong&gt;: Aktuelle Version und Update-Status&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Auto-Update-Faehigkeit&lt;/strong&gt;: Ob Updates angewendet werden koennen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Suchfunktionalitaet&lt;/strong&gt;: Ob ripgrep ordnungsgemaess gebundelt/installiert ist&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pfad-Konfiguration&lt;/strong&gt;: Ob Claude korrekt in Ihrem PATH ist&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ausfuehrungspfad&lt;/strong&gt;: Die tatsaechlich ausgefuehrte Binary&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;alle-bestehenden-installationen-entfernen&quot;&gt;ALLE bestehenden Installationen entfernen&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Bun-Installation entfernen&lt;/span&gt;
bun uninstall &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt; ~/.bun/bin/claude

&lt;span class=&quot;token comment&quot;&gt;# npm/Node.js-Installation entfernen&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; uninstall &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code

&lt;span class=&quot;token comment&quot;&gt;# Alle nvm-spezifischen Installationen entfernen&lt;/span&gt;
nvm list
&lt;span class=&quot;token comment&quot;&gt;# Fuer jede Version wechseln und deinstallieren&lt;/span&gt;
nvm use &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;version&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; uninstall &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;brew-uninstall-claude-code&quot;&gt;Brew Uninstall Claude Code&lt;/h3&gt;
&lt;p&gt;Wenn Sie Claude Code via Homebrew installiert haben:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Claude Code von Homebrew deinstallieren&lt;/span&gt;
brew uninstall claude-code

&lt;span class=&quot;token comment&quot;&gt;# Gecachte Dateien bereinigen&lt;/span&gt;
brew cleanup claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;frische-native-binary-installation&quot;&gt;Frische Native Binary Installation&lt;/h3&gt;
&lt;p&gt;Jetzt installieren Sie die native Binary:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;fix-verifizieren&quot;&gt;Fix verifizieren&lt;/h3&gt;
&lt;p&gt;Nach der Installation verifizieren Sie, dass alles funktioniert:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Version pruefen&lt;/span&gt;
claude &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Diagnose ausfuehren&lt;/span&gt;
claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Eine gesunde Installation sollte zeigen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Version: native (2.0.x oder hoeher)&lt;/li&gt;
&lt;li&gt;Config install method: native&lt;/li&gt;
&lt;li&gt;Auto-updates: enabled&lt;/li&gt;
&lt;li&gt;Search: OK (bundled)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;alternative-installationsmethoden&quot;&gt;Alternative Installationsmethoden&lt;/h2&gt;
&lt;p&gt;Waehrend die native Binary empfohlen wird, hier sind andere Optionen:&lt;/p&gt;
&lt;h3 id=&quot;npm-installation-npm-install--g-anthropic-aiclaude-code&quot;&gt;npm Installation: npm install -g @anthropic-ai/claude-code&lt;/h3&gt;
&lt;p&gt;Wenn Sie npm (Node Package Manager) bevorzugen, koennen Sie Claude Code global installieren. Diese Methode erfordert Node.js 18 oder hoeher.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Wichtig:&lt;/strong&gt; Verwenden Sie niemals &lt;code class=&quot;language-text&quot;&gt;sudo npm install -g&lt;/code&gt;, da dies Berechtigungsprobleme verursacht.&lt;/p&gt;
&lt;h3 id=&quot;windows-verwendung-von-irm-httpsclaudeaiinstallps1--iex&quot;&gt;Windows: Verwendung von irm &lt;a href=&quot;https://claude.ai/install.ps1&quot;&gt;https://claude.ai/install.ps1&lt;/a&gt; | iex&lt;/h3&gt;
&lt;p&gt;Fuer Windows-Nutzer haben Sie drei Optionen:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;WSL (Empfohlen)&lt;/strong&gt;: WSL installieren und den Linux-Anweisungen folgen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Git Bash&lt;/strong&gt;: Den nativen Installer mit Git Bash verwenden&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PowerShell&lt;/strong&gt; (Natives Windows):
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;powershell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-powershell line-numbers&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;irm&lt;/span&gt; https:&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;claude&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ai/install&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ps1 &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;iex&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;den-irm-befehl-verstehen&quot;&gt;Den irm-Befehl verstehen&lt;/h4&gt;
&lt;p&gt;Der &lt;code class=&quot;language-text&quot;&gt;irm&lt;/code&gt;-Befehl ist PowerShells &lt;strong&gt;Invoke-RestMethod&lt;/strong&gt;, der Inhalte von einer URL herunterlaed. Hier ist, was der Befehl macht:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;irm https://claude.ai/install.ps1&lt;/code&gt; - Laedt das Installations-Script von Anthropics Servern herunter&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;| iex&lt;/code&gt; - Leitet das Script an &lt;strong&gt;Invoke-Expression&lt;/strong&gt; weiter, das es ausfuehrt&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Das &lt;code class=&quot;language-text&quot;&gt;https://claude.ai/install.ps1&lt;/code&gt;-Script handhabt:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Erkennung Ihrer Windows-Architektur (x64, ARM64)&lt;/li&gt;
&lt;li&gt;Download der entsprechenden Claude Code Binary&lt;/li&gt;
&lt;li&gt;Installation in Ihr Benutzerverzeichnis&lt;/li&gt;
&lt;li&gt;Hinzufuegen von Claude zu Ihrer PATH-Umgebungsvariable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Sicherheitshinweis:&lt;/strong&gt; Verifizieren Sie immer, dass Sie von der offiziellen &lt;code class=&quot;language-text&quot;&gt;claude.ai&lt;/code&gt;-Domain herunterladen, bevor Sie Installations-Scripts ausfuehren.&lt;/p&gt;
&lt;h2 id=&quot;nach-der-installation-setup&quot;&gt;Nach der Installation: Setup&lt;/h2&gt;
&lt;h3 id=&quot;authentifizierung&quot;&gt;Authentifizierung&lt;/h3&gt;
&lt;p&gt;Nach der Installation authentifizieren Sie Claude Code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sie werden aufgefordert, Ihre Authentifizierungsmethode zu waehlen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Claude Console&lt;/strong&gt; (Standard): Fuer API-Zugang mit Abrechnung unter console.anthropic.com&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude Pro/Max&lt;/strong&gt;: Wenn Sie ein Claude-Abonnement haben&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enterprise&lt;/strong&gt;: Fuer AWS Bedrock oder Google Vertex AI Deployments&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;grundlegende-verwendung&quot;&gt;Grundlegende Verwendung&lt;/h3&gt;
&lt;p&gt;Beginnen Sie mit Claude Code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Zu Ihrem Projekt navigieren&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; /pfad/zu/ihrem/projekt

&lt;span class=&quot;token comment&quot;&gt;# Claude Code starten&lt;/span&gt;
claude

&lt;span class=&quot;token comment&quot;&gt;# Hilfe anzeigen&lt;/span&gt;
claude &lt;span class=&quot;token builtin class-name&quot;&gt;help&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# In einer Sitzung Slash-Befehle verwenden&lt;/span&gt;
/help    &lt;span class=&quot;token comment&quot;&gt;# Verfuegbare Befehle anzeigen&lt;/span&gt;
/clear   &lt;span class=&quot;token comment&quot;&gt;# Konversation loeschen&lt;/span&gt;
/exit    &lt;span class=&quot;token comment&quot;&gt;# Claude Code beenden&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;haeufige-probleme-und-loesungen&quot;&gt;Haeufige Probleme und Loesungen&lt;/h2&gt;
&lt;h3 id=&quot;problem-insufficient-permissions-to-install-update&quot;&gt;Problem: &quot;Insufficient permissions to install update&quot;&lt;/h3&gt;
&lt;p&gt;Das passiert typischerweise bei npm/Bun-Installationen. Loesung: Zur nativen Binary-Installation wechseln.&lt;/p&gt;
&lt;h3 id=&quot;problem-command-not-found-claude&quot;&gt;Problem: &quot;command not found: claude&quot;&lt;/h3&gt;
&lt;p&gt;Der PATH wurde nicht aktualisiert. Zu Ihrer Shell-Konfiguration hinzufuegen:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export PATH=&quot;$HOME/.local/bin:$PATH&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;best-practices&quot;&gt;Best Practices&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Immer die native Binary verwenden&lt;/strong&gt;, es sei denn, Sie haben spezifische Anforderungen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;sudo vermeiden&lt;/strong&gt; bei jeder Installationsmethode&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Auto-Updates aktiviert lassen&lt;/strong&gt; fuer Sicherheit und Features&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; ausfuehren&lt;/strong&gt; nach jeder Installation oder jedem Update&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alte Installationen bereinigen&lt;/strong&gt; bevor Sie neue Versionen installieren&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;fazit&quot;&gt;Fazit&lt;/h2&gt;
&lt;p&gt;Denken Sie daran: Im Zweifel alles entfernen und frisch mit der nativen Binary starten. Es ist die einfachste, schnellste und zuverlaessigste Art, Claude Code auszufuehren.&lt;/p&gt;
&lt;h2 id=&quot;weiterfuehrende-lektuere&quot;&gt;Weiterfuehrende Lektuere&lt;/h2&gt;
&lt;p&gt;Jetzt, wo Sie Claude Code installiert haben, setzen Sie es ein:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Einen Warenkorb mit Flask bauen&lt;/a&gt;&lt;/strong&gt; - Ein praktisches Tutorial, in dem Sie Claude Code verwenden koennen, um ein komplettes E-Commerce-Backend mit Python und Flask zu bauen&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;kurzreferenz&quot;&gt;Kurzreferenz&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Installieren&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;curl -fsSL https://claude.ai/install.sh | bash&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Version pruefen&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude --version&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Diagnostizieren&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Aktualisieren&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude update&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Starten&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hilfe&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude help&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Lovable Rueckerstattung: Vom Helden zur Null mit 2.0-Problemen]]></title><description><![CDATA[Erkunden Sie, warum Lovable 2.0 vom Helden zur Null wurde, einschliesslich Rueckerstattungsrichtlinien, Nutzerbeschwerden und Support-Herausforderungen, um Ihnen bei den juengsten Problemen der Plattform zu helfen.]]></description><link>https://vibecodingwithfred.com/de/blog/lovable-from-hero-to-zero/</link><guid isPermaLink="false">https://vibecodingwithfred.com/de/blog/lovable-from-hero-to-zero/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 26 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Erinnern Sie sich, als Lovable der Liebling der KI-Entwicklerwelt war? Ihre intuitive Oberflaeche und zuverlaessige Performance machten sie zu einer bevorzugten Plattform fuer Entwickler aller Erfahrungsstufen. Leider hat dieser Ruf seit der Veroeffentlichung von &lt;strong&gt;Lovable 2.0&lt;/strong&gt; einen dramatischen Sturzflug erlebt, wobei Nutzer auf Reddit und anderen Plattformen ihre Frustration ueber das Update aeussern.&lt;/p&gt;
&lt;h2 id=&quot;die-goldene-aera-von-10&quot;&gt;Die goldene Aera von 1.0&lt;/h2&gt;
&lt;p&gt;Bevor wir in die aktuellen Probleme eintauchen, erinnern wir uns daran, was Lovable besonders gemacht hat:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Intuitive UI&lt;/strong&gt;: Nutzer lobten haeufig die saubere, animierte Oberflaeche, die Entwicklung angenehm machte&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zuverlaessige Performance&lt;/strong&gt;: Projekte funktionierten konsistent mit minimalem Debugging&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Faires Credit-System&lt;/strong&gt;: Nutzer verstanden, wofuer sie bezahlten und wie Credits verwendet wurden&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reaktionsschneller Support&lt;/strong&gt;: Probleme wurden zeitnah mit klarer Kommunikation behandelt&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ein Nutzer erinnerte sich: &quot;Ich habe das 1.0 UI-Design absolut geliebt. Tolle Animationen. Coole Ideen. Einzigartige UI-Kreationen. Ich war super beeindruckt und nutzte Lovable fuer alle meine Projekte.&quot;&lt;/p&gt;
&lt;h2 id=&quot;das-lovable-20-update-was-ging-schief&quot;&gt;Das Lovable 2.0 Update: Was ging schief?&lt;/h2&gt;
&lt;p&gt;Die Veroeffentlichung von &lt;strong&gt;Lovable 2.0&lt;/strong&gt; Anfang 2025 brachte ein komplettes Redesign der Plattform. Waehrend es erweiterte Faehigkeiten versprach, erleben Nutzer zahlreiche kritische Probleme:&lt;/p&gt;
&lt;h3 id=&quot;1-mysterioser-credit-verbrauch&quot;&gt;1. Mysterioser Credit-Verbrauch&lt;/h3&gt;
&lt;p&gt;Nutzer berichten, dass Credits ohne Erklaerung verschwinden:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Ich versetzte mich in den Chat-Modus, stellte ein paar Fragen und machte eine manuelle Bearbeitung an einem Wort... ploetzlich bin ich auf 3/5 taegliche Credits runter?!? Ich bat Lovable zu untersuchen und es konnte mir nicht einmal sagen, wofuer die Credits verwendet wurden!&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;2-ui-regression&quot;&gt;2. UI-Regression&lt;/h3&gt;
&lt;p&gt;Die neue Oberflaeche wurde fast universell kritisiert:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;2.0 UI-Design ist schrecklich. Bitte zurueckrollen!! Ploetzlich rollt 2.0 aus und ich verwende dieselben beschreibenden Prompts, die in 1.0 wunderschoene UI-Kunst erstellten, und jetzt in 2.0 ist es Mist.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;3-kaputte-funktionalitaet&quot;&gt;3. Kaputte Funktionalitaet&lt;/h3&gt;
&lt;p&gt;Viele Nutzer berichten, dass das Update zuvor funktionierende Anwendungen kaputt gemacht hat:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Nachdem ich Lovable fuer die letzten zwei Tage aufgegeben hatte (nachdem ich kurz vor dem Upgrade auf das 100$-Tier upgradet hatte und seit Tagen nichts von ihrem ueberwaeltigten Support-Personal gehoert hatte), beschloss ich, meinen Zeh wieder reinzustecken... Es tat nichts, was ich verlangte.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;4-ueberwaeltigter-support&quot;&gt;4. Ueberwaeltigter Support&lt;/h3&gt;
&lt;p&gt;Der Kundensupport scheint voellig von der Menge der Probleme ueberwaeltigt zu sein:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Ich versuchte, euren &apos;Support&apos; zu kontaktieren und erhielt eine Nachricht, dass er nur fuer zahlende Nutzer verfuegbar ist.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;was-sollten-sie-tun-wenn-sie-von-lovable-20-betroffen-sind&quot;&gt;Was sollten Sie tun, wenn Sie von Lovable 2.0 betroffen sind?&lt;/h2&gt;
&lt;p&gt;Wenn Sie Probleme mit &lt;strong&gt;Lovable 2.0&lt;/strong&gt; erleben, hier sind Ihre Optionen:&lt;/p&gt;
&lt;h3 id=&quot;option-1-zu-externem-hosting-migrieren&quot;&gt;Option 1: Zu externem Hosting migrieren&lt;/h3&gt;
&lt;p&gt;Exportieren Sie Ihr Lovable-Projekt und hosten Sie es woanders fuer bessere Zuverlaessigkeit:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;Zu Cloudflare wechseln&lt;/a&gt; - Beste Performance und unbegrenzte Anfragen&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website/&quot;&gt;Zu Vercel wechseln&lt;/a&gt; - Einfachstes Setup mit automatischen Deployments&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website&quot;&gt;10 kostenlose Hosting-Optionen&lt;/a&gt; - Kompletter Guide zu allen kostenlosen Hosting-Plattformen&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Die Migration gibt Ihnen volle Kontrolle ueber Ihre Codebase und entfernt die Abhaengigkeit von Lovables Plattform-Problemen.&lt;/p&gt;
&lt;h3 id=&quot;option-2-exportieren-und-entwicklung-lokal-fortsetzen&quot;&gt;Option 2: Exportieren und Entwicklung lokal fortsetzen&lt;/h3&gt;
&lt;p&gt;Laden Sie Ihren Projektcode herunter und setzen Sie die Entwicklung in VS Code mit voller Kontrolle ueber Ihre Codebase fort.&lt;/p&gt;
&lt;h3 id=&quot;option-3-auf-fixes-warten&quot;&gt;Option 3: Auf Fixes warten&lt;/h3&gt;
&lt;p&gt;Ueberwachen Sie die Lovable-Community und Support-Kanaele auf Updates und Bugfixes. Angesichts des Umfangs der gemeldeten Probleme kann dies jedoch betraechtliche Zeit in Anspruch nehmen.&lt;/p&gt;
&lt;h3 id=&quot;wie-sie-ihr-lovable-projekt-exportieren&quot;&gt;Wie Sie Ihr Lovable-Projekt exportieren&lt;/h3&gt;
&lt;p&gt;Unabhaengig davon, welchen Weg Sie waehlen, stellt der Export Ihres Projekts sicher, dass Sie nicht eingesperrt sind und volle Eigentumsrechte an Ihrer Arbeit haben:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;In Lovable&lt;/strong&gt;: Klicken Sie auf Menue-Symbol -&gt; Export -&gt; Als ZIP herunterladen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Extrahieren&lt;/strong&gt; Sie die ZIP-Datei, um auf Ihre vollstaendige Codebase zuzugreifen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zu Git pushen&lt;/strong&gt; fuer Versionskontrolle und Deployment&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ueberall deployen&lt;/strong&gt;: Ihr Code funktioniert auf jeder Plattform, die React unterstuetzt&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Sehen Sie unsere kompletten Migrations-Guides fuer Schritt-fuer-Schritt-Anleitungen.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Guida Installazione Claude Code: Script irm, Setup npm e Script https://claude.ai/install.ps1]]></title><description><![CDATA[Setup CLI IDE Claude Code passo-passo, installazione e disinstallazione del binario nativo, npm e troubleshooting con claude doctor.]]></description><link>https://vibecodingwithfred.com/it/blog/claude-code-installation-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/it/blog/claude-code-installation-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 26 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;introduzione&quot;&gt;Introduzione&lt;/h2&gt;
&lt;p&gt;Claude Code e il mio strumento da riga di comando preferito per il coding assistito dall&apos;AI. Che tu sia su Windows, macOS o Linux, l&apos;installazione e semplice con diverse opzioni:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Binario Nativo&lt;/strong&gt; (Raccomandato): &lt;code class=&quot;language-text&quot;&gt;curl -fsSL https://claude.ai/install.sh | bash&lt;/code&gt; per Linux/macOS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Windows PowerShell&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;irm https://claude.ai/install.ps1 | iex&lt;/code&gt; per utenti Windows&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Installazione Globale npm&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;npm install -g @anthropic-ai/claude-code&lt;/code&gt; per ambienti Node.js&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Questa guida copre ogni metodo di installazione in dettaglio, piu il troubleshooting con il comando &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; per diagnosticare e risolvere problemi comuni.&lt;/p&gt;
&lt;h2 id=&quot;raccomandato-binario-nativo&quot;&gt;Raccomandato: Binario Nativo&lt;/h2&gt;
&lt;p&gt;Dal 2025, ci sono diversi runtime in cui Claude e disponibile, inclusi node.js e bun.js. Anthropic raccomanda l&apos;installazione del binario nativo. Questo metodo evita conflitti del package manager ed e il piu stabile.&lt;/p&gt;
&lt;h3 id=&quot;installare-il-binario-nativo&quot;&gt;Installare il Binario Nativo&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Esegui lo script di installazione:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ricarica la configurazione della tua shell:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token comment&quot;&gt;# o per utenti zsh:&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.zshrc&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Verifica l&apos;installazione:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;
claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;E tutto! Claude Code dovrebbe ora essere installato in &lt;code class=&quot;language-text&quot;&gt;~/.claude/bin/claude&lt;/code&gt; o &lt;code class=&quot;language-text&quot;&gt;~/.local/bin/claude&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;troubleshooting-risolvere-installazioni-problematiche&quot;&gt;Troubleshooting: Risolvere Installazioni Problematiche&lt;/h2&gt;
&lt;p&gt;Se stai riscontrando problemi con Claude Code come errori di segmentation fault, probabilmente hai un&apos;installazione mista o obsoleta. Se usi Claude dall&apos;inizio come me, potresti avere versioni node.js o bun.js installate. Ecco come risolvere:&lt;/p&gt;
&lt;h3 id=&quot;diagnostica-la-tua-installazione-attuale-con-claude-doctor&quot;&gt;Diagnostica la Tua Installazione Attuale con claude doctor&lt;/h3&gt;
&lt;p&gt;Il comando &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; e il tuo primo stop per il troubleshooting. Analizza la tua installazione e riporta potenziali problemi.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;cosa-controlla-claude-doctor&quot;&gt;Cosa Controlla claude doctor&lt;/h4&gt;
&lt;p&gt;Il comando &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; ispeziona:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Metodo di installazione&lt;/strong&gt;: Binario nativo, npm, Bun, o Homebrew&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Informazioni versione&lt;/strong&gt;: Versione attuale e stato aggiornamenti&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Capacita auto-aggiornamento&lt;/strong&gt;: Se gli aggiornamenti possono essere applicati&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Funzionalita di ricerca&lt;/strong&gt;: Se ripgrep e correttamente bundled/installato&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configurazione PATH&lt;/strong&gt;: Se Claude e nel tuo PATH correttamente&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Percorso di esecuzione&lt;/strong&gt;: L&apos;effettivo binario in esecuzione&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;output-problematici-comuni&quot;&gt;Output Problematici Comuni&lt;/h4&gt;
&lt;p&gt;Fai attenzione a questi segnali di avvertimento nell&apos;output di &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;unknown (2.0.0)&lt;/code&gt; - Rilevamento versione fallito, probabilmente installazione mista&lt;/li&gt;
&lt;li&gt;Percorsi misti tra Bun, npm e Node.js&lt;/li&gt;
&lt;li&gt;Percorso di invocazione diverso dal percorso di esecuzione&lt;/li&gt;
&lt;li&gt;Auto-aggiornamenti disabilitati o falliti&lt;/li&gt;
&lt;li&gt;Stato ricerca che mostra errori&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Controlla anche installazioni multiple che potrebbero essere in conflitto:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;which&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; claude&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;rimuovi-tutte-le-installazioni-esistenti&quot;&gt;Rimuovi TUTTE le Installazioni Esistenti&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Rimuovi installazione Bun&lt;/span&gt;
bun uninstall &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt; ~/.bun/bin/claude

&lt;span class=&quot;token comment&quot;&gt;# Rimuovi installazione npm/Node.js&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; uninstall &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code

&lt;span class=&quot;token comment&quot;&gt;# Rimuovi installazioni specifiche nvm&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Controlla ogni versione Node nvm che hai&lt;/span&gt;
nvm list
&lt;span class=&quot;token comment&quot;&gt;# Per ogni versione, passa ad essa e disinstalla&lt;/span&gt;
nvm use &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;version&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; uninstall &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;disinstallazione-brew-di-claude-code&quot;&gt;Disinstallazione Brew di Claude Code&lt;/h3&gt;
&lt;p&gt;Se hai installato Claude Code via Homebrew:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Disinstalla Claude Code da Homebrew&lt;/span&gt;
brew uninstall claude-code

&lt;span class=&quot;token comment&quot;&gt;# Pulisci eventuali file in cache&lt;/span&gt;
brew cleanup claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Dopo la disinstallazione via brew, puoi passare all&apos;installazione del binario nativo per un miglior supporto auto-aggiornamento.&lt;/p&gt;
&lt;h3 id=&quot;step-3-pulisci-configurazione-e-cache&quot;&gt;Step 3: Pulisci Configurazione e Cache&lt;/h3&gt;
&lt;p&gt;Rimuovi eventuali file di configurazione residui:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Rimuovi directory config Claude Code&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-rf&lt;/span&gt; ~/.claude-code
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-rf&lt;/span&gt; ~/.config/claude-code
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-rf&lt;/span&gt; ~/.cache/claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-4-installazione-fresca-del-binario-nativo&quot;&gt;Step 4: Installazione Fresca del Binario Nativo&lt;/h3&gt;
&lt;p&gt;Ora installa il binario nativo:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-5-verifica-la-correzione&quot;&gt;Step 5: Verifica la Correzione&lt;/h3&gt;
&lt;p&gt;Dopo l&apos;installazione, verifica che tutto funzioni:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Controlla versione&lt;/span&gt;
claude &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Esegui diagnostica&lt;/span&gt;
claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Un&apos;installazione sana dovrebbe mostrare:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Version: native (2.0.x o superiore)&lt;/li&gt;
&lt;li&gt;Config install method: native&lt;/li&gt;
&lt;li&gt;Auto-updates: enabled&lt;/li&gt;
&lt;li&gt;Search: OK (bundled)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;metodi-di-installazione-alternativi&quot;&gt;Metodi di Installazione Alternativi&lt;/h2&gt;
&lt;p&gt;Mentre il binario nativo e raccomandato, ecco altre opzioni:&lt;/p&gt;
&lt;h3 id=&quot;installazione-npm-npm-install--g-anthropic-aiclaude-code&quot;&gt;Installazione npm: npm install -g @anthropic-ai/claude-code&lt;/h3&gt;
&lt;p&gt;Se preferisci usare npm (Node Package Manager), puoi installare Claude Code globalmente. Questo metodo richiede Node.js 18 o superiore.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;cosa-fa-npm-install--g&quot;&gt;Cosa Fa npm install -g&lt;/h4&gt;
&lt;p&gt;Il flag &lt;code class=&quot;language-text&quot;&gt;-g&lt;/code&gt; installa il pacchetto globalmente, rendendo &lt;code class=&quot;language-text&quot;&gt;claude&lt;/code&gt; disponibile come comando ovunque nel tuo terminale. Il pacchetto &lt;code class=&quot;language-text&quot;&gt;@anthropic-ai/claude-code&lt;/code&gt; e il pacchetto npm ufficiale mantenuto da Anthropic.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Benefici dell&apos;installazione npm:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Workflow familiare per sviluppatori Node.js&lt;/li&gt;
&lt;li&gt;Facile da gestire insieme ad altri pacchetti globali&lt;/li&gt;
&lt;li&gt;Funziona bene in ambienti containerizzati/CI&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Svantaggi:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Richiede runtime Node.js&lt;/li&gt;
&lt;li&gt;Potrebbe essere in conflitto con altri package manager (Bun, pnpm)&lt;/li&gt;
&lt;li&gt;Gli aggiornamenti richiedono &lt;code class=&quot;language-text&quot;&gt;npm update -g @anthropic-ai/claude-code&lt;/code&gt; manuale&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Importante:&lt;/strong&gt; Non usare mai &lt;code class=&quot;language-text&quot;&gt;sudo npm install -g&lt;/code&gt; perche causa problemi di permessi. Se ottieni errori EACCES, correggi i permessi npm invece.&lt;/p&gt;
&lt;h3 id=&quot;installazione-versione-specifica&quot;&gt;Installazione Versione Specifica&lt;/h3&gt;
&lt;p&gt;Per installare una versione specifica del binario nativo:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Installa versione piu recente&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; latest

&lt;span class=&quot;token comment&quot;&gt;# Installa versione specifica&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.0&lt;/span&gt;.22&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;istruzioni-specifiche-per-piattaforma&quot;&gt;Istruzioni Specifiche per Piattaforma&lt;/h2&gt;
&lt;h3 id=&quot;macos-con-homebrew&quot;&gt;macOS con Homebrew&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Nota: Le installazioni Homebrew si auto-aggiornano indipendentemente dalla directory brew.&lt;/p&gt;
&lt;h3 id=&quot;windows-usando-irm-httpsclaudeaiinstallps1--iex&quot;&gt;Windows: Usando irm &lt;a href=&quot;https://claude.ai/install.ps1&quot;&gt;https://claude.ai/install.ps1&lt;/a&gt; | iex&lt;/h3&gt;
&lt;p&gt;Per utenti Windows, hai tre opzioni:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;WSL (Raccomandato)&lt;/strong&gt;: Installa WSL e segui le istruzioni Linux&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Git Bash&lt;/strong&gt;: Usa l&apos;installer nativo con Git Bash&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PowerShell&lt;/strong&gt; (Windows Nativo):
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;powershell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-powershell line-numbers&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;irm&lt;/span&gt; https:&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;claude&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ai/install&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ps1 &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;iex&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;capire-il-comando-irm&quot;&gt;Capire il Comando irm&lt;/h4&gt;
&lt;p&gt;Il comando &lt;code class=&quot;language-text&quot;&gt;irm&lt;/code&gt; e &lt;strong&gt;Invoke-RestMethod&lt;/strong&gt; di PowerShell, che scarica contenuto da un URL. Ecco cosa fa il comando:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;irm https://claude.ai/install.ps1&lt;/code&gt; - Scarica lo script di installazione dai server di Anthropic&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;| iex&lt;/code&gt; - Passa lo script a &lt;strong&gt;Invoke-Expression&lt;/strong&gt;, che lo esegue&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lo script &lt;code class=&quot;language-text&quot;&gt;https://claude.ai/install.ps1&lt;/code&gt; gestisce:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rilevamento della tua architettura Windows (x64, ARM64)&lt;/li&gt;
&lt;li&gt;Download del binario Claude Code appropriato&lt;/li&gt;
&lt;li&gt;Installazione nella tua directory utente&lt;/li&gt;
&lt;li&gt;Aggiunta di Claude alla tua variabile d&apos;ambiente PATH&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Nota sulla Sicurezza:&lt;/strong&gt; Verifica sempre di star scaricando dal dominio ufficiale &lt;code class=&quot;language-text&quot;&gt;claude.ai&lt;/code&gt; prima di eseguire script di installazione.&lt;/p&gt;
&lt;h3 id=&quot;alpine-linux&quot;&gt;Alpine Linux&lt;/h3&gt;
&lt;p&gt;Alpine e altre distribuzioni basate su musl necessitano dipendenze aggiuntive:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;apk &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; libgcc libstdc++ ripgrep
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;USE_BUILTIN_RIPGREP&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;setup-post-installazione&quot;&gt;Setup Post-Installazione&lt;/h2&gt;
&lt;h3 id=&quot;autenticazione&quot;&gt;Autenticazione&lt;/h3&gt;
&lt;p&gt;Dopo l&apos;installazione, autentica Claude Code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ti verra chiesto di scegliere il tuo metodo di autenticazione:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Claude Console&lt;/strong&gt; (default): Per accesso API con fatturazione su console.anthropic.com&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude Pro/Max&lt;/strong&gt;: Se hai un abbonamento Claude&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enterprise&lt;/strong&gt;: Per deployment AWS Bedrock o Google Vertex AI&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;uso-base&quot;&gt;Uso Base&lt;/h3&gt;
&lt;p&gt;Inizia a usare Claude Code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Naviga al tuo progetto&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; /path/to/your/project

&lt;span class=&quot;token comment&quot;&gt;# Avvia Claude Code&lt;/span&gt;
claude

&lt;span class=&quot;token comment&quot;&gt;# Ottieni aiuto&lt;/span&gt;
claude &lt;span class=&quot;token builtin class-name&quot;&gt;help&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# All&apos;interno di una sessione, usa comandi slash&lt;/span&gt;
/help    &lt;span class=&quot;token comment&quot;&gt;# Mostra comandi disponibili&lt;/span&gt;
/clear   &lt;span class=&quot;token comment&quot;&gt;# Pulisci conversazione&lt;/span&gt;
/exit    &lt;span class=&quot;token comment&quot;&gt;# Esci da Claude Code&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;gestione-aggiornamenti&quot;&gt;Gestione Aggiornamenti&lt;/h2&gt;
&lt;h3 id=&quot;auto-aggiornamenti&quot;&gt;Auto-Aggiornamenti&lt;/h3&gt;
&lt;p&gt;Claude Code si aggiorna automaticamente per default. Gli aggiornamenti sono controllati all&apos;avvio e applicati in background.&lt;/p&gt;
&lt;h3 id=&quot;come-aggiornare-claude-code&quot;&gt;Come aggiornare Claude Code&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude update&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Aggiungi questo al tuo &lt;code class=&quot;language-text&quot;&gt;.bashrc&lt;/code&gt; o &lt;code class=&quot;language-text&quot;&gt;.zshrc&lt;/code&gt; per renderlo permanente.&lt;/p&gt;
&lt;h2 id=&quot;problemi-comuni-e-soluzioni&quot;&gt;Problemi Comuni e Soluzioni&lt;/h2&gt;
&lt;h3 id=&quot;problema-insufficient-permissions-to-install-update&quot;&gt;Problema: &quot;Insufficient permissions to install update&quot;&lt;/h3&gt;
&lt;p&gt;Questo succede tipicamente con installazioni npm/Bun. Soluzione: Passa all&apos;installazione del binario nativo.&lt;/p&gt;
&lt;h3 id=&quot;problema-command-not-found-claude&quot;&gt;Problema: &quot;command not found: claude&quot;&lt;/h3&gt;
&lt;p&gt;Il PATH non e stato aggiornato. Aggiungi alla configurazione della tua shell:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export PATH=&quot;$HOME/.local/bin:$PATH&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;problema-funzionalita-di-ricerca-non-funzionante&quot;&gt;Problema: Funzionalita di ricerca non funzionante&lt;/h3&gt;
&lt;p&gt;Di solito risolto dall&apos;installazione nativa, ma se persiste:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Installa ripgrep manualmente&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;apt-get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; ripgrep  &lt;span class=&quot;token comment&quot;&gt;# Ubuntu/Debian&lt;/span&gt;
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; ripgrep          &lt;span class=&quot;token comment&quot;&gt;# macOS&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;best-practice&quot;&gt;Best Practice&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Usa sempre il binario nativo&lt;/strong&gt; a meno che tu non abbia requisiti specifici&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Evita sudo&lt;/strong&gt; con qualsiasi metodo di installazione&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mantieni gli auto-aggiornamenti abilitati&lt;/strong&gt; per sicurezza e funzionalita&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Esegui &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt;&lt;/strong&gt; dopo ogni installazione o aggiornamento&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pulisci le vecchie installazioni&lt;/strong&gt; prima di installare nuove versioni&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;conclusione&quot;&gt;Conclusione&lt;/h2&gt;
&lt;p&gt;Ricorda: quando hai dubbi, rimuovi tutto e ricomincia da zero con il binario nativo. E il modo piu semplice, veloce e affidabile per eseguire Claude Code.&lt;/p&gt;
&lt;h2 id=&quot;letture-correlate&quot;&gt;Letture Correlate&lt;/h2&gt;
&lt;p&gt;Ora che hai Claude Code installato, mettilo al lavoro:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Costruisci un Carrello con Flask&lt;/a&gt;&lt;/strong&gt; - Un tutorial pratico dove puoi usare Claude Code per costruire un backend e-commerce completo con Python e Flask&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;riferimento-rapido&quot;&gt;Riferimento Rapido&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Installa&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;curl -fsSL https://claude.ai/install.sh | bash&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Controlla versione&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude --version&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Diagnostica&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Aggiorna&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude update&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Avvia&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Aiuto&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude help&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Rimborso Lovable: Da Eroe a Zero con i Problemi del 2.0]]></title><description><![CDATA[Esplora perche Lovable 2.0 e passato da eroe a zero, incluse le politiche di rimborso, le lamentele degli utenti e le sfide del supporto per aiutarti a navigare i recenti problemi della piattaforma.]]></description><link>https://vibecodingwithfred.com/it/blog/lovable-from-hero-to-zero/</link><guid isPermaLink="false">https://vibecodingwithfred.com/it/blog/lovable-from-hero-to-zero/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 26 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Ricordi quando Lovable era il beniamino del mondo dello sviluppo AI? La sua interfaccia intuitiva e le prestazioni affidabili lo rendevano una piattaforma di riferimento per sviluppatori di tutti i livelli. Sfortunatamente, quella reputazione ha subito un drammatico crollo dal rilascio di &lt;strong&gt;Lovable 2.0&lt;/strong&gt;, con utenti su Reddit e altre piattaforme che esprimono le loro frustrazioni riguardo all&apos;aggiornamento.&lt;/p&gt;
&lt;h2 id=&quot;lera-doro-del-10&quot;&gt;L&apos;Era d&apos;Oro del 1.0&lt;/h2&gt;
&lt;p&gt;Prima di immergerci nei problemi attuali, ricordiamo cosa rendeva Lovable speciale:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;UI Intuitiva&lt;/strong&gt;: Gli utenti elogiavano frequentemente l&apos;interfaccia pulita e animata che rendeva lo sviluppo piacevole&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prestazioni Affidabili&lt;/strong&gt;: I progetti funzionavano costantemente con minimo debugging richiesto&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sistema di Crediti Equo&lt;/strong&gt;: Gli utenti capivano per cosa stavano pagando e come venivano usati i crediti&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Supporto Reattivo&lt;/strong&gt;: I problemi venivano affrontati prontamente, con comunicazione chiara&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Un utente ha ricordato: &quot;Mi piaceva assolutamente il design UI del 1.0. Ottime animazioni. Idee interessanti. Creazioni UI uniche. Ero super impressionato e usavo Lovable per tutti i miei progetti.&quot;&lt;/p&gt;
&lt;h2 id=&quot;laggiornamento-lovable-20-cosa-e-andato-storto&quot;&gt;L&apos;Aggiornamento Lovable 2.0: Cosa E Andato Storto?&lt;/h2&gt;
&lt;p&gt;Il rilascio di &lt;strong&gt;Lovable 2.0&lt;/strong&gt; all&apos;inizio del 2025 ha portato una riprogettazione completa della piattaforma. Pur promettendo capacita migliorate, gli utenti stanno sperimentando numerosi problemi critici:&lt;/p&gt;
&lt;h3 id=&quot;1-consumo-misterioso-dei-crediti&quot;&gt;1. Consumo Misterioso dei Crediti&lt;/h3&gt;
&lt;p&gt;Gli utenti riportano crediti che scompaiono senza spiegazione:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Mi sono messo in modalita chat, ho fatto un paio di domande e fatto una modifica manuale a una parola... improvvisamente sono sceso a 3/5 crediti giornalieri?!? Ho chiesto a Lovable di indagare e non e riuscito nemmeno a dirmi per cosa sono stati usati i crediti!&quot; - u/neuralgroov2&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Un altro utente ha condiviso: &quot;Stavo pagando un abbonamento scale 1 quando e arrivato questo nuovo aggiornamento... All&apos;epoca avevo ancora 360 crediti che avevo gia pagato, e dopo aver cancellato / declassato il mio abbonamento, ne avevo solo 5. Ma sul serio, Lovable?&quot;&lt;/p&gt;
&lt;h3 id=&quot;2-regressione-dellui&quot;&gt;2. Regressione dell&apos;UI&lt;/h3&gt;
&lt;p&gt;La nuova interfaccia e stata quasi universalmente stroncata:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Il design UI del 2.0 e orribile. Per favore tornate indietro!! All&apos;improvviso esce il 2.0 e sto usando gli stessi prompt descrittivi che creavano bellissima arte UI nel 1.0 e ora nel 2.0 e cacca. Blando noioso niente animazioni brutte idee UI banali che sembrano come se fossero tornati ai primi anni 2000 per il design UI.&quot; - u/digitalml&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;3-funzionalita-rotte&quot;&gt;3. Funzionalita Rotte&lt;/h3&gt;
&lt;p&gt;Molti utenti riportano che l&apos;aggiornamento ha rotto applicazioni che prima funzionavano:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Dopo aver rinunciato a Lovable per gli ultimi due giorni (dopo essere passato al tier da $100 appena prima dell&apos;upgrade e non avendo avuto risposta dal loro staff di supporto sommerso per giorni), ho deciso di rituffarmi... Non ha fatto niente di quello che gli ho chiesto. Ha aggiunto due link di login nell&apos;header, e rimosso tutto il contenuto della home page con 20 card che davano 404.&quot; - u/who_am_i_to_say_so&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Un altro utente ha condiviso: &quot;Ho speso piu di 20 crediti cercando di sistemare un codice che risulta nella mia app bloccata su una &apos;pagina di caricamento&apos;. L&apos;AI sembra credere con sicurezza che sia sistemato ma non lo e, continuo ad andare in cerchio.&quot;&lt;/p&gt;
&lt;h3 id=&quot;4-supporto-sommerso&quot;&gt;4. Supporto Sommerso&lt;/h3&gt;
&lt;p&gt;Il supporto clienti sembra essere completamente sommerso dal volume dei problemi:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Ho provato a contattare il vostro &apos;supporto&apos; e ho ricevuto un messaggio che diceva che e disponibile solo per gli utenti paganti.&quot; - u/AI_4U&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Anche gli utenti paganti riportano di aspettare giorni per le risposte: &quot;Dopo essere passato al tier da $100 appena prima dell&apos;upgrade e non avendo avuto risposta dal loro staff di supporto sommerso per giorni...&quot;&lt;/p&gt;
&lt;h3 id=&quot;5-promesse-seo-vs-realta&quot;&gt;5. Promesse SEO vs. Realta&lt;/h3&gt;
&lt;p&gt;Diversi utenti hanno sottolineato discrepanze tra quello che Lovable promette e quello che offre:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Perche parlano di SEO quando le loro app sono CSR e non hanno alcuna capacita SEO?&quot; - u/VisionaryOS&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Questo ha portato sviluppatori di terze parti a creare strumenti per affrontare le carenze di Lovable, con un utente che ha annunciato: &quot;Ho costruito uno strumento per aiutarti nei tuoi progetti Lovable e impedire che diventino spaghetti.&quot;&lt;/p&gt;
&lt;h2 id=&quot;risposta-della-community&quot;&gt;Risposta della Community&lt;/h2&gt;
&lt;p&gt;La risposta della community e stata rapida e severa. Molti utenti chiedono a Lovable di tornare alla versione 1.0:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Questa non e una minaccia ma consideratela un avvertimento. Cosi muoiono le aziende (start up) o vengono cancellate. Se non tornate al 1.0 e rimborsate i crediti persi cosi che possiamo sistemare le app che la vostra piattaforma aggiornata ha distrutto... non avrete altra scelta che affrontare un&apos;azione di cancellazione.&quot; - u/r4g3z29&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Altri chiedono rimborsi:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Lovable; dovete rimborsare alcuni di questi crediti, fare qualcosa, affrontare i problemi. Penso che sia giusto; ci deve essere qualche tipo di rimborso in termini di crediti, 2.Lento non funziona bene e non siamo solo una manciata di noi.&quot; - u/Horror_Brother67&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;preoccupazioni-sulla-qualita-del-codice&quot;&gt;Preoccupazioni sulla Qualita del Codice&lt;/h2&gt;
&lt;p&gt;Alcuni utenti hanno persino iniziato ad analizzare la qualita del codice delle applicazioni generate da Lovable, con risultati preoccupanti:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Ho dato il mio progetto github a grok e ho pensato..... wow. Voto Sicurezza: 4/10, Voto Testing: 2/10&quot; - u/adreportcard&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Questo suggerisce che oltre ai problemi di interfaccia e crediti, potrebbero esserci problemi fondamentali con il codice che Lovable 2.0 sta generando.&lt;/p&gt;
&lt;h2 id=&quot;ce-speranza-per-lovable-20&quot;&gt;C&apos;e Speranza per Lovable 2.0?&lt;/h2&gt;
&lt;p&gt;Mentre alcuni utenti stanno ancora trovando successo con &lt;strong&gt;Lovable 2.0&lt;/strong&gt;, il sentiment generale e negativo. Un utente ha condiviso un prompt di sistema che ha creato per cercare di migliorare le prestazioni:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Lo uso da una settimana, e sembra ridurre la testardaggine e le riscritture di codice indesiderate. Mentre Lovable stesso ha recentemente fatto modifiche per riscrivere solo le righe necessarie, non e stato consistente.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Questo suggerisce che con workaround significativi, gli utenti potrebbero essere in grado di salvare qualche funzionalita, ma e ben lontano dall&apos;esperienza fluida promessa.&lt;/p&gt;
&lt;h2 id=&quot;lezioni-apprese&quot;&gt;Lezioni Apprese&lt;/h2&gt;
&lt;p&gt;Il fiasco di Lovable 2.0 offre diverse lezioni importanti sia per gli utenti che per le aziende:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Testare accuratamente prima dei rilasci importanti&lt;/strong&gt;: Il volume e la gravita dei problemi suggeriscono testing inadeguato&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mantenere comunicazione trasparente&lt;/strong&gt;: Molti utenti citano la mancanza di informazioni chiare su cosa sta succedendo&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Considerare rollout graduali&lt;/strong&gt;: Una transizione graduale avrebbe potuto prevenire lo shock dei cambiamenti improvvisi&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Avere supporto adeguato pronto&lt;/strong&gt;: I sistemi di supporto dovrebbero scalare con i problemi anticipati&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fornire opzioni di rollback&lt;/strong&gt;: Quando le cose vanno male, gli utenti hanno bisogno di un modo per tornare a quello che funzionava&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;qual-e-la-tua-esperienza&quot;&gt;Qual E la Tua Esperienza?&lt;/h2&gt;
&lt;p&gt;Hai usato Lovable prima e dopo l&apos;aggiornamento 2.0? Condividi le tue esperienze nei commenti qui sotto. E se hai trovato buone alternative con supporto migliore, mi piacerebbe sentirne parlare!&lt;/p&gt;
&lt;p&gt;Come un utente ha giustamente detto: &quot;Questo aggiornamento 2.0 e davvero il peggior aggiornamento che abbia mai visto.&quot; Per una piattaforma che un tempo mostrava cosi tante promesse, e una caduta devastante dalla grazia.&lt;/p&gt;
&lt;h2 id=&quot;cosa-dovresti-fare-se-sei-colpito-da-lovable-20&quot;&gt;Cosa Dovresti Fare Se Sei Colpito da Lovable 2.0?&lt;/h2&gt;
&lt;p&gt;Se stai sperimentando problemi con &lt;strong&gt;Lovable 2.0&lt;/strong&gt;, ecco le tue opzioni:&lt;/p&gt;
&lt;h3 id=&quot;opzione-1-migrare-a-hosting-esterno&quot;&gt;Opzione 1: Migrare a Hosting Esterno&lt;/h3&gt;
&lt;p&gt;Esporta il tuo progetto Lovable e ospitalo altrove per maggiore affidabilita:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;Passa a Cloudflare&lt;/a&gt; - Migliori prestazioni e richieste illimitate&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website/&quot;&gt;Passa a Vercel&lt;/a&gt; - Setup piu facile con deployment automatici&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website&quot;&gt;10 Opzioni di Hosting Gratuito&lt;/a&gt; - Guida completa a tutte le piattaforme di hosting gratuite&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Migrare ti da controllo completo sulla tua codebase e rimuove la dipendenza dai problemi della piattaforma Lovable.&lt;/p&gt;
&lt;h3 id=&quot;opzione-2-esporta-e-continua-lo-sviluppo-localmente&quot;&gt;Opzione 2: Esporta e Continua lo Sviluppo Localmente&lt;/h3&gt;
&lt;p&gt;Scarica il codice del tuo progetto e continua lo sviluppo in VS Code con controllo completo sulla tua codebase. Questo ti permette di:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sistemare problemi che Lovable non riesce a risolvere&lt;/li&gt;
&lt;li&gt;Migliorare qualita del codice e sicurezza&lt;/li&gt;
&lt;li&gt;Aggiungere funzionalita personalizzate senza limiti di crediti&lt;/li&gt;
&lt;li&gt;Lavorare offline senza dipendenze dalla piattaforma&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;opzione-3-aspettare-le-correzioni&quot;&gt;Opzione 3: Aspettare le Correzioni&lt;/h3&gt;
&lt;p&gt;Monitora la community di Lovable e i canali di supporto per aggiornamenti e bug fix. Tuttavia, data la scala dei problemi riportati, questo potrebbe richiedere tempo considerevole.&lt;/p&gt;
&lt;h3 id=&quot;come-esportare-il-tuo-progetto-lovable&quot;&gt;Come Esportare il Tuo Progetto Lovable&lt;/h3&gt;
&lt;p&gt;Indipendentemente da quale percorso scegli, esportare il tuo progetto assicura che tu non sia bloccato e abbia piena proprieta del tuo lavoro:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;In Lovable&lt;/strong&gt;: Clicca icona menu -&gt; Esporta -&gt; Scarica come ZIP&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Estrai&lt;/strong&gt; il file ZIP per accedere alla tua codebase completa&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Push su Git&lt;/strong&gt; per controllo versione e deployment&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deploya ovunque&lt;/strong&gt;: Il tuo codice funziona su qualsiasi piattaforma che supporta React&lt;/li&gt;
&lt;/ol&gt;</content:encoded></item><item><title><![CDATA[Claude Codeインストールガイド: irmスクリプト、npmセットアップ、https://claude.ai/install.ps1スクリプト]]></title><description><![CDATA[ステップバイステップのClaude Code CLI IDEセットアップ、ネイティブバイナリのインストールとアンインストール、npmとclaude doctorによるトラブルシューティング。]]></description><link>https://vibecodingwithfred.com/ja/blog/claude-code-installation-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/ja/blog/claude-code-installation-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 26 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;はじめに&quot;&gt;はじめに&lt;/h2&gt;
&lt;p&gt;Claude Codeは私のAI支援コーディングのためのお気に入りのコマンドラインツールです。Windows、macOS、Linuxのいずれでも、複数のオプションでインストールは簡単です：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ネイティブバイナリ&lt;/strong&gt;（推奨）：Linux/macOSの場合 &lt;code class=&quot;language-text&quot;&gt;curl -fsSL https://claude.ai/install.sh | bash&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Windows PowerShell&lt;/strong&gt;：Windowsユーザーの場合 &lt;code class=&quot;language-text&quot;&gt;irm https://claude.ai/install.ps1 | iex&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;npm グローバルインストール&lt;/strong&gt;：Node.js環境の場合 &lt;code class=&quot;language-text&quot;&gt;npm install -g @anthropic-ai/claude-code&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;このガイドでは、各インストール方法を詳しく説明し、さらに&lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt;コマンドを使用した一般的な問題の診断と修正についてのトラブルシューティングも扱います。&lt;/p&gt;
&lt;h2 id=&quot;推奨ネイティブバイナリ&quot;&gt;推奨：ネイティブバイナリ&lt;/h2&gt;
&lt;p&gt;2025年現在、Claudeはnode.jsやbun.jsを含む複数のランタイムで利用可能です。Anthropicはネイティブバイナリインストールの使用を推奨しています。この方法はパッケージマネージャーの競合を避け、最も安定しています。&lt;/p&gt;
&lt;h3 id=&quot;ネイティブバイナリのインストール&quot;&gt;ネイティブバイナリのインストール&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;インストールスクリプトを実行：&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;シェル設定をリロード：&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token comment&quot;&gt;# または zsh ユーザーの場合：&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.zshrc&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;インストールを確認：&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;
claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;以上です！Claude Codeは&lt;code class=&quot;language-text&quot;&gt;~/.claude/bin/claude&lt;/code&gt;または&lt;code class=&quot;language-text&quot;&gt;~/.local/bin/claude&lt;/code&gt;にインストールされているはずです。&lt;/p&gt;
&lt;h2 id=&quot;トラブルシューティング壊れたインストールの修正&quot;&gt;トラブルシューティング：壊れたインストールの修正&lt;/h2&gt;
&lt;p&gt;セグメンテーションフォールトエラーなどClaude Codeで問題が発生している場合、混合または古いインストールがある可能性があります。私のように最初からClaudeを使用している場合、node.jsまたはbun.jsバージョンもインストールされているかもしれません。以下はその修正方法です：&lt;/p&gt;
&lt;h3 id=&quot;claude-doctorで現在のインストールを診断&quot;&gt;claude doctorで現在のインストールを診断&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt;コマンドはトラブルシューティングの最初のステップです。インストールを分析し、潜在的な問題を報告します。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;claude-doctorがチェックすること&quot;&gt;claude doctorがチェックすること&lt;/h4&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt;コマンドは以下を検査します：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;インストール方法&lt;/strong&gt;：ネイティブバイナリ、npm、Bun、またはHomebrew&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;バージョン情報&lt;/strong&gt;：現在のバージョンと更新状況&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自動更新機能&lt;/strong&gt;：更新を適用できるかどうか&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;検索機能&lt;/strong&gt;：ripgrepが適切にバンドル/インストールされているか&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;パス設定&lt;/strong&gt;：ClaudeがPATHに正しく設定されているか&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;実行パス&lt;/strong&gt;：実際に実行されているバイナリ&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;一般的な問題のある出力&quot;&gt;一般的な問題のある出力&lt;/h4&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt;の出力で以下の警告サインに注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;unknown (2.0.0)&lt;/code&gt; - バージョン検出が失敗、おそらく混合インストール&lt;/li&gt;
&lt;li&gt;Bun、npm、Node.js間のパスの混在&lt;/li&gt;
&lt;li&gt;呼び出しパスと実行パスの相違&lt;/li&gt;
&lt;li&gt;自動更新が無効または失敗&lt;/li&gt;
&lt;li&gt;検索ステータスがエラーを表示&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;また、競合する可能性のある複数のインストールを確認：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;which&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; claude&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;すべての既存インストールを削除&quot;&gt;すべての既存インストールを削除&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Bunインストールを削除&lt;/span&gt;
bun uninstall &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt; ~/.bun/bin/claude

&lt;span class=&quot;token comment&quot;&gt;# npm/Node.jsインストールを削除&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; uninstall &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code

&lt;span class=&quot;token comment&quot;&gt;# nvm固有のインストールを削除&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# 持っている各nvmのNodeバージョンを確認&lt;/span&gt;
nvm list
&lt;span class=&quot;token comment&quot;&gt;# 各バージョンに切り替えてアンインストール&lt;/span&gt;
nvm use &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;version&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; uninstall &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;brew-uninstall-claude-code&quot;&gt;Brew Uninstall Claude Code&lt;/h3&gt;
&lt;p&gt;HomebrewでClaude Codeをインストールした場合：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# HomebrewからClaude Codeをアンインストール&lt;/span&gt;
brew uninstall claude-code

&lt;span class=&quot;token comment&quot;&gt;# キャッシュファイルをクリーンアップ&lt;/span&gt;
brew cleanup claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;brew経由でアンインストールした後、より良い自動更新サポートのためにネイティブバイナリインストールに切り替えることができます。&lt;/p&gt;
&lt;h3 id=&quot;ステップ3設定とキャッシュをクリア&quot;&gt;ステップ3：設定とキャッシュをクリア&lt;/h3&gt;
&lt;p&gt;残っている設定ファイルを削除：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Claude Code設定ディレクトリを削除&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-rf&lt;/span&gt; ~/.claude-code
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-rf&lt;/span&gt; ~/.config/claude-code
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-rf&lt;/span&gt; ~/.cache/claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;ステップ4新しいネイティブバイナリインストール&quot;&gt;ステップ4：新しいネイティブバイナリインストール&lt;/h3&gt;
&lt;p&gt;ネイティブバイナリをインストール：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;ステップ5修正を確認&quot;&gt;ステップ5：修正を確認&lt;/h3&gt;
&lt;p&gt;インストール後、すべてが動作していることを確認：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# バージョンを確認&lt;/span&gt;
claude &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 診断を実行&lt;/span&gt;
claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;健全なインストールは以下を表示するはずです：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Version: native (2.0.x以上)&lt;/li&gt;
&lt;li&gt;Config install method: native&lt;/li&gt;
&lt;li&gt;Auto-updates: enabled&lt;/li&gt;
&lt;li&gt;Search: OK (bundled)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;代替インストール方法&quot;&gt;代替インストール方法&lt;/h2&gt;
&lt;p&gt;ネイティブバイナリが推奨されますが、他のオプションもあります：&lt;/p&gt;
&lt;h3 id=&quot;npmインストール-npm-install--g-anthropic-aiclaude-code&quot;&gt;npmインストール: npm install -g @anthropic-ai/claude-code&lt;/h3&gt;
&lt;p&gt;npm（Node Package Manager）を使用する場合、Claude Codeをグローバルにインストールできます。この方法にはNode.js 18以上が必要です。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;npm-install--gが行うこと&quot;&gt;npm install -gが行うこと&lt;/h4&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;-g&lt;/code&gt;フラグはパッケージをグローバルにインストールし、ターミナルのどこからでも&lt;code class=&quot;language-text&quot;&gt;claude&lt;/code&gt;をコマンドとして使用できるようにします。パッケージ&lt;code class=&quot;language-text&quot;&gt;@anthropic-ai/claude-code&lt;/code&gt;はAnthropicが管理する公式npmパッケージです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;npmインストールの利点：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Node.js開発者にとって馴染みのあるワークフロー&lt;/li&gt;
&lt;li&gt;他のグローバルパッケージと一緒に管理しやすい&lt;/li&gt;
&lt;li&gt;コンテナ化/CI環境でうまく動作&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;欠点：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Node.jsランタイムが必要&lt;/li&gt;
&lt;li&gt;他のパッケージマネージャー（Bun、pnpm）と競合する可能性&lt;/li&gt;
&lt;li&gt;更新には手動で&lt;code class=&quot;language-text&quot;&gt;npm update -g @anthropic-ai/claude-code&lt;/code&gt;が必要&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;重要：&lt;/strong&gt; &lt;code class=&quot;language-text&quot;&gt;sudo npm install -g&lt;/code&gt;は絶対に使用しないでください。これは権限の問題を引き起こします。EACCESエラーが発生した場合は、代わりにnpmの権限を修正してください。&lt;/p&gt;
&lt;h3 id=&quot;特定バージョンのインストール&quot;&gt;特定バージョンのインストール&lt;/h3&gt;
&lt;p&gt;ネイティブバイナリの特定バージョンをインストールするには：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 最新バージョンをインストール&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; latest

&lt;span class=&quot;token comment&quot;&gt;# 特定バージョンをインストール&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.0&lt;/span&gt;.22&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;プラットフォーム固有の手順&quot;&gt;プラットフォーム固有の手順&lt;/h2&gt;
&lt;h3 id=&quot;homebrewを使用したmacos&quot;&gt;Homebrewを使用したmacOS&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;注：Homebrewインストールはbrewディレクトリとは独立して自動更新されます。&lt;/p&gt;
&lt;h3 id=&quot;windows-irm-httpsclaudeaiinstallps1--iex-を使用&quot;&gt;Windows: irm &lt;a href=&quot;https://claude.ai/install.ps1&quot;&gt;https://claude.ai/install.ps1&lt;/a&gt; | iex を使用&lt;/h3&gt;
&lt;p&gt;Windowsユーザーには3つのオプションがあります：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;WSL（推奨）&lt;/strong&gt;：WSLをインストールしてLinuxの手順に従う&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Git Bash&lt;/strong&gt;：Git Bashでネイティブインストーラーを使用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PowerShell&lt;/strong&gt;（ネイティブWindows）：
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;powershell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-powershell line-numbers&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;irm&lt;/span&gt; https:&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;claude&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ai/install&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ps1 &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;iex&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;irmコマンドの理解&quot;&gt;irmコマンドの理解&lt;/h4&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;irm&lt;/code&gt;コマンドはPowerShellの&lt;strong&gt;Invoke-RestMethod&lt;/strong&gt;で、URLからコンテンツをダウンロードします。コマンドの動作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;irm https://claude.ai/install.ps1&lt;/code&gt; - Anthropicのサーバーからインストールスクリプトをダウンロード&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;| iex&lt;/code&gt; - スクリプトを&lt;strong&gt;Invoke-Expression&lt;/strong&gt;にパイプし、実行&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;https://claude.ai/install.ps1&lt;/code&gt;スクリプトは以下を処理：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windowsアーキテクチャの検出（x64、ARM64）&lt;/li&gt;
&lt;li&gt;適切なClaude Codeバイナリのダウンロード&lt;/li&gt;
&lt;li&gt;ユーザーディレクトリへのインストール&lt;/li&gt;
&lt;li&gt;PATH環境変数へのClaudeの追加&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;セキュリティ注意：&lt;/strong&gt; インストールスクリプトを実行する前に、公式の&lt;code class=&quot;language-text&quot;&gt;claude.ai&lt;/code&gt;ドメインからダウンロードしていることを必ず確認してください。&lt;/p&gt;
&lt;h3 id=&quot;alpine-linux&quot;&gt;Alpine Linux&lt;/h3&gt;
&lt;p&gt;Alpineや他のmuslベースのディストリビューションには追加の依存関係が必要：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;apk &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; libgcc libstdc++ ripgrep
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;USE_BUILTIN_RIPGREP&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;インストール後のセットアップ&quot;&gt;インストール後のセットアップ&lt;/h2&gt;
&lt;h3 id=&quot;認証&quot;&gt;認証&lt;/h3&gt;
&lt;p&gt;インストール後、Claude Codeを認証：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;認証方法の選択を求められます：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Claude Console&lt;/strong&gt;（デフォルト）：console.anthropic.comでの課金を伴うAPIアクセス用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude Pro/Max&lt;/strong&gt;：Claudeサブスクリプションがある場合&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enterprise&lt;/strong&gt;：AWS BedrockまたはGoogle Vertex AIデプロイメント用&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;基本的な使用方法&quot;&gt;基本的な使用方法&lt;/h3&gt;
&lt;p&gt;Claude Codeの使用開始：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# プロジェクトに移動&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; /path/to/your/project

&lt;span class=&quot;token comment&quot;&gt;# Claude Codeを開始&lt;/span&gt;
claude

&lt;span class=&quot;token comment&quot;&gt;# ヘルプを取得&lt;/span&gt;
claude &lt;span class=&quot;token builtin class-name&quot;&gt;help&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# セッション内でスラッシュコマンドを使用&lt;/span&gt;
/help    &lt;span class=&quot;token comment&quot;&gt;# 利用可能なコマンドを表示&lt;/span&gt;
/clear   &lt;span class=&quot;token comment&quot;&gt;# 会話をクリア&lt;/span&gt;
/exit    &lt;span class=&quot;token comment&quot;&gt;# Claude Codeを終了&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;更新の管理&quot;&gt;更新の管理&lt;/h2&gt;
&lt;h3 id=&quot;自動更新&quot;&gt;自動更新&lt;/h3&gt;
&lt;p&gt;Claude Codeはデフォルトで自動的に更新されます。更新は起動時にチェックされ、バックグラウンドで適用されます。&lt;/p&gt;
&lt;h3 id=&quot;claude-codeを更新する方法&quot;&gt;Claude Codeを更新する方法&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude update&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これを&lt;code class=&quot;language-text&quot;&gt;.bashrc&lt;/code&gt;または&lt;code class=&quot;language-text&quot;&gt;.zshrc&lt;/code&gt;に追加して永続的にしてください。&lt;/p&gt;
&lt;h2 id=&quot;一般的な問題と解決策&quot;&gt;一般的な問題と解決策&lt;/h2&gt;
&lt;h3 id=&quot;問題insufficient-permissions-to-install-update&quot;&gt;問題：「Insufficient permissions to install update」&lt;/h3&gt;
&lt;p&gt;これは通常npm/Bunインストールで発生します。解決策：ネイティブバイナリインストールに切り替え。&lt;/p&gt;
&lt;h3 id=&quot;問題command-not-found-claude&quot;&gt;問題：「command not found: claude」&lt;/h3&gt;
&lt;p&gt;PATHが更新されていません。シェル設定に追加：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export PATH=&quot;$HOME/.local/bin:$PATH&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;問題検索機能が動作しない&quot;&gt;問題：検索機能が動作しない&lt;/h3&gt;
&lt;p&gt;通常ネイティブインストールで修正されますが、持続する場合：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# ripgrepを手動でインストール&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;apt-get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; ripgrep  &lt;span class=&quot;token comment&quot;&gt;# Ubuntu/Debian&lt;/span&gt;
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; ripgrep          &lt;span class=&quot;token comment&quot;&gt;# macOS&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;ベストプラクティス&quot;&gt;ベストプラクティス&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;特定の要件がない限り、常にネイティブバイナリを使用する&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;どのインストール方法でもsudoを避ける&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;セキュリティと機能のために自動更新を有効に保つ&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;インストールまたは更新後に&lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt;を実行する&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;新しいバージョンをインストールする前に古いインストールをクリーンアップする&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;結論&quot;&gt;結論&lt;/h2&gt;
&lt;p&gt;迷ったら、すべてを削除してネイティブバイナリで新たに始めてください。Claude Codeを実行する最もシンプルで、最速で、最も信頼性の高い方法です。&lt;/p&gt;
&lt;h2 id=&quot;関連記事&quot;&gt;関連記事&lt;/h2&gt;
&lt;p&gt;Claude Codeがインストールされたので、活用しましょう：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Flaskでショッピングカートを構築&lt;/a&gt;&lt;/strong&gt; - Claude Codeを使用してPythonとFlaskで完全なeコマースバックエンドを構築する実践チュートリアル&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;クイックリファレンス&quot;&gt;クイックリファレンス&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;インストール&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;curl -fsSL https://claude.ai/install.sh | bash&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;バージョン確認&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude --version&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;診断&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;更新&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude update&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;開始&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ヘルプ&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude help&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Claude Code 설치 가이드: irm 스크립트, npm 설정 및 https://claude.ai/install.ps1 사용법]]></title><description><![CDATA[네이티브 바이너리, npm 설치 및 claude doctor 명령어를 통한 문제 해결을 포함한 Claude Code CLI IDE 설정, 설치 및 제거 단계별 가이드입니다.]]></description><link>https://vibecodingwithfred.com/ko/blog/claude-code-installation-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/ko/blog/claude-code-installation-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 26 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;소개&quot;&gt;소개&lt;/h2&gt;
&lt;p&gt;Claude Code는 AI 지원 코딩을 위한 제가 가장 선호하는 명령줄 도구입니다. Windows, macOS, Linux 어디서든 설치가 간단하며 여러 옵션이 있습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;네이티브 바이너리&lt;/strong&gt; (권장): Linux/macOS용 &lt;code class=&quot;language-text&quot;&gt;curl -fsSL https://claude.ai/install.sh | bash&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Windows PowerShell&lt;/strong&gt;: Windows 사용자용 &lt;code class=&quot;language-text&quot;&gt;irm https://claude.ai/install.ps1 | iex&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;npm 전역 설치&lt;/strong&gt;: Node.js 환경용 &lt;code class=&quot;language-text&quot;&gt;npm install -g @anthropic-ai/claude-code&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 가이드에서는 각 설치 방법과 일반적인 문제를 진단하고 수정하기 위한 &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; 명령어 사용법을 자세히 다룹니다.&lt;/p&gt;
&lt;h2 id=&quot;권장-네이티브-바이너리&quot;&gt;권장: 네이티브 바이너리&lt;/h2&gt;
&lt;p&gt;2025년 현재, Claude는 node.js와 bun.js를 포함한 여러 런타임에서 사용 가능합니다. Anthropic은 네이티브 바이너리 설치를 권장합니다. 이 방법은 패키지 관리자 충돌을 피하고 가장 안정적입니다.&lt;/p&gt;
&lt;h3 id=&quot;네이티브-바이너리-설치하기&quot;&gt;네이티브 바이너리 설치하기&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;설치 스크립트 실행:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;셸 설정 다시 로드:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token comment&quot;&gt;# zsh 사용자의 경우:&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.zshrc&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;설치 확인:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;
claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;완료입니다! Claude Code가 이제 &lt;code class=&quot;language-text&quot;&gt;~/.claude/bin/claude&lt;/code&gt; 또는 &lt;code class=&quot;language-text&quot;&gt;~/.local/bin/claude&lt;/code&gt;에 설치되었습니다.&lt;/p&gt;
&lt;h2 id=&quot;문제-해결-손상된-설치-수정하기&quot;&gt;문제 해결: 손상된 설치 수정하기&lt;/h2&gt;
&lt;p&gt;세그멘테이션 오류와 같은 문제가 발생한다면 혼합되거나 오래된 설치가 있을 가능성이 높습니다. 저처럼 처음부터 Claude를 사용해왔다면 node.js 또는 bun.js 버전이 설치되어 있을 수 있습니다. 다음은 수정 방법입니다:&lt;/p&gt;
&lt;h3 id=&quot;claude-doctor로-현재-설치-진단하기&quot;&gt;claude doctor로 현재 설치 진단하기&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; 명령어는 문제 해결의 첫 번째 단계입니다. 설치를 분석하고 잠재적인 문제를 보고합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;claude-doctor가-확인하는-항목&quot;&gt;claude doctor가 확인하는 항목&lt;/h4&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; 명령어는 다음을 검사합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;설치 방법&lt;/strong&gt;: 네이티브 바이너리, npm, Bun 또는 Homebrew&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;버전 정보&lt;/strong&gt;: 현재 버전 및 업데이트 상태&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;자동 업데이트 기능&lt;/strong&gt;: 업데이트 적용 가능 여부&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;검색 기능&lt;/strong&gt;: ripgrep이 제대로 번들/설치되었는지&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;경로 설정&lt;/strong&gt;: Claude가 PATH에 올바르게 있는지&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;실행 경로&lt;/strong&gt;: 실행되는 실제 바이너리&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;일반적인-문제-출력&quot;&gt;일반적인 문제 출력&lt;/h4&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; 출력에서 다음 경고 신호를 주시하세요:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;unknown (2.0.0)&lt;/code&gt; - 버전 감지 실패, 혼합 설치 가능성&lt;/li&gt;
&lt;li&gt;Bun, npm, Node.js 간의 혼합 경로&lt;/li&gt;
&lt;li&gt;호출 경로와 실행 경로가 다름&lt;/li&gt;
&lt;li&gt;자동 업데이트 비활성화 또는 실패&lt;/li&gt;
&lt;li&gt;검색 상태에 오류 표시&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;또한 충돌할 수 있는 여러 설치가 있는지 확인하세요:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;which&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; claude&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;모든-기존-설치-제거&quot;&gt;모든 기존 설치 제거&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Bun 설치 제거&lt;/span&gt;
bun uninstall &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt; ~/.bun/bin/claude

&lt;span class=&quot;token comment&quot;&gt;# npm/Node.js 설치 제거&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; uninstall &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code

&lt;span class=&quot;token comment&quot;&gt;# nvm 특정 설치 제거&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# 각 nvm Node 버전 확인&lt;/span&gt;
nvm list
&lt;span class=&quot;token comment&quot;&gt;# 각 버전에 대해 해당 버전으로 전환하고 제거&lt;/span&gt;
nvm use &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;version&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; uninstall &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;homebrew로-claude-code-제거&quot;&gt;Homebrew로 Claude Code 제거&lt;/h3&gt;
&lt;p&gt;Homebrew를 통해 Claude Code를 설치한 경우:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Homebrew에서 Claude Code 제거&lt;/span&gt;
brew uninstall claude-code

&lt;span class=&quot;token comment&quot;&gt;# 캐시된 파일 정리&lt;/span&gt;
brew cleanup claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;brew로 제거한 후 더 나은 자동 업데이트 지원을 위해 네이티브 바이너리 설치로 전환할 수 있습니다.&lt;/p&gt;
&lt;h3 id=&quot;3단계-설정-및-캐시-지우기&quot;&gt;3단계: 설정 및 캐시 지우기&lt;/h3&gt;
&lt;p&gt;남아있는 설정 파일 제거:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Claude Code 설정 디렉토리 제거&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-rf&lt;/span&gt; ~/.claude-code
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-rf&lt;/span&gt; ~/.config/claude-code
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-rf&lt;/span&gt; ~/.cache/claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4단계-새로운-네이티브-바이너리-설치&quot;&gt;4단계: 새로운 네이티브 바이너리 설치&lt;/h3&gt;
&lt;p&gt;이제 네이티브 바이너리를 설치합니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;5단계-수정-확인&quot;&gt;5단계: 수정 확인&lt;/h3&gt;
&lt;p&gt;설치 후 모든 것이 작동하는지 확인합니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 버전 확인&lt;/span&gt;
claude &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 진단 실행&lt;/span&gt;
claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;정상적인 설치는 다음을 표시해야 합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Version: native (2.0.x 이상)&lt;/li&gt;
&lt;li&gt;Config install method: native&lt;/li&gt;
&lt;li&gt;Auto-updates: enabled&lt;/li&gt;
&lt;li&gt;Search: OK (bundled)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;대안-설치-방법&quot;&gt;대안 설치 방법&lt;/h2&gt;
&lt;p&gt;네이티브 바이너리가 권장되지만 다른 옵션도 있습니다:&lt;/p&gt;
&lt;h3 id=&quot;npm-설치-npm-install--g-anthropic-aiclaude-code&quot;&gt;npm 설치: npm install -g @anthropic-ai/claude-code&lt;/h3&gt;
&lt;p&gt;npm(Node Package Manager)을 선호한다면 Claude Code를 전역으로 설치할 수 있습니다. 이 방법은 Node.js 18 이상이 필요합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;npm-install--g가-하는-일&quot;&gt;npm install -g가 하는 일&lt;/h4&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;-g&lt;/code&gt; 플래그는 패키지를 전역으로 설치하여 터미널 어디서나 &lt;code class=&quot;language-text&quot;&gt;claude&lt;/code&gt;를 명령어로 사용할 수 있게 합니다. &lt;code class=&quot;language-text&quot;&gt;@anthropic-ai/claude-code&lt;/code&gt; 패키지는 Anthropic에서 유지 관리하는 공식 npm 패키지입니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;npm 설치의 장점:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Node.js 개발자에게 익숙한 워크플로우&lt;/li&gt;
&lt;li&gt;다른 전역 패키지와 함께 관리하기 쉬움&lt;/li&gt;
&lt;li&gt;컨테이너화된/CI 환경에서 잘 작동&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;단점:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Node.js 런타임 필요&lt;/li&gt;
&lt;li&gt;다른 패키지 관리자(Bun, pnpm)와 충돌할 수 있음&lt;/li&gt;
&lt;li&gt;업데이트를 위해 수동으로 &lt;code class=&quot;language-text&quot;&gt;npm update -g @anthropic-ai/claude-code&lt;/code&gt; 실행 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;중요:&lt;/strong&gt; 권한 문제를 일으키므로 &lt;code class=&quot;language-text&quot;&gt;sudo npm install -g&lt;/code&gt;를 절대 사용하지 마세요. EACCES 오류가 발생하면 대신 npm 권한을 수정하세요.&lt;/p&gt;
&lt;h3 id=&quot;특정-버전-설치&quot;&gt;특정 버전 설치&lt;/h3&gt;
&lt;p&gt;네이티브 바이너리의 특정 버전을 설치하려면:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 최신 버전 설치&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; latest

&lt;span class=&quot;token comment&quot;&gt;# 특정 버전 설치&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.0&lt;/span&gt;.22&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;플랫폼별-안내&quot;&gt;플랫폼별 안내&lt;/h2&gt;
&lt;h3 id=&quot;homebrew가-있는-macos&quot;&gt;Homebrew가 있는 macOS&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;참고: Homebrew 설치는 brew 디렉토리와 독립적으로 자동 업데이트됩니다.&lt;/p&gt;
&lt;h3 id=&quot;windows-irm-httpsclaudeaiinstallps1--iex-사용&quot;&gt;Windows: irm &lt;a href=&quot;https://claude.ai/install.ps1&quot;&gt;https://claude.ai/install.ps1&lt;/a&gt; | iex 사용&lt;/h3&gt;
&lt;p&gt;Windows 사용자의 경우 세 가지 옵션이 있습니다:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;WSL (권장)&lt;/strong&gt;: WSL을 설치하고 Linux 지침 따르기&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Git Bash&lt;/strong&gt;: Git Bash에서 네이티브 설치 프로그램 사용&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PowerShell&lt;/strong&gt; (네이티브 Windows):
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;powershell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-powershell line-numbers&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;irm&lt;/span&gt; https:&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;claude&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ai/install&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ps1 &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;iex&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;irm-명령어-이해하기&quot;&gt;irm 명령어 이해하기&lt;/h4&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;irm&lt;/code&gt; 명령어는 PowerShell의 &lt;strong&gt;Invoke-RestMethod&lt;/strong&gt;로, URL에서 콘텐츠를 다운로드합니다. 이 명령이 하는 일은 다음과 같습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;irm https://claude.ai/install.ps1&lt;/code&gt; - Anthropic 서버에서 설치 스크립트 다운로드&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;| iex&lt;/code&gt; - 스크립트를 &lt;strong&gt;Invoke-Expression&lt;/strong&gt;으로 파이프하여 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;https://claude.ai/install.ps1&lt;/code&gt; 스크립트는 다음을 처리합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows 아키텍처 감지 (x64, ARM64)&lt;/li&gt;
&lt;li&gt;적절한 Claude Code 바이너리 다운로드&lt;/li&gt;
&lt;li&gt;사용자 디렉토리에 설치&lt;/li&gt;
&lt;li&gt;PATH 환경 변수에 Claude 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;보안 참고:&lt;/strong&gt; 설치 스크립트를 실행하기 전에 항상 공식 &lt;code class=&quot;language-text&quot;&gt;claude.ai&lt;/code&gt; 도메인에서 다운로드하는지 확인하세요.&lt;/p&gt;
&lt;h3 id=&quot;alpine-linux&quot;&gt;Alpine Linux&lt;/h3&gt;
&lt;p&gt;Alpine 및 기타 musl 기반 배포판은 추가 의존성이 필요합니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;apk &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; libgcc libstdc++ ripgrep
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;USE_BUILTIN_RIPGREP&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;설치-후-설정&quot;&gt;설치 후 설정&lt;/h2&gt;
&lt;h3 id=&quot;인증&quot;&gt;인증&lt;/h3&gt;
&lt;p&gt;설치 후 Claude Code를 인증합니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;인증 방법을 선택하라는 메시지가 표시됩니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Claude Console&lt;/strong&gt; (기본): console.anthropic.com에서 청구되는 API 액세스&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude Pro/Max&lt;/strong&gt;: Claude 구독이 있는 경우&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enterprise&lt;/strong&gt;: AWS Bedrock 또는 Google Vertex AI 배포용&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;기본-사용법&quot;&gt;기본 사용법&lt;/h3&gt;
&lt;p&gt;Claude Code 사용 시작:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 프로젝트로 이동&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; /path/to/your/project

&lt;span class=&quot;token comment&quot;&gt;# Claude Code 시작&lt;/span&gt;
claude

&lt;span class=&quot;token comment&quot;&gt;# 도움말 보기&lt;/span&gt;
claude &lt;span class=&quot;token builtin class-name&quot;&gt;help&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 세션 내에서 슬래시 명령어 사용&lt;/span&gt;
/help    &lt;span class=&quot;token comment&quot;&gt;# 사용 가능한 명령어 표시&lt;/span&gt;
/clear   &lt;span class=&quot;token comment&quot;&gt;# 대화 지우기&lt;/span&gt;
/exit    &lt;span class=&quot;token comment&quot;&gt;# Claude Code 종료&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;업데이트-관리&quot;&gt;업데이트 관리&lt;/h2&gt;
&lt;h3 id=&quot;자동-업데이트&quot;&gt;자동 업데이트&lt;/h3&gt;
&lt;p&gt;Claude Code는 기본적으로 자동 업데이트됩니다. 시작 시 업데이트를 확인하고 백그라운드에서 적용합니다.&lt;/p&gt;
&lt;h3 id=&quot;claude-code-업데이트-방법&quot;&gt;Claude Code 업데이트 방법&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude update&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이를 영구적으로 적용하려면 &lt;code class=&quot;language-text&quot;&gt;.bashrc&lt;/code&gt; 또는 &lt;code class=&quot;language-text&quot;&gt;.zshrc&lt;/code&gt;에 추가하세요.&lt;/p&gt;
&lt;h2 id=&quot;일반적인-문제-및-해결책&quot;&gt;일반적인 문제 및 해결책&lt;/h2&gt;
&lt;h3 id=&quot;문제-insufficient-permissions-to-install-update&quot;&gt;문제: &quot;Insufficient permissions to install update&quot;&lt;/h3&gt;
&lt;p&gt;이 문제는 일반적으로 npm/Bun 설치에서 발생합니다. 해결책: 네이티브 바이너리 설치로 전환하세요.&lt;/p&gt;
&lt;h3 id=&quot;문제-command-not-found-claude&quot;&gt;문제: &quot;command not found: claude&quot;&lt;/h3&gt;
&lt;p&gt;PATH가 업데이트되지 않았습니다. 셸 설정에 추가하세요:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export PATH=&quot;$HOME/.local/bin:$PATH&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;문제-검색-기능이-작동하지-않음&quot;&gt;문제: 검색 기능이 작동하지 않음&lt;/h3&gt;
&lt;p&gt;보통 네이티브 설치로 해결되지만 계속 문제가 있다면:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# ripgrep 수동 설치&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;apt-get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; ripgrep  &lt;span class=&quot;token comment&quot;&gt;# Ubuntu/Debian&lt;/span&gt;
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; ripgrep          &lt;span class=&quot;token comment&quot;&gt;# macOS&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;모범-사례&quot;&gt;모범 사례&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;항상 네이티브 바이너리 사용&lt;/strong&gt; - 특별한 요구 사항이 없는 한&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;sudo 사용 금지&lt;/strong&gt; - 어떤 설치 방법에서도&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;자동 업데이트 활성화 유지&lt;/strong&gt; - 보안 및 기능을 위해&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;설치 또는 업데이트 후 &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; 실행&lt;/strong&gt; - 상태 확인&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;새 버전 설치 전 이전 설치 정리&lt;/strong&gt; - 충돌 방지&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;결론&quot;&gt;결론&lt;/h2&gt;
&lt;p&gt;의심스러울 때는 모든 것을 제거하고 네이티브 바이너리로 새로 시작하세요. Claude Code를 실행하는 가장 간단하고 빠르며 안정적인 방법입니다.&lt;/p&gt;
&lt;h2 id=&quot;관련-읽기&quot;&gt;관련 읽기&lt;/h2&gt;
&lt;p&gt;이제 Claude Code가 설치되었으니 실제로 사용해보세요:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Flask로 쇼핑 카트 만들기&lt;/a&gt;&lt;/strong&gt; - Claude Code를 사용하여 Python과 Flask로 완전한 전자상거래 백엔드를 구축하는 실습 튜토리얼&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;빠른-참조&quot;&gt;빠른 참조&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;설치&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;curl -fsSL https://claude.ai/install.sh | bash&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;버전 확인&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude --version&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;진단&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;업데이트&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude update&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;시작&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;도움말&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude help&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Claude Code Installatiehandleiding: irm Script, npm Setup en https://claude.ai/install.ps1 Script Gebruiken]]></title><description><![CDATA[Stapsgewijze Claude Code CLI IDE setup, installatie en de-installatie van de native binary, npm en probleemoplossing met claude doctor.]]></description><link>https://vibecodingwithfred.com/nl/blog/claude-code-installation-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/nl/blog/claude-code-installation-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 26 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;introductie&quot;&gt;Introductie&lt;/h2&gt;
&lt;p&gt;Claude Code is mijn favoriete command-line tool voor AI-geassisteerd coderen. Of je nu op Windows, macOS of Linux werkt, installatie is eenvoudig met meerdere opties:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Native Binary&lt;/strong&gt; (Aanbevolen): &lt;code class=&quot;language-text&quot;&gt;curl -fsSL https://claude.ai/install.sh | bash&lt;/code&gt; voor Linux/macOS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Windows PowerShell&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;irm https://claude.ai/install.ps1 | iex&lt;/code&gt; voor Windows-gebruikers&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;npm Global Install&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;npm install -g @anthropic-ai/claude-code&lt;/code&gt; voor Node.js omgevingen&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Deze handleiding behandelt elke installatiemethode in detail, plus probleemoplossing met het &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; commando om veelvoorkomende problemen te diagnosticeren en op te lossen.&lt;/p&gt;
&lt;h2 id=&quot;aanbevolen-native-binary&quot;&gt;Aanbevolen: Native Binary&lt;/h2&gt;
&lt;p&gt;Vanaf 2025 is Claude beschikbaar in verschillende runtimes, waaronder node.js en bun.js. Anthropic raadt aan om de native binary-installatie te gebruiken. Deze methode vermijdt conflicten met package managers en is het meest stabiel.&lt;/p&gt;
&lt;h3 id=&quot;de-native-binary-installeren&quot;&gt;De Native Binary Installeren&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Voer het installatiescript uit:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Herlaad je shell-configuratie:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token comment&quot;&gt;# of voor zsh-gebruikers:&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.zshrc&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Verifieer de installatie:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;
claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Dat is het! Claude Code zou nu geïnstalleerd moeten zijn op &lt;code class=&quot;language-text&quot;&gt;~/.claude/bin/claude&lt;/code&gt; of &lt;code class=&quot;language-text&quot;&gt;~/.local/bin/claude&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;probleemoplossing-kapotte-installaties-repareren&quot;&gt;Probleemoplossing: Kapotte Installaties Repareren&lt;/h2&gt;
&lt;p&gt;Als je problemen ondervindt met Claude Code zoals segmentation fault errors, heb je waarschijnlijk een gemixte of verouderde installatie. Als je Claude al vanaf het begin gebruikt zoals ik, heb je misschien ook node.js of bun.js versies geïnstalleerd. Hier is hoe je dat repareert:&lt;/p&gt;
&lt;h3 id=&quot;diagnose-van-je-huidige-installatie-met-claude-doctor&quot;&gt;Diagnose van Je Huidige Installatie met claude doctor&lt;/h3&gt;
&lt;p&gt;Het &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; commando is je eerste stop voor probleemoplossing. Het analyseert je installatie en rapporteert potentiële problemen.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;wat-claude-doctor-controleert&quot;&gt;Wat claude doctor Controleert&lt;/h4&gt;
&lt;p&gt;Het &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; commando inspecteert:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Installatiemethode&lt;/strong&gt;: Native binary, npm, Bun of Homebrew&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Versie-informatie&lt;/strong&gt;: Huidige versie en updatestatus&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Auto-update mogelijkheid&lt;/strong&gt;: Of updates kunnen worden toegepast&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zoekfunctionaliteit&lt;/strong&gt;: Of ripgrep correct gebundeld/geïnstalleerd is&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Padconfiguratie&lt;/strong&gt;: Of Claude correct in je PATH staat&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Uitvoeringspad&lt;/strong&gt;: De daadwerkelijke binary die wordt uitgevoerd&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;veelvoorkomende-problematische-outputs&quot;&gt;Veelvoorkomende Problematische Outputs&lt;/h4&gt;
&lt;p&gt;Let op deze waarschuwingstekens in &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; output:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;unknown (2.0.0)&lt;/code&gt; - Versiedetectie mislukt, waarschijnlijk gemixte installatie&lt;/li&gt;
&lt;li&gt;Gemixte paden tussen Bun, npm en Node.js&lt;/li&gt;
&lt;li&gt;Aanroeppad verschilt van uitvoeringspad&lt;/li&gt;
&lt;li&gt;Auto-updates uitgeschakeld of falend&lt;/li&gt;
&lt;li&gt;Zoekstatus toont fouten&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Controleer ook op meerdere installaties die kunnen conflicteren:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;which&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; claude&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;verwijder-alle-bestaande-installaties&quot;&gt;Verwijder ALLE Bestaande Installaties&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Verwijder Bun-installatie&lt;/span&gt;
bun uninstall &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt; ~/.bun/bin/claude

&lt;span class=&quot;token comment&quot;&gt;# Verwijder npm/Node.js-installatie&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; uninstall &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code

&lt;span class=&quot;token comment&quot;&gt;# Verwijder eventuele nvm-specifieke installaties&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Controleer elke nvm Node-versie die je hebt&lt;/span&gt;
nvm list
&lt;span class=&quot;token comment&quot;&gt;# Voor elke versie, schakel ernaar en de-installeer&lt;/span&gt;
nvm use &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;version&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; uninstall &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;brew-uninstall-claude-code&quot;&gt;Brew Uninstall Claude Code&lt;/h3&gt;
&lt;p&gt;Als je Claude Code via Homebrew hebt geïnstalleerd:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# De-installeer Claude Code van Homebrew&lt;/span&gt;
brew uninstall claude-code

&lt;span class=&quot;token comment&quot;&gt;# Ruim gecachte bestanden op&lt;/span&gt;
brew cleanup claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Na de-installatie via brew kun je overschakelen naar de native binary-installatie voor betere auto-update ondersteuning.&lt;/p&gt;
&lt;h3 id=&quot;stap-3-configuratie-en-cache-opruimen&quot;&gt;Stap 3: Configuratie en Cache Opruimen&lt;/h3&gt;
&lt;p&gt;Verwijder eventuele achtergebleven configuratiebestanden:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Verwijder Claude Code config directories&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-rf&lt;/span&gt; ~/.claude-code
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-rf&lt;/span&gt; ~/.config/claude-code
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-rf&lt;/span&gt; ~/.cache/claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;stap-4-verse-native-binary-installatie&quot;&gt;Stap 4: Verse Native Binary Installatie&lt;/h3&gt;
&lt;p&gt;Installeer nu de native binary:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;stap-5-de-reparatie-verifieren&quot;&gt;Stap 5: De Reparatie Verifiëren&lt;/h3&gt;
&lt;p&gt;Na installatie, verifieer of alles werkt:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Controleer versie&lt;/span&gt;
claude &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Voer diagnostiek uit&lt;/span&gt;
claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Een gezonde installatie zou moeten tonen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Version: native (2.0.x of hoger)&lt;/li&gt;
&lt;li&gt;Config install method: native&lt;/li&gt;
&lt;li&gt;Auto-updates: enabled&lt;/li&gt;
&lt;li&gt;Search: OK (bundled)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;alternatieve-installatiemethoden&quot;&gt;Alternatieve Installatiemethoden&lt;/h2&gt;
&lt;p&gt;Hoewel de native binary wordt aanbevolen, hier zijn andere opties:&lt;/p&gt;
&lt;h3 id=&quot;npm-installatie-npm-install--g-anthropic-aiclaude-code&quot;&gt;npm Installatie: npm install -g @anthropic-ai/claude-code&lt;/h3&gt;
&lt;p&gt;Als je liever npm (Node Package Manager) gebruikt, kun je Claude Code globaal installeren. Deze methode vereist Node.js 18 of hoger.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;wat-npm-install--g-doet&quot;&gt;Wat npm install -g Doet&lt;/h4&gt;
&lt;p&gt;De &lt;code class=&quot;language-text&quot;&gt;-g&lt;/code&gt; flag installeert het pakket globaal, waardoor &lt;code class=&quot;language-text&quot;&gt;claude&lt;/code&gt; beschikbaar wordt als commando overal in je terminal. Het pakket &lt;code class=&quot;language-text&quot;&gt;@anthropic-ai/claude-code&lt;/code&gt; is het officiële npm-pakket onderhouden door Anthropic.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Voordelen van npm-installatie:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vertrouwde workflow voor Node.js-ontwikkelaars&lt;/li&gt;
&lt;li&gt;Eenvoudig te beheren naast andere globale pakketten&lt;/li&gt;
&lt;li&gt;Werkt goed in gecontaineriseerde/CI-omgevingen&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Nadelen:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vereist Node.js runtime&lt;/li&gt;
&lt;li&gt;Kan conflicteren met andere package managers (Bun, pnpm)&lt;/li&gt;
&lt;li&gt;Updates vereisen handmatig &lt;code class=&quot;language-text&quot;&gt;npm update -g @anthropic-ai/claude-code&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Belangrijk:&lt;/strong&gt; Gebruik nooit &lt;code class=&quot;language-text&quot;&gt;sudo npm install -g&lt;/code&gt; want dit veroorzaakt permissieproblemen. Als je EACCES-fouten krijgt, repareer dan je npm-permissies.&lt;/p&gt;
&lt;h3 id=&quot;specifieke-versie-installatie&quot;&gt;Specifieke Versie Installatie&lt;/h3&gt;
&lt;p&gt;Om een specifieke versie van de native binary te installeren:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Installeer nieuwste versie&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; latest

&lt;span class=&quot;token comment&quot;&gt;# Installeer specifieke versie&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.0&lt;/span&gt;.22&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;platform-specifieke-instructies&quot;&gt;Platform-Specifieke Instructies&lt;/h2&gt;
&lt;h3 id=&quot;macos-met-homebrew&quot;&gt;macOS met Homebrew&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Opmerking: Homebrew-installaties updaten automatisch onafhankelijk van de brew-directory.&lt;/p&gt;
&lt;h3 id=&quot;windows-irm-httpsclaudeaiinstallps1--iex-gebruiken&quot;&gt;Windows: irm &lt;a href=&quot;https://claude.ai/install.ps1&quot;&gt;https://claude.ai/install.ps1&lt;/a&gt; | iex Gebruiken&lt;/h3&gt;
&lt;p&gt;Voor Windows-gebruikers heb je drie opties:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;WSL (Aanbevolen)&lt;/strong&gt;: Installeer WSL en volg de Linux-instructies&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Git Bash&lt;/strong&gt;: Gebruik de native installer met Git Bash&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PowerShell&lt;/strong&gt; (Native Windows):
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;powershell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-powershell line-numbers&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;irm&lt;/span&gt; https:&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;claude&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ai/install&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ps1 &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;iex&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;het-irm-commando-begrijpen&quot;&gt;Het irm Commando Begrijpen&lt;/h4&gt;
&lt;p&gt;Het &lt;code class=&quot;language-text&quot;&gt;irm&lt;/code&gt; commando is PowerShell&apos;s &lt;strong&gt;Invoke-RestMethod&lt;/strong&gt;, dat content downloadt van een URL. Dit is wat het commando doet:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;irm https://claude.ai/install.ps1&lt;/code&gt; - Downloadt het installatiescript van Anthropic&apos;s servers&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;| iex&lt;/code&gt; - Stuurt het script naar &lt;strong&gt;Invoke-Expression&lt;/strong&gt;, dat het uitvoert&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Het &lt;code class=&quot;language-text&quot;&gt;https://claude.ai/install.ps1&lt;/code&gt; script handelt af:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Detectie van je Windows-architectuur (x64, ARM64)&lt;/li&gt;
&lt;li&gt;Downloaden van de juiste Claude Code binary&lt;/li&gt;
&lt;li&gt;Installeren naar je gebruikersdirectory&lt;/li&gt;
&lt;li&gt;Toevoegen van Claude aan je PATH-omgevingsvariabele&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Beveiligingsopmerking:&lt;/strong&gt; Verifieer altijd dat je downloadt van het officiële &lt;code class=&quot;language-text&quot;&gt;claude.ai&lt;/code&gt;-domein voordat je installatiescripts uitvoert.&lt;/p&gt;
&lt;h3 id=&quot;alpine-linux&quot;&gt;Alpine Linux&lt;/h3&gt;
&lt;p&gt;Alpine en andere musl-gebaseerde distributies hebben extra dependencies nodig:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;apk &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; libgcc libstdc++ ripgrep
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;USE_BUILTIN_RIPGREP&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;post-installatie-setup&quot;&gt;Post-Installatie Setup&lt;/h2&gt;
&lt;h3 id=&quot;authenticatie&quot;&gt;Authenticatie&lt;/h3&gt;
&lt;p&gt;Na installatie, authenticeer Claude Code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Je wordt gevraagd om je authenticatiemethode te kiezen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Claude Console&lt;/strong&gt; (standaard): Voor API-toegang met facturering op console.anthropic.com&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude Pro/Max&lt;/strong&gt;: Als je een Claude-abonnement hebt&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enterprise&lt;/strong&gt;: Voor AWS Bedrock of Google Vertex AI deployments&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;basisgebruik&quot;&gt;Basisgebruik&lt;/h3&gt;
&lt;p&gt;Begin Claude Code te gebruiken:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Navigeer naar je project&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; /path/to/your/project

&lt;span class=&quot;token comment&quot;&gt;# Start Claude Code&lt;/span&gt;
claude

&lt;span class=&quot;token comment&quot;&gt;# Krijg hulp&lt;/span&gt;
claude &lt;span class=&quot;token builtin class-name&quot;&gt;help&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Binnen een sessie, gebruik slash-commando&apos;s&lt;/span&gt;
/help    &lt;span class=&quot;token comment&quot;&gt;# Toon beschikbare commando&apos;s&lt;/span&gt;
/clear   &lt;span class=&quot;token comment&quot;&gt;# Wis conversatie&lt;/span&gt;
/exit    &lt;span class=&quot;token comment&quot;&gt;# Sluit Claude Code af&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;updates-beheren&quot;&gt;Updates Beheren&lt;/h2&gt;
&lt;h3 id=&quot;auto-updates&quot;&gt;Auto-Updates&lt;/h3&gt;
&lt;p&gt;Claude Code werkt standaard automatisch bij. Updates worden bij opstarten gecontroleerd en op de achtergrond toegepast.&lt;/p&gt;
&lt;h3 id=&quot;hoe-claude-code-te-updaten&quot;&gt;Hoe Claude Code te Updaten&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude update&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Voeg dit toe aan je &lt;code class=&quot;language-text&quot;&gt;.bashrc&lt;/code&gt; of &lt;code class=&quot;language-text&quot;&gt;.zshrc&lt;/code&gt; om het permanent te maken.&lt;/p&gt;
&lt;h2 id=&quot;veelvoorkomende-problemen-en-oplossingen&quot;&gt;Veelvoorkomende Problemen en Oplossingen&lt;/h2&gt;
&lt;h3 id=&quot;probleem-insufficient-permissions-to-install-update&quot;&gt;Probleem: &quot;Insufficient permissions to install update&quot;&lt;/h3&gt;
&lt;p&gt;Dit gebeurt meestal bij npm/Bun-installaties. Oplossing: Schakel over naar native binary-installatie.&lt;/p&gt;
&lt;h3 id=&quot;probleem-command-not-found-claude&quot;&gt;Probleem: &quot;command not found: claude&quot;&lt;/h3&gt;
&lt;p&gt;Het PATH is niet bijgewerkt. Voeg toe aan je shell-configuratie:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export PATH=&quot;$HOME/.local/bin:$PATH&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;probleem-zoekfunctionaliteit-werkt-niet&quot;&gt;Probleem: Zoekfunctionaliteit werkt niet&lt;/h3&gt;
&lt;p&gt;Meestal opgelost door de native installatie, maar als het aanhoudt:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Installeer ripgrep handmatig&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;apt-get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; ripgrep  &lt;span class=&quot;token comment&quot;&gt;# Ubuntu/Debian&lt;/span&gt;
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; ripgrep          &lt;span class=&quot;token comment&quot;&gt;# macOS&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;best-practices&quot;&gt;Best Practices&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Gebruik altijd de native binary&lt;/strong&gt; tenzij je specifieke vereisten hebt&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vermijd sudo&lt;/strong&gt; bij elke installatiemethode&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Houd auto-updates ingeschakeld&lt;/strong&gt; voor beveiliging en features&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Voer &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; uit&lt;/strong&gt; na elke installatie of update&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ruim oude installaties op&lt;/strong&gt; voordat je nieuwe versies installeert&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;conclusie&quot;&gt;Conclusie&lt;/h2&gt;
&lt;p&gt;Onthoud: bij twijfel, verwijder alles en begin opnieuw met de native binary. Het is de eenvoudigste, snelste en meest betrouwbare manier om Claude Code te draaien.&lt;/p&gt;
&lt;h2 id=&quot;gerelateerde-lectuur&quot;&gt;Gerelateerde Lectuur&lt;/h2&gt;
&lt;p&gt;Nu je Claude Code hebt geïnstalleerd, zet het aan het werk:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Bouw een Winkelwagen met Flask&lt;/a&gt;&lt;/strong&gt; - Een hands-on tutorial waar je Claude Code kunt gebruiken om een complete e-commerce backend te bouwen met Python en Flask&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;snelle-referentie&quot;&gt;Snelle Referentie&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Installeren&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;curl -fsSL https://claude.ai/install.sh | bash&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Versie controleren&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude --version&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Diagnosticeren&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Updaten&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude update&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Starten&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hulp&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude help&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Lovable Terugbetaling: Van Held naar Nul met 2.0 Problemen]]></title><description><![CDATA[Ontdek waarom Lovable 2.0 van held naar nul is gegaan, inclusief terugbetalingsbeleid, gebruikersklachten en supportuitdagingen om je te helpen navigeren door de recente problemen van het platform.]]></description><link>https://vibecodingwithfred.com/nl/blog/lovable-from-hero-to-zero/</link><guid isPermaLink="false">https://vibecodingwithfred.com/nl/blog/lovable-from-hero-to-zero/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 26 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Herinner je je nog toen Lovable de lieveling van de AI-ontwikkelwereld was? Hun intuïtieve interface en betrouwbare prestaties maakten hen een go-to platform voor ontwikkelaars van alle niveaus. Helaas heeft die reputatie een dramatische duikvlucht genomen sinds de release van &lt;strong&gt;Lovable 2.0&lt;/strong&gt;, met gebruikers op Reddit en andere platforms die hun frustraties uiten over de update.&lt;/p&gt;
&lt;h2 id=&quot;het-gouden-tijdperk-van-10&quot;&gt;Het Gouden Tijdperk van 1.0&lt;/h2&gt;
&lt;p&gt;Voordat we in de huidige problemen duiken, laten we herinneren wat Lovable speciaal maakte:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Intuïtieve UI&lt;/strong&gt;: Gebruikers prezen regelmatig de schone, geanimeerde interface die ontwikkeling aangenaam maakte&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Betrouwbare Prestaties&lt;/strong&gt;: Projecten werkten consistent met minimale debugging nodig&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Eerlijk Creditsysteem&lt;/strong&gt;: Gebruikers begrepen waarvoor ze betaalden en hoe credits werden gebruikt&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Responsieve Support&lt;/strong&gt;: Problemen werden snel aangepakt, met duidelijke communicatie&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Een gebruiker herinnerde zich: &quot;Ik hield absoluut van het 1.0 UI-ontwerp. Geweldige animaties. Coole ideeën. Unieke UI-creaties. Ik was super onder de indruk en gebruikte Lovable voor al mijn projecten.&quot;&lt;/p&gt;
&lt;h2 id=&quot;de-lovable-20-update-wat-ging-er-mis&quot;&gt;De Lovable 2.0 Update: Wat Ging Er Mis?&lt;/h2&gt;
&lt;p&gt;De release van &lt;strong&gt;Lovable 2.0&lt;/strong&gt; begin 2025 bracht een complete herontwerp van het platform. Hoewel verbeterde mogelijkheden werden beloofd, ervaren gebruikers talrijke kritieke problemen:&lt;/p&gt;
&lt;h3 id=&quot;1-mysterieus-creditverbruik&quot;&gt;1. Mysterieus Creditverbruik&lt;/h3&gt;
&lt;p&gt;Gebruikers melden dat credits zonder uitleg verdwijnen:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Ik zette mezelf in chatmodus, stelde een paar vragen en maakte een handmatige bewerking aan één woord... plotseling ben ik terug naar 3/5 dagelijkse credits?!? Ik vroeg Lovable om te onderzoeken en het kon me niet eens vertellen waarvoor de credits werden gebruikt!&quot; - u/neuralgroov2&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Een andere gebruiker deelde: &quot;Ik betaalde voor een scale 1 abonnement toen deze nieuwe update kwam... Op dat moment had ik nog 360 credits waarvoor ik al had betaald, en nadat ik mijn abonnement annuleerde / downgrade, had ik er nog maar 5. Meen je dat nou, Lovable?&quot;&lt;/p&gt;
&lt;h3 id=&quot;2-ui-achteruitgang&quot;&gt;2. UI Achteruitgang&lt;/h3&gt;
&lt;p&gt;De nieuwe interface is bijna universeel bekritiseerd:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;2.0 UI-ontwerp is verschrikkelijk. Draai alsjeblieft terug!! Ineens rolt 2.0 uit en ik gebruik dezelfde beschrijvende prompts die prachtige UI-kunst creëerden in 1.0 en nu in 2.0 is het poep. Saai, geen animatie, lelijk, koekjessnijder, verschrikkelijke UI-ideeën die lijken alsof je terugging naar vroeg 2000s voor UI-ontwerp.&quot; - u/digitalml&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;3-kapotte-functionaliteit&quot;&gt;3. Kapotte Functionaliteit&lt;/h3&gt;
&lt;p&gt;Veel gebruikers melden dat de update eerder werkende applicaties heeft gebroken:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Na twee dagen Lovable op te geven (nadat ik net voor de upgrade naar de $100-tier was gegaan en nog geen antwoord van hun overweldigde supportpersoneel had gekregen in dagen), besloot ik mijn teen weer in het water te steken... Het deed niets van wat ik vroeg. Het voegde twee login-links toe in de header en verwijderde alle homepage-content met 20 kaarten die 404&apos;d.&quot; - u/who_am_i_to_say_so&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Een andere gebruiker deelde: &quot;Ik heb meer dan 20 credits besteed aan het proberen te repareren van code die resulteert in mijn app die vast zit op een &apos;laadpagina&apos;. De AI lijkt vol vertrouwen te geloven dat het gerepareerd is, maar dat is het niet, blijf in cirkels gaan.&quot;&lt;/p&gt;
&lt;h3 id=&quot;4-overweldigde-support&quot;&gt;4. Overweldigde Support&lt;/h3&gt;
&lt;p&gt;Klantenservice lijkt volledig overweldigd door het volume aan problemen:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Ik probeerde contact op te nemen met jullie &apos;support&apos; en ontving een bericht dat het alleen beschikbaar is voor betalende gebruikers.&quot; - u/AI_4U&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Zelfs betalende gebruikers melden dagenlang wachten op antwoorden: &quot;Na het upgraden naar de $100-tier net voor de upgrade en nog geen antwoord van hun overweldigde supportpersoneel in dagen...&quot;&lt;/p&gt;
&lt;h3 id=&quot;5-seo-beloftes-vs-realiteit&quot;&gt;5. SEO Beloftes vs. Realiteit&lt;/h3&gt;
&lt;p&gt;Meerdere gebruikers hebben discrepanties opgemerkt tussen wat Lovable belooft en wat het levert:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Waarom praten ze over SEO terwijl hun apps CSR zijn en geen SEO-mogelijkheden hebben?&quot; - u/VisionaryOS&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Dit heeft geleid tot third-party ontwikkelaars die tools maken om Lovable&apos;s tekortkomingen aan te pakken, met een gebruiker die aankondigde: &quot;Ik heb een tool gebouwd om je te helpen met je Lovable-projecten en te voorkomen dat ze in spaghetti veranderen.&quot;&lt;/p&gt;
&lt;h2 id=&quot;reactie-van-de-community&quot;&gt;Reactie van de Community&lt;/h2&gt;
&lt;p&gt;De reactie van de community is snel en hevig geweest. Veel gebruikers roepen Lovable op om terug te gaan naar versie 1.0:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Dit is geen bedreiging maar beschouw dit als een waarschuwing. Dit is hoe bedrijven (startups) sterven of gecanceld worden. Als jullie niet teruggaan naar 1.0 en verloren credits terugbetalen zodat we de apps kunnen repareren die jullie geüpgradede platform heeft vernietigd... zullen jullie geen andere optie hebben dan cancel-actie onder ogen te zien.&quot; - u/r4g3z29&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Anderen eisen terugbetalingen:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Lovable; jullie moeten wat van deze credits terugbetalen, iets doen, de problemen aanpakken. Ik denk dat eerlijk eerlijk is; er moet een soort terugbetaling komen in de vorm van credits, 2.Slow werkt niet goed en het is niet zomaar een handjevol van ons.&quot; - u/Horror_Brother67&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;zorgen-over-codekwaliteit&quot;&gt;Zorgen over Codekwaliteit&lt;/h2&gt;
&lt;p&gt;Sommige gebruikers hebben zelfs de codekwaliteit van Lovable-gegenereerde applicaties geanalyseerd, met zorgwekkende resultaten:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Ik gaf mijn github-project aan grok en ik was zoals... wauw. Security Grade: 4/10, Testing Grade: 2/10&quot; - u/adreportcard&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Dit suggereert dat er naast de interface- en creditproblemen fundamentele problemen kunnen zijn met de code die Lovable 2.0 genereert.&lt;/p&gt;
&lt;h2 id=&quot;is-er-hoop-voor-lovable-20&quot;&gt;Is Er Hoop voor Lovable 2.0?&lt;/h2&gt;
&lt;p&gt;Hoewel sommige gebruikers nog steeds succes vinden met &lt;strong&gt;Lovable 2.0&lt;/strong&gt;, is het overweldigende sentiment negatief. Een gebruiker deelde een systeemprompt die ze creëerden om de prestaties te verbeteren:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Ik gebruik het een week en het lijkt koppigheid en ongewenste code-herschrijvingen te verminderen. Hoewel Lovable zelf recent wijzigingen heeft gemaakt om alleen noodzakelijke regels te herschrijven, is het niet consistent geweest.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Dit suggereert dat gebruikers met significante workarounds misschien wat functionaliteit kunnen redden, maar het is ver van de naadloze ervaring die werd beloofd.&lt;/p&gt;
&lt;h2 id=&quot;geleerde-lessen&quot;&gt;Geleerde Lessen&lt;/h2&gt;
&lt;p&gt;Het Lovable 2.0 debacle biedt verschillende belangrijke lessen voor zowel gebruikers als bedrijven:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Test grondig voor grote releases&lt;/strong&gt;: Het volume en de ernst van problemen suggereren onvoldoende testen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Onderhoud transparante communicatie&lt;/strong&gt;: Veel gebruikers noemen gebrek aan duidelijke informatie over wat er gebeurt&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Overweeg gefaseerde uitrollen&lt;/strong&gt;: Een geleidelijke overgang had de schok van plotselinge veranderingen kunnen voorkomen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zorg voor adequate support&lt;/strong&gt;: Supportsystemen moeten schalen met verwachte problemen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bied rollback-opties&lt;/strong&gt;: Wanneer dingen misgaan, hebben gebruikers een manier nodig om terug te keren naar wat werkte&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;wat-is-jouw-ervaring&quot;&gt;Wat Is Jouw Ervaring?&lt;/h2&gt;
&lt;p&gt;Heb je Lovable gebruikt voor en na de 2.0-update? Deel je ervaringen in de reacties hieronder. En als je goede alternatieven hebt gevonden met betere support, hoor ik er graag over!&lt;/p&gt;
&lt;p&gt;Zoals een gebruiker treffend zei: &quot;Deze 2.0-update is echt de slechtste update die ik ooit heb gezien.&quot; Voor een platform dat ooit zoveel belofte toonde, is dat een verwoestende val van genade.&lt;/p&gt;
&lt;h2 id=&quot;wat-moet-je-doen-als-je-getroffen-bent-door-lovable-20&quot;&gt;Wat Moet Je Doen Als Je Getroffen Bent door Lovable 2.0?&lt;/h2&gt;
&lt;p&gt;Als je problemen ondervindt met &lt;strong&gt;Lovable 2.0&lt;/strong&gt;, hier zijn je opties:&lt;/p&gt;
&lt;h3 id=&quot;optie-1-migreren-naar-externe-hosting&quot;&gt;Optie 1: Migreren naar Externe Hosting&lt;/h3&gt;
&lt;p&gt;Exporteer je Lovable-project en host het elders voor betere betrouwbaarheid:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;Verhuizen naar Cloudflare&lt;/a&gt; - Beste prestaties en onbeperkte requests&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website/&quot;&gt;Verhuizen naar Vercel&lt;/a&gt; - Makkelijkste setup met automatische deployments&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website&quot;&gt;10 Gratis Hostingopties&lt;/a&gt; - Complete gids voor alle gratis hostingplatforms&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Migreren geeft je volledige controle over je codebase en verwijdert afhankelijkheid van Lovable&apos;s platformproblemen.&lt;/p&gt;
&lt;h3 id=&quot;optie-2-exporteren-en-lokaal-verder-ontwikkelen&quot;&gt;Optie 2: Exporteren en Lokaal Verder Ontwikkelen&lt;/h3&gt;
&lt;p&gt;Download je projectcode en ga verder met ontwikkeling in VS Code met volledige controle over je codebase. Dit laat je:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Problemen oplossen die Lovable niet kan&lt;/li&gt;
&lt;li&gt;Codekwaliteit en beveiliging verbeteren&lt;/li&gt;
&lt;li&gt;Aangepaste features toevoegen zonder creditlimieten&lt;/li&gt;
&lt;li&gt;Offline werken zonder platformafhankelijkheden&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;optie-3-wachten-op-fixes&quot;&gt;Optie 3: Wachten op Fixes&lt;/h3&gt;
&lt;p&gt;Monitor de Lovable-community en supportkanalen voor updates en bugfixes. Echter, gezien de schaal van gemelde problemen, kan dit aanzienlijke tijd kosten.&lt;/p&gt;
&lt;h3 id=&quot;hoe-je-lovable-project-te-exporteren&quot;&gt;Hoe Je Lovable-Project te Exporteren&lt;/h3&gt;
&lt;p&gt;Ongeacht welk pad je kiest, exporteren van je project zorgt ervoor dat je niet opgesloten zit en volledig eigendom hebt van je werk:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;In Lovable&lt;/strong&gt;: Klik op menu-icoon → Export → Download als ZIP&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pak&lt;/strong&gt; het ZIP-bestand uit om toegang te krijgen tot je complete codebase&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Push naar Git&lt;/strong&gt; voor versiebeheer en deployment&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deploy overal&lt;/strong&gt;: Je code werkt op elk platform dat React ondersteunt&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Zie onze complete migratiegidsen voor stapsgewijze instructies.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Przewodnik instalacji Claude Code: Skrypt irm, konfiguracja npm i https://claude.ai/install.ps1]]></title><description><![CDATA[Krok po kroku konfiguracja Claude Code CLI IDE, instalacja i deinstalacja natywnego pliku binarnego, npm oraz rozwiazywanie problemow z claude doctor.]]></description><link>https://vibecodingwithfred.com/pl/blog/claude-code-installation-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pl/blog/claude-code-installation-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 26 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;wprowadzenie&quot;&gt;Wprowadzenie&lt;/h2&gt;
&lt;p&gt;Claude Code to moje glowne narzedzie linii polecen do kodowania wspomaganego AI. Niezaleznie czy jestes na Windows, macOS czy Linux, instalacja jest prosta z wieloma opcjami:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Natywny plik binarny&lt;/strong&gt; (Zalecany): &lt;code class=&quot;language-text&quot;&gt;curl -fsSL https://claude.ai/install.sh | bash&lt;/code&gt; dla Linux/macOS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Windows PowerShell&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;irm https://claude.ai/install.ps1 | iex&lt;/code&gt; dla uzytkownikow Windows&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Globalna instalacja npm&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;npm install -g @anthropic-ai/claude-code&lt;/code&gt; dla srodowisk Node.js&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ten przewodnik opisuje szczegolowo kazda metode instalacji, plus rozwiazywanie problemow za pomoca polecenia &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; do diagnozowania i naprawiania typowych problemow.&lt;/p&gt;
&lt;h2 id=&quot;zalecane-natywny-plik-binarny&quot;&gt;Zalecane: Natywny plik binarny&lt;/h2&gt;
&lt;p&gt;Od 2025 roku jest kilka srodowisk uruchomieniowych dla Claude, w tym Node.js i Bun.js. Anthropic zaleca uzywanie instalacji natywnego pliku binarnego. Ta metoda unika konfliktow miedzy menedzerami pakietow i jest najbardziej stabilna.&lt;/p&gt;
&lt;h3 id=&quot;instalacja-natywnego-pliku-binarnego&quot;&gt;Instalacja natywnego pliku binarnego&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Uruchom skrypt instalacyjny:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Przeladuj konfiguracje powloki:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token comment&quot;&gt;# lub dla uzytkownikow zsh:&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.zshrc&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Zweryfikuj instalacje:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;
claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To wszystko! Claude Code powinien byc teraz zainstalowany w &lt;code class=&quot;language-text&quot;&gt;~/.claude/bin/claude&lt;/code&gt; lub &lt;code class=&quot;language-text&quot;&gt;~/.local/bin/claude&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;rozwiazywanie-problemow-z-claude-doctor&quot;&gt;Rozwiazywanie problemow z claude doctor&lt;/h2&gt;
&lt;p&gt;Polecenie &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; to pierwsze miejsce do rozwiazywania problemow. Analizuje twoja instalacje i raportuje potencjalne problemy.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude doctor&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;co-sprawdza-claude-doctor&quot;&gt;Co sprawdza claude doctor&lt;/h3&gt;
&lt;p&gt;Polecenie &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt; sprawdza:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Metode instalacji&lt;/strong&gt;: Natywny plik binarny, npm, Bun lub Homebrew&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Informacje o wersji&lt;/strong&gt;: Aktualna wersja i status aktualizacji&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mozliwosc automatycznej aktualizacji&lt;/strong&gt;: Czy aktualizacje moga byc stosowane&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Funkcjonalnosc wyszukiwania&lt;/strong&gt;: Czy ripgrep jest prawidlowo dolaczony/zainstalowany&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Konfiguracja PATH&lt;/strong&gt;: Czy Claude jest prawidlowo w twoim PATH&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sciezka wykonania&lt;/strong&gt;: Faktyczny uruchamiany plik binarny&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;alternatywne-metody-instalacji&quot;&gt;Alternatywne metody instalacji&lt;/h2&gt;
&lt;h3 id=&quot;instalacja-npm-npm-install--g-anthropic-aiclaude-code&quot;&gt;Instalacja npm: npm install -g @anthropic-ai/claude-code&lt;/h3&gt;
&lt;p&gt;Jesli wolisz uzywac npm (Node Package Manager), mozesz zainstalowac Claude Code globalnie. Ta metoda wymaga Node.js 18 lub wyzszego.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @anthropic-ai/claude-code&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Wazne:&lt;/strong&gt; Nigdy nie uzywaj &lt;code class=&quot;language-text&quot;&gt;sudo npm install -g&lt;/code&gt; poniewaz powoduje to problemy z uprawnieniami.&lt;/p&gt;
&lt;h3 id=&quot;windows-uzywanie-irm-httpsclaudeaiinstallps1--iex&quot;&gt;Windows: Uzywanie irm &lt;a href=&quot;https://claude.ai/install.ps1&quot;&gt;https://claude.ai/install.ps1&lt;/a&gt; | iex&lt;/h3&gt;
&lt;p&gt;Dla uzytkownikow Windows masz trzy opcje:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;WSL (Zalecane)&lt;/strong&gt;: Zainstaluj WSL i postepuj wedlug instrukcji dla Linux&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Git Bash&lt;/strong&gt;: Uzyj natywnego instalatora z Git Bash&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PowerShell&lt;/strong&gt; (Natywny Windows):
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;powershell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-powershell line-numbers&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;irm&lt;/span&gt; https:&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;claude&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ai/install&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ps1 &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;iex&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Polecenie &lt;code class=&quot;language-text&quot;&gt;irm&lt;/code&gt; to &lt;strong&gt;Invoke-RestMethod&lt;/strong&gt; PowerShella, ktore pobiera zawartosc z URL. Skrypt &lt;code class=&quot;language-text&quot;&gt;https://claude.ai/install.ps1&lt;/code&gt; obsluguje:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wykrywanie architektury Windows (x64, ARM64)&lt;/li&gt;
&lt;li&gt;Pobieranie odpowiedniego pliku binarnego Claude Code&lt;/li&gt;
&lt;li&gt;Instalacje do katalogu uzytkownika&lt;/li&gt;
&lt;li&gt;Dodawanie Claude do zmiennej srodowiskowej PATH&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;po-instalacji&quot;&gt;Po instalacji&lt;/h2&gt;
&lt;h3 id=&quot;uwierzytelnianie&quot;&gt;Uwierzytelnianie&lt;/h3&gt;
&lt;p&gt;Po instalacji uwierzytelnij Claude Code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Zostaniesz poproszony o wybor metody uwierzytelniania:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Claude Console&lt;/strong&gt; (domyslnie): Dla dostepu API z rozliczeniami na console.anthropic.com&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude Pro/Max&lt;/strong&gt;: Jesli masz subskrypcje Claude&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enterprise&lt;/strong&gt;: Dla wdrozen AWS Bedrock lub Google Vertex AI&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;podstawowe-uzycie&quot;&gt;Podstawowe uzycie&lt;/h3&gt;
&lt;p&gt;Zacznij uzywac Claude Code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Przejdz do swojego projektu&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; /sciezka/do/twojego/projektu

&lt;span class=&quot;token comment&quot;&gt;# Uruchom Claude Code&lt;/span&gt;
claude

&lt;span class=&quot;token comment&quot;&gt;# Uzyskaj pomoc&lt;/span&gt;
claude &lt;span class=&quot;token builtin class-name&quot;&gt;help&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# W sesji uzyj polecen slash&lt;/span&gt;
/help    &lt;span class=&quot;token comment&quot;&gt;# Pokaz dostepne polecenia&lt;/span&gt;
/clear   &lt;span class=&quot;token comment&quot;&gt;# Wyczysc rozmowe&lt;/span&gt;
/exit    &lt;span class=&quot;token comment&quot;&gt;# Wyjdz z Claude Code&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;zarzadzanie-aktualizacjami&quot;&gt;Zarzadzanie aktualizacjami&lt;/h2&gt;
&lt;p&gt;Claude Code automatycznie aktualizuje sie domyslnie. Aktualizacje sa sprawdzane przy uruchomieniu i stosowane w tle.&lt;/p&gt;
&lt;h3 id=&quot;jak-zaktualizowac-claude-code&quot;&gt;Jak zaktualizowac Claude Code&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claude update&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;typowe-problemy-i-rozwiazania&quot;&gt;Typowe problemy i rozwiazania&lt;/h2&gt;
&lt;h3 id=&quot;problem-command-not-found-claude&quot;&gt;Problem: &quot;command not found: claude&quot;&lt;/h3&gt;
&lt;p&gt;PATH nie zostal zaktualizowany. Dodaj do konfiguracji powloki:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export PATH=&quot;$HOME/.local/bin:$PATH&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;problem-funkcja-wyszukiwania-nie-dziala&quot;&gt;Problem: Funkcja wyszukiwania nie dziala&lt;/h3&gt;
&lt;p&gt;Zwykle naprawiana przez natywna instalacje, ale jesli problem trwa:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Zainstaluj ripgrep recznie&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;apt-get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; ripgrep  &lt;span class=&quot;token comment&quot;&gt;# Ubuntu/Debian&lt;/span&gt;
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; ripgrep          &lt;span class=&quot;token comment&quot;&gt;# macOS&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;najlepsze-praktyki&quot;&gt;Najlepsze praktyki&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Zawsze uzywaj natywnego pliku binarnego&lt;/strong&gt; chyba ze masz specyficzne wymagania&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unikaj sudo&lt;/strong&gt; przy kazdej metodzie instalacji&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trzymaj automatyczne aktualizacje wlaczone&lt;/strong&gt; dla bezpieczenstwa i funkcji&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Uruchom &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt;&lt;/strong&gt; po kazdej instalacji lub aktualizacji&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Posprzataj stare instalacje&lt;/strong&gt; przed instalacja nowych wersji&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;podsumowanie&quot;&gt;Podsumowanie&lt;/h2&gt;
&lt;p&gt;Pamietaj: w razie watpliwosci usun wszystko i zacznij od nowa z natywnym plikiem binarnym. To najprostszy, najszybszy i najbardziej niezawodny sposob uruchamiania Claude Code.&lt;/p&gt;
&lt;h2 id=&quot;szybka-referencja&quot;&gt;Szybka referencja&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Instalacja&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;curl -fsSL https://claude.ai/install.sh | bash&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sprawdz wersje&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude --version&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Diagnoza&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude doctor&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Aktualizacja&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude update&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Uruchom&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pomoc&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;claude help&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Managing Cloudflare DNS Records via API: Create & Update with Curl Examples]]></title><description><![CDATA[Learn how to manage Cloudflare DNS records using the API with step-by-step curl examples. Covers creating, updating, deleting DNS records and API authentication for effective DNS automation.]]></description><link>https://vibecodingwithfred.com/blog/cloudflare-dns-api/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/cloudflare-dns-api/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 19 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Updating DNS records through Cloudflare&apos;s web interface gets old fast. If you&apos;re managing multiple domains, running deployments, or just tired of clicking through menus, the Cloudflare API will save you hours of work. This guide shows you exactly how to automate your DNS management with working code examples.&lt;/p&gt;
&lt;h2 id=&quot;what-you-need&quot;&gt;What You Need&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A Cloudflare account with at least one domain&lt;/li&gt;
&lt;li&gt;Basic understanding of DNS (A records, CNAMEs, etc.)&lt;/li&gt;
&lt;li&gt;curl, Node.js, Python, or PHP installed&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;getting-your-api-credentials&quot;&gt;Getting Your API Credentials&lt;/h2&gt;
&lt;p&gt;You need an API token to interact with Cloudflare. Here&apos;s how to create one:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Log into your Cloudflare dashboard&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;My Profile&lt;/strong&gt; → &lt;strong&gt;API Tokens&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create Token&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Use the &quot;Edit zone DNS&quot; template&lt;/li&gt;
&lt;li&gt;Set permissions to &lt;strong&gt;Zone → DNS → Edit&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Select the zones this token can access&lt;/li&gt;
&lt;li&gt;Create the token and &lt;strong&gt;save it immediately&lt;/strong&gt; (you won&apos;t see it again)&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important Note:&lt;/strong&gt; Store your API token securely. Never commit it to version control. Use environment variables instead.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;api-fundamentals&quot;&gt;API Fundamentals&lt;/h2&gt;
&lt;p&gt;All Cloudflare API requests go to: &lt;code class=&quot;language-text&quot;&gt;https://api.cloudflare.com/client/v4/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Every request needs these headers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Authorization: Bearer YOUR_API_TOKEN&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Content-Type: application/json&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;step-1-find-your-zone-id&quot;&gt;Step 1: Find Your Zone ID&lt;/h2&gt;
&lt;p&gt;Every domain in Cloudflare has a Zone ID, which us usually present in the address bar when navigating through your project on Cloudfalre. You&apos;ll need this for all DNS operations.&lt;/p&gt;
&lt;p&gt;Run this once and save the ID:&lt;/p&gt;
&lt;h3 id=&quot;curl&quot;&gt;curl&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; GET &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer YOUR_API_TOKEN&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;javascript&quot;&gt;JavaScript&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CLOUDFLARE_API_TOKEN&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CLOUDFLARE_API_TOKEN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;BASE_URL&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://api.cloudflare.com/client/v4&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;listZones&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;BASE_URL&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/zones&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token string-property property&quot;&gt;&apos;Authorization&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CLOUDFLARE_API_TOKEN&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string-property property&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;success&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;zone&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Domain: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;zone&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;, Zone ID: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;zone&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;listZones&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;python&quot;&gt;Python&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; requests
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os

CLOUDFLARE_API_TOKEN &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;CLOUDFLARE_API_TOKEN&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
BASE_URL &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://api.cloudflare.com/client/v4&apos;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;list_zones&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    headers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;Authorization&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;CLOUDFLARE_API_TOKEN&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; requests&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;BASE_URL&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/zones&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; headers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;json&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;success&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; zone &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;result&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;Domain: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;zone&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;, Zone ID: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;zone&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

list_zones&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;php&quot;&gt;PHP&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token php language-php&quot;&gt;&lt;span class=&quot;token delimiter important&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$token&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$_ENV&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;CLOUDFLARE_API_TOKEN&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$baseUrl&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;https://api.cloudflare.com/client/v4&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;curl_init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$baseUrl&lt;/span&gt;&lt;/span&gt;/zones&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl_setopt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CURLOPT_HTTPHEADER&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Authorization: Bearer &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$token&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl_setopt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CURLOPT_RETURNTRANSFER&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token variable&quot;&gt;$response&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;curl_exec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;json_decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;success&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;result&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$zone&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Domain: &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$zone&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;, Zone ID: &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$zone&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;curl_close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Save your Zone ID in an environment variable. You&apos;ll use it for every DNS operation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;step-2-list-all-dns-records&quot;&gt;Step 2: List All DNS Records&lt;/h2&gt;
&lt;p&gt;This will display all DNS records for your domain. You&apos;ll need record IDs for updates and deletions:&lt;/p&gt;
&lt;h3 id=&quot;curl-1&quot;&gt;curl&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;ZONE_ID&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;your_zone_id_here&quot;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; GET &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones/&lt;span class=&quot;token variable&quot;&gt;${ZONE_ID}&lt;/span&gt;/dns_records&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer YOUR_API_TOKEN&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Filter by type (optional)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; GET &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones/&lt;span class=&quot;token variable&quot;&gt;${ZONE_ID}&lt;/span&gt;/dns_records?type=A&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer YOUR_API_TOKEN&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;javascript-1&quot;&gt;JavaScript&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;listDNSRecords&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;zoneId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; type &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; url &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;BASE_URL&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/zones/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;zoneId&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/dns_records&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; url &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;?type=&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;type&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token string-property property&quot;&gt;&apos;Authorization&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CLOUDFLARE_API_TOKEN&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string-property property&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;success&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;record&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;record&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;record&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; | ID: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;record&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// List all records&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;listDNSRecords&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;your_zone_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// List only A records&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;listDNSRecords&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;your_zone_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;python-1&quot;&gt;Python&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;list_dns_records&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;zone_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; record_type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    headers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;Authorization&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;CLOUDFLARE_API_TOKEN&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    url &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;BASE_URL&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/zones/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;zone_id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/dns_records&apos;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; record_type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        url &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;?type=&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;record_type&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;
    
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; requests&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; headers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;json&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;success&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; record &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;result&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;record&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;type&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;record&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;record&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;content&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; | ID: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;record&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;result&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# List all records&lt;/span&gt;
list_dns_records&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;your_zone_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# List only A records  &lt;/span&gt;
list_dns_records&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;your_zone_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;php-1&quot;&gt;PHP&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token php language-php&quot;&gt;&lt;span class=&quot;token delimiter important&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;listDNSRecords&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$zoneId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$type&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;global&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$token&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$baseUrl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token variable&quot;&gt;$url&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$baseUrl&lt;/span&gt;&lt;/span&gt;/zones/&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$zoneId&lt;/span&gt;&lt;/span&gt;/dns_records&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$url&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;?type=&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$type&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;curl_init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;curl_setopt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CURLOPT_HTTPHEADER&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Authorization: Bearer &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$token&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;curl_setopt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CURLOPT_RETURNTRANSFER&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token variable&quot;&gt;$response&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;curl_exec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;json_decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;success&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;result&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$record&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$record&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;type&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; | &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$record&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; | &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$record&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;content&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; | ID: &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$record&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;result&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token function&quot;&gt;curl_close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// List all records&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;listDNSRecords&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;your_zone_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// List only A records&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;listDNSRecords&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;your_zone_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;step-3-create-dns-records&quot;&gt;Step 3: Create DNS Records&lt;/h2&gt;
&lt;p&gt;Creating new DNS records is straightforward. Here&apos;s what each field means:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;type&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Record type&lt;/td&gt;
&lt;td&gt;A, AAAA, CNAME, TXT, MX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Full domain or subdomain&lt;/td&gt;
&lt;td&gt;app.example.com or @ for root&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;content&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The value (IP, domain, text)&lt;/td&gt;
&lt;td&gt;192.0.2.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;ttl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Time to live (1 = automatic)&lt;/td&gt;
&lt;td&gt;1 or 3600 (seconds)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;proxied&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Use Cloudflare&apos;s proxy/CDN&lt;/td&gt;
&lt;td&gt;true or false&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;create-an-a-record&quot;&gt;Create an &quot;A&quot; Record&lt;/h3&gt;
&lt;p&gt;An &quot;A&quot; record is the IP of the server you wish to point to. Add an &quot;A&quot; record with the following:&lt;/p&gt;
&lt;h4 id=&quot;curl-2&quot;&gt;curl&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;ZONE_ID&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;your_zone_id_here&quot;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; POST &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones/&lt;span class=&quot;token variable&quot;&gt;${ZONE_ID}&lt;/span&gt;/dns_records&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer YOUR_API_TOKEN&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;--data&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{
    &quot;type&quot;: &quot;A&quot;,
    &quot;name&quot;: &quot;app.example.com&quot;,
    &quot;content&quot;: &quot;192.0.2.1&quot;,
    &quot;ttl&quot;: 1,
    &quot;proxied&quot;: true
  }&apos;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;javascript-2&quot;&gt;JavaScript&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createARecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;zoneId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ip&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; proxied &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;BASE_URL&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/zones/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;zoneId&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/dns_records&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;POST&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token string-property property&quot;&gt;&apos;Authorization&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CLOUDFLARE_API_TOKEN&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string-property property&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ip&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;ttl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;proxied&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; proxied
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;success&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;A record created:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Error:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;errors&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;createARecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;your_zone_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app.example.com&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;192.0.2.1&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;python-2&quot;&gt;Python&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;create_a_record&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;zone_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ip&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; proxied&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    headers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;Authorization&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;CLOUDFLARE_API_TOKEN&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    record_data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;type&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;content&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ip&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;ttl&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;proxied&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; proxied
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; requests&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;BASE_URL&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/zones/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;zone_id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/dns_records&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        headers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        json&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;record_data
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;json&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;success&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;A record created:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;result&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;result&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Error:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;errors&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

create_a_record&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;your_zone_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app.example.com&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;192.0.2.1&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;php-2&quot;&gt;PHP&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token php language-php&quot;&gt;&lt;span class=&quot;token delimiter important&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;createARecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$zoneId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$proxied&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;global&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$token&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$baseUrl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;type&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;name&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;content&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ttl&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;proxied&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$proxied&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;curl_init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$baseUrl&lt;/span&gt;&lt;/span&gt;/zones/&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$zoneId&lt;/span&gt;&lt;/span&gt;/dns_records&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;curl_setopt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CURLOPT_HTTPHEADER&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Authorization: Bearer &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$token&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;curl_setopt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CURLOPT_POST&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;curl_setopt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CURLOPT_POSTFIELDS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;curl_setopt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CURLOPT_RETURNTRANSFER&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token variable&quot;&gt;$response&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;curl_exec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;json_decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;success&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;A record created\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;result&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Error: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;errors&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token function&quot;&gt;curl_close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;createARecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;your_zone_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;app.example.com&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;192.0.2.1&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;create-other-record-types&quot;&gt;Create Other Record Types&lt;/h3&gt;
&lt;p&gt;CNAMES are for the subdomains and redirecting &quot;www&quot; prefixes to the root domain.&lt;/p&gt;
&lt;h4 id=&quot;cname-record-point-www-to-root-domain&quot;&gt;CNAME Record (point www to root domain)&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; POST &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones/&lt;span class=&quot;token variable&quot;&gt;${ZONE_ID}&lt;/span&gt;/dns_records&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer YOUR_API_TOKEN&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;--data&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{
    &quot;type&quot;: &quot;CNAME&quot;,
    &quot;name&quot;: &quot;www.example.com&quot;,
    &quot;content&quot;: &quot;example.com&quot;,
    &quot;ttl&quot;: 1,
    &quot;proxied&quot;: true
  }&apos;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;txt-record-for-domain-verification-spf-etc&quot;&gt;TXT Record (for domain verification, SPF, etc.)&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; POST &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones/&lt;span class=&quot;token variable&quot;&gt;${ZONE_ID}&lt;/span&gt;/dns_records&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer YOUR_API_TOKEN&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;--data&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{
    &quot;type&quot;: &quot;TXT&quot;,
    &quot;name&quot;: &quot;_verification.example.com&quot;,
    &quot;content&quot;: &quot;verification-code-12345&quot;,
    &quot;ttl&quot;: 1
  }&apos;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;mx-record-for-email&quot;&gt;MX Record (for email)&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; POST &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones/&lt;span class=&quot;token variable&quot;&gt;${ZONE_ID}&lt;/span&gt;/dns_records&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer YOUR_API_TOKEN&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;--data&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{
    &quot;type&quot;: &quot;MX&quot;,
    &quot;name&quot;: &quot;example.com&quot;,
    &quot;content&quot;: &quot;mail.example.com&quot;,
    &quot;priority&quot;: 10,
    &quot;ttl&quot;: 3600
  }&apos;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;step-4-update-dns-records&quot;&gt;Step 4: Update DNS Records&lt;/h2&gt;
&lt;p&gt;To update a record, you need its ID (from Step 2). Use PUT to replace the entire record or PATCH to update specific fields:&lt;/p&gt;
&lt;h3 id=&quot;curl-3&quot;&gt;curl&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Full update (PUT)&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;RECORD_ID&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;your_record_id_here&quot;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; PUT &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones/&lt;span class=&quot;token variable&quot;&gt;${ZONE_ID}&lt;/span&gt;/dns_records/&lt;span class=&quot;token variable&quot;&gt;${RECORD_ID}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer YOUR_API_TOKEN&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;--data&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{
    &quot;type&quot;: &quot;A&quot;,
    &quot;name&quot;: &quot;app.example.com&quot;,
    &quot;content&quot;: &quot;203.0.113.50&quot;,
    &quot;ttl&quot;: 1,
    &quot;proxied&quot;: true
  }&apos;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Partial update (PATCH) - just change the IP&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; PATCH &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones/&lt;span class=&quot;token variable&quot;&gt;${ZONE_ID}&lt;/span&gt;/dns_records/&lt;span class=&quot;token variable&quot;&gt;${RECORD_ID}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer YOUR_API_TOKEN&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;--data&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{
    &quot;content&quot;: &quot;203.0.113.100&quot;
  }&apos;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;javascript-3&quot;&gt;JavaScript&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;updateDNSRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;zoneId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; recordId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; updates&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Use PATCH for partial updates&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;BASE_URL&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/zones/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;zoneId&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/dns_records/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;recordId&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;PATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string-property property&quot;&gt;&apos;Authorization&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CLOUDFLARE_API_TOKEN&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string-property property&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;updates&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;success&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Record updated:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Error:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;errors&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Just update the IP&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;updateDNSRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;zone_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;record_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;203.0.113.100&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;python-3&quot;&gt;Python&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;update_dns_record&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;zone_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; record_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; updates&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    headers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;Authorization&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;CLOUDFLARE_API_TOKEN&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;# Use PATCH for partial updates&lt;/span&gt;
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; requests&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;patch&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;BASE_URL&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/zones/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;zone_id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/dns_records/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;record_id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        headers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        json&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;updates
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;json&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;success&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Record updated:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;result&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;result&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Error:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;errors&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Just update the IP&lt;/span&gt;
update_dns_record&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;zone_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;record_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;content&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;203.0.113.100&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;php-3&quot;&gt;PHP&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token php language-php&quot;&gt;&lt;span class=&quot;token delimiter important&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;updateDNSRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$zoneId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$recordId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$updates&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;global&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$token&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$baseUrl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;curl_init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$baseUrl&lt;/span&gt;&lt;/span&gt;/zones/&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$zoneId&lt;/span&gt;&lt;/span&gt;/dns_records/&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$recordId&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;curl_setopt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CURLOPT_HTTPHEADER&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Authorization: Bearer &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$token&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;curl_setopt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CURLOPT_CUSTOMREQUEST&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;PATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;curl_setopt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CURLOPT_POSTFIELDS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$updates&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;curl_setopt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CURLOPT_RETURNTRANSFER&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token variable&quot;&gt;$response&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;curl_exec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;json_decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;success&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Record updated\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;result&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Error: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;errors&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token function&quot;&gt;curl_close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Just update the IP&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;updateDNSRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;zone_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;record_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;content&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;203.0.113.100&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;step-5-delete-dns-records&quot;&gt;Step 5: Delete DNS Records&lt;/h2&gt;
&lt;p&gt;Deleting a record is simple. Just need the record ID:&lt;/p&gt;
&lt;h3 id=&quot;curl-4&quot;&gt;curl&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;RECORD_ID&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;your_record_id_here&quot;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; DELETE &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones/&lt;span class=&quot;token variable&quot;&gt;${ZONE_ID}&lt;/span&gt;/dns_records/&lt;span class=&quot;token variable&quot;&gt;${RECORD_ID}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer YOUR_API_TOKEN&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;javascript-4&quot;&gt;JavaScript&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;deleteDNSRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;zoneId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; recordId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;BASE_URL&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/zones/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;zoneId&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/dns_records/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;recordId&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;DELETE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string-property property&quot;&gt;&apos;Authorization&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CLOUDFLARE_API_TOKEN&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string-property property&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;success&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Record deleted successfully&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Error:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;errors&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;deleteDNSRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;zone_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;record_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;python-4&quot;&gt;Python&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;delete_dns_record&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;zone_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; record_id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    headers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;Authorization&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;CLOUDFLARE_API_TOKEN&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; requests&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;delete&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;BASE_URL&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/zones/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;zone_id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/dns_records/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;record_id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        headers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;headers
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;json&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;success&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Record deleted successfully&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Error:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;errors&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;

delete_dns_record&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;zone_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;record_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;php-4&quot;&gt;PHP&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token php language-php&quot;&gt;&lt;span class=&quot;token delimiter important&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;deleteDNSRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$zoneId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$recordId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;global&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$token&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$baseUrl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;curl_init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$baseUrl&lt;/span&gt;&lt;/span&gt;/zones/&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$zoneId&lt;/span&gt;&lt;/span&gt;/dns_records/&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$recordId&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;curl_setopt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CURLOPT_HTTPHEADER&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Authorization: Bearer &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$token&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;curl_setopt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CURLOPT_CUSTOMREQUEST&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;DELETE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;curl_setopt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CURLOPT_RETURNTRANSFER&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token variable&quot;&gt;$response&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;curl_exec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;json_decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;success&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Record deleted successfully\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Error: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;errors&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token function&quot;&gt;curl_close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;deleteDNSRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;zone_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;record_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;practical-example-dynamic-dns-updater&quot;&gt;Practical Example: Dynamic DNS Updater&lt;/h2&gt;
&lt;p&gt;Here&apos;s a complete script that updates your DNS when your IP changes. Perfect for home servers:&lt;/p&gt;
&lt;h3 id=&quot;python-version&quot;&gt;Python Version&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;#!/usr/bin/env python3&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; requests
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; sys

CLOUDFLARE_API_TOKEN &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;CLOUDFLARE_API_TOKEN&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
ZONE_ID &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;CLOUDFLARE_ZONE_ID&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
RECORD_NAME &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;home.example.com&apos;&lt;/span&gt;
BASE_URL &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://api.cloudflare.com/client/v4&apos;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get_public_ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;Get current public IP address&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; requests&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;https://api.ipify.org?format=json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;json&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;ip&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;except&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Failed to get public IP&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        sys&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exit&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get_dns_record&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;zone_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; record_name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;Find the DNS record by name&quot;&quot;&quot;&lt;/span&gt;
    headers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;Authorization&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;CLOUDFLARE_API_TOKEN&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; requests&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;BASE_URL&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/zones/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;zone_id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/dns_records?name=&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;record_name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;amp;type=A&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        headers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;headers
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;json&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;success&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;result&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        record &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;result&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; record&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; record&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;content&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;update_dns_record&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;zone_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; record_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; record_name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; new_ip&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;Update DNS record with new IP&quot;&quot;&quot;&lt;/span&gt;
    headers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;Authorization&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;CLOUDFLARE_API_TOKEN&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; requests&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;patch&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;BASE_URL&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/zones/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;zone_id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/dns_records/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;record_id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        headers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        json&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;content&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; new_ip&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;json&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Get current public IP&lt;/span&gt;
    current_ip &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; get_public_ip&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;Current public IP: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;current_ip&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;# Get existing DNS record&lt;/span&gt;
    record_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; existing_ip &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; get_dns_record&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ZONE_ID&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; RECORD_NAME&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; record_id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;DNS record &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;RECORD_NAME&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; not found. Create it first.&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        sys&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exit&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;DNS currently points to: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;existing_ip&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;# Update if IP changed&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; current_ip &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; existing_ip&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;IP changed! Updating DNS...&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; update_dns_record&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ZONE_ID&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; record_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; RECORD_NAME&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; current_ip&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;success&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;✓ DNS updated to &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;current_ip&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;✗ Update failed: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;errors&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            sys&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exit&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;IP unchanged. Nothing to do.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; __name__ &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;__main__&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    main&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;javascript-version&quot;&gt;JavaScript Version&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token hashbang comment&quot;&gt;#!/usr/bin/env node&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CLOUDFLARE_API_TOKEN&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CLOUDFLARE_API_TOKEN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ZONE_ID&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CLOUDFLARE_ZONE_ID&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;RECORD_NAME&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;home.example.com&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;BASE_URL&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://api.cloudflare.com/client/v4&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getPublicIP&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;https://api.ipify.org?format=json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ip&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Failed to get public IP&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getDNSRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;zoneId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; recordName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;BASE_URL&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/zones/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;zoneId&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/dns_records?name=&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;recordName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;amp;type=A&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token string-property property&quot;&gt;&apos;Authorization&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CLOUDFLARE_API_TOKEN&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string-property property&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;success &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; record &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; record&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; record&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;updateDNSRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;zoneId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; recordId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; newIP&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;BASE_URL&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/zones/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;zoneId&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/dns_records/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;recordId&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;PATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token string-property property&quot;&gt;&apos;Authorization&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;CLOUDFLARE_API_TOKEN&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string-property property&quot;&gt;&apos;Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;application/json&apos;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; newIP &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Get current public IP&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; currentIP &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getPublicIP&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Current public IP: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;currentIP&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// Get existing DNS record&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; recordId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; existingIP &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getDNSRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ZONE_ID&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;RECORD_NAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;recordId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;DNS record &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;RECORD_NAME&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; not found. Create it first.&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;DNS currently points to: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;existingIP&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// Update if IP changed&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;currentIP &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; existingIP&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;IP changed! Updating DNS...&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;updateDNSRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ZONE_ID&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; recordId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; currentIP&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;success&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;✓ DNS updated to &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;currentIP&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;✗ Update failed:&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;errors&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;IP unchanged. Nothing to do.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Setup tip:&lt;/strong&gt; Add this script to cron (Linux/Mac) or Task Scheduler (Windows) to run every 5-10 minutes for automatic dynamic DNS.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;error-handling&quot;&gt;Error Handling&lt;/h2&gt;
&lt;p&gt;Always check the &lt;code class=&quot;language-text&quot;&gt;success&lt;/code&gt; field in responses. Cloudflare provides detailed error messages:&lt;/p&gt;
&lt;h3 id=&quot;javascript-5&quot;&gt;JavaScript&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;safeAPICall&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;success&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;API Error:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;errors&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;errors&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Code &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;code&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Request failed:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;python-5&quot;&gt;Python&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;safe_api_call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;method&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; headers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; json_data&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; method &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GET&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; requests&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; headers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; method &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;POST&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; requests&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; headers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; json&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;json_data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; method &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;PATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; requests&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;patch&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; headers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; json&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;json_data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; method &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;DELETE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; requests&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;delete&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; headers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        
        data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;json&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;success&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;API Error:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;errors&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; error &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;errors&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;Code &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;code&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;message&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;
        
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;result&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;except&lt;/span&gt; Exception &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;Request failed: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;rate-limits&quot;&gt;Rate Limits&lt;/h2&gt;
&lt;p&gt;Cloudflare allows &lt;strong&gt;1200 requests per 5 minutes&lt;/strong&gt; per API token. If you hit the limit, you&apos;ll get a 429 status code. The response includes a &lt;code class=&quot;language-text&quot;&gt;Retry-After&lt;/code&gt; header telling you how long to wait.&lt;/p&gt;
&lt;p&gt;For production scripts, implement retry logic with exponential backoff. Most operations won&apos;t hit these limits unless you&apos;re doing bulk updates.&lt;/p&gt;
&lt;h2 id=&quot;security-best-practices&quot;&gt;Security Best Practices&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Never hardcode tokens&lt;/strong&gt; - Use environment variables&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use .env files locally&lt;/strong&gt; - Add to .gitignore immediately&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Create specific tokens&lt;/strong&gt; - One per application, minimal permissions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rotate tokens regularly&lt;/strong&gt; - Set calendar reminders&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Monitor token usage&lt;/strong&gt; - Check Cloudflare&apos;s audit logs&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;quick-reference&quot;&gt;Quick Reference&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;List zones&lt;/td&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/zones&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List DNS records&lt;/td&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/zones/{zone_id}/dns_records&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Create DNS record&lt;/td&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/zones/{zone_id}/dns_records&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Update DNS record&lt;/td&gt;
&lt;td&gt;PUT/PATCH&lt;/td&gt;
&lt;td&gt;/zones/{zone_id}/dns_records/{record_id}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete DNS record&lt;/td&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;/zones/{zone_id}/dns_records/{record_id}&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;common-dns-record-types&quot;&gt;Common DNS Record Types&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Example Content&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;IPv4 address&lt;/td&gt;
&lt;td&gt;192.0.2.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AAAA&lt;/td&gt;
&lt;td&gt;IPv6 address&lt;/td&gt;
&lt;td&gt;2001:db8::1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CNAME&lt;/td&gt;
&lt;td&gt;Alias to another domain&lt;/td&gt;
&lt;td&gt;example.com&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MX&lt;/td&gt;
&lt;td&gt;Mail server (with priority)&lt;/td&gt;
&lt;td&gt;mail.example.com&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TXT&lt;/td&gt;
&lt;td&gt;Text data (SPF, DKIM, verification)&lt;/td&gt;
&lt;td&gt;v=spf1 include:_spf.example.com ~all&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The Cloudflare API makes DNS automation straightforward. Whether you&apos;re building deployment pipelines, managing multiple domains, or just tired of clicking through web interfaces, these API calls will save you hours.&lt;/p&gt;
&lt;p&gt;Start simple - maybe just automate your most common DNS task. Once you see how much time it saves, you&apos;ll find yourself automating more and more of your DNS management.&lt;/p&gt;
&lt;h2 id=&quot;related-guides&quot;&gt;Related Guides&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/godaddy-to-cloudflare-dns/&quot;&gt;How to Move Your DNS from GoDaddy to Cloudflare&lt;/a&gt;&lt;/strong&gt; - If you haven&apos;t migrated to Cloudflare yet, start here with the complete DNS migration guide&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/cloudflare-workers-deployment/&quot;&gt;Deploy Your Static Site to Cloudflare Workers&lt;/a&gt;&lt;/strong&gt; - Once you have DNS automation down, learn how to deploy your entire site to Cloudflare&apos;s edge network&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;official-cloudflare-resources&quot;&gt;Official Cloudflare Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/api/&quot;&gt;Official Cloudflare API Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Fix Fly.io www Subdomain SSL Errors with Cloudflare (Error 525)]]></title><description><![CDATA[Getting Error 525 when accessing www.yoursite.com on Fly.io? Here's how to fix the SSL handshake error by adding separate certificates for www subdomains—a critical step most deployment guides skip.]]></description><link>https://vibecodingwithfred.com/blog/flyio-cloudflare-www-setup/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/flyio-cloudflare-www-setup/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 19 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Deployed your app to Fly.io and the root domain works fine, but &lt;code class=&quot;language-text&quot;&gt;www.yoursite.com&lt;/code&gt; throws an SSL handshake error? You&apos;re not alone. This Error 525 happens because Fly.io requires &lt;strong&gt;separate SSL certificates for each hostname&lt;/strong&gt;—and most deployment guides completely skip this step.&lt;/p&gt;
&lt;p&gt;Here&apos;s the fix, tested and verified on a production deployment.&lt;/p&gt;
&lt;h2 id=&quot;the-problem&quot;&gt;The Problem&lt;/h2&gt;
&lt;p&gt;You&apos;ve deployed to Fly.io, added your custom domain, and everything looks good. Then you try visiting &lt;code class=&quot;language-text&quot;&gt;www.yoursite.com&lt;/code&gt; and get:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Error 525: SSL handshake failed&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Meanwhile, &lt;code class=&quot;language-text&quot;&gt;yoursite.com&lt;/code&gt; (without www) works fine. What gives?&lt;/p&gt;
&lt;h2 id=&quot;why-this-happens&quot;&gt;Why This Happens&lt;/h2&gt;
&lt;p&gt;Fly.io uses Let&apos;s Encrypt to provision SSL certificates, but here&apos;s the catch: &lt;strong&gt;adding a certificate for &lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt; does NOT automatically cover &lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;They&apos;re treated as completely separate hostnames. You need to explicitly add a certificate for the www subdomain.&lt;/p&gt;
&lt;h2 id=&quot;the-solution-5-steps&quot;&gt;The Solution (5 Steps)&lt;/h2&gt;
&lt;h3 id=&quot;step-1-install-flyio-cli&quot;&gt;Step 1: Install Fly.io CLI&lt;/h3&gt;
&lt;p&gt;If you haven&apos;t already, install flyctl:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Install flyctl&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Add to PATH&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;FLYCTL_INSTALL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/.fly&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;PATH&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$FLYCTL_INSTALL&lt;/span&gt;/bin:&lt;span class=&quot;token environment constant&quot;&gt;$PATH&lt;/span&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Make it permanent (add to ~/.bashrc or ~/.zshrc)&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export FLYCTL_INSTALL=&quot;$HOME/.fly&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export PATH=&quot;$FLYCTL_INSTALL/bin:$PATH&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc

&lt;span class=&quot;token comment&quot;&gt;# Verify it works&lt;/span&gt;
flyctl version&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-2-check-your-current-certificates&quot;&gt;Step 2: Check Your Current Certificates&lt;/h3&gt;
&lt;p&gt;First, see what certificates you already have:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You&apos;ll probably see something like:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Host Name                 Added                Status
example.com              1 month ago          Ready
api.example.com          1 month ago          Ready&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Notice what&apos;s missing? The &lt;code class=&quot;language-text&quot;&gt;www&lt;/code&gt; subdomain.&lt;/p&gt;
&lt;h3 id=&quot;step-3-add-the-www-certificate-this-fixes-it&quot;&gt;Step 3: Add the www Certificate (This Fixes It)&lt;/h3&gt;
&lt;p&gt;Here&apos;s the critical command that solves the problem:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fly.io will automatically provision a Let&apos;s Encrypt SSL certificate for your www subdomain. You&apos;ll see output like:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;You are creating a certificate for www.example.com
We are using Let&apos;s Encrypt for this certificate.

Your certificate for www.example.com is being issued.
You can validate your ownership of www.example.com by:

1: Adding an AAAA record to your DNS service which reads:
    AAAA @ 2a09:8280:1::X:XXXX&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Don&apos;t worry about the DNS validation—if your root domain is already working, the www subdomain will validate automatically.&lt;/p&gt;
&lt;h3 id=&quot;step-4-verify-the-certificate-is-ready&quot;&gt;Step 4: Verify the Certificate Is Ready&lt;/h3&gt;
&lt;p&gt;Wait 1-2 minutes, then check the certificate status:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs show www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Look for &lt;strong&gt;&quot;Status: Ready&quot;&lt;/strong&gt;. If it says &quot;Awaiting certificates&quot;, wait another minute and check again.&lt;/p&gt;
&lt;p&gt;Once ready, your certificate list should show:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Host Name                 Added                Status
example.com              1 month ago          Ready
www.example.com          13 seconds ago       Ready&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Perfect.&lt;/p&gt;
&lt;h3 id=&quot;step-5-configure-cloudflare-ssltls-mode&quot;&gt;Step 5: Configure Cloudflare SSL/TLS Mode&lt;/h3&gt;
&lt;p&gt;This step is critical if you&apos;re using Cloudflare for DNS (which you should be).&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Log in to your Cloudflare dashboard&lt;/li&gt;
&lt;li&gt;Select your domain&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;SSL/TLS&lt;/strong&gt; → &lt;strong&gt;Overview&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Set the encryption mode to &lt;strong&gt;&quot;Full&quot;&lt;/strong&gt; (not &quot;Flexible&quot; or &quot;Full (strict)&quot;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Why &quot;Full&quot;?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Flexible&lt;/strong&gt;: Cloudflare uses HTTPS to your visitors, but HTTP to Fly.io (insecure, causes issues)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Full&lt;/strong&gt;: Cloudflare uses HTTPS to both visitors and Fly.io (correct)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Full (strict)&lt;/strong&gt;: Requires a trusted certificate authority, but Fly.io manages its own certs (causes errors)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;configure-your-dns-records-cloudflare&quot;&gt;Configure Your DNS Records (Cloudflare)&lt;/h2&gt;
&lt;p&gt;Make sure your DNS records are set up correctly:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Root Domain (&lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt;):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;A&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;AAAA&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Name&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;@&lt;/code&gt; (or leave blank)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Content&lt;/strong&gt;: Your Fly.io IP address (from &lt;code class=&quot;language-text&quot;&gt;flyctl ips list&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Proxy status&lt;/strong&gt;: &lt;strong&gt;Proxied&lt;/strong&gt; (orange cloud enabled)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;www Subdomain (&lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt;):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;CNAME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Name&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;www&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Target&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt; (points to root domain)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Proxy status&lt;/strong&gt;: &lt;strong&gt;Proxied&lt;/strong&gt; (orange cloud enabled)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The orange cloud (Proxied) is important—it routes traffic through Cloudflare&apos;s CDN and enables SSL.&lt;/p&gt;
&lt;h2 id=&quot;test-everything&quot;&gt;Test Everything&lt;/h2&gt;
&lt;p&gt;Verify both domains work:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Test root domain&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; https://example.com

&lt;span class=&quot;token comment&quot;&gt;# Test www subdomain&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; https://www.example.com&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Both should return &lt;code class=&quot;language-text&quot;&gt;HTTP/2 200&lt;/code&gt; (or &lt;code class=&quot;language-text&quot;&gt;HTTP/1.1 200&lt;/code&gt;). If you get errors, see the troubleshooting section below.&lt;/p&gt;
&lt;h2 id=&quot;common-errors-and-fixes&quot;&gt;Common Errors and Fixes&lt;/h2&gt;
&lt;h3 id=&quot;error-525-ssl-handshake-failed&quot;&gt;Error 525: SSL Handshake Failed&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: www subdomain throws Error 525, root domain works fine&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Causes&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Missing www certificate on Fly.io&lt;/li&gt;
&lt;li&gt;Cloudflare SSL/TLS mode is set to &quot;Flexible&quot; or &quot;Full (strict)&quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Fix&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Add the www certificate&lt;/span&gt;
flyctl certs &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME

&lt;span class=&quot;token comment&quot;&gt;# Wait 2 minutes for certificate issuance&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sleep&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;120&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Verify it&apos;s ready&lt;/span&gt;
flyctl certs show www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Also verify Cloudflare SSL/TLS mode is set to &lt;strong&gt;&quot;Full&quot;&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;www-subdomain-returns-connection-timeout&quot;&gt;www Subdomain Returns Connection Timeout&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: www subdomain doesn&apos;t load at all, no error page&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Causes&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;DNS CNAME record missing or incorrect&lt;/li&gt;
&lt;li&gt;DNS not proxied through Cloudflare&lt;/li&gt;
&lt;li&gt;DNS propagation incomplete&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Fix&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Check your Cloudflare DNS settings for the www CNAME record&lt;/li&gt;
&lt;li&gt;Ensure the orange cloud (Proxied) is enabled&lt;/li&gt;
&lt;li&gt;Wait 5-15 minutes for DNS propagation&lt;/li&gt;
&lt;li&gt;Clear your browser cache or test in incognito mode&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;certificate-shows-awaiting-certificates-for-more-than-5-minutes&quot;&gt;Certificate Shows &quot;Awaiting Certificates&quot; for More Than 5 Minutes&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;flyctl certs show&lt;/code&gt; keeps saying &quot;Awaiting certificates&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Causes&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;DNS records not pointing to Fly.io correctly&lt;/li&gt;
&lt;li&gt;Cloudflare proxy interfering with certificate validation&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Fix&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Verify your DNS records are correct&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; www.example.com

&lt;span class=&quot;token comment&quot;&gt;# Check if DNS is resolving to Fly.io&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;nslookup&lt;/span&gt; www.example.com

&lt;span class=&quot;token comment&quot;&gt;# If stuck, delete and re-add the certificate&lt;/span&gt;
flyctl certs delete www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME
flyctl certs &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;root-domain-works-www-redirects-to-root-but-you-want-both&quot;&gt;Root Domain Works, www Redirects to Root (But You Want Both)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: Visiting &lt;a href=&quot;http://www.example.com&quot;&gt;www.example.com&lt;/a&gt; redirects to example.com&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Causes&lt;/strong&gt;: This might be intentional behavior in your app code&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fix&lt;/strong&gt;: If you want both to work independently, ensure:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Both certificates exist in Fly.io&lt;/li&gt;
&lt;li&gt;Your app doesn&apos;t have redirect logic forcing www → non-www&lt;/li&gt;
&lt;li&gt;Both DNS records are configured correctly&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;why-separate-certificates-matter&quot;&gt;Why Separate Certificates Matter&lt;/h2&gt;
&lt;p&gt;In traditional shared hosting, a wildcard SSL certificate (*.example.com) covers all subdomains. But Fly.io provisions certificates individually through Let&apos;s Encrypt.&lt;/p&gt;
&lt;p&gt;This gives you more control but requires explicit setup for each subdomain:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt; → needs its own certificate&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt; → needs its own certificate&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;api.example.com&lt;/code&gt; → needs its own certificate&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;blog.example.com&lt;/code&gt; → needs its own certificate&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You get the idea.&lt;/p&gt;
&lt;h2 id=&quot;best-practices-for-flyio--cloudflare&quot;&gt;Best Practices for Fly.io + Cloudflare&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Add certificates for all subdomains you plan to use&lt;/strong&gt; before going live&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use Cloudflare&apos;s &quot;Full&quot; SSL/TLS mode&lt;/strong&gt; for Fly.io deployments&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enable Cloudflare proxy&lt;/strong&gt; (orange cloud) for CDN and DDoS protection&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Test both www and non-www&lt;/strong&gt; versions before announcing your site&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Set up redirects&lt;/strong&gt; in your app if you want to force one version over the other&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;useful-commands-for-troubleshooting&quot;&gt;Useful Commands for Troubleshooting&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# List all certificates for your app&lt;/span&gt;
flyctl certs list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME

&lt;span class=&quot;token comment&quot;&gt;# View detailed info for a specific certificate&lt;/span&gt;
flyctl certs show www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME

&lt;span class=&quot;token comment&quot;&gt;# Delete a certificate (if you need to start over)&lt;/span&gt;
flyctl certs delete www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME

&lt;span class=&quot;token comment&quot;&gt;# Check your app&apos;s IP addresses&lt;/span&gt;
flyctl ips list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME

&lt;span class=&quot;token comment&quot;&gt;# Check DNS resolution&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; example.com
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; www.example.com

&lt;span class=&quot;token comment&quot;&gt;# Test SSL connection with verbose output&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-vI&lt;/span&gt; https://www.example.com

&lt;span class=&quot;token comment&quot;&gt;# Check app status&lt;/span&gt;
flyctl status &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME

&lt;span class=&quot;token comment&quot;&gt;# View app logs (useful for debugging)&lt;/span&gt;
flyctl logs &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;complete-setup-checklist&quot;&gt;Complete Setup Checklist&lt;/h2&gt;
&lt;p&gt;Use this checklist to verify everything is configured correctly:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fly.io Certificates:&lt;/strong&gt;&lt;/p&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Root domain certificate exists and shows &quot;Ready&quot;&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; www subdomain certificate exists and shows &quot;Ready&quot;&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Any other subdomains have certificates added&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare DNS:&lt;/strong&gt;&lt;/p&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; A or AAAA record for root domain pointing to Fly.io IP&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; CNAME record for www subdomain pointing to root domain&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; All records have orange cloud (Proxied) enabled&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare SSL/TLS:&lt;/strong&gt;&lt;/p&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Encryption mode set to &quot;Full&quot; (not Flexible or Full strict)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Edge Certificates shows valid SSL&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Testing:&lt;/strong&gt;&lt;/p&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;code class=&quot;language-text&quot;&gt;https://example.com&lt;/code&gt; returns 200 OK&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;code class=&quot;language-text&quot;&gt;https://www.example.com&lt;/code&gt; returns 200 OK&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; No SSL warnings in browser&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Both domains show secure lock icon&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;real-world-example&quot;&gt;Real-World Example&lt;/h2&gt;
&lt;p&gt;Here&apos;s what the complete setup looks like for &lt;code class=&quot;language-text&quot;&gt;ftashark.com&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Check certificates&lt;/span&gt;
$ flyctl certs list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; ftashark

Host Name                 Added                Status
ftashark.com              &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; month ago          Ready
www.ftashark.com          &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt; seconds ago       Ready
api.ftashark.com          &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; month ago          Ready&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare DNS:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Type    Name    Content                          Proxy
A       @       66.241.124.123                   Proxied
CNAME   www     ftashark.com                     Proxied
CNAME   api     ftashark.com                     Proxied&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare SSL/TLS:&lt;/strong&gt; Full mode&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; All three URLs work correctly with valid SSL.&lt;/p&gt;
&lt;h2 id=&quot;why-most-guides-skip-this&quot;&gt;Why Most Guides Skip This&lt;/h2&gt;
&lt;p&gt;Most Fly.io deployment tutorials focus on getting your app running and adding a single custom domain. They assume you&apos;ll only use &lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt;—not both.&lt;/p&gt;
&lt;p&gt;But in reality, users type both versions. Search engines index both. And you don&apos;t want half your traffic hitting SSL errors.&lt;/p&gt;
&lt;p&gt;Adding the www certificate takes 30 seconds but saves hours of debugging later.&lt;/p&gt;
&lt;h2 id=&quot;alternative-redirect-www-to-non-www-or-vice-versa&quot;&gt;Alternative: Redirect www to Non-www (Or Vice Versa)&lt;/h2&gt;
&lt;p&gt;If you don&apos;t want to maintain both versions, you can set up a redirect in your app.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Option 1: Redirect www → non-www&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Most frameworks have middleware for this. For example, in Express.js:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hostname&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;www.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;redirect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;301&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;https://&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hostname&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Option 2: Redirect non-www → www&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hostname&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;www.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;redirect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;301&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;https://www.&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hostname&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But even if you redirect, &lt;strong&gt;you still need both certificates&lt;/strong&gt; or the redirect won&apos;t work (users will hit the SSL error before your app can redirect them).&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The Fly.io www subdomain SSL issue is one of those &quot;gotchas&quot; that trips up even experienced developers. The fix is simple once you know it:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Add a separate certificate for www: &lt;code class=&quot;language-text&quot;&gt;flyctl certs add www.example.com -a YOUR_APP_NAME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Set Cloudflare SSL/TLS to &quot;Full&quot; mode&lt;/li&gt;
&lt;li&gt;Wait 1-2 minutes for the certificate to be ready&lt;/li&gt;
&lt;li&gt;Test both domains&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That&apos;s it. No complex configuration, no server restarts, no editing config files. Just one command that most deployment guides forget to mention.&lt;/p&gt;
&lt;h2 id=&quot;related-flyio-guides&quot;&gt;Related Fly.io Guides&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/flyio-free-tier-guide/&quot;&gt;Fly.io Free Tier Guide&lt;/a&gt;&lt;/strong&gt; - Understand Fly.io&apos;s pricing, free tier limits, and how to maximize your free resources&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now your users can access your site with or without www, and both will work correctly.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Related guides:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;Complete Guide: Deploying Lovable Projects to Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/deploy-claude-code-cloudflare&quot;&gt;Deploy Claude Code &amp;#x26; Codex Apps to Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/cloudflare-workers-deployment&quot;&gt;Cloudflare Workers Deployment Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://fly.io/docs/networking/custom-domain/&quot;&gt;Fly.io Custom Domains Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/ssl/&quot;&gt;Cloudflare SSL/TLS Settings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://letsencrypt.org/&quot;&gt;Let&apos;s Encrypt Certificate Authority&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[What 15 Years of Coding Taught Me About Staying Healthy (And Sane)]]></title><description><![CDATA[Fifteen years into my coding career, I've learned that staying productive isn't just about better algorithms—it's about not destroying your body in the process. Here's what matters.]]></description><link>https://vibecodingwithfred.com/blog/webdev-career-reality-check-2025/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/webdev-career-reality-check-2025/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 19 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;m writing this from my standing desk at 2 PM on a Tuesday, having just finished a 25-minute walk around the block. Fifteen years ago, when I was grinding through my first real development job, this would have seemed ridiculous. Take a break? In the middle of the day? When there&apos;s code to ship?&lt;/p&gt;
&lt;p&gt;Yeah, past-me was an idiot.&lt;/p&gt;
&lt;p&gt;Fifteen years into this career, I&apos;ve learned something that nobody tells you in bootcamp or computer science programs: the biggest threat to your long-term success as a developer isn&apos;t the job market, learning the wrong framework, or even imposter syndrome.&lt;/p&gt;
&lt;p&gt;It&apos;s what all those hours in the chair do to your body.&lt;/p&gt;
&lt;p&gt;I used to be one of those developers who wore &quot;marathon coding sessions&quot; like a badge of honor. I&apos;d sit for 8-10 hours straight, hunched over my laptop, living on coffee and the high of solving complex problems. I was productive. I was shipping features. I was also slowly destroying myself.&lt;/p&gt;
&lt;p&gt;Around year seven, my back started complaining. Not the occasional ache—the kind of persistent pain that makes you wince when you stand up. By year ten, I was spending more money on physical therapy than I&apos;d ever spent on courses or conferences. That&apos;s when I finally realized: you can have all the technical skills in the world, but if your body gives out, none of it matters.&lt;/p&gt;
&lt;p&gt;Here&apos;s what I wish someone had told me on day one.&lt;/p&gt;
&lt;h2 id=&quot;the-job-market-yeah-its-different-now&quot;&gt;The Job Market (Yeah, It&apos;s Different Now)&lt;/h2&gt;
&lt;p&gt;Look, I&apos;m not going to sugarcoat it. The job market in 2025 is more competitive than when I started. The days of &quot;learn to code, guaranteed job&quot; are behind us. You&apos;re competing with hundreds of applicants for positions that used to be easier to land.&lt;/p&gt;
&lt;p&gt;But here&apos;s what hasn&apos;t changed: programming is still one of the most accessible paths to building a meaningful career. You need a computer, internet access, and the willingness to put in the work. No six-figure student loans, no trade school equipment, no gatekeeping certifications.&lt;/p&gt;
&lt;p&gt;I&apos;ve watched dozens of self-taught developers break into the field and build solid careers. The barriers are higher, yes. But if you&apos;re committed to learning (not just tutorial hell), you can still make this work.&lt;/p&gt;
&lt;p&gt;That said, this article isn&apos;t really about the job market. There are a hundred other posts about that. This is about the thing that caught me completely off guard: what happens to your body when you spend 8-10 hours a day in a chair.&lt;/p&gt;
&lt;h2 id=&quot;the-wake-up-call&quot;&gt;The Wake-Up Call&lt;/h2&gt;
&lt;p&gt;Year seven is when my body sent me an invoice.&lt;/p&gt;
&lt;p&gt;I&apos;d been having occasional back pain, but I ignored it. Developers sit all day—of course your back hurts sometimes, right? Then one morning I stood up from my desk and my lower back seized up so badly I couldn&apos;t straighten. I spent the next three days mostly horizontal, popping ibuprofen and wondering if this was just my life now.&lt;/p&gt;
&lt;p&gt;That was my wake-up call. I was 30 years old and moving like I was 60.&lt;/p&gt;
&lt;p&gt;I did what any developer would do: I researched the hell out of it. I talked to physical therapists, dove into ergonomics research, experimented with different setups, and compared notes with other developers who&apos;d been through the same thing.&lt;/p&gt;
&lt;p&gt;Here&apos;s what I learned: preventing this is way easier than fixing it. And it comes down to three interconnected things—ergonomics, movement, and building a sustainable relationship with your work.&lt;/p&gt;
&lt;h2 id=&quot;ergonomics-the-foundation-you-cant-skip&quot;&gt;Ergonomics: The Foundation You Can&apos;t Skip&lt;/h2&gt;
&lt;p&gt;Let me be clear about something: good ergonomics isn&apos;t optional. It&apos;s not a luxury purchase you make after you &quot;make it.&quot; It&apos;s the foundation of a sustainable development career.&lt;/p&gt;
&lt;p&gt;After my back incident, the first thing I did was fix my setup. And I mean really fix it, not just buy an expensive chair and hope for the best.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What mattered:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The chair&lt;/strong&gt;: I invested in a quality office chair with proper lumbar support. Not because it&apos;s cool to have a Herman Miller, but because you&apos;re going to spend 2,000+ hours a year in this thing. That&apos;s more time than you spend in your car or your bed. I went with a Steelcase Leap—bought it used for $400. Eight years later, it&apos;s still in excellent condition. You don&apos;t need to drop $2,000, but you do need something that supports your lower back properly and adjusts to your body.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Monitor height&lt;/strong&gt;: This one&apos;s huge and costs almost nothing. Your monitor should be at eye level—not below it, not above it. At eye level. I stack mine on a couple of books. Cheap, effective, and it stopped the neck pain I didn&apos;t even realize I had.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Standing desk&lt;/strong&gt;: This changed everything for me. I alternate between sitting and standing throughout the day. Not because standing is inherently better (it&apos;s not—standing all day is also terrible for you), but because changing positions matters. I went with an electric adjustable desk from Autonomous. Worth every penny.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Keyboard and mouse&lt;/strong&gt;: If you start feeling wrist pain, don&apos;t ignore it. I switched to an ergonomic keyboard and a vertical mouse after some warning twinges. Both are relatively cheap preventive measures compared to dealing with carpal tunnel later.&lt;/p&gt;
&lt;p&gt;Here&apos;s the thing though: ergonomics alone isn&apos;t enough. It&apos;s the foundation, but you need to build on it.&lt;/p&gt;
&lt;h2 id=&quot;movement-the-other-half-of-the-equation&quot;&gt;Movement: The Other Half of the Equation&lt;/h2&gt;
&lt;p&gt;I learned this the hard way. I bought all the ergonomic gear, felt pretty good about myself, and kept sitting for 8-hour stretches. My back still hurt.&lt;/p&gt;
&lt;p&gt;Turns out, you can have the best ergonomic setup and still destroy yourself if you never move. Your body wasn&apos;t designed to be stationary for hours, no matter how good your posture is.&lt;/p&gt;
&lt;p&gt;What works:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Take actual breaks&lt;/strong&gt;: I use a modified Pomodoro approach—50 minutes of work, 10-minute break. During those breaks, I move. Not &quot;scroll Twitter while sitting,&quot; but stand up, walk around, do some stretches. Sometimes I&apos;ll do a few pushups or bodyweight squats. It feels ridiculous at first, but your back doesn&apos;t care about your feelings.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stand regularly&lt;/strong&gt;: I alternate between sitting and standing every hour or so. I&apos;m standing right now as I write this. The key is changing positions, not just picking one and sticking with it all day.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Walk meetings&lt;/strong&gt;: Whenever possible, I take calls while walking. It&apos;s not always practical, but when it is, I&apos;m getting movement while staying productive.&lt;/p&gt;
&lt;p&gt;Now, I know what some of you are thinking: &quot;But I work best in flow state! I can&apos;t interrupt deep work every hour!&quot;&lt;/p&gt;
&lt;p&gt;I get it. I used to be that developer. I&apos;d hit a groove and code for 4-5 hours straight, and those sessions felt incredibly productive. And they were—in the short term. But they were also slowly breaking my body.&lt;/p&gt;
&lt;p&gt;Here&apos;s what I learned: you can have flow state OR you can have long-term health, but not both if your only strategy is sitting motionless for hours. If you&apos;re going to ride the flow state (and I still do sometimes), you need a serious exercise routine outside of work to compensate. You can&apos;t have it both ways without consequences.&lt;/p&gt;
&lt;h2 id=&quot;exercise-isnt-optionalits-part-of-the-job&quot;&gt;Exercise Isn&apos;t Optional—It&apos;s Part of the Job&lt;/h2&gt;
&lt;p&gt;This is the part that finally fixed everything for me: regular exercise.&lt;/p&gt;
&lt;p&gt;Not &quot;I&apos;ll get to it someday&quot; exercise. Not &quot;I walk from my car to the office&quot; exercise. Real, consistent, make-it-a-priority exercise.&lt;/p&gt;
&lt;p&gt;After my physical therapist finished working the knots out of my back, she looked at me and said, &quot;This is going to keep happening unless you build strength. Your core is weak, your glutes aren&apos;t firing, and your back is compensating for everything.&quot;&lt;/p&gt;
&lt;p&gt;She was right.&lt;/p&gt;
&lt;p&gt;I started with yoga twice a week. Just basic classes, nothing fancy. Within two months, my chronic back pain improved more than it had with months of passive treatment. Yoga taught me what proper posture felt like and strengthened the muscles that support my spine.&lt;/p&gt;
&lt;p&gt;Then I added strength training—squats, deadlifts, core work. Nothing crazy, just the basics three times a week. Deadlifts especially made a massive difference. When you train your posterior chain properly, your back stops having to do all the work of holding you upright.&lt;/p&gt;
&lt;p&gt;Now, 15 years in, I exercise 4-5 times per week. Not because I&apos;m a fitness buff, but because it&apos;s what allows me to keep doing the job I love without constant pain. It&apos;s as much a part of my professional toolkit as Git or my IDE.&lt;/p&gt;
&lt;p&gt;Here&apos;s the honest truth: I&apos;ve talked to developers who sit on couches, work from coffee shops with terrible chairs, hunch over laptops in bed—and they&apos;re fine. The difference? They&apos;re all active outside of work. They climb, they run, they lift, they do yoga, they surf. They move their bodies regularly and build the strength to compensate for all the sitting.&lt;/p&gt;
&lt;p&gt;Meanwhile, developers with expensive ergonomic setups but zero exercise routines are the ones with chronic pain in their 30s.&lt;/p&gt;
&lt;h2 id=&quot;the-three-legged-stool&quot;&gt;The Three-Legged Stool&lt;/h2&gt;
&lt;p&gt;Think of sustainable development work as a three-legged stool:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Ergonomics&lt;/strong&gt; - Your foundation. The right chair, desk, and setup reduce the baseline stress on your body.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Movement&lt;/strong&gt; - Regular breaks and position changes keep your body from seizing up during the workday.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Exercise&lt;/strong&gt; - Building strength and mobility outside of work gives your body the resilience to handle all the sitting.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Remove any one of these legs and the stool tips over. I learned this by trying to cheap out on each one at different points in my career:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Great ergonomics + no movement = neck and shoulder pain&lt;/li&gt;
&lt;li&gt;Great ergonomics + no exercise = chronic lower back issues&lt;/li&gt;
&lt;li&gt;Lots of exercise + terrible setup = RSI and wrist problems&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You need all three. The good news? None of them are that hard once you commit to them.&lt;/p&gt;
&lt;h2 id=&quot;the-lifestyle-stuff-that-matters&quot;&gt;The Lifestyle Stuff That Matters&lt;/h2&gt;
&lt;p&gt;There are a bunch of smaller factors that I used to dismiss as &quot;wellness bullshit&quot; but turned out to be surprisingly important:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Water&lt;/strong&gt;: I keep a small water bottle at my desk. Not because staying hydrated is magic, but because it forces me to get up and refill it several times a day. It&apos;s a built-in movement reminder. Also, you know, hydration is important.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Real food&lt;/strong&gt;: I used to live on coffee, energy drinks, and whatever was fastest. Shocking nobody, this made me feel like garbage. I&apos;m not going to preach about specific diets, but eating actual food at regular times made a noticeable difference in my energy levels and focus.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sleep schedule&lt;/strong&gt;: Going to bed and waking up at consistent times isn&apos;t sexy advice, but it works. When I&apos;m sleep-deprived, my posture collapses and I make worse decisions about everything—including whether to take breaks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Non-screen hobbies&lt;/strong&gt;: This was a weird one for me. I&apos;m a developer—of course I spend my free time on screens too, right? But picking up guitar and woodworking gave me activities that use my hands and body differently. Plus, you know, it&apos;s nice to have something in your life besides code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Social connection&lt;/strong&gt;: Working remote full-time, I had to be intentional about this. Regular lunches with friends, joining a climbing gym, calling people instead of just texting. Isolation makes everything worse, including physical health.&lt;/p&gt;
&lt;h2 id=&quot;the-reality-check&quot;&gt;The Reality Check&lt;/h2&gt;
&lt;p&gt;Look, I&apos;m aware that complaining about back pain from a desk job can sound privileged. There are people doing physically demanding labor well into their 60s who&apos;d love to have my &quot;problems.&quot;&lt;/p&gt;
&lt;p&gt;Fair enough. But here&apos;s the thing: every job has physical demands. The difference is that most physically demanding jobs make those demands obvious. If you&apos;re in construction, you know your body is part of the work. You wear safety gear, you train proper lifting technique, you expect to be sore.&lt;/p&gt;
&lt;p&gt;Office workers—especially developers—often don&apos;t realize their job has physical demands until the damage is done. We think of coding as purely mental work, so we ignore the physical reality of 8-10 hours a day in the same position.&lt;/p&gt;
&lt;p&gt;That&apos;s the warning I wish I&apos;d gotten: this job will wear on your body. Not as obviously as construction or nursing or warehouse work, but it will. And unlike those jobs, nobody&apos;s going to remind you to protect yourself. No OSHA regulations for proper sitting breaks.&lt;/p&gt;
&lt;h2 id=&quot;the-real-risk&quot;&gt;The Real Risk&lt;/h2&gt;
&lt;p&gt;The risk isn&apos;t just some back pain you can manage with ibuprofen. The risk is burning out completely—not mentally, but physically.&lt;/p&gt;
&lt;p&gt;I know developers who left the field entirely because they couldn&apos;t find a sustainable way to work. They loved coding, but their bodies couldn&apos;t handle the sedentary lifestyle, and they didn&apos;t know how (or didn&apos;t want) to change their habits.&lt;/p&gt;
&lt;p&gt;That&apos;s preventable. But only if you take it seriously before the pain starts, not after.&lt;/p&gt;
&lt;h2 id=&quot;what-id-tell-my-younger-self&quot;&gt;What I&apos;d Tell My Younger Self&lt;/h2&gt;
&lt;p&gt;If I could go back to day one of my development career, here&apos;s what I&apos;d say:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Invest in your setup from the start&lt;/strong&gt;: Don&apos;t wait until you have back pain to buy a good chair. Future you will thank you. A proper ergonomic foundation isn&apos;t a luxury—it&apos;s infrastructure.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Build movement into your routine immediately&lt;/strong&gt;: Don&apos;t wait to &quot;get more disciplined later.&quot; Start with 50-minute work blocks and 10-minute movement breaks. Make it non-negotiable from day one.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Exercise like it&apos;s part of your job&lt;/strong&gt;: Because it is. Put it on your calendar. Treat it like a standup or a deployment. Your career depends on your body functioning properly.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;No marathon coding sessions&lt;/strong&gt;: They&apos;re not a badge of honor. They&apos;re a slow-motion injury. The code you write in hour eight isn&apos;t that good anyway.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Pain is information&lt;/strong&gt;: If something hurts, address it immediately. That little wrist twinge won&apos;t go away on its own. That occasional back stiffness will become chronic if you ignore it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;You get one body&lt;/strong&gt;: There&apos;s no &quot;switch to a different career later if this doesn&apos;t work out&quot; when it comes to your physical health. The damage is cumulative and some of it is permanent.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;the-sustainable-developer&quot;&gt;The Sustainable Developer&lt;/h2&gt;
&lt;p&gt;Fifteen years in, I&apos;m still coding and still love it. But I&apos;m a different kind of developer now than I was at year one.&lt;/p&gt;
&lt;p&gt;I take breaks. I stand regularly. I exercise four times a week. I have a proper ergonomic setup. I eat real food. I maintain a sleep schedule. I have hobbies that don&apos;t involve screens.&lt;/p&gt;
&lt;p&gt;None of this makes me a worse developer. If anything, I&apos;m more productive now because I&apos;m not constantly fighting pain or exhaustion. I can focus better, I make fewer mistakes, and I don&apos;t crash at 3 PM every day.&lt;/p&gt;
&lt;p&gt;The developers I know who&apos;ve been in the field for 20+ years and still love it? They all figured this out at some point. Some learned early, some learned the hard way like me. But they all learned.&lt;/p&gt;
&lt;p&gt;The ones who didn&apos;t either left the field or are miserable.&lt;/p&gt;
&lt;h2 id=&quot;the-bottom-line&quot;&gt;The Bottom Line&lt;/h2&gt;
&lt;p&gt;You can have a long, healthy, productive career in development. The work is still intellectually engaging, the pay is still good, and the flexibility is still better than most jobs.&lt;/p&gt;
&lt;p&gt;But it requires treating your physical health with the same intentionality you treat your professional development. You research frameworks, you learn new languages, you keep up with industry trends. You need to bring that same energy to taking care of your body.&lt;/p&gt;
&lt;p&gt;Because here&apos;s what nobody tells you in the &quot;learn to code&quot; hype: your career isn&apos;t limited by your technical skills or the job market or AI or any of that. Your career is limited by how long your body can handle sitting in a chair.&lt;/p&gt;
&lt;p&gt;Make it a long time. Invest in the right setup, move regularly, exercise consistently, and build sustainable habits from the start.&lt;/p&gt;
&lt;p&gt;Your 15-year-from-now self is already thanking you.&lt;/p&gt;
&lt;h2 id=&quot;build-your-skills-while-building-your-career&quot;&gt;Build Your Skills While Building Your Career&lt;/h2&gt;
&lt;p&gt;While you&apos;re taking care of your body, keep sharpening your technical skills. Start with practical projects that employers want to see:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;Build a Portfolio&lt;/a&gt;&lt;/strong&gt; (Laravel or &lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Flask&lt;/a&gt; or &lt;a href=&quot;/tutorials/portfolio-scratch/&quot;&gt;from scratch&lt;/a&gt;) - Showcase your work professionally&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-laravel/&quot;&gt;Build a Blog&lt;/a&gt;&lt;/strong&gt; (Laravel or &lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Flask&lt;/a&gt; or &lt;a href=&quot;/tutorials/blog-scratch/&quot;&gt;from scratch&lt;/a&gt;) - Master CRUD operations and content management&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-laravel/&quot;&gt;Build E-Commerce&lt;/a&gt;&lt;/strong&gt; (Laravel or &lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Flask&lt;/a&gt; or &lt;a href=&quot;/tutorials/shopping-scratch/&quot;&gt;from scratch&lt;/a&gt;) - Learn complex business logic and payment integration&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each tutorial path includes AI-assisted prompts to guide you through building production-ready applications. Pick the stack that matches the jobs you want, then build something you can show employers.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Fly.io www-Subdomain SSL-Fehler mit Cloudflare beheben (Error 525)]]></title><description><![CDATA[Erhalten Sie Error 525 beim Zugriff auf www.ihreseite.com auf Fly.io? Hier erfahren Sie, wie Sie den SSL-Handshake-Fehler beheben, indem Sie separate Zertifikate fuer www-Subdomains hinzufuegen - ein kritischer Schritt, den die meisten Deployment-Guides ueberspringen.]]></description><link>https://vibecodingwithfred.com/de/blog/flyio-cloudflare-www-setup/</link><guid isPermaLink="false">https://vibecodingwithfred.com/de/blog/flyio-cloudflare-www-setup/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 19 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Ihre App auf Fly.io deployed und die Root-Domain funktioniert einwandfrei, aber &lt;code class=&quot;language-text&quot;&gt;www.ihreseite.com&lt;/code&gt; wirft einen SSL-Handshake-Fehler? Sie sind nicht allein. Dieser Error 525 passiert, weil Fly.io &lt;strong&gt;separate SSL-Zertifikate fuer jeden Hostnamen&lt;/strong&gt; benoetigt - und die meisten Deployment-Guides ueberspringen diesen Schritt komplett.&lt;/p&gt;
&lt;p&gt;Hier ist die Loesung, getestet und verifiziert bei einem Produktions-Deployment.&lt;/p&gt;
&lt;h2 id=&quot;das-problem&quot;&gt;Das Problem&lt;/h2&gt;
&lt;p&gt;Sie haben auf Fly.io deployed, Ihre Custom Domain hinzugefuegt, und alles sieht gut aus. Dann versuchen Sie &lt;code class=&quot;language-text&quot;&gt;www.ihreseite.com&lt;/code&gt; zu besuchen und bekommen:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Error 525: SSL handshake failed&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Inzwischen funktioniert &lt;code class=&quot;language-text&quot;&gt;ihreseite.com&lt;/code&gt; (ohne www) einwandfrei. Was ist los?&lt;/p&gt;
&lt;h2 id=&quot;warum-das-passiert&quot;&gt;Warum das passiert&lt;/h2&gt;
&lt;p&gt;Fly.io verwendet Let&apos;s Encrypt, um SSL-Zertifikate auszustellen, aber hier ist der Haken: &lt;strong&gt;Ein Zertifikat fuer &lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt; hinzuzufuegen deckt NICHT automatisch &lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt; ab&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Sie werden als komplett separate Hostnamen behandelt. Sie muessen explizit ein Zertifikat fuer die www-Subdomain hinzufuegen.&lt;/p&gt;
&lt;h2 id=&quot;die-loesung-5-schritte&quot;&gt;Die Loesung (5 Schritte)&lt;/h2&gt;
&lt;h3 id=&quot;schritt-1-flyio-cli-installieren&quot;&gt;Schritt 1: Fly.io CLI installieren&lt;/h3&gt;
&lt;p&gt;Falls noch nicht geschehen, installieren Sie flyctl:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# flyctl installieren&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Zum PATH hinzufuegen&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;FLYCTL_INSTALL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/.fly&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;PATH&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$FLYCTL_INSTALL&lt;/span&gt;/bin:&lt;span class=&quot;token environment constant&quot;&gt;$PATH&lt;/span&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Dauerhaft machen (zu ~/.bashrc oder ~/.zshrc hinzufuegen)&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export FLYCTL_INSTALL=&quot;$HOME/.fly&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export PATH=&quot;$FLYCTL_INSTALL/bin:$PATH&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc

&lt;span class=&quot;token comment&quot;&gt;# Verifizieren, dass es funktioniert&lt;/span&gt;
flyctl version&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;schritt-2-aktuelle-zertifikate-pruefen&quot;&gt;Schritt 2: Aktuelle Zertifikate pruefen&lt;/h3&gt;
&lt;p&gt;Zuerst sehen Sie, welche Zertifikate Sie bereits haben:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; IHR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sie werden wahrscheinlich so etwas sehen:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Host Name                 Added                Status
example.com              1 month ago          Ready
api.example.com          1 month ago          Ready&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Bemerken Sie, was fehlt? Die &lt;code class=&quot;language-text&quot;&gt;www&lt;/code&gt;-Subdomain.&lt;/p&gt;
&lt;h3 id=&quot;schritt-3-das-www-zertifikat-hinzufuegen-das-behebt-es&quot;&gt;Schritt 3: Das www-Zertifikat hinzufuegen (Das behebt es)&lt;/h3&gt;
&lt;p&gt;Hier ist der kritische Befehl, der das Problem loest:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; IHR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fly.io wird automatisch ein Let&apos;s Encrypt SSL-Zertifikat fuer Ihre www-Subdomain ausstellen.&lt;/p&gt;
&lt;h3 id=&quot;schritt-4-verifizieren-dass-das-zertifikat-bereit-ist&quot;&gt;Schritt 4: Verifizieren, dass das Zertifikat bereit ist&lt;/h3&gt;
&lt;p&gt;Warten Sie 1-2 Minuten, dann pruefen Sie den Zertifikatsstatus:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs show www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; IHR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Suchen Sie nach &lt;strong&gt;&quot;Status: Ready&quot;&lt;/strong&gt;. Wenn es &quot;Awaiting certificates&quot; sagt, warten Sie noch eine Minute und pruefen Sie erneut.&lt;/p&gt;
&lt;h3 id=&quot;schritt-5-cloudflare-ssltls-modus-konfigurieren&quot;&gt;Schritt 5: Cloudflare SSL/TLS-Modus konfigurieren&lt;/h3&gt;
&lt;p&gt;Dieser Schritt ist kritisch, wenn Sie Cloudflare fuer DNS verwenden (was Sie sollten).&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Melden Sie sich in Ihrem Cloudflare-Dashboard an&lt;/li&gt;
&lt;li&gt;Waehlen Sie Ihre Domain&lt;/li&gt;
&lt;li&gt;Gehen Sie zu &lt;strong&gt;SSL/TLS&lt;/strong&gt; -&gt; &lt;strong&gt;Overview&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Setzen Sie den Verschluesselungsmodus auf &lt;strong&gt;&quot;Full&quot;&lt;/strong&gt; (nicht &quot;Flexible&quot; oder &quot;Full (strict)&quot;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Warum &quot;Full&quot;?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Flexible&lt;/strong&gt;: Cloudflare nutzt HTTPS zu Ihren Besuchern, aber HTTP zu Fly.io (unsicher, verursacht Probleme)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Full&lt;/strong&gt;: Cloudflare nutzt HTTPS sowohl zu Besuchern als auch zu Fly.io (korrekt)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Full (strict)&lt;/strong&gt;: Erfordert eine vertrauenswuerdige Zertifizierungsstelle, aber Fly.io verwaltet eigene Zertifikate (verursacht Fehler)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;alles-testen&quot;&gt;Alles testen&lt;/h2&gt;
&lt;p&gt;Verifizieren Sie, dass beide Domains funktionieren:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Root-Domain testen&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; https://example.com

&lt;span class=&quot;token comment&quot;&gt;# www-Subdomain testen&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; https://www.example.com&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Beide sollten &lt;code class=&quot;language-text&quot;&gt;HTTP/2 200&lt;/code&gt; (oder &lt;code class=&quot;language-text&quot;&gt;HTTP/1.1 200&lt;/code&gt;) zurueckgeben.&lt;/p&gt;
&lt;h2 id=&quot;fazit&quot;&gt;Fazit&lt;/h2&gt;
&lt;p&gt;Das Fly.io www-Subdomain-SSL-Problem ist eines dieser &quot;Gotchas&quot;, die selbst erfahrene Entwickler erwischen. Die Loesung ist einfach, sobald Sie sie kennen:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ein separates Zertifikat fuer www hinzufuegen: &lt;code class=&quot;language-text&quot;&gt;flyctl certs add www.example.com -a IHR_APP_NAME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Cloudflare SSL/TLS auf &quot;Full&quot;-Modus setzen&lt;/li&gt;
&lt;li&gt;1-2 Minuten warten, bis das Zertifikat bereit ist&lt;/li&gt;
&lt;li&gt;Beide Domains testen&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Das ist alles. Keine komplexe Konfiguration, keine Server-Neustarts, keine Config-Dateien bearbeiten. Nur ein Befehl, den die meisten Deployment-Guides vergessen zu erwaehnen.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Verwandte Guides:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;Kompletter Guide: Lovable-Projekte auf Cloudflare deployen&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/deploy-claude-code-cloudflare&quot;&gt;Claude Code &amp;#x26; Codex Apps auf Cloudflare deployen&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/cloudflare-workers-deployment&quot;&gt;Cloudflare Workers Deployment Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Was 15 Jahre Coding mich ueber Gesundbleiben (und Zuruechnungsfaehigkeit) gelehrt haben]]></title><description><![CDATA[Fuenfzehn Jahre in meiner Coding-Karriere habe ich gelernt, dass produktiv bleiben nicht nur bessere Algorithmen bedeutet - es geht darum, seinen Koerper dabei nicht zu zerstoeren. Hier ist, was zaehlt.]]></description><link>https://vibecodingwithfred.com/de/blog/webdev-career-reality-check-2025/</link><guid isPermaLink="false">https://vibecodingwithfred.com/de/blog/webdev-career-reality-check-2025/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 19 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Ich schreibe dies von meinem Stehschreibtisch um 14 Uhr an einem Dienstag, nachdem ich gerade einen 25-minuetigen Spaziergang um den Block beendet habe. Vor fuenfzehn Jahren, als ich meinen ersten echten Entwicklerjob durchackerte, waere das laecherlich erschienen. Eine Pause machen? Mitten am Tag? Wenn es Code zu shippen gibt?&lt;/p&gt;
&lt;p&gt;Ja, mein frueheres Ich war ein Idiot.&lt;/p&gt;
&lt;p&gt;Fuenfzehn Jahre in dieser Karriere habe ich etwas gelernt, das Ihnen niemand im Bootcamp oder in Informatik-Programmen sagt: Die groesste Bedrohung fuer Ihren langfristigen Erfolg als Entwickler ist nicht der Arbeitsmarkt, das falsche Framework lernen oder sogar Imposter-Syndrom.&lt;/p&gt;
&lt;p&gt;Es ist, was all diese Stunden im Stuhl mit Ihrem Koerper machen.&lt;/p&gt;
&lt;h2 id=&quot;der-weckruf&quot;&gt;Der Weckruf&lt;/h2&gt;
&lt;p&gt;Jahr sieben war, als mein Koerper mir eine Rechnung schickte.&lt;/p&gt;
&lt;p&gt;Ich hatte gelegentliche Rueckenschmerzen gehabt, aber ich ignorierte sie. Entwickler sitzen den ganzen Tag - natuerlich tut manchmal der Ruecken weh, oder? Dann stand ich eines Morgens von meinem Schreibtisch auf und mein unterer Ruecken verkrampfte sich so schlimm, dass ich mich nicht aufrichten konnte. Ich verbrachte die naechsten drei Tage groesstenteils horizontal, schluckte Ibuprofen und fragte mich, ob das jetzt einfach mein Leben ist.&lt;/p&gt;
&lt;p&gt;Das war mein Weckruf. Ich war 30 Jahre alt und bewegte mich wie 60.&lt;/p&gt;
&lt;h2 id=&quot;ergonomie-die-grundlage-die-sie-nicht-ueberspringen-koennen&quot;&gt;Ergonomie: Die Grundlage, die Sie nicht ueberspringen koennen&lt;/h2&gt;
&lt;p&gt;Lassen Sie mich etwas klarstellen: Gute Ergonomie ist nicht optional. Es ist kein Luxuskauf, den Sie machen, nachdem Sie &quot;es geschafft&quot; haben. Es ist die Grundlage einer nachhaltigen Entwicklerkarriere.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Was wichtig war:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Der Stuhl&lt;/strong&gt;: Ich investierte in einen qualitativ hochwertigen Buerostuhl mit ordentlicher Lendenstuetze. Nicht weil es cool ist, einen Herman Miller zu haben, sondern weil Sie ueber 2.000 Stunden pro Jahr in diesem Ding verbringen werden.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Monitorhoehe&lt;/strong&gt;: Das ist riesig und kostet fast nichts. Ihr Monitor sollte auf Augenhoehe sein - nicht darunter, nicht darueber. Auf Augenhoehe. Ich stapele meinen auf ein paar Buecher.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stehschreibtisch&lt;/strong&gt;: Das hat alles fuer mich veraendert. Ich wechsle zwischen Sitzen und Stehen ueber den Tag. Nicht weil Stehen von Natur aus besser ist (ist es nicht - den ganzen Tag zu stehen ist auch schrecklich fuer Sie), sondern weil Positionswechsel wichtig sind.&lt;/p&gt;
&lt;h2 id=&quot;bewegung-die-andere-haelfte-der-gleichung&quot;&gt;Bewegung: Die andere Haelfte der Gleichung&lt;/h2&gt;
&lt;p&gt;Ich lernte dies auf die harte Tour. Ich kaufte die ganze ergonomische Ausruestung, fuehlte mich ziemlich gut dabei und sass weiter 8-Stunden-Strecken. Mein Ruecken tat immer noch weh.&lt;/p&gt;
&lt;p&gt;Es stellt sich heraus, Sie koennen das beste ergonomische Setup haben und sich trotzdem zerstoeren, wenn Sie sich nie bewegen. Ihr Koerper war nicht dafuer konzipiert, stundenlang stationaer zu sein, egal wie gut Ihre Haltung ist.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Was funktioniert:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Echte Pausen machen&lt;/strong&gt;: Ich verwende einen modifizierten Pomodoro-Ansatz - 50 Minuten Arbeit, 10 Minuten Pause. Waehrend dieser Pausen bewege ich mich. Nicht &quot;Twitter scrollen waehrend ich sitze&quot;, sondern aufstehen, herumlaufen, einige Dehnungen machen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Regelmaessig stehen&lt;/strong&gt;: Ich wechsle etwa jede Stunde zwischen Sitzen und Stehen. Der Schluessel ist, Positionen zu wechseln, nicht nur eine zu waehlen und den ganzen Tag dabei zu bleiben.&lt;/p&gt;
&lt;h2 id=&quot;uebung-ist-nicht-optional---es-ist-teil-des-jobs&quot;&gt;Uebung ist nicht optional - Es ist Teil des Jobs&lt;/h2&gt;
&lt;p&gt;Das ist der Teil, der schliesslich alles fuer mich behoben hat: Regelmaessige Uebung.&lt;/p&gt;
&lt;p&gt;Nachdem meine Physiotherapeutin die Knoten aus meinem Ruecken herausgearbeitet hatte, schaute sie mich an und sagte: &quot;Das wird immer wieder passieren, es sei denn, Sie bauen Staerke auf. Ihr Core ist schwach, Ihre Gesaessmuskeln feuern nicht, und Ihr Ruecken kompensiert fuer alles.&quot;&lt;/p&gt;
&lt;p&gt;Sie hatte recht.&lt;/p&gt;
&lt;p&gt;Ich begann mit Yoga zweimal pro Woche. Dann fuegte ich Krafttraining hinzu - Squats, Deadlifts, Core-Arbeit. Jetzt, 15 Jahre drin, trainiere ich 4-5 Mal pro Woche. Nicht weil ich ein Fitness-Enthusiast bin, sondern weil es das ist, was mir erlaubt, den Job, den ich liebe, ohne staendige Schmerzen weiter zu machen.&lt;/p&gt;
&lt;h2 id=&quot;der-drei-bein-hocker&quot;&gt;Der Drei-Bein-Hocker&lt;/h2&gt;
&lt;p&gt;Denken Sie an nachhaltige Entwicklungsarbeit als einen Drei-Bein-Hocker:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Ergonomie&lt;/strong&gt; - Ihre Grundlage. Der richtige Stuhl, Schreibtisch und Setup reduzieren die Grundbelastung Ihres Koerpers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bewegung&lt;/strong&gt; - Regelmaessige Pausen und Positionswechsel halten Ihren Koerper davon ab, sich waehrend des Arbeitstages zu verkrampfen.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Uebung&lt;/strong&gt; - Ausserhalb der Arbeit Staerke und Mobilitaet aufbauen gibt Ihrem Koerper die Widerstandsfaehigkeit, all das Sitzen zu handhaben.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Entfernen Sie eines dieser Beine und der Hocker kippt um.&lt;/p&gt;
&lt;h2 id=&quot;was-ich-meinem-juengeren-ich-sagen-wuerde&quot;&gt;Was ich meinem juengeren Ich sagen wuerde&lt;/h2&gt;
&lt;p&gt;Wenn ich zum ersten Tag meiner Entwicklerkarriere zurueckgehen koennte, wuerde ich das sagen:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Investieren Sie von Anfang an in Ihr Setup&lt;/strong&gt;: Warten Sie nicht, bis Sie Rueckenschmerzen haben, um einen guten Stuhl zu kaufen.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bauen Sie Bewegung sofort in Ihre Routine ein&lt;/strong&gt;: Warten Sie nicht darauf, &quot;spaeter disziplinierter zu werden.&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trainieren Sie, als waere es Teil Ihres Jobs&lt;/strong&gt;: Weil es das ist.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keine Marathon-Coding-Sessions&lt;/strong&gt;: Sie sind kein Ehrenabzeichen. Sie sind eine Verletzung in Zeitlupe.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Schmerz ist Information&lt;/strong&gt;: Wenn etwas wehtut, kuemmern Sie sich sofort darum.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sie haben nur einen Koerper&lt;/strong&gt;: Es gibt kein &quot;spaeter zu einer anderen Karriere wechseln, wenn das nicht klappt&quot;, wenn es um Ihre koerperliche Gesundheit geht.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;das-fazit&quot;&gt;Das Fazit&lt;/h2&gt;
&lt;p&gt;Sie koennen eine lange, gesunde, produktive Karriere in der Entwicklung haben. Die Arbeit ist immer noch intellektuell ansprechend, die Bezahlung ist immer noch gut, und die Flexibilitaet ist immer noch besser als bei den meisten Jobs.&lt;/p&gt;
&lt;p&gt;Aber es erfordert, Ihre koerperliche Gesundheit mit derselben Absicht zu behandeln wie Ihre berufliche Entwicklung. Sie recherchieren Frameworks, lernen neue Sprachen, halten sich ueber Branchentrends auf dem Laufenden. Sie muessen dieselbe Energie aufbringen, um auf Ihren Koerper zu achten.&lt;/p&gt;
&lt;p&gt;Denn hier ist, was Ihnen niemand im &quot;learn to code&quot;-Hype sagt: Ihre Karriere ist nicht durch Ihre technischen Faehigkeiten oder den Arbeitsmarkt oder KI oder irgendetwas davon begrenzt. Ihre Karriere ist dadurch begrenzt, wie lange Ihr Koerper das Sitzen auf einem Stuhl aushalten kann.&lt;/p&gt;
&lt;p&gt;Machen Sie es zu einer langen Zeit. Investieren Sie in das richtige Setup, bewegen Sie sich regelmaessig, trainieren Sie konsequent und bauen Sie von Anfang an nachhaltige Gewohnheiten auf.&lt;/p&gt;
&lt;h2 id=&quot;bauen-sie-ihre-faehigkeiten-auf-waehrend-sie-ihre-karriere-aufbauen&quot;&gt;Bauen Sie Ihre Faehigkeiten auf, waehrend Sie Ihre Karriere aufbauen&lt;/h2&gt;
&lt;p&gt;Waehrend Sie auf Ihren Koerper achten, schaerfen Sie weiterhin Ihre technischen Faehigkeiten. Beginnen Sie mit praktischen Projekten, die Arbeitgeber sehen wollen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;Ein Portfolio bauen&lt;/a&gt;&lt;/strong&gt; (Laravel oder &lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Flask&lt;/a&gt; oder &lt;a href=&quot;/tutorials/portfolio-scratch/&quot;&gt;von Grund auf&lt;/a&gt;) - Praesentieren Sie Ihre Arbeit professionell&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-laravel/&quot;&gt;Einen Blog bauen&lt;/a&gt;&lt;/strong&gt; (Laravel oder &lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Flask&lt;/a&gt; oder &lt;a href=&quot;/tutorials/blog-scratch/&quot;&gt;von Grund auf&lt;/a&gt;) - Meistern Sie CRUD-Operationen und Content-Management&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-laravel/&quot;&gt;E-Commerce bauen&lt;/a&gt;&lt;/strong&gt; (Laravel oder &lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Flask&lt;/a&gt; oder &lt;a href=&quot;/tutorials/shopping-scratch/&quot;&gt;von Grund auf&lt;/a&gt;) - Lernen Sie komplexe Geschaeftslogik und Zahlungsintegration&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Jeder Tutorial-Pfad enthaelt KI-unterstuetzte Prompts, die Sie durch den Bau produktionsreifer Anwendungen fuehren. Waehlen Sie den Stack, der zu den gewuenschten Jobs passt, und bauen Sie dann etwas, das Sie Arbeitgebern zeigen koennen.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Corregir Errores SSL de Subdominio www en Fly.io con Cloudflare (Error 525)]]></title><description><![CDATA[Tienes Error 525 al acceder a www.tusitio.com en Fly.io? Aqui te explico como corregir el error de handshake SSL agregando certificados separados para subdominios www—un paso critico que la mayoria de guias de despliegue omiten.]]></description><link>https://vibecodingwithfred.com/es/blog/flyio-cloudflare-www-setup/</link><guid isPermaLink="false">https://vibecodingwithfred.com/es/blog/flyio-cloudflare-www-setup/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 19 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Desplegaste tu app en Fly.io y el dominio raiz funciona bien, pero &lt;code class=&quot;language-text&quot;&gt;www.tusitio.com&lt;/code&gt; da un error de handshake SSL? No estas solo. Este Error 525 ocurre porque Fly.io requiere &lt;strong&gt;certificados SSL separados para cada hostname&lt;/strong&gt;—y la mayoria de guias de despliegue omiten completamente este paso.&lt;/p&gt;
&lt;p&gt;Aqui esta la solucion, probada y verificada en un despliegue de produccion.&lt;/p&gt;
&lt;h2 id=&quot;el-problema&quot;&gt;El Problema&lt;/h2&gt;
&lt;p&gt;Has desplegado en Fly.io, agregaste tu dominio personalizado, y todo se ve bien. Luego intentas visitar &lt;code class=&quot;language-text&quot;&gt;www.tusitio.com&lt;/code&gt; y obtienes:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Error 525: SSL handshake failed&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Mientras tanto, &lt;code class=&quot;language-text&quot;&gt;tusitio.com&lt;/code&gt; (sin www) funciona perfecto. Que pasa?&lt;/p&gt;
&lt;h2 id=&quot;por-que-sucede-esto&quot;&gt;Por Que Sucede Esto&lt;/h2&gt;
&lt;p&gt;Fly.io usa Let&apos;s Encrypt para aprovisionar certificados SSL, pero aqui esta el detalle: &lt;strong&gt;agregar un certificado para &lt;code class=&quot;language-text&quot;&gt;ejemplo.com&lt;/code&gt; NO cubre automaticamente &lt;code class=&quot;language-text&quot;&gt;www.ejemplo.com&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Son tratados como hostnames completamente separados. Necesitas agregar explicitamente un certificado para el subdominio &lt;a href=&quot;http://www&quot;&gt;www&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;la-solucion-5-pasos&quot;&gt;La Solucion (5 Pasos)&lt;/h2&gt;
&lt;h3 id=&quot;paso-1-instalar-flyio-cli&quot;&gt;Paso 1: Instalar Fly.io CLI&lt;/h3&gt;
&lt;p&gt;Si aun no lo has hecho, instala flyctl:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Instalar flyctl&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Agregar al PATH&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;FLYCTL_INSTALL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/.fly&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;PATH&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$FLYCTL_INSTALL&lt;/span&gt;/bin:&lt;span class=&quot;token environment constant&quot;&gt;$PATH&lt;/span&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Hacerlo permanente (agregar a ~/.bashrc o ~/.zshrc)&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export FLYCTL_INSTALL=&quot;$HOME/.fly&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export PATH=&quot;$FLYCTL_INSTALL/bin:$PATH&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc

&lt;span class=&quot;token comment&quot;&gt;# Verificar que funciona&lt;/span&gt;
flyctl version&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;paso-2-verificar-tus-certificados-actuales&quot;&gt;Paso 2: Verificar Tus Certificados Actuales&lt;/h3&gt;
&lt;p&gt;Primero, ve que certificados ya tienes:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; TU_NOMBRE_DE_APP&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Probablemente veras algo como:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Host Name                 Added                Status
ejemplo.com              1 month ago          Ready
api.ejemplo.com          1 month ago          Ready&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Notas lo que falta? El subdominio &lt;code class=&quot;language-text&quot;&gt;www&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;paso-3-agregar-el-certificado-www-esto-lo-arregla&quot;&gt;Paso 3: Agregar el Certificado www (Esto Lo Arregla)&lt;/h3&gt;
&lt;p&gt;Aqui esta el comando critico que resuelve el problema:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; www.ejemplo.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; TU_NOMBRE_DE_APP&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fly.io aprovisionara automaticamente un certificado SSL de Let&apos;s Encrypt para tu subdominio &lt;a href=&quot;http://www&quot;&gt;www&lt;/a&gt;. Veras una salida como:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;You are creating a certificate for www.ejemplo.com
We are using Let&apos;s Encrypt for this certificate.

Your certificate for www.ejemplo.com is being issued.
You can validate your ownership of www.ejemplo.com by:

1: Adding an AAAA record to your DNS service which reads:
    AAAA @ 2a09:8280:1::X:XXXX&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;No te preocupes por la validacion DNS—si tu dominio raiz ya esta funcionando, el subdominio www se validara automaticamente.&lt;/p&gt;
&lt;h3 id=&quot;paso-4-verificar-que-el-certificado-esta-listo&quot;&gt;Paso 4: Verificar que el Certificado Esta Listo&lt;/h3&gt;
&lt;p&gt;Espera 1-2 minutos, luego verifica el estado del certificado:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs show www.ejemplo.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; TU_NOMBRE_DE_APP&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Busca &lt;strong&gt;&quot;Status: Ready&quot;&lt;/strong&gt;. Si dice &quot;Awaiting certificates&quot;, espera otro minuto y verifica de nuevo.&lt;/p&gt;
&lt;p&gt;Una vez listo, tu lista de certificados deberia mostrar:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; TU_NOMBRE_DE_APP&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Host Name                 Added                Status
ejemplo.com              1 month ago          Ready
www.ejemplo.com          13 seconds ago       Ready&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Perfecto.&lt;/p&gt;
&lt;h3 id=&quot;paso-5-configurar-el-modo-ssltls-de-cloudflare&quot;&gt;Paso 5: Configurar el Modo SSL/TLS de Cloudflare&lt;/h3&gt;
&lt;p&gt;Este paso es critico si estas usando Cloudflare para DNS (como deberias).&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Inicia sesion en tu dashboard de Cloudflare&lt;/li&gt;
&lt;li&gt;Selecciona tu dominio&lt;/li&gt;
&lt;li&gt;Ve a &lt;strong&gt;SSL/TLS&lt;/strong&gt; → &lt;strong&gt;Overview&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Configura el modo de encriptacion a &lt;strong&gt;&quot;Full&quot;&lt;/strong&gt; (no &quot;Flexible&quot; o &quot;Full (strict)&quot;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Por que &quot;Full&quot;?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Flexible&lt;/strong&gt;: Cloudflare usa HTTPS hacia tus visitantes, pero HTTP hacia Fly.io (inseguro, causa problemas)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Full&lt;/strong&gt;: Cloudflare usa HTTPS tanto hacia visitantes como hacia Fly.io (correcto)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Full (strict)&lt;/strong&gt;: Requiere una autoridad de certificados confiable, pero Fly.io gestiona sus propios certs (causa errores)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;configura-tus-registros-dns-cloudflare&quot;&gt;Configura Tus Registros DNS (Cloudflare)&lt;/h2&gt;
&lt;p&gt;Asegurate de que tus registros DNS estan configurados correctamente:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dominio Raiz (&lt;code class=&quot;language-text&quot;&gt;ejemplo.com&lt;/code&gt;):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tipo&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;A&lt;/code&gt; o &lt;code class=&quot;language-text&quot;&gt;AAAA&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nombre&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;@&lt;/code&gt; (o dejar vacio)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contenido&lt;/strong&gt;: Tu direccion IP de Fly.io (de &lt;code class=&quot;language-text&quot;&gt;flyctl ips list&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Estado del proxy&lt;/strong&gt;: &lt;strong&gt;Proxied&lt;/strong&gt; (nube naranja habilitada)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Subdominio www (&lt;code class=&quot;language-text&quot;&gt;www.ejemplo.com&lt;/code&gt;):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tipo&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;CNAME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nombre&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;www&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Target&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;ejemplo.com&lt;/code&gt; (apunta al dominio raiz)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Estado del proxy&lt;/strong&gt;: &lt;strong&gt;Proxied&lt;/strong&gt; (nube naranja habilitada)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La nube naranja (Proxied) es importante—enruta el trafico a traves del CDN de Cloudflare y habilita SSL.&lt;/p&gt;
&lt;h2 id=&quot;probar-todo&quot;&gt;Probar Todo&lt;/h2&gt;
&lt;p&gt;Verifica que ambos dominios funcionen:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Probar dominio raiz&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; https://ejemplo.com

&lt;span class=&quot;token comment&quot;&gt;# Probar subdominio www&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; https://www.ejemplo.com&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ambos deberian retornar &lt;code class=&quot;language-text&quot;&gt;HTTP/2 200&lt;/code&gt; (o &lt;code class=&quot;language-text&quot;&gt;HTTP/1.1 200&lt;/code&gt;). Si obtienes errores, ve la seccion de solucion de problemas abajo.&lt;/p&gt;
&lt;h2 id=&quot;errores-comunes-y-soluciones&quot;&gt;Errores Comunes y Soluciones&lt;/h2&gt;
&lt;h3 id=&quot;error-525-ssl-handshake-failed&quot;&gt;Error 525: SSL Handshake Failed&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Sintomas&lt;/strong&gt;: El subdominio www da Error 525, el dominio raiz funciona bien&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Causas&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Falta el certificado www en Fly.io&lt;/li&gt;
&lt;li&gt;El modo SSL/TLS de Cloudflare esta configurado a &quot;Flexible&quot; o &quot;Full (strict)&quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Solucion&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Agregar el certificado www&lt;/span&gt;
flyctl certs &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; www.ejemplo.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; TU_NOMBRE_DE_APP

&lt;span class=&quot;token comment&quot;&gt;# Esperar 2 minutos para la emision del certificado&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sleep&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;120&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Verificar que esta listo&lt;/span&gt;
flyctl certs show www.ejemplo.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; TU_NOMBRE_DE_APP&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Tambien verifica que el modo SSL/TLS de Cloudflare este configurado a &lt;strong&gt;&quot;Full&quot;&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;el-subdominio-www-retorna-timeout-de-conexion&quot;&gt;El Subdominio www Retorna Timeout de Conexion&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Sintomas&lt;/strong&gt;: El subdominio www no carga para nada, sin pagina de error&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Causas&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Registro DNS CNAME faltante o incorrecto&lt;/li&gt;
&lt;li&gt;DNS no proxied a traves de Cloudflare&lt;/li&gt;
&lt;li&gt;Propagacion DNS incompleta&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Solucion&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Verifica tu configuracion DNS de Cloudflare para el registro CNAME www&lt;/li&gt;
&lt;li&gt;Asegurate de que la nube naranja (Proxied) este habilitada&lt;/li&gt;
&lt;li&gt;Espera 5-15 minutos para propagacion DNS&lt;/li&gt;
&lt;li&gt;Limpia el cache de tu navegador o prueba en modo incognito/privado&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;por-que-importan-los-certificados-separados&quot;&gt;Por Que Importan los Certificados Separados&lt;/h2&gt;
&lt;p&gt;En hosting compartido tradicional, un certificado SSL comodin (*.ejemplo.com) cubre todos los subdominios. Pero Fly.io aprovisiona certificados individualmente a traves de Let&apos;s Encrypt.&lt;/p&gt;
&lt;p&gt;Esto te da mas control pero requiere configuracion explicita para cada subdominio:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ejemplo.com&lt;/code&gt; → necesita su propio certificado&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;www.ejemplo.com&lt;/code&gt; → necesita su propio certificado&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;api.ejemplo.com&lt;/code&gt; → necesita su propio certificado&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;blog.ejemplo.com&lt;/code&gt; → necesita su propio certificado&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ya entiendes la idea.&lt;/p&gt;
&lt;h2 id=&quot;mejores-practicas-para-flyio--cloudflare&quot;&gt;Mejores Practicas para Fly.io + Cloudflare&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Agrega certificados para todos los subdominios que planeas usar&lt;/strong&gt; antes de ir a produccion&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Usa el modo SSL/TLS &quot;Full&quot; de Cloudflare&lt;/strong&gt; para despliegues en Fly.io&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Habilita el proxy de Cloudflare&lt;/strong&gt; (nube naranja) para CDN y proteccion DDoS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prueba ambas versiones www y no-www&lt;/strong&gt; antes de anunciar tu sitio&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configura redirecciones&lt;/strong&gt; en tu app si quieres forzar una version sobre la otra&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;comandos-utiles-para-solucion-de-problemas&quot;&gt;Comandos Utiles para Solucion de Problemas&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Listar todos los certificados para tu app&lt;/span&gt;
flyctl certs list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; TU_NOMBRE_DE_APP

&lt;span class=&quot;token comment&quot;&gt;# Ver informacion detallada para un certificado especifico&lt;/span&gt;
flyctl certs show www.ejemplo.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; TU_NOMBRE_DE_APP

&lt;span class=&quot;token comment&quot;&gt;# Eliminar un certificado (si necesitas empezar de nuevo)&lt;/span&gt;
flyctl certs delete www.ejemplo.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; TU_NOMBRE_DE_APP

&lt;span class=&quot;token comment&quot;&gt;# Verificar las direcciones IP de tu app&lt;/span&gt;
flyctl ips list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; TU_NOMBRE_DE_APP

&lt;span class=&quot;token comment&quot;&gt;# Verificar resolucion DNS&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; ejemplo.com
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; www.ejemplo.com

&lt;span class=&quot;token comment&quot;&gt;# Probar conexion SSL con salida detallada&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-vI&lt;/span&gt; https://www.ejemplo.com

&lt;span class=&quot;token comment&quot;&gt;# Verificar estado de la app&lt;/span&gt;
flyctl status &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; TU_NOMBRE_DE_APP

&lt;span class=&quot;token comment&quot;&gt;# Ver logs de la app (util para debugging)&lt;/span&gt;
flyctl logs &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; TU_NOMBRE_DE_APP&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;El problema de SSL de subdominio www en Fly.io es una de esas &quot;trampas&quot; que atrapan incluso a desarrolladores experimentados. La solucion es simple una vez que la conoces:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Agrega un certificado separado para www: &lt;code class=&quot;language-text&quot;&gt;flyctl certs add www.ejemplo.com -a TU_NOMBRE_DE_APP&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Configura SSL/TLS de Cloudflare a modo &quot;Full&quot;&lt;/li&gt;
&lt;li&gt;Espera 1-2 minutos para que el certificado este listo&lt;/li&gt;
&lt;li&gt;Prueba ambos dominios&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Eso es todo. Sin configuracion compleja, sin reinicios de servidor, sin editar archivos de configuracion. Solo un comando que la mayoria de guias de despliegue olvidan mencionar.&lt;/p&gt;
&lt;p&gt;Ahora tus usuarios pueden acceder a tu sitio con o sin www, y ambos funcionaran correctamente.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Guias relacionadas:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;Guia Completa: Desplegar Proyectos Lovable a Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/deploy-claude-code-cloudflare&quot;&gt;Desplegar Apps de Claude Code y Codex a Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/cloudflare-workers-deployment&quot;&gt;Guia de Despliegue de Cloudflare Workers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Recursos:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://fly.io/docs/networking/custom-domain/&quot;&gt;Documentacion de Dominios Personalizados de Fly.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/ssl/&quot;&gt;Configuracion SSL/TLS de Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://letsencrypt.org/&quot;&gt;Autoridad de Certificados Let&apos;s Encrypt&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Lo Que 15 Anos de Programacion Me Ensenaron Sobre Mantenerme Saludable (Y Cuerdo)]]></title><description><![CDATA[Quince anos en mi carrera de programacion, he aprendido que mantenerse productivo no es solo sobre mejores algoritmos—es sobre no destruir tu cuerpo en el proceso. Aqui esta lo que importa.]]></description><link>https://vibecodingwithfred.com/es/blog/webdev-career-reality-check-2025/</link><guid isPermaLink="false">https://vibecodingwithfred.com/es/blog/webdev-career-reality-check-2025/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 19 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Escribo esto desde mi escritorio de pie a las 2 PM de un martes, habiendo terminado una caminata de 25 minutos alrededor de la cuadra. Hace quince anos, cuando estaba trabajando duro en mi primer trabajo real de desarrollo, esto habria parecido ridiculo. Tomar un descanso? En medio del dia? Cuando hay codigo que enviar?&lt;/p&gt;
&lt;p&gt;Si, el yo del pasado era un idiota.&lt;/p&gt;
&lt;p&gt;Quince anos en esta carrera, he aprendido algo que nadie te dice en bootcamp o programas de ciencias de la computacion: la mayor amenaza para tu exito a largo plazo como desarrollador no es el mercado laboral, aprender el framework equivocado, o siquiera el sindrome del impostor.&lt;/p&gt;
&lt;p&gt;Es lo que todas esas horas en la silla le hacen a tu cuerpo.&lt;/p&gt;
&lt;p&gt;Solia ser uno de esos desarrolladores que usaban &quot;sesiones de codificacion maratonica&quot; como insignia de honor. Me sentaba por 8-10 horas seguidas, encorvado sobre mi laptop, viviendo de cafe y la adrenalina de resolver problemas complejos. Era productivo. Estaba enviando funciones. Tambien me estaba destruyendo lentamente.&lt;/p&gt;
&lt;p&gt;Alrededor del ano siete, mi espalda empezo a quejarse. No el dolor ocasional—el tipo de dolor persistente que te hace hacer muecas cuando te paras. Para el ano diez, estaba gastando mas dinero en terapia fisica de lo que habia gastado en cursos o conferencias. Ahi fue cuando finalmente me di cuenta: puedes tener todas las habilidades tecnicas del mundo, pero si tu cuerpo falla, nada de eso importa.&lt;/p&gt;
&lt;p&gt;Esto es lo que desearia que alguien me hubiera dicho el dia uno.&lt;/p&gt;
&lt;h2 id=&quot;el-mercado-laboral-si-es-diferente-ahora&quot;&gt;El Mercado Laboral (Si, Es Diferente Ahora)&lt;/h2&gt;
&lt;p&gt;Mira, no voy a endulzarlo. El mercado laboral en 2025 es mas competitivo que cuando empece. Los dias de &quot;aprende a programar, trabajo garantizado&quot; quedaron atras. Estas compitiendo con cientos de aplicantes para posiciones que solian ser mas faciles de conseguir.&lt;/p&gt;
&lt;p&gt;Pero esto es lo que no ha cambiado: la programacion sigue siendo uno de los caminos mas accesibles para construir una carrera significativa. Necesitas una computadora, acceso a internet, y la voluntad de trabajar. Sin prestamos estudiantiles de seis cifras, sin equipo de escuela tecnica, sin certificaciones que te bloqueen.&lt;/p&gt;
&lt;p&gt;He visto a docenas de desarrolladores autodidactas entrar al campo y construir carreras solidas. Las barreras son mas altas, si. Pero si estas comprometido a aprender (no solo el infierno de tutoriales), aun puedes lograrlo.&lt;/p&gt;
&lt;p&gt;Dicho eso, este articulo no es realmente sobre el mercado laboral. Hay cien otros posts sobre eso. Esto es sobre lo que me agarro completamente desprevenido: lo que pasa con tu cuerpo cuando pasas 8-10 horas al dia en una silla.&lt;/p&gt;
&lt;h2 id=&quot;la-llamada-de-atencion&quot;&gt;La Llamada de Atencion&lt;/h2&gt;
&lt;p&gt;El ano siete es cuando mi cuerpo me paso la factura.&lt;/p&gt;
&lt;p&gt;Habia tenido dolor de espalda ocasional, pero lo ignore. Los desarrolladores se sientan todo el dia—claro que te duele la espalda a veces, verdad? Luego una manana me levante de mi escritorio y mi espalda baja se contrajo tan fuerte que no podia enderezarme. Pase los siguientes tres dias mayormente horizontal, tomando ibuprofeno y preguntandome si esta era mi vida ahora.&lt;/p&gt;
&lt;p&gt;Esa fue mi llamada de atencion. Tenia 30 anos y me movia como si tuviera 60.&lt;/p&gt;
&lt;p&gt;Hice lo que cualquier desarrollador haria: investigue a fondo. Hable con fisioterapeutas, me sumergi en investigacion ergonomica, experimente con diferentes configuraciones, y compare notas con otros desarrolladores que habian pasado por lo mismo.&lt;/p&gt;
&lt;p&gt;Esto es lo que aprendi: prevenir esto es mucho mas facil que arreglarlo. Y se reduce a tres cosas interconectadas—ergonomia, movimiento, y construir una relacion sostenible con tu trabajo.&lt;/p&gt;
&lt;h2 id=&quot;ergonomia-la-base-que-no-puedes-saltarte&quot;&gt;Ergonomia: La Base Que No Puedes Saltarte&lt;/h2&gt;
&lt;p&gt;Dejame ser claro sobre algo: la buena ergonomia no es opcional. No es una compra de lujo que haces despues de &quot;lograrlo.&quot; Es la base de una carrera sostenible en desarrollo.&lt;/p&gt;
&lt;p&gt;Despues de mi incidente de espalda, lo primero que hice fue arreglar mi configuracion. Y me refiero a arreglarlo de verdad, no solo comprar una silla cara y esperar lo mejor.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lo que importo:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;La silla&lt;/strong&gt;: Inverti en una silla de oficina de calidad con soporte lumbar apropiado. No porque sea cool tener una Herman Miller, sino porque vas a pasar 2,000+ horas al ano en esta cosa. Eso es mas tiempo del que pasas en tu auto o tu cama. Elegi una Steelcase Leap—la compre usada por $400. Ocho anos despues, aun esta en excelente condicion. No necesitas gastar $2,000, pero necesitas algo que soporte tu espalda baja apropiadamente y se ajuste a tu cuerpo.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Altura del monitor&lt;/strong&gt;: Esta es enorme y no cuesta casi nada. Tu monitor debe estar a nivel de los ojos—no debajo, no encima. A nivel de los ojos. Pongo el mio sobre un par de libros. Barato, efectivo, y detuvo el dolor de cuello que ni siquiera sabia que tenia.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Escritorio de pie&lt;/strong&gt;: Esto cambio todo para mi. Alterno entre sentado y parado durante el dia. No porque estar parado sea inherentemente mejor (no lo es—estar parado todo el dia tambien es terrible para ti), sino porque cambiar posiciones importa. Elegi un escritorio ajustable electrico de Autonomous. Vale cada centavo.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Teclado y mouse&lt;/strong&gt;: Si empiezas a sentir dolor en las munecas, no lo ignores. Cambie a un teclado ergonomico y un mouse vertical despues de algunas punzadas de advertencia. Ambos son medidas preventivas relativamente baratas comparadas con tratar el tunel carpiano despues.&lt;/p&gt;
&lt;p&gt;Pero aqui esta la cosa: la ergonomia sola no es suficiente. Es la base, pero necesitas construir sobre ella.&lt;/p&gt;
&lt;h2 id=&quot;movimiento-la-otra-mitad-de-la-ecuacion&quot;&gt;Movimiento: La Otra Mitad de la Ecuacion&lt;/h2&gt;
&lt;p&gt;Aprendi esto por las malas. Compre todo el equipo ergonomico, me senti bastante bien conmigo mismo, y segui sentado por periodos de 8 horas. Mi espalda seguia doliendo.&lt;/p&gt;
&lt;p&gt;Resulta que puedes tener la mejor configuracion ergonomica y aun destruirte si nunca te mueves. Tu cuerpo no fue disenado para estar estacionario por horas, sin importar que tan buena sea tu postura.&lt;/p&gt;
&lt;p&gt;Lo que funciona:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Toma descansos reales&lt;/strong&gt;: Uso un enfoque Pomodoro modificado—50 minutos de trabajo, 10 minutos de descanso. Durante esos descansos, me muevo. No &quot;scroll en Twitter sentado,&quot; sino levantarme, caminar, hacer algunos estiramientos. A veces hago algunas lagartijas o sentadillas. Se siente ridiculo al principio, pero a tu espalda no le importan tus sentimientos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Parate regularmente&lt;/strong&gt;: Alterno entre sentado y parado cada hora mas o menos. Estoy parado ahora mismo mientras escribo esto. La clave es cambiar posiciones, no solo elegir una y quedarte con ella todo el dia.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reuniones caminando&lt;/strong&gt;: Siempre que es posible, tomo llamadas mientras camino. No siempre es practico, pero cuando lo es, estoy haciendo movimiento mientras me mantengo productivo.&lt;/p&gt;
&lt;p&gt;Ahora, se lo que algunos estan pensando: &quot;Pero trabajo mejor en estado de flujo! No puedo interrumpir el trabajo profundo cada hora!&quot;&lt;/p&gt;
&lt;p&gt;Lo entiendo. Solia ser ese desarrollador. Entraba en ritmo y programaba por 4-5 horas seguidas, y esas sesiones se sentian increiblemente productivas. Y lo eran—a corto plazo. Pero tambien estaban rompiendo lentamente mi cuerpo.&lt;/p&gt;
&lt;p&gt;Esto es lo que aprendi: puedes tener estado de flujo O puedes tener salud a largo plazo, pero no ambos si tu unica estrategia es sentarte inmovil por horas. Si vas a montar el estado de flujo (y todavia lo hago a veces), necesitas una rutina de ejercicio seria fuera del trabajo para compensar. No puedes tenerlo de las dos formas sin consecuencias.&lt;/p&gt;
&lt;h2 id=&quot;el-ejercicio-no-es-opcionales-parte-del-trabajo&quot;&gt;El Ejercicio No Es Opcional—Es Parte del Trabajo&lt;/h2&gt;
&lt;p&gt;Esta es la parte que finalmente arreglo todo para mi: ejercicio regular.&lt;/p&gt;
&lt;p&gt;No ejercicio de &quot;llegare a eso algun dia&quot;. No ejercicio de &quot;camino de mi auto a la oficina&quot;. Ejercicio real, consistente, hacerlo-una-prioridad.&lt;/p&gt;
&lt;p&gt;Despues de que mi fisioterapeuta termino de trabajar los nudos de mi espalda, me miro y dijo, &quot;Esto va a seguir pasando a menos que construyas fuerza. Tu core es debil, tus gluteos no estan disparando, y tu espalda esta compensando por todo.&quot;&lt;/p&gt;
&lt;p&gt;Tenia razon.&lt;/p&gt;
&lt;p&gt;Empece con yoga dos veces por semana. Solo clases basicas, nada fancy. En dos meses, mi dolor cronico de espalda mejoro mas de lo que habia mejorado con meses de tratamiento pasivo. El yoga me enseno como se siente la postura correcta y fortalecio los musculos que soportan mi columna.&lt;/p&gt;
&lt;p&gt;Luego agregue entrenamiento de fuerza—sentadillas, deadlifts, trabajo de core. Nada loco, solo lo basico tres veces por semana. Los deadlifts especialmente hicieron una diferencia masiva. Cuando entrenas tu cadena posterior apropiadamente, tu espalda deja de tener que hacer todo el trabajo de mantenerte erguido.&lt;/p&gt;
&lt;p&gt;Ahora, 15 anos despues, hago ejercicio 4-5 veces por semana. No porque sea un entusiasta del fitness, sino porque es lo que me permite seguir haciendo el trabajo que amo sin dolor constante. Es tanto parte de mi kit de herramientas profesional como Git o mi IDE.&lt;/p&gt;
&lt;p&gt;Aqui esta la verdad honesta: he hablado con desarrolladores que se sientan en sofas, trabajan desde cafeterias con sillas terribles, se encorvan sobre laptops en la cama—y estan bien. La diferencia? Todos son activos fuera del trabajo. Escalan, corren, levantan pesas, hacen yoga, surfean. Mueven sus cuerpos regularmente y construyen la fuerza para compensar toda la sentada.&lt;/p&gt;
&lt;p&gt;Mientras tanto, desarrolladores con configuraciones ergonomicas caras pero rutinas de ejercicio cero son los que tienen dolor cronico a los 30.&lt;/p&gt;
&lt;h2 id=&quot;el-taburete-de-tres-patas&quot;&gt;El Taburete de Tres Patas&lt;/h2&gt;
&lt;p&gt;Piensa en el trabajo sostenible de desarrollo como un taburete de tres patas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Ergonomia&lt;/strong&gt; - Tu base. La silla, escritorio, y configuracion correctos reducen el estres de linea base en tu cuerpo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Movimiento&lt;/strong&gt; - Descansos regulares y cambios de posicion evitan que tu cuerpo se tense durante el dia de trabajo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ejercicio&lt;/strong&gt; - Construir fuerza y movilidad fuera del trabajo le da a tu cuerpo la resiliencia para manejar toda la sentada.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Quita cualquiera de estas patas y el taburete se cae. Aprendi esto intentando escatimar en cada una en diferentes puntos de mi carrera:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gran ergonomia + sin movimiento = dolor de cuello y hombros&lt;/li&gt;
&lt;li&gt;Gran ergonomia + sin ejercicio = problemas cronicos de espalda baja&lt;/li&gt;
&lt;li&gt;Mucho ejercicio + configuracion terrible = RSI y problemas de muneca&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Necesitas los tres. La buena noticia? Ninguno de ellos es tan dificil una vez que te comprometes.&lt;/p&gt;
&lt;h2 id=&quot;las-cosas-de-estilo-de-vida-que-importan&quot;&gt;Las Cosas de Estilo de Vida Que Importan&lt;/h2&gt;
&lt;p&gt;Hay un monton de factores mas pequenos que solia descartar como &quot;tonterias de bienestar&quot; pero resultaron ser sorprendentemente importantes:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Agua&lt;/strong&gt;: Mantengo una botella de agua pequena en mi escritorio. No porque mantenerse hidratado sea magia, sino porque me fuerza a levantarme y rellenarla varias veces al dia. Es un recordatorio de movimiento incorporado. Ademas, ya sabes, la hidratacion es importante.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Comida real&lt;/strong&gt;: Solia vivir de cafe, bebidas energeticas, y lo que fuera mas rapido. Sorprendiendo a nadie, esto me hacia sentir como basura. No voy a predicar sobre dietas especificas, pero comer comida real a horas regulares hizo una diferencia notable en mis niveles de energia y enfoque.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Horario de sueno&lt;/strong&gt;: Ir a la cama y despertarse a horas consistentes no es un consejo sexy, pero funciona. Cuando estoy privado de sueno, mi postura colapsa y tomo peores decisiones sobre todo—incluyendo si tomar descansos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hobbies sin pantalla&lt;/strong&gt;: Este fue raro para mi. Soy un desarrollador—claro que paso mi tiempo libre en pantallas tambien, verdad? Pero empezar guitarra y carpinteria me dio actividades que usan mis manos y cuerpo de manera diferente. Ademas, ya sabes, es bueno tener algo en tu vida ademas de codigo.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conexion social&lt;/strong&gt;: Trabajando remoto tiempo completo, tuve que ser intencional sobre esto. Almuerzos regulares con amigos, unirme a un gimnasio de escalada, llamar a personas en lugar de solo enviar mensajes. El aislamiento hace que todo sea peor, incluyendo la salud fisica.&lt;/p&gt;
&lt;h2 id=&quot;el-chequeo-de-realidad&quot;&gt;El Chequeo de Realidad&lt;/h2&gt;
&lt;p&gt;Mira, soy consciente de que quejarse del dolor de espalda de un trabajo de escritorio puede sonar privilegiado. Hay personas haciendo trabajo fisicamente demandante hasta bien entrada su vejez que amarian tener mis &quot;problemas.&quot;&lt;/p&gt;
&lt;p&gt;Justo suficiente. Pero aqui esta la cosa: cada trabajo tiene demandas fisicas. La diferencia es que la mayoria de los trabajos fisicamente demandantes hacen esas demandas obvias. Si estas en construccion, sabes que tu cuerpo es parte del trabajo. Usas equipo de seguridad, entrenas tecnica de levantamiento apropiada, esperas estar adolorido.&lt;/p&gt;
&lt;p&gt;Los trabajadores de oficina—especialmente desarrolladores—frecuentemente no se dan cuenta de que su trabajo tiene demandas fisicas hasta que el dano esta hecho. Pensamos en la programacion como trabajo puramente mental, asi que ignoramos la realidad fisica de 8-10 horas al dia en la misma posicion.&lt;/p&gt;
&lt;p&gt;Esa es la advertencia que desearia haber recibido: este trabajo desgastara tu cuerpo. No tan obviamente como la construccion o enfermeria o trabajo de almacen, pero lo hara. Y a diferencia de esos trabajos, nadie te va a recordar que te protejas. Sin regulaciones OSHA para descansos apropiados de sentada.&lt;/p&gt;
&lt;h2 id=&quot;el-riesgo-real&quot;&gt;El Riesgo Real&lt;/h2&gt;
&lt;p&gt;El riesgo no es solo algun dolor de espalda que puedas manejar con ibuprofeno. El riesgo es quemarte completamente—no mentalmente, sino fisicamente.&lt;/p&gt;
&lt;p&gt;Conozco desarrolladores que dejaron el campo completamente porque no pudieron encontrar una forma sostenible de trabajar. Amaban programar, pero sus cuerpos no podian manejar el estilo de vida sedentario, y no sabian como (o no querian) cambiar sus habitos.&lt;/p&gt;
&lt;p&gt;Eso es prevenible. Pero solo si lo tomas en serio antes de que empiece el dolor, no despues.&lt;/p&gt;
&lt;h2 id=&quot;lo-que-le-diria-a-mi-yo-mas-joven&quot;&gt;Lo Que Le Diria a Mi Yo Mas Joven&lt;/h2&gt;
&lt;p&gt;Si pudiera volver al dia uno de mi carrera de desarrollo, esto es lo que diria:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Invierte en tu configuracion desde el inicio&lt;/strong&gt;: No esperes hasta que tengas dolor de espalda para comprar una buena silla. El tu del futuro te lo agradecera. Una base ergonomica apropiada no es un lujo—es infraestructura.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Incorpora movimiento en tu rutina inmediatamente&lt;/strong&gt;: No esperes a &quot;ser mas disciplinado despues.&quot; Empieza con bloques de trabajo de 50 minutos y descansos de movimiento de 10 minutos. Hazlo no negociable desde el dia uno.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Haz ejercicio como si fuera parte de tu trabajo&lt;/strong&gt;: Porque lo es. Ponlo en tu calendario. Tratalo como un standup o un despliegue. Tu carrera depende de que tu cuerpo funcione apropiadamente.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sin sesiones de codificacion maratonica&lt;/strong&gt;: No son una insignia de honor. Son una lesion en camara lenta. El codigo que escribes en la hora ocho no es tan bueno de todos modos.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;El dolor es informacion&lt;/strong&gt;: Si algo duele, atenderlo inmediatamente. Esa pequena punzada en la muneca no se ira sola. Esa rigidez ocasional de espalda se volvera cronica si la ignoras.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Solo tienes un cuerpo&lt;/strong&gt;: No hay &quot;cambiar a otra carrera despues si esto no funciona&quot; cuando se trata de tu salud fisica. El dano es acumulativo y algo de el es permanente.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;el-desarrollador-sostenible&quot;&gt;El Desarrollador Sostenible&lt;/h2&gt;
&lt;p&gt;Quince anos despues, todavia estoy programando y todavia lo amo. Pero soy un tipo diferente de desarrollador ahora de lo que era en el ano uno.&lt;/p&gt;
&lt;p&gt;Tomo descansos. Me paro regularmente. Hago ejercicio cuatro veces por semana. Tengo una configuracion ergonomica apropiada. Como comida real. Mantengo un horario de sueno. Tengo hobbies que no involucran pantallas.&lt;/p&gt;
&lt;p&gt;Nada de esto me hace un peor desarrollador. Si acaso, soy mas productivo ahora porque no estoy constantemente peleando contra el dolor o el agotamiento. Puedo enfocarme mejor, cometo menos errores, y no me derrumbo a las 3 PM todos los dias.&lt;/p&gt;
&lt;p&gt;Los desarrolladores que conozco que han estado en el campo por 20+ anos y aun lo aman? Todos descubrieron esto en algun punto. Algunos aprendieron temprano, algunos aprendieron por las malas como yo. Pero todos aprendieron.&lt;/p&gt;
&lt;p&gt;Los que no, o dejaron el campo o son miserables.&lt;/p&gt;
&lt;h2 id=&quot;la-linea-de-fondo&quot;&gt;La Linea de Fondo&lt;/h2&gt;
&lt;p&gt;Puedes tener una carrera larga, saludable, productiva en desarrollo. El trabajo sigue siendo intelectualmente atractivo, el pago sigue siendo bueno, y la flexibilidad sigue siendo mejor que la mayoria de trabajos.&lt;/p&gt;
&lt;p&gt;Pero requiere tratar tu salud fisica con la misma intencionalidad que tratas tu desarrollo profesional. Investigas frameworks, aprendes nuevos lenguajes, te mantienes al dia con tendencias de la industria. Necesitas traer esa misma energia a cuidar de tu cuerpo.&lt;/p&gt;
&lt;p&gt;Porque aqui esta lo que nadie te dice en el hype de &quot;aprende a programar&quot;: tu carrera no esta limitada por tus habilidades tecnicas o el mercado laboral o IA o nada de eso. Tu carrera esta limitada por cuanto tiempo tu cuerpo pueda aguantar sentado en una silla.&lt;/p&gt;
&lt;p&gt;Haz que sea mucho tiempo. Invierte en la configuracion correcta, muevete regularmente, haz ejercicio consistentemente, y construye habitos sostenibles desde el inicio.&lt;/p&gt;
&lt;p&gt;El tu de 15 anos en el futuro ya te esta agradeciendo.&lt;/p&gt;
&lt;h2 id=&quot;construye-tus-habilidades-mientras-construyes-tu-carrera&quot;&gt;Construye Tus Habilidades Mientras Construyes Tu Carrera&lt;/h2&gt;
&lt;p&gt;Mientras cuidas tu cuerpo, sigue afilando tus habilidades tecnicas. Empieza con proyectos practicos que los empleadores quieren ver:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;Construye un Portafolio&lt;/a&gt;&lt;/strong&gt; (Laravel o &lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Flask&lt;/a&gt; o &lt;a href=&quot;/tutorials/portfolio-scratch/&quot;&gt;desde cero&lt;/a&gt;) - Muestra tu trabajo profesionalmente&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-laravel/&quot;&gt;Construye un Blog&lt;/a&gt;&lt;/strong&gt; (Laravel o &lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Flask&lt;/a&gt; o &lt;a href=&quot;/tutorials/blog-scratch/&quot;&gt;desde cero&lt;/a&gt;) - Domina operaciones CRUD y gestion de contenido&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-laravel/&quot;&gt;Construye E-Commerce&lt;/a&gt;&lt;/strong&gt; (Laravel o &lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Flask&lt;/a&gt; o &lt;a href=&quot;/tutorials/shopping-scratch/&quot;&gt;desde cero&lt;/a&gt;) - Aprende logica de negocio compleja e integracion de pagos&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cada tutorial incluye prompts asistidos por IA para ayudarte a construir aplicaciones listas para produccion. Elige el stack que coincida con los trabajos que quieres y empieza a entregar.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Corriger les erreurs SSL du sous-domaine www Fly.io avec Cloudflare (Erreur 525)]]></title><description><![CDATA[Vous avez l'erreur 525 en accedant a www.votresite.com sur Fly.io ? Voici comment corriger l'erreur de handshake SSL en ajoutant des certificats separes pour les sous-domaines www - une etape critique que la plupart des guides de deploiement sautent.]]></description><link>https://vibecodingwithfred.com/fr/blog/flyio-cloudflare-www-setup/</link><guid isPermaLink="false">https://vibecodingwithfred.com/fr/blog/flyio-cloudflare-www-setup/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 19 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Vous avez deploye votre app sur Fly.io et le domaine racine fonctionne bien, mais &lt;code class=&quot;language-text&quot;&gt;www.votresite.com&lt;/code&gt; lance une erreur de handshake SSL ? Vous n&apos;etes pas seul. Cette erreur 525 arrive parce que Fly.io necessite &lt;strong&gt;des certificats SSL separes pour chaque nom d&apos;hote&lt;/strong&gt; - et la plupart des guides de deploiement sautent completement cette etape.&lt;/p&gt;
&lt;p&gt;Voici la correction, testee et verifiee sur un deploiement de production.&lt;/p&gt;
&lt;h2 id=&quot;le-probleme&quot;&gt;Le probleme&lt;/h2&gt;
&lt;p&gt;Vous avez deploye sur Fly.io, ajoute votre domaine personnalise, et tout semble bon. Puis vous essayez de visiter &lt;code class=&quot;language-text&quot;&gt;www.votresite.com&lt;/code&gt; et vous obtenez :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Error 525: SSL handshake failed&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Pendant ce temps, &lt;code class=&quot;language-text&quot;&gt;votresite.com&lt;/code&gt; (sans www) fonctionne bien. Que se passe-t-il ?&lt;/p&gt;
&lt;h2 id=&quot;pourquoi-cela-arrive&quot;&gt;Pourquoi cela arrive&lt;/h2&gt;
&lt;p&gt;Fly.io utilise Let&apos;s Encrypt pour provisionner les certificats SSL, mais voici le piege : &lt;strong&gt;ajouter un certificat pour &lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt; ne couvre PAS automatiquement &lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Ils sont traites comme des noms d&apos;hote completement separes. Vous devez explicitement ajouter un certificat pour le sous-domaine &lt;a href=&quot;http://www&quot;&gt;www&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;la-solution-5-etapes&quot;&gt;La solution (5 etapes)&lt;/h2&gt;
&lt;h3 id=&quot;etape-1--installer-flyio-cli&quot;&gt;Etape 1 : Installer Fly.io CLI&lt;/h3&gt;
&lt;p&gt;Si vous ne l&apos;avez pas deja fait, installez flyctl :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Installer flyctl&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Ajouter au PATH&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;FLYCTL_INSTALL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/.fly&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;PATH&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$FLYCTL_INSTALL&lt;/span&gt;/bin:&lt;span class=&quot;token environment constant&quot;&gt;$PATH&lt;/span&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Rendre permanent (ajouter a ~/.bashrc ou ~/.zshrc)&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export FLYCTL_INSTALL=&quot;$HOME/.fly&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export PATH=&quot;$FLYCTL_INSTALL/bin:$PATH&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc

&lt;span class=&quot;token comment&quot;&gt;# Verifier que ca fonctionne&lt;/span&gt;
flyctl version&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;etape-2--verifier-vos-certificats-actuels&quot;&gt;Etape 2 : Verifier vos certificats actuels&lt;/h3&gt;
&lt;p&gt;D&apos;abord, voyez quels certificats vous avez deja :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; VOTRE_NOM_APP&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Vous verrez probablement quelque chose comme :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Host Name                 Added                Status
example.com              1 month ago          Ready
api.example.com          1 month ago          Ready&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Remarquez ce qui manque ? Le sous-domaine &lt;code class=&quot;language-text&quot;&gt;www&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;etape-3--ajouter-le-certificat-www-ceci-corrige-le-probleme&quot;&gt;Etape 3 : Ajouter le certificat www (ceci corrige le probleme)&lt;/h3&gt;
&lt;p&gt;Voici la commande critique qui resout le probleme :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; VOTRE_NOM_APP&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fly.io provisionne automatiquement un certificat SSL Let&apos;s Encrypt pour votre sous-domaine &lt;a href=&quot;http://www&quot;&gt;www&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;etape-4--verifier-que-le-certificat-est-pret&quot;&gt;Etape 4 : Verifier que le certificat est pret&lt;/h3&gt;
&lt;p&gt;Attendez 1-2 minutes, puis verifiez le statut du certificat :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs show www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; VOTRE_NOM_APP&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Cherchez &lt;strong&gt;&quot;Status: Ready&quot;&lt;/strong&gt;. S&apos;il dit &quot;Awaiting certificates&quot;, attendez encore une minute et reverifiez.&lt;/p&gt;
&lt;h3 id=&quot;etape-5--configurer-le-mode-ssltls-cloudflare&quot;&gt;Etape 5 : Configurer le mode SSL/TLS Cloudflare&lt;/h3&gt;
&lt;p&gt;Cette etape est critique si vous utilisez Cloudflare pour le DNS (ce que vous devriez faire).&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Connectez-vous a votre tableau de bord Cloudflare&lt;/li&gt;
&lt;li&gt;Selectionnez votre domaine&lt;/li&gt;
&lt;li&gt;Allez a &lt;strong&gt;SSL/TLS&lt;/strong&gt; → &lt;strong&gt;Overview&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Definissez le mode de chiffrement sur &lt;strong&gt;&quot;Full&quot;&lt;/strong&gt; (pas &quot;Flexible&quot; ou &quot;Full (strict)&quot;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Pourquoi &quot;Full&quot; ?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Flexible&lt;/strong&gt; : Cloudflare utilise HTTPS pour vos visiteurs, mais HTTP vers Fly.io (non securise, cause des problemes)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Full&lt;/strong&gt; : Cloudflare utilise HTTPS pour les visiteurs et vers Fly.io (correct)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Full (strict)&lt;/strong&gt; : Necessite une autorite de certification de confiance, mais Fly.io gere ses propres certificats (cause des erreurs)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;configurer-vos-enregistrements-dns-cloudflare&quot;&gt;Configurer vos enregistrements DNS (Cloudflare)&lt;/h2&gt;
&lt;p&gt;Assurez-vous que vos enregistrements DNS sont configures correctement :&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Domaine racine (&lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt;) :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;/strong&gt; : &lt;code class=&quot;language-text&quot;&gt;A&lt;/code&gt; ou &lt;code class=&quot;language-text&quot;&gt;AAAA&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nom&lt;/strong&gt; : &lt;code class=&quot;language-text&quot;&gt;@&lt;/code&gt; (ou laisser vide)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contenu&lt;/strong&gt; : Votre adresse IP Fly.io (depuis &lt;code class=&quot;language-text&quot;&gt;flyctl ips list&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Statut proxy&lt;/strong&gt; : &lt;strong&gt;Proxied&lt;/strong&gt; (nuage orange active)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Sous-domaine www (&lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt;) :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;/strong&gt; : &lt;code class=&quot;language-text&quot;&gt;CNAME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nom&lt;/strong&gt; : &lt;code class=&quot;language-text&quot;&gt;www&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cible&lt;/strong&gt; : &lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt; (pointe vers le domaine racine)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Statut proxy&lt;/strong&gt; : &lt;strong&gt;Proxied&lt;/strong&gt; (nuage orange active)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Le nuage orange (Proxied) est important - il route le trafic a travers le CDN de Cloudflare et active le SSL.&lt;/p&gt;
&lt;h2 id=&quot;tester-tout&quot;&gt;Tester tout&lt;/h2&gt;
&lt;p&gt;Verifiez que les deux domaines fonctionnent :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Tester le domaine racine&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; https://example.com

&lt;span class=&quot;token comment&quot;&gt;# Tester le sous-domaine www&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; https://www.example.com&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Les deux devraient retourner &lt;code class=&quot;language-text&quot;&gt;HTTP/2 200&lt;/code&gt; (ou &lt;code class=&quot;language-text&quot;&gt;HTTP/1.1 200&lt;/code&gt;). Si vous obtenez des erreurs, voyez la section depannage ci-dessous.&lt;/p&gt;
&lt;h2 id=&quot;pourquoi-les-certificats-separes-comptent&quot;&gt;Pourquoi les certificats separes comptent&lt;/h2&gt;
&lt;p&gt;Dans l&apos;hebergement mutualise traditionnel, un certificat SSL wildcard (*.example.com) couvre tous les sous-domaines. Mais Fly.io provisionne les certificats individuellement via Let&apos;s Encrypt.&lt;/p&gt;
&lt;p&gt;Cela vous donne plus de controle mais necessite une configuration explicite pour chaque sous-domaine :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt; → a besoin de son propre certificat&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt; → a besoin de son propre certificat&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;api.example.com&lt;/code&gt; → a besoin de son propre certificat&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;blog.example.com&lt;/code&gt; → a besoin de son propre certificat&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Vous comprenez l&apos;idee.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Le probleme de certificat SSL du sous-domaine www Fly.io est l&apos;un de ces &quot;pieges&quot; qui fait trebucher meme les developpeurs experimentes. La correction est simple une fois que vous la connaissez :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ajoutez un certificat separe pour www : &lt;code class=&quot;language-text&quot;&gt;flyctl certs add www.example.com -a VOTRE_NOM_APP&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Definissez le SSL/TLS Cloudflare sur le mode &quot;Full&quot;&lt;/li&gt;
&lt;li&gt;Attendez 1-2 minutes que le certificat soit pret&lt;/li&gt;
&lt;li&gt;Testez les deux domaines&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;C&apos;est tout. Pas de configuration complexe, pas de redemarrages de serveur, pas d&apos;edition de fichiers de configuration. Juste une commande que la plupart des guides de deploiement oublient de mentionner.&lt;/p&gt;
&lt;p&gt;Maintenant vos utilisateurs peuvent acceder a votre site avec ou sans www, et les deux fonctionneront correctement.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Guides connexes :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;Guide complet : Deployer des projets Lovable sur Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/deploy-claude-code-cloudflare&quot;&gt;Deployer des apps Claude Code et Codex sur Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/cloudflare-workers-deployment&quot;&gt;Guide de deploiement Cloudflare Workers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Cosa 15 Anni di Programmazione Mi Hanno Insegnato Sul Restare in Salute (E Sani di Mente)]]></title><description><![CDATA[Quindici anni nella mia carriera di programmatore, ho imparato che restare produttivi non riguarda solo algoritmi migliori - riguarda non distruggere il proprio corpo nel processo. Ecco cosa conta.]]></description><link>https://vibecodingwithfred.com/it/blog/webdev-career-reality-check-2025/</link><guid isPermaLink="false">https://vibecodingwithfred.com/it/blog/webdev-career-reality-check-2025/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 19 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Sto scrivendo questo dalla mia scrivania in piedi alle 14 di un martedi, avendo appena finito una passeggiata di 25 minuti intorno all&apos;isolato. Quindici anni fa, quando stavo macinando nel mio primo vero lavoro di sviluppo, questo sarebbe sembrato ridicolo. Fare una pausa? Nel mezzo della giornata? Quando c&apos;e codice da rilasciare?&lt;/p&gt;
&lt;p&gt;Si, il me del passato era un idiota.&lt;/p&gt;
&lt;p&gt;Quindici anni in questa carriera, ho imparato qualcosa che nessuno ti dice nei bootcamp o nei programmi di informatica: la piu grande minaccia al tuo successo a lungo termine come sviluppatore non e il mercato del lavoro, imparare il framework sbagliato, o nemmeno la sindrome dell&apos;impostore.&lt;/p&gt;
&lt;p&gt;E quello che tutte quelle ore sulla sedia fanno al tuo corpo.&lt;/p&gt;
&lt;p&gt;Ero uno di quegli sviluppatori che indossava le &quot;sessioni di coding maratona&quot; come una medaglia d&apos;onore. Stavo seduto 8-10 ore di fila, curvo sul mio laptop, vivendo di caffe e l&apos;euforia di risolvere problemi complessi. Ero produttivo. Stavo rilasciando feature. Mi stavo anche lentamente distruggendo.&lt;/p&gt;
&lt;p&gt;Intorno all&apos;anno sette, la mia schiena ha iniziato a lamentarsi. Non il dolore occasionale - il tipo di dolore persistente che ti fa sussultare quando ti alzi. All&apos;anno dieci, stavo spendendo piu soldi in fisioterapia di quanto avessi mai speso in corsi o conferenze. E stato allora che ho finalmente realizzato: puoi avere tutte le competenze tecniche del mondo, ma se il tuo corpo cede, niente di questo conta.&lt;/p&gt;
&lt;p&gt;Ecco cosa vorrei che qualcuno mi avesse detto il primo giorno.&lt;/p&gt;
&lt;h2 id=&quot;il-mercato-del-lavoro-si-e-diverso-ora&quot;&gt;Il Mercato del Lavoro (Si, E Diverso Ora)&lt;/h2&gt;
&lt;p&gt;Guarda, non ti addolciro la pillola. Il mercato del lavoro nel 2025 e piu competitivo di quando ho iniziato. I giorni del &quot;impara a programmare, lavoro garantito&quot; sono alle nostre spalle. Stai competendo con centinaia di candidati per posizioni che una volta erano piu facili da ottenere.&lt;/p&gt;
&lt;p&gt;Ma ecco cosa non e cambiato: la programmazione e ancora uno dei percorsi piu accessibili per costruire una carriera significativa. Ti servono un computer, accesso a internet, e la volonta di impegnarti. Niente prestiti studenteschi a sei cifre, niente attrezzature da scuola professionale, niente certificazioni che fanno da guardiane.&lt;/p&gt;
&lt;p&gt;Ho visto dozzine di sviluppatori autodidatti entrare nel campo e costruire carriere solide. Le barriere sono piu alte, si. Ma se ti impegni a imparare (non solo l&apos;inferno dei tutorial), puoi ancora farcela.&lt;/p&gt;
&lt;p&gt;Detto questo, questo articolo non riguarda veramente il mercato del lavoro. Ci sono un centinaio di altri post su quello. Questo riguarda la cosa che mi ha colto completamente di sorpresa: cosa succede al tuo corpo quando passi 8-10 ore al giorno su una sedia.&lt;/p&gt;
&lt;h2 id=&quot;la-sveglia&quot;&gt;La Sveglia&lt;/h2&gt;
&lt;p&gt;L&apos;anno sette e quando il mio corpo mi ha mandato una fattura.&lt;/p&gt;
&lt;p&gt;Avevo avuto dolore alla schiena occasionale, ma l&apos;avevo ignorato. Gli sviluppatori stanno seduti tutto il giorno - certo che la schiena fa male a volte, giusto? Poi una mattina mi sono alzato dalla scrivania e la parte bassa della schiena si e bloccata cosi forte che non riuscivo a raddrizzarmi. Ho passato i tre giorni successivi principalmente in orizzontale, prendendo ibuprofene e chiedendomi se questa fosse semplicemente la mia vita ora.&lt;/p&gt;
&lt;p&gt;Quella e stata la mia sveglia. Avevo 30 anni e mi muovevo come se ne avessi 60.&lt;/p&gt;
&lt;p&gt;Ho fatto quello che farebbe qualsiasi sviluppatore: ho ricercato a fondo. Ho parlato con fisioterapisti, mi sono immerso nella ricerca sull&apos;ergonomia, ho sperimentato con diversi setup, e ho confrontato appunti con altri sviluppatori che avevano passato la stessa cosa.&lt;/p&gt;
&lt;p&gt;Ecco cosa ho imparato: prevenire questo e molto piu facile che sistemarlo. E si riduce a tre cose interconnesse - ergonomia, movimento, e costruire una relazione sostenibile con il tuo lavoro.&lt;/p&gt;
&lt;h2 id=&quot;ergonomia-la-base-che-non-puoi-saltare&quot;&gt;Ergonomia: La Base Che Non Puoi Saltare&lt;/h2&gt;
&lt;p&gt;Lasciami essere chiaro su una cosa: una buona ergonomia non e opzionale. Non e un acquisto di lusso che fai dopo aver &quot;sfondato.&quot; E la base di una carriera di sviluppo sostenibile.&lt;/p&gt;
&lt;p&gt;Dopo il mio incidente alla schiena, la prima cosa che ho fatto e stata sistemare il mio setup. E intendo sistemarlo davvero, non solo comprare una sedia costosa e sperare per il meglio.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cosa ha contato:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;La sedia&lt;/strong&gt;: Ho investito in una sedia da ufficio di qualita con supporto lombare adeguato. Non perche sia figo avere una Herman Miller, ma perche passerai 2.000+ ore all&apos;anno su questa cosa. E piu tempo di quello che passi nella tua auto o nel tuo letto. Sono andato con una Steelcase Leap - comprata usata per $400. Otto anni dopo, e ancora in condizioni eccellenti. Non devi spendere $2.000, ma ti serve qualcosa che supporti adeguatamente la parte bassa della schiena e si regoli al tuo corpo.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Altezza del monitor&lt;/strong&gt;: Questo e enorme e non costa quasi nulla. Il tuo monitor dovrebbe essere all&apos;altezza degli occhi - non sotto, non sopra. All&apos;altezza degli occhi. Impilo il mio su un paio di libri. Economico, efficace, e ha fermato il dolore al collo di cui non mi rendevo nemmeno conto di avere.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scrivania in piedi&lt;/strong&gt;: Questo ha cambiato tutto per me. Alterno tra stare seduto e in piedi durante la giornata. Non perche stare in piedi sia intrinsecamente meglio (non lo e - stare in piedi tutto il giorno e anche terribile per te), ma perche cambiare posizione conta. Sono andato con una scrivania elettrica regolabile di Autonomous. Vale ogni centesimo.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tastiera e mouse&lt;/strong&gt;: Se inizi a sentire dolore al polso, non ignorarlo. Sono passato a una tastiera ergonomica e un mouse verticale dopo alcuni avvertimenti. Entrambe sono misure preventive relativamente economiche rispetto ad affrontare il tunnel carpale piu tardi.&lt;/p&gt;
&lt;p&gt;Ecco la cosa pero: l&apos;ergonomia da sola non basta. E la base, ma devi costruirci sopra.&lt;/p&gt;
&lt;h2 id=&quot;movimento-laltra-meta-dellequazione&quot;&gt;Movimento: L&apos;Altra Meta dell&apos;Equazione&lt;/h2&gt;
&lt;p&gt;L&apos;ho imparato nel modo difficile. Ho comprato tutta l&apos;attrezzatura ergonomica, mi sono sentito abbastanza soddisfatto di me stesso, e ho continuato a stare seduto per 8 ore di fila. La mia schiena faceva ancora male.&lt;/p&gt;
&lt;p&gt;A quanto pare, puoi avere il miglior setup ergonomico e comunque distruggerti se non ti muovi mai. Il tuo corpo non e stato progettato per essere fermo per ore, non importa quanto sia buona la tua postura.&lt;/p&gt;
&lt;p&gt;Cosa funziona:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fai pause vere&lt;/strong&gt;: Uso un approccio Pomodoro modificato - 50 minuti di lavoro, 10 minuti di pausa. Durante quelle pause, mi muovo. Non &quot;scrollare Twitter stando seduto,&quot; ma alzarmi, camminare, fare qualche stretching. A volte faccio qualche flessione o squat a corpo libero. Sembra ridicolo all&apos;inizio, ma alla tua schiena non importano i tuoi sentimenti.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stai in piedi regolarmente&lt;/strong&gt;: Alterno tra stare seduto e in piedi ogni ora circa. Sono in piedi adesso mentre scrivo questo. La chiave e cambiare posizione, non solo sceglierne una e restare li tutto il giorno.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Riunioni camminando&lt;/strong&gt;: Quando possibile, faccio le chiamate mentre cammino. Non e sempre pratico, ma quando lo e, sto facendo movimento mentre resto produttivo.&lt;/p&gt;
&lt;p&gt;Ora, so cosa alcuni di voi stanno pensando: &quot;Ma lavoro meglio in stato di flow! Non posso interrompere il deep work ogni ora!&quot;&lt;/p&gt;
&lt;p&gt;Capisco. Ero quello sviluppatore. Entravo in un ritmo e programmavo per 4-5 ore di fila, e quelle sessioni sembravano incredibilmente produttive. E lo erano - a breve termine. Ma stavano anche lentamente rompendo il mio corpo.&lt;/p&gt;
&lt;p&gt;Ecco cosa ho imparato: puoi avere lo stato di flow OPPURE puoi avere salute a lungo termine, ma non entrambi se la tua unica strategia e stare immobile per ore. Se vuoi cavalcare lo stato di flow (e lo faccio ancora a volte), hai bisogno di una seria routine di esercizi fuori dal lavoro per compensare. Non puoi avere entrambi senza conseguenze.&lt;/p&gt;
&lt;h2 id=&quot;lesercizio-non-e-opzionale---fa-parte-del-lavoro&quot;&gt;L&apos;Esercizio Non E Opzionale - Fa Parte del Lavoro&lt;/h2&gt;
&lt;p&gt;Questa e la parte che ha finalmente sistemato tutto per me: esercizio regolare.&lt;/p&gt;
&lt;p&gt;Non esercizio &quot;ci arrivero un giorno.&quot; Non esercizio &quot;cammino dalla macchina all&apos;ufficio.&quot; Esercizio reale, consistente, fallo-una-priorita.&lt;/p&gt;
&lt;p&gt;Dopo che la mia fisioterapista ha finito di lavorare i nodi dalla mia schiena, mi ha guardato e ha detto, &quot;Questo continuera a succedere a meno che tu non costruisca forza. Il tuo core e debole, i tuoi glutei non si attivano, e la tua schiena sta compensando per tutto.&quot;&lt;/p&gt;
&lt;p&gt;Aveva ragione.&lt;/p&gt;
&lt;p&gt;Ho iniziato con yoga due volte a settimana. Solo lezioni base, niente di elaborato. Entro due mesi, il mio dolore cronico alla schiena era migliorato piu di quanto avesse fatto con mesi di trattamento passivo. Lo yoga mi ha insegnato com&apos;e una postura corretta e ha rafforzato i muscoli che supportano la mia colonna vertebrale.&lt;/p&gt;
&lt;p&gt;Poi ho aggiunto allenamento con i pesi - squat, stacchi, lavoro sul core. Niente di esagerato, solo i fondamentali tre volte a settimana. Gli stacchi in particolare hanno fatto una differenza enorme. Quando alleni la catena posteriore correttamente, la tua schiena smette di dover fare tutto il lavoro di tenerti dritto.&lt;/p&gt;
&lt;p&gt;Ora, 15 anni in, faccio esercizio 4-5 volte a settimana. Non perche sia un appassionato di fitness, ma perche e quello che mi permette di continuare a fare il lavoro che amo senza dolore costante. E tanto parte del mio kit di strumenti professionali quanto Git o il mio IDE.&lt;/p&gt;
&lt;p&gt;Ecco la verita onesta: ho parlato con sviluppatori che siedono sui divani, lavorano dai bar con sedie terribili, stanno curvi sui laptop a letto - e stanno bene. La differenza? Sono tutti attivi fuori dal lavoro. Arrampicano, corrono, sollevano pesi, fanno yoga, surfano. Muovono i loro corpi regolarmente e costruiscono la forza per compensare tutto lo stare seduti.&lt;/p&gt;
&lt;p&gt;Nel frattempo, sviluppatori con setup ergonomici costosi ma zero routine di esercizio sono quelli con dolore cronico a 30 anni.&lt;/p&gt;
&lt;h2 id=&quot;lo-sgabello-a-tre-gambe&quot;&gt;Lo Sgabello a Tre Gambe&lt;/h2&gt;
&lt;p&gt;Pensa al lavoro di sviluppo sostenibile come a uno sgabello a tre gambe:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Ergonomia&lt;/strong&gt; - La tua base. La sedia, scrivania e setup giusti riducono lo stress di base sul tuo corpo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Movimento&lt;/strong&gt; - Pause regolari e cambi di posizione impediscono al tuo corpo di bloccarsi durante la giornata lavorativa.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Esercizio&lt;/strong&gt; - Costruire forza e mobilita fuori dal lavoro da al tuo corpo la resilienza per gestire tutto lo stare seduti.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Rimuovi una qualsiasi di queste gambe e lo sgabello cade. L&apos;ho imparato cercando di risparmiare su ciascuna in diversi momenti della mia carriera:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ottima ergonomia + niente movimento = dolore a collo e spalle&lt;/li&gt;
&lt;li&gt;Ottima ergonomia + niente esercizio = problemi cronici alla schiena&lt;/li&gt;
&lt;li&gt;Tanto esercizio + setup terribile = RSI e problemi ai polsi&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ti servono tutte e tre. La buona notizia? Nessuna di loro e cosi difficile una volta che ti impegni.&lt;/p&gt;
&lt;h2 id=&quot;la-realta&quot;&gt;La Realta&lt;/h2&gt;
&lt;p&gt;Guarda, sono consapevole che lamentarsi del mal di schiena da un lavoro d&apos;ufficio puo sembrare privilegiato. Ci sono persone che fanno lavori fisicamente impegnativi ben oltre i 60 anni che adorerebbero avere i miei &quot;problemi.&quot;&lt;/p&gt;
&lt;p&gt;Abbastanza giusto. Ma ecco la cosa: ogni lavoro ha richieste fisiche. La differenza e che la maggior parte dei lavori fisicamente impegnativi rende quelle richieste ovvie. Se sei nell&apos;edilizia, sai che il tuo corpo fa parte del lavoro. Indossi equipaggiamento di sicurezza, impari la tecnica corretta di sollevamento, ti aspetti di essere indolenzito.&lt;/p&gt;
&lt;p&gt;I lavoratori d&apos;ufficio - specialmente gli sviluppatori - spesso non si rendono conto che il loro lavoro ha richieste fisiche finche il danno non e fatto. Pensiamo al coding come lavoro puramente mentale, quindi ignoriamo la realta fisica di 8-10 ore al giorno nella stessa posizione.&lt;/p&gt;
&lt;p&gt;Questo e l&apos;avvertimento che avrei voluto ricevere: questo lavoro logorera il tuo corpo. Non cosi ovviamente come l&apos;edilizia o l&apos;infermieristica o il lavoro in magazzino, ma lo fara. E a differenza di quei lavori, nessuno ti ricordera di proteggerti. Nessuna regolamentazione OSHA per pause corrette da seduti.&lt;/p&gt;
&lt;h2 id=&quot;il-vero-rischio&quot;&gt;Il Vero Rischio&lt;/h2&gt;
&lt;p&gt;Il rischio non e solo qualche mal di schiena che puoi gestire con l&apos;ibuprofene. Il rischio e esaurirsi completamente - non mentalmente, ma fisicamente.&lt;/p&gt;
&lt;p&gt;Conosco sviluppatori che hanno lasciato il campo completamente perche non riuscivano a trovare un modo sostenibile di lavorare. Amavano programmare, ma i loro corpi non riuscivano a gestire lo stile di vita sedentario, e non sapevano come (o non volevano) cambiare le loro abitudini.&lt;/p&gt;
&lt;p&gt;Questo e prevenibile. Ma solo se lo prendi sul serio prima che inizi il dolore, non dopo.&lt;/p&gt;
&lt;h2 id=&quot;cosa-direi-al-me-stesso-piu-giovane&quot;&gt;Cosa Direi al Me Stesso Piu Giovane&lt;/h2&gt;
&lt;p&gt;Se potessi tornare al primo giorno della mia carriera di sviluppo, ecco cosa direi:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Investi nel tuo setup dall&apos;inizio&lt;/strong&gt;: Non aspettare finche hai mal di schiena per comprare una buona sedia. Il te stesso futuro ti ringraziera. Una base ergonomica adeguata non e un lusso - e infrastruttura.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Costruisci il movimento nella tua routine immediatamente&lt;/strong&gt;: Non aspettare di &quot;diventare piu disciplinato dopo.&quot; Inizia con blocchi di lavoro da 50 minuti e pause di movimento da 10 minuti. Rendilo non negoziabile dal primo giorno.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Fai esercizio come se fosse parte del tuo lavoro&lt;/strong&gt;: Perche lo e. Mettilo sul tuo calendario. Trattalo come uno standup o un deployment. La tua carriera dipende dal funzionamento corretto del tuo corpo.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Niente sessioni di coding maratona&lt;/strong&gt;: Non sono una medaglia d&apos;onore. Sono un infortunio al rallentatore. Il codice che scrivi nell&apos;ora otto non e poi cosi buono comunque.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Il dolore e informazione&lt;/strong&gt;: Se qualcosa fa male, affrontalo immediatamente. Quella piccola fitta al polso non andra via da sola. Quella rigidita occasionale alla schiena diventera cronica se la ignori.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Hai un solo corpo&lt;/strong&gt;: Non c&apos;e &quot;passare a una carriera diversa dopo se questa non funziona&quot; quando si tratta della tua salute fisica. Il danno e cumulativo e parte di esso e permanente.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;lo-sviluppatore-sostenibile&quot;&gt;Lo Sviluppatore Sostenibile&lt;/h2&gt;
&lt;p&gt;Quindici anni in, sto ancora programmando e lo amo ancora. Ma sono un tipo di sviluppatore diverso ora rispetto all&apos;anno uno.&lt;/p&gt;
&lt;p&gt;Faccio pause. Sto in piedi regolarmente. Faccio esercizio quattro volte a settimana. Ho un setup ergonomico adeguato. Mangio cibo vero. Mantengo un programma di sonno. Ho hobby che non coinvolgono schermi.&lt;/p&gt;
&lt;p&gt;Niente di questo mi rende uno sviluppatore peggiore. Semmai, sono piu produttivo ora perche non sto costantemente lottando contro il dolore o la stanchezza. Riesco a concentrarmi meglio, faccio meno errori, e non crollo alle 15 ogni giorno.&lt;/p&gt;
&lt;p&gt;Gli sviluppatori che conosco che sono nel campo da 20+ anni e lo amano ancora? L&apos;hanno tutti capito a un certo punto. Alcuni hanno imparato presto, alcuni hanno imparato nel modo difficile come me. Ma hanno tutti imparato.&lt;/p&gt;
&lt;p&gt;Quelli che non l&apos;hanno fatto o hanno lasciato il campo o sono infelici.&lt;/p&gt;
&lt;h2 id=&quot;il-punto-finale&quot;&gt;Il Punto Finale&lt;/h2&gt;
&lt;p&gt;Puoi avere una carriera lunga, sana e produttiva nello sviluppo. Il lavoro e ancora intellettualmente coinvolgente, la paga e ancora buona, e la flessibilita e ancora migliore della maggior parte dei lavori.&lt;/p&gt;
&lt;p&gt;Ma richiede trattare la tua salute fisica con la stessa intenzionalita con cui tratti il tuo sviluppo professionale. Ricerchi framework, impari nuovi linguaggi, ti tieni aggiornato sulle tendenze del settore. Devi portare la stessa energia nel prenderti cura del tuo corpo.&lt;/p&gt;
&lt;p&gt;Perche ecco cosa nessuno ti dice nell&apos;hype &quot;impara a programmare&quot;: la tua carriera non e limitata dalle tue competenze tecniche o dal mercato del lavoro o dall&apos;AI o niente del genere. La tua carriera e limitata da quanto a lungo il tuo corpo riesce a gestire stare seduto su una sedia.&lt;/p&gt;
&lt;p&gt;Fai in modo che sia a lungo. Investi nel setup giusto, muoviti regolarmente, fai esercizio costantemente, e costruisci abitudini sostenibili dall&apos;inizio.&lt;/p&gt;
&lt;p&gt;Il te stesso tra 15 anni ti sta gia ringraziando.&lt;/p&gt;
&lt;h2 id=&quot;costruisci-le-tue-competenze-mentre-costruisci-la-tua-carriera&quot;&gt;Costruisci le Tue Competenze Mentre Costruisci la Tua Carriera&lt;/h2&gt;
&lt;p&gt;Mentre ti prendi cura del tuo corpo, continua ad affilare le tue competenze tecniche. Inizia con progetti pratici che i datori di lavoro vogliono vedere:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;Costruisci un Portfolio&lt;/a&gt;&lt;/strong&gt; (Laravel o &lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Flask&lt;/a&gt; o &lt;a href=&quot;/tutorials/portfolio-scratch/&quot;&gt;da zero&lt;/a&gt;) - Mostra il tuo lavoro professionalmente&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-laravel/&quot;&gt;Costruisci un Blog&lt;/a&gt;&lt;/strong&gt; (Laravel o &lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Flask&lt;/a&gt; o &lt;a href=&quot;/tutorials/blog-scratch/&quot;&gt;da zero&lt;/a&gt;) - Padroneggia le operazioni CRUD e la gestione contenuti&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-laravel/&quot;&gt;Costruisci E-Commerce&lt;/a&gt;&lt;/strong&gt; (Laravel o &lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Flask&lt;/a&gt; o &lt;a href=&quot;/tutorials/shopping-scratch/&quot;&gt;da zero&lt;/a&gt;) - Impara logica di business complessa e integrazione pagamenti&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ogni percorso tutorial include prompt assistiti da AI per guidarti nella costruzione di applicazioni pronte per la produzione. Scegli lo stack che corrisponde ai lavori che vuoi, poi costruisci qualcosa che puoi mostrare ai datori di lavoro.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Fly.ioのwwwサブドメインSSLエラーをCloudflareで修正する（エラー525）]]></title><description><![CDATA[Fly.ioでwww.yoursite.comにアクセスするとエラー525が発生しますか？wwwサブドメイン用に個別の証明書を追加することでSSLハンドシェイクエラーを修正する方法を解説します。これはほとんどのデプロイメントガイドがスキップする重要なステップです。]]></description><link>https://vibecodingwithfred.com/ja/blog/flyio-cloudflare-www-setup/</link><guid isPermaLink="false">https://vibecodingwithfred.com/ja/blog/flyio-cloudflare-www-setup/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 19 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;アプリをFly.ioにデプロイしてルートドメインは正常に動作するのに、&lt;code class=&quot;language-text&quot;&gt;www.yoursite.com&lt;/code&gt;がSSLハンドシェイクエラーをスローしますか？あなただけではありません。このエラー525は、Fly.ioが&lt;strong&gt;各ホスト名に個別のSSL証明書を必要とする&lt;/strong&gt;ために発生します。そしてほとんどのデプロイメントガイドはこのステップを完全にスキップしています。&lt;/p&gt;
&lt;p&gt;以下は、本番デプロイメントでテスト・検証済みの修正方法です。&lt;/p&gt;
&lt;h2 id=&quot;問題&quot;&gt;問題&lt;/h2&gt;
&lt;p&gt;Fly.ioにデプロイし、カスタムドメインを追加し、すべてが正常に見えます。そして&lt;code class=&quot;language-text&quot;&gt;www.yoursite.com&lt;/code&gt;にアクセスしようとすると：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Error 525: SSL handshake failed&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;一方、&lt;code class=&quot;language-text&quot;&gt;yoursite.com&lt;/code&gt;（wwwなし）は正常に動作します。なぜでしょうか？&lt;/p&gt;
&lt;h2 id=&quot;なぜこれが起こるか&quot;&gt;なぜこれが起こるか&lt;/h2&gt;
&lt;p&gt;Fly.ioはLet&apos;s Encryptを使用してSSL証明書をプロビジョニングしますが、ここに落とし穴があります：&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt;の証明書を追加しても、自動的に&lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt;はカバーされません&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;それらは完全に別のホスト名として扱われます。wwwサブドメイン用の証明書を明示的に追加する必要があります。&lt;/p&gt;
&lt;h2 id=&quot;解決策5ステップ&quot;&gt;解決策（5ステップ）&lt;/h2&gt;
&lt;h3 id=&quot;ステップ1flyio-cliをインストール&quot;&gt;ステップ1：Fly.io CLIをインストール&lt;/h3&gt;
&lt;p&gt;まだの場合は、flyctlをインストールします：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Install flyctl&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Add to PATH&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;FLYCTL_INSTALL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/.fly&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;PATH&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$FLYCTL_INSTALL&lt;/span&gt;/bin:&lt;span class=&quot;token environment constant&quot;&gt;$PATH&lt;/span&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Make it permanent (add to ~/.bashrc or ~/.zshrc)&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export FLYCTL_INSTALL=&quot;$HOME/.fly&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export PATH=&quot;$FLYCTL_INSTALL/bin:$PATH&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc

&lt;span class=&quot;token comment&quot;&gt;# Verify it works&lt;/span&gt;
flyctl version&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;ステップ2現在の証明書を確認&quot;&gt;ステップ2：現在の証明書を確認&lt;/h3&gt;
&lt;p&gt;まず、どの証明書があるか確認します：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;おそらく次のように表示されるでしょう：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Host Name                 Added                Status
example.com              1 month ago          Ready
api.example.com          1 month ago          Ready&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;何が足りないか気づきましたか？&lt;code class=&quot;language-text&quot;&gt;www&lt;/code&gt;サブドメインです。&lt;/p&gt;
&lt;h3 id=&quot;ステップ3www証明書を追加これで修正されます&quot;&gt;ステップ3：www証明書を追加（これで修正されます）&lt;/h3&gt;
&lt;p&gt;問題を解決する重要なコマンドはこちら：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fly.ioはwwwサブドメイン用のLet&apos;s Encrypt SSL証明書を自動的にプロビジョニングします。次のような出力が表示されます：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;You are creating a certificate for www.example.com
We are using Let&apos;s Encrypt for this certificate.

Your certificate for www.example.com is being issued.
You can validate your ownership of www.example.com by:

1: Adding an AAAA record to your DNS service which reads:
    AAAA @ 2a09:8280:1::X:XXXX&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;DNS検証について心配しないでください。ルートドメインがすでに動作していれば、wwwサブドメインは自動的に検証されます。&lt;/p&gt;
&lt;h3 id=&quot;ステップ4証明書の準備完了を確認&quot;&gt;ステップ4：証明書の準備完了を確認&lt;/h3&gt;
&lt;p&gt;1〜2分待ってから、証明書のステータスを確認します：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs show www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;**&quot;Status: Ready&quot;**を探してください。「Awaiting certificates」と表示されている場合は、もう1分待ってから再度確認してください。&lt;/p&gt;
&lt;p&gt;準備ができたら、証明書リストは次のように表示されるはずです：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Host Name                 Added                Status
example.com              1 month ago          Ready
www.example.com          13 seconds ago       Ready&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;完璧です。&lt;/p&gt;
&lt;h3 id=&quot;ステップ5cloudflare-ssltlsモードを設定&quot;&gt;ステップ5：Cloudflare SSL/TLSモードを設定&lt;/h3&gt;
&lt;p&gt;DNS（推奨）にCloudflareを使用している場合、このステップは重要です。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Cloudflareダッシュボードにログイン&lt;/li&gt;
&lt;li&gt;ドメインを選択&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SSL/TLS&lt;/strong&gt; → &lt;strong&gt;Overview&lt;/strong&gt;に移動&lt;/li&gt;
&lt;li&gt;暗号化モードを**&quot;Full&quot;**に設定（「Flexible」や「Full (strict)」ではなく）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;なぜ&quot;Full&quot;か？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Flexible&lt;/strong&gt;: Cloudflareは訪問者にはHTTPSを使用しますが、Fly.ioにはHTTPを使用します（安全でなく、問題が発生します）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Full&lt;/strong&gt;: Cloudflareは訪問者とFly.ioの両方にHTTPSを使用します（正しい）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Full (strict)&lt;/strong&gt;: 信頼された認証局が必要ですが、Fly.ioは独自の証明書を管理しています（エラーが発生します）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;dnsレコードの設定cloudflare&quot;&gt;DNSレコードの設定（Cloudflare）&lt;/h2&gt;
&lt;p&gt;DNSレコードが正しく設定されていることを確認します：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ルートドメイン（&lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt;）：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;タイプ&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;A&lt;/code&gt;または&lt;code class=&quot;language-text&quot;&gt;AAAA&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;名前&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;@&lt;/code&gt;（または空白）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コンテンツ&lt;/strong&gt;: Fly.io IPアドレス（&lt;code class=&quot;language-text&quot;&gt;flyctl ips list&lt;/code&gt;から）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;プロキシステータス&lt;/strong&gt;: &lt;strong&gt;Proxied&lt;/strong&gt;（オレンジのクラウドが有効）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;wwwサブドメイン（&lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt;）：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;タイプ&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;CNAME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;名前&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;www&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ターゲット&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt;（ルートドメインを指す）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;プロキシステータス&lt;/strong&gt;: &lt;strong&gt;Proxied&lt;/strong&gt;（オレンジのクラウドが有効）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;オレンジのクラウド（Proxied）は重要です。トラフィックをCloudflareのCDN経由でルーティングし、SSLを有効にします。&lt;/p&gt;
&lt;h2 id=&quot;すべてをテスト&quot;&gt;すべてをテスト&lt;/h2&gt;
&lt;p&gt;両方のドメインが動作することを確認します：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Test root domain&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; https://example.com

&lt;span class=&quot;token comment&quot;&gt;# Test www subdomain&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; https://www.example.com&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;両方とも&lt;code class=&quot;language-text&quot;&gt;HTTP/2 200&lt;/code&gt;（または&lt;code class=&quot;language-text&quot;&gt;HTTP/1.1 200&lt;/code&gt;）を返すはずです。エラーが発生した場合は、以下のトラブルシューティングセクションを参照してください。&lt;/p&gt;
&lt;h2 id=&quot;一般的なエラーと修正&quot;&gt;一般的なエラーと修正&lt;/h2&gt;
&lt;h3 id=&quot;エラー525sslハンドシェイク失敗&quot;&gt;エラー525：SSLハンドシェイク失敗&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;症状&lt;/strong&gt;: wwwサブドメインがエラー525をスロー、ルートドメインは正常に動作&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;原因&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Fly.ioにwww証明書がない&lt;/li&gt;
&lt;li&gt;Cloudflare SSL/TLSモードが「Flexible」または「Full (strict)」に設定されている&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;修正&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Add the www certificate&lt;/span&gt;
flyctl certs &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME

&lt;span class=&quot;token comment&quot;&gt;# Wait 2 minutes for certificate issuance&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sleep&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;120&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Verify it&apos;s ready&lt;/span&gt;
flyctl certs show www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;また、Cloudflare SSL/TLSモードが**&quot;Full&quot;**に設定されていることを確認してください。&lt;/p&gt;
&lt;h3 id=&quot;wwwサブドメインが接続タイムアウトを返す&quot;&gt;wwwサブドメインが接続タイムアウトを返す&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;症状&lt;/strong&gt;: wwwサブドメインがまったくロードされない、エラーページがない&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;原因&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;DNS CNAMEレコードが欠落しているか不正&lt;/li&gt;
&lt;li&gt;DNSがCloudflare経由でプロキシされていない&lt;/li&gt;
&lt;li&gt;DNS伝播が不完全&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;修正&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;www CNAMEレコードのCloudflare DNS設定を確認&lt;/li&gt;
&lt;li&gt;オレンジのクラウド（Proxied）が有効であることを確認&lt;/li&gt;
&lt;li&gt;DNS伝播のために5〜15分待つ&lt;/li&gt;
&lt;li&gt;ブラウザキャッシュをクリアするか、シークレットモードでテスト&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;証明書が5分以上awaiting-certificatesと表示される&quot;&gt;証明書が5分以上「Awaiting Certificates」と表示される&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;症状&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;flyctl certs show&lt;/code&gt;が「Awaiting certificates」と言い続ける&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;原因&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;DNSレコードがFly.ioを正しく指していない&lt;/li&gt;
&lt;li&gt;Cloudflareプロキシが証明書検証に干渉している&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;修正&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Verify your DNS records are correct&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; www.example.com

&lt;span class=&quot;token comment&quot;&gt;# Check if DNS is resolving to Fly.io&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;nslookup&lt;/span&gt; www.example.com

&lt;span class=&quot;token comment&quot;&gt;# If stuck, delete and re-add the certificate&lt;/span&gt;
flyctl certs delete www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME
flyctl certs &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;ルートドメインは動作wwwはルートにリダイレクト両方が必要な場合&quot;&gt;ルートドメインは動作、wwwはルートにリダイレクト（両方が必要な場合）&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;症状&lt;/strong&gt;: &lt;a href=&quot;http://www.example.com%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%99%E3%82%8B%E3%81%A8example.com%E3%81%AB%E3%83%AA%E3%83%80%E3%82%A4%E3%83%AC%E3%82%AF%E3%83%88%E3%81%99%E3%82%8B&quot;&gt;www.example.comにアクセスするとexample.comにリダイレクトする&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;原因&lt;/strong&gt;: これはアプリコードでの意図的な動作かもしれません&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修正&lt;/strong&gt;: 両方が独立して動作するようにしたい場合は、以下を確認：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Fly.ioに両方の証明書が存在する&lt;/li&gt;
&lt;li&gt;アプリにwww→非wwwへの強制リダイレクトロジックがない&lt;/li&gt;
&lt;li&gt;両方のDNSレコードが正しく設定されている&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;なぜ個別の証明書が重要か&quot;&gt;なぜ個別の証明書が重要か&lt;/h2&gt;
&lt;p&gt;従来の共有ホスティングでは、ワイルドカードSSL証明書（*.example.com）がすべてのサブドメインをカバーします。しかしFly.ioはLet&apos;s Encryptを通じて証明書を個別にプロビジョニングします。&lt;/p&gt;
&lt;p&gt;これにより、より多くの制御が可能になりますが、各サブドメインの明示的なセットアップが必要です：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt; → 独自の証明書が必要&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt; → 独自の証明書が必要&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;api.example.com&lt;/code&gt; → 独自の証明書が必要&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;blog.example.com&lt;/code&gt; → 独自の証明書が必要&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;お分かりでしょう。&lt;/p&gt;
&lt;h2 id=&quot;flyio--cloudflareのベストプラクティス&quot;&gt;Fly.io + Cloudflareのベストプラクティス&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;本番稼働前に使用予定のすべてのサブドメインに証明書を追加する&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fly.ioデプロイメントにはCloudflareの&quot;Full&quot; SSL/TLSモードを使用する&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CDNとDDoS保護のためにCloudflareプロキシ（オレンジのクラウド）を有効にする&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;サイトを発表する前にwwwと非wwwの両方のバージョンをテストする&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;どちらか一方のバージョンを強制したい場合はアプリでリダイレクトを設定する&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;トラブルシューティング用の便利なコマンド&quot;&gt;トラブルシューティング用の便利なコマンド&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# List all certificates for your app&lt;/span&gt;
flyctl certs list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME

&lt;span class=&quot;token comment&quot;&gt;# View detailed info for a specific certificate&lt;/span&gt;
flyctl certs show www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME

&lt;span class=&quot;token comment&quot;&gt;# Delete a certificate (if you need to start over)&lt;/span&gt;
flyctl certs delete www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME

&lt;span class=&quot;token comment&quot;&gt;# Check your app&apos;s IP addresses&lt;/span&gt;
flyctl ips list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME

&lt;span class=&quot;token comment&quot;&gt;# Check DNS resolution&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; example.com
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; www.example.com

&lt;span class=&quot;token comment&quot;&gt;# Test SSL connection with verbose output&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-vI&lt;/span&gt; https://www.example.com

&lt;span class=&quot;token comment&quot;&gt;# Check app status&lt;/span&gt;
flyctl status &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME

&lt;span class=&quot;token comment&quot;&gt;# View app logs (useful for debugging)&lt;/span&gt;
flyctl logs &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;完全セットアップチェックリスト&quot;&gt;完全セットアップチェックリスト&lt;/h2&gt;
&lt;p&gt;すべてが正しく設定されていることを確認するためにこのチェックリストを使用してください：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fly.io証明書：&lt;/strong&gt;&lt;/p&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; ルートドメイン証明書が存在し「Ready」と表示&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; wwwサブドメイン証明書が存在し「Ready」と表示&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; その他のサブドメインにも証明書を追加済み&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare DNS：&lt;/strong&gt;&lt;/p&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; ルートドメイン用のAまたはAAAAレコードがFly.io IPを指している&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; wwwサブドメイン用のCNAMEレコードがルートドメインを指している&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; すべてのレコードでオレンジのクラウド（Proxied）が有効&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare SSL/TLS：&lt;/strong&gt;&lt;/p&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; 暗号化モードが「Full」に設定（FlexibleやFull strictではなく）&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Edge Certificatesが有効なSSLを表示&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;テスト：&lt;/strong&gt;&lt;/p&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;code class=&quot;language-text&quot;&gt;https://example.com&lt;/code&gt;が200 OKを返す&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;code class=&quot;language-text&quot;&gt;https://www.example.com&lt;/code&gt;が200 OKを返す&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; ブラウザでSSL警告がない&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; 両方のドメインがセキュアなロックアイコンを表示&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;実際の例&quot;&gt;実際の例&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;ftashark.com&lt;/code&gt;の完全なセットアップはこのようになります：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Check certificates&lt;/span&gt;
$ flyctl certs list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; ftashark

Host Name                 Added                Status
ftashark.com              &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; month ago          Ready
www.ftashark.com          &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt; seconds ago       Ready
api.ftashark.com          &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; month ago          Ready&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare DNS：&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Type    Name    Content                          Proxy
A       @       66.241.124.123                   Proxied
CNAME   www     ftashark.com                     Proxied
CNAME   api     ftashark.com                     Proxied&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare SSL/TLS:&lt;/strong&gt; Fullモード&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;結果:&lt;/strong&gt; 3つのURLすべてが有効なSSLで正しく動作。&lt;/p&gt;
&lt;h2 id=&quot;なぜほとんどのガイドがこれをスキップするか&quot;&gt;なぜほとんどのガイドがこれをスキップするか&lt;/h2&gt;
&lt;p&gt;ほとんどのFly.ioデプロイメントチュートリアルは、アプリを実行し、単一のカスタムドメインを追加することに焦点を当てています。&lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt;または&lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt;のみを使用し、両方は使用しないと想定しています。&lt;/p&gt;
&lt;p&gt;しかし実際には、ユーザーは両方のバージョンを入力します。検索エンジンは両方をインデックスします。そして、トラフィックの半分がSSLエラーにヒットすることは望ましくありません。&lt;/p&gt;
&lt;p&gt;www証明書の追加は30秒で済みますが、後で何時間ものデバッグを節約します。&lt;/p&gt;
&lt;h2 id=&quot;代替案wwwを非wwwにリダイレクトまたは逆&quot;&gt;代替案：wwwを非wwwにリダイレクト（または逆）&lt;/h2&gt;
&lt;p&gt;両方のバージョンを維持したくない場合は、アプリでリダイレクトを設定できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;オプション1：www → 非wwwにリダイレクト&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ほとんどのフレームワークにはこのためのミドルウェアがあります。例えば、Express.jsでは：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hostname&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;www.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;redirect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;301&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;https://&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hostname&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;オプション2：非www → wwwにリダイレクト&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hostname&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;www.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;redirect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;301&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;https://www.&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hostname&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ただし、リダイレクトする場合でも、&lt;strong&gt;両方の証明書が必要です&lt;/strong&gt;。そうでないとリダイレクトが機能しません（ユーザーはアプリがリダイレクトする前にSSLエラーにヒットします）。&lt;/p&gt;
&lt;h2 id=&quot;結論&quot;&gt;結論&lt;/h2&gt;
&lt;p&gt;Fly.ioのwwwサブドメインSSLの問題は、経験豊富な開発者でもつまずく「落とし穴」の1つです。一度知れば修正は簡単です：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;www用の個別証明書を追加：&lt;code class=&quot;language-text&quot;&gt;flyctl certs add www.example.com -a YOUR_APP_NAME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Cloudflare SSL/TLSを「Full」モードに設定&lt;/li&gt;
&lt;li&gt;証明書の準備ができるまで1〜2分待つ&lt;/li&gt;
&lt;li&gt;両方のドメインをテスト&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;それだけです。複雑な設定なし、サーバー再起動なし、設定ファイルの編集なし。ほとんどのデプロイメントガイドが言及し忘れる1つのコマンドだけです。&lt;/p&gt;
&lt;p&gt;これで、ユーザーはwwwの有無に関係なくサイトにアクセスでき、両方が正しく動作します。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;関連ガイド：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;完全ガイド：LovableプロジェクトをCloudflareにデプロイ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/deploy-claude-code-cloudflare&quot;&gt;Claude Code &amp;#x26; CodexアプリをCloudflareにデプロイ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/cloudflare-workers-deployment&quot;&gt;Cloudflare Workersデプロイメントガイド&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;リソース：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://fly.io/docs/networking/custom-domain/&quot;&gt;Fly.ioカスタムドメインドキュメント&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/ssl/&quot;&gt;Cloudflare SSL/TLS設定&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://letsencrypt.org/&quot;&gt;Let&apos;s Encrypt認証局&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[15年のコーディングが教えてくれた健康でいること（そして正気を保つこと）]]></title><description><![CDATA[コーディングキャリア15年目の私は、生産性を維持することは単により良いアルゴリズムについてではなく、その過程で身体を壊さないことだと学びました。重要なことをお伝えします。]]></description><link>https://vibecodingwithfred.com/ja/blog/webdev-career-reality-check-2025/</link><guid isPermaLink="false">https://vibecodingwithfred.com/ja/blog/webdev-career-reality-check-2025/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 19 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;火曜日の午後2時、ブロック周りの25分間のウォーキングを終えたばかりの私は、スタンディングデスクからこれを書いています。15年前、最初の本格的な開発の仕事に取り組んでいた頃、これはばかげて見えたでしょう。休憩を取る？日中に？出荷すべきコードがあるのに？&lt;/p&gt;
&lt;p&gt;ええ、過去の私はバカでした。&lt;/p&gt;
&lt;p&gt;このキャリアで15年を経て、ブートキャンプやコンピューターサイエンスプログラムでは誰も教えてくれないことを学びました：開発者としての長期的な成功への最大の脅威は、求人市場でも、間違ったフレームワークを学ぶことでも、インポスター症候群でさえありません。&lt;/p&gt;
&lt;p&gt;椅子に座り続ける何時間もの時間があなたの身体に何をするかです。&lt;/p&gt;
&lt;p&gt;私はかつて「マラソンコーディングセッション」を名誉の勲章のように着けていた開発者の一人でした。ラップトップに覆いかぶさって8〜10時間連続で座り、コーヒーと複雑な問題を解決する高揚感で生活していました。私は生産的でした。機能を出荷していました。同時に、ゆっくりと自分自身を破壊していました。&lt;/p&gt;
&lt;p&gt;7年目あたりで、背中が不平を言い始めました。時折の痛みではなく、立ち上がるときに顔をしかめるような持続的な痛みです。10年目までには、コースやカンファレンスに費やした以上のお金を理学療法に費やしていました。そのとき初めて気づきました：世界中のすべての技術スキルを持っていても、身体が壊れたら、何の意味もありません。&lt;/p&gt;
&lt;p&gt;1日目に誰かが教えてくれていたらと思うことをお伝えします。&lt;/p&gt;
&lt;h2 id=&quot;求人市場そう今は違います&quot;&gt;求人市場（そう、今は違います）&lt;/h2&gt;
&lt;p&gt;正直に言います。2025年の求人市場は、私が始めた頃よりも競争が激しくなっています。「コードを学べば、仕事が保証される」という時代は過去のものです。以前は簡単に取れたポジションに、何百人もの応募者と競争しています。&lt;/p&gt;
&lt;p&gt;しかし変わっていないのは：プログラミングは依然として意味のあるキャリアを築くための最もアクセスしやすい道の一つです。コンピュータ、インターネットアクセス、そして努力する意志が必要です。6桁の学生ローンも、専門学校の設備も、門番となる資格も必要ありません。&lt;/p&gt;
&lt;p&gt;私は何十人もの独学の開発者がこの分野に参入し、堅実なキャリアを築くのを見てきました。障壁は高くなっています、はい。しかし、学ぶことにコミットしているなら（チュートリアル地獄ではなく）、まだこれを実現できます。&lt;/p&gt;
&lt;p&gt;とはいえ、この記事は求人市場についてではありません。それについては他に百の投稿があります。これは私を完全に不意打ちしたことについてです：1日8〜10時間椅子に座っていると身体に何が起こるか。&lt;/p&gt;
&lt;h2 id=&quot;目覚めの呼び声&quot;&gt;目覚めの呼び声&lt;/h2&gt;
&lt;p&gt;7年目に身体が請求書を送ってきました。&lt;/p&gt;
&lt;p&gt;時々背中の痛みがありましたが、無視していました。開発者は一日中座っている—もちろん時々背中が痛むでしょう？それからある朝、デスクから立ち上がったとき、腰がひどく固まって真っ直ぐに立てませんでした。その後3日間、イブプロフェンを飲みながらほとんど横になって過ごし、これが今後の人生なのかと思いました。&lt;/p&gt;
&lt;p&gt;それが私の目覚めの呼び声でした。30歳なのに60歳のように動いていました。&lt;/p&gt;
&lt;p&gt;開発者なら誰でもするように、徹底的に調べました。理学療法士と話し、人間工学の研究に飛び込み、さまざまなセットアップを試し、同じ経験をした他の開発者とメモを比較しました。&lt;/p&gt;
&lt;p&gt;学んだこと：これを防ぐ方が直すよりずっと簡単です。そして、3つの相互に関連することに帰着します—人間工学、動き、そして仕事との持続可能な関係を築くこと。&lt;/p&gt;
&lt;h2 id=&quot;人間工学スキップできない基盤&quot;&gt;人間工学：スキップできない基盤&lt;/h2&gt;
&lt;p&gt;一つ明確にしておきます：良い人間工学はオプションではありません。「成功してから」購入する贅沢品ではありません。持続可能な開発キャリアの基盤です。&lt;/p&gt;
&lt;p&gt;背中の事件の後、最初にしたのはセットアップを修正することでした。本当に修正すること、高価な椅子を買って最善を期待することではなく。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;重要だったこと：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;椅子&lt;/strong&gt;：適切な腰椎サポートを備えた高品質のオフィスチェアに投資しました。Herman Millerを持つのがクールだからではなく、この椅子で年間2,000時間以上過ごすからです。車やベッドよりも長い時間です。Steelcase Leapを選び、中古で$400で購入しました。8年後、まだ優れた状態です。$2,000を出す必要はありませんが、腰を適切にサポートし、身体に合わせて調整できるものが必要です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;モニターの高さ&lt;/strong&gt;：これは重要で、ほとんど何もコストがかかりません。モニターは目の高さにあるべきです—下でも上でもなく。目の高さに。私は本を数冊積み重ねています。安くて効果的で、気づいていなかった首の痛みが止まりました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;スタンディングデスク&lt;/strong&gt;：これはすべてを変えました。一日中座ったり立ったりを交互に行っています。立つことが本質的に良いからではなく（そうではありません—一日中立っているのも身体に悪い）、体勢を変えることが重要だからです。Autonomousの電動調節可能なデスクを選びました。すべてのペニーの価値があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;キーボードとマウス&lt;/strong&gt;：手首の痛みを感じ始めたら、無視しないでください。警告のうずきの後、人間工学キーボードと垂直マウスに切り替えました。どちらも、後で手根管症候群に対処するのに比べれば比較的安価な予防措置です。&lt;/p&gt;
&lt;p&gt;ただし、人間工学だけでは十分ではありません。それは基盤ですが、その上に構築する必要があります。&lt;/p&gt;
&lt;h2 id=&quot;動き方程式のもう半分&quot;&gt;動き：方程式のもう半分&lt;/h2&gt;
&lt;p&gt;これは苦労して学びました。すべての人間工学的ギアを購入し、自分に満足して、8時間のストレッチで座り続けました。背中はまだ痛みました。&lt;/p&gt;
&lt;p&gt;結局、最高の人間工学的セットアップがあっても、動かなければ自分自身を破壊できるのです。姿勢がどんなに良くても、あなたの身体は何時間も静止しているようにはデザインされていません。&lt;/p&gt;
&lt;p&gt;機能すること：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;実際の休憩を取る&lt;/strong&gt;：修正されたポモドーロアプローチを使用しています—50分の作業、10分の休憩。その休憩中に動きます。「座りながらTwitterをスクロール」ではなく、立ち上がって歩き回り、ストレッチをします。時々腕立て伏せや自重スクワットをします。最初はばかげて感じますが、背中はあなたの気持ちを気にしません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;定期的に立つ&lt;/strong&gt;：約1時間ごとに座ったり立ったりを交互に行います。これを書いている今、立っています。重要なのは体勢を変えることであり、一つを選んで一日中固執することではありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ウォーキングミーティング&lt;/strong&gt;：可能な限り、歩きながら電話を取ります。常に実用的ではありませんが、そうである場合、生産性を維持しながら動いています。&lt;/p&gt;
&lt;p&gt;さて、一部の方は考えていると思います：「でも私はフロー状態で最もよく働きます！1時間ごとにディープワークを中断できません！」&lt;/p&gt;
&lt;p&gt;分かります。私もそういう開発者でした。勢いに乗って4〜5時間連続でコーディングし、そのセッションは信じられないほど生産的に感じました。そうでした—短期的には。しかし、ゆっくりと身体を壊していました。&lt;/p&gt;
&lt;p&gt;学んだこと：フロー状態を持つか、長期的な健康を持つか、どちらかしか選べません。あなたの唯一の戦略が何時間も動かずに座ることであれば、両方は持てません。フロー状態に乗るなら（私はまだ時々そうします）、仕事以外に補うための真剣な運動ルーティンが必要です。結果なしに両方を持つことはできません。&lt;/p&gt;
&lt;h2 id=&quot;運動はオプションではない仕事の一部&quot;&gt;運動はオプションではない—仕事の一部&lt;/h2&gt;
&lt;p&gt;これがすべてを最終的に修正した部分です：定期的な運動。&lt;/p&gt;
&lt;p&gt;「いつかやる」運動ではありません。「車からオフィスまで歩く」運動ではありません。本物の、一貫した、優先事項にする運動です。&lt;/p&gt;
&lt;p&gt;理学療法士が背中の結び目を解いた後、私を見て言いました：「筋力をつけない限り、これは繰り返し起こります。体幹が弱く、臀筋が機能しておらず、背中がすべてを補償しています。」&lt;/p&gt;
&lt;p&gt;彼女は正しかったです。&lt;/p&gt;
&lt;p&gt;週2回のヨガから始めました。基本的なクラス、特別なものではありません。2ヶ月以内に、慢性的な背中の痛みは、何ヶ月もの受動的な治療より改善しました。ヨガは適切な姿勢がどのような感じかを教え、脊椎を支える筋肉を強化しました。&lt;/p&gt;
&lt;p&gt;次に筋力トレーニングを追加しました—スクワット、デッドリフト、体幹トレーニング。特別なことではなく、週3回の基本だけ。特にデッドリフトは大きな違いを生みました。後方連鎖を適切にトレーニングすると、背中は直立姿勢を維持するためのすべての仕事をする必要がなくなります。&lt;/p&gt;
&lt;p&gt;15年目の今、週4〜5回運動しています。フィットネス愛好家だからではなく、愛する仕事を継続的な痛みなしに続けられるものだからです。GitやIDEと同様に、プロフェッショナルツールキットの一部です。&lt;/p&gt;
&lt;p&gt;正直な真実はこれです：ソファに座り、ひどい椅子のコーヒーショップで仕事をし、ベッドでラップトップに覆いかぶさる開発者と話したことがありますが—彼らは大丈夫です。違いは何でしょうか？彼らは皆、仕事以外でアクティブです。クライミング、ランニング、ウェイトトレーニング、ヨガ、サーフィンをしています。定期的に身体を動かし、座ることを補うための筋力を構築しています。&lt;/p&gt;
&lt;p&gt;一方、高価な人間工学的セットアップがあっても運動ルーティンがゼロの開発者は、30代で慢性的な痛みを抱えている人たちです。&lt;/p&gt;
&lt;h2 id=&quot;三脚スツール&quot;&gt;三脚スツール&lt;/h2&gt;
&lt;p&gt;持続可能な開発作業を三脚スツールとして考えてください：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;人間工学&lt;/strong&gt; - あなたの基盤。適切な椅子、デスク、セットアップは身体への基本的なストレスを軽減します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;動き&lt;/strong&gt; - 定期的な休憩と体勢変更は、作業日中に身体が固まるのを防ぎます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;運動&lt;/strong&gt; - 仕事以外で筋力と可動性を構築することで、すべての座りに対処できる回復力を身体に与えます。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;これらの脚のいずれかを取り除くとスツールは倒れます。私はキャリアのさまざまな時点でそれぞれを節約しようとして、これを学びました：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;素晴らしい人間工学 + 動きなし = 首と肩の痛み&lt;/li&gt;
&lt;li&gt;素晴らしい人間工学 + 運動なし = 慢性的な腰痛&lt;/li&gt;
&lt;li&gt;多くの運動 + ひどいセットアップ = RSIと手首の問題&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;3つすべてが必要です。良いニュースは？一度コミットすれば、どれもそれほど難しくありません。&lt;/p&gt;
&lt;h2 id=&quot;重要なライフスタイルのこと&quot;&gt;重要なライフスタイルのこと&lt;/h2&gt;
&lt;p&gt;以前は「ウェルネスの戯言」として却下していた小さな要因がいくつかありますが、驚くほど重要であることが判明しました：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;水&lt;/strong&gt;：デスクに小さな水筒を置いています。水分補給が魔法だからではなく、1日に何度か立ち上がって補充することを強制されるからです。組み込みの動きリマインダーです。また、水分補給は重要です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;本物の食べ物&lt;/strong&gt;：以前はコーヒー、エナジードリンク、そして最も速いものだけで生活していました。驚くことなく、これはひどい気分にさせました。特定の食事について説教するつもりはありませんが、定期的な時間に実際の食べ物を食べることは、エネルギーレベルと集中力に顕著な違いを生みました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;睡眠スケジュール&lt;/strong&gt;：一貫した時間に就寝して起床することはセクシーなアドバイスではありませんが、機能します。睡眠不足のとき、姿勢が崩壊し、休憩を取るかどうかを含むすべてについてより悪い決定を下します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;スクリーン以外の趣味&lt;/strong&gt;：これは私には奇妙でした。私は開発者です—もちろん自由時間もスクリーンで過ごしますよね？しかし、ギターと木工を始めることで、手と身体を異なる方法で使う活動を得ました。さらに、コード以外の何かが人生にあるのは素晴らしいことです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;社会的つながり&lt;/strong&gt;：フルタイムでリモートで働いている私は、これについて意図的でなければなりませんでした。友人との定期的なランチ、クライミングジムへの参加、テキストするだけでなく人に電話をかけること。孤立は身体的健康を含むすべてを悪化させます。&lt;/p&gt;
&lt;h2 id=&quot;現実チェック&quot;&gt;現実チェック&lt;/h2&gt;
&lt;p&gt;デスクワークからの背中の痛みについて不満を言うことが特権的に聞こえるかもしれないことは承知しています。60代まで肉体的に要求の厳しい労働をしている人々がいて、私の「問題」を持ちたいと思うでしょう。&lt;/p&gt;
&lt;p&gt;確かに。しかしここがポイントです：すべての仕事には身体的要求があります。違いは、ほとんどの肉体的に要求の厳しい仕事はそれらの要求を明白にしていることです。建設業にいるなら、身体が仕事の一部であることを知っています。安全装備を着用し、適切な持ち上げ技術を訓練し、筋肉痛を予想します。&lt;/p&gt;
&lt;p&gt;オフィスワーカー—特に開発者—は、ダメージが完了するまで仕事に身体的要求があることに気づかないことがよくあります。コーディングを純粋に精神的な仕事と考えているので、1日8〜10時間同じ姿勢でいることの身体的現実を無視します。&lt;/p&gt;
&lt;p&gt;それが私が受けたかった警告です：この仕事はあなたの身体を消耗させます。建設や看護や倉庫作業ほど明白ではありませんが、そうなります。そして、それらの仕事とは異なり、誰もあなたを守るようにリマインドしてくれません。適切な座り休憩のためのOSHA規制はありません。&lt;/p&gt;
&lt;h2 id=&quot;本当のリスク&quot;&gt;本当のリスク&lt;/h2&gt;
&lt;p&gt;リスクはイブプロフェンで管理できる背中の痛みだけではありません。リスクは完全に燃え尽きることです—精神的にではなく、身体的に。&lt;/p&gt;
&lt;p&gt;私は、持続可能な働き方を見つけられなかったため、フィールドを完全に去った開発者を知っています。彼らはコーディングを愛していましたが、彼らの身体は座りがちなライフスタイルに対処できず、習慣を変える方法を知らなかった（または変えたくなかった）のです。&lt;/p&gt;
&lt;p&gt;それは予防可能です。しかし、痛みが始まる前に、そうではなく後に真剣に取り組む場合にのみ。&lt;/p&gt;
&lt;h2 id=&quot;若い自分に言いたいこと&quot;&gt;若い自分に言いたいこと&lt;/h2&gt;
&lt;p&gt;開発キャリアの1日目に戻れたら、こう言うでしょう：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;最初からセットアップに投資する&lt;/strong&gt;：背中が痛くなるまで良い椅子を買うのを待たないでください。将来のあなたが感謝するでしょう。適切な人間工学的基盤は贅沢品ではなく、インフラです。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;すぐに動きをルーティンに組み込む&lt;/strong&gt;：「後でもっと規律を持つ」のを待たないでください。50分の作業ブロックと10分の動き休憩から始めてください。1日目から譲れないものにしてください。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;仕事の一部として運動する&lt;/strong&gt;：なぜなら、そうだからです。カレンダーに入れてください。スタンドアップやデプロイメントのように扱ってください。あなたのキャリアは身体が適切に機能することに依存しています。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;マラソンコーディングセッションはやめる&lt;/strong&gt;：それは名誉の勲章ではありません。スローモーションの怪我です。8時間目に書くコードはそれほど良くないです。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;痛みは情報&lt;/strong&gt;：何かが痛いなら、すぐに対処してください。小さな手首のうずきは自然に消えません。時々の背中の硬さは、無視すると慢性的になります。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;身体は一つだけ&lt;/strong&gt;：身体的健康に関しては、「これがうまくいかなければ後で別のキャリアに切り替える」というオプションはありません。ダメージは累積的で、一部は永久的です。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;持続可能な開発者&quot;&gt;持続可能な開発者&lt;/h2&gt;
&lt;p&gt;15年目、まだコーディングをしていて、まだ愛しています。しかし、1年目とは異なる種類の開発者になりました。&lt;/p&gt;
&lt;p&gt;私は休憩を取ります。定期的に立ちます。週4回運動します。適切な人間工学的セットアップがあります。本物の食べ物を食べます。睡眠スケジュールを維持します。スクリーンを使わない趣味があります。&lt;/p&gt;
&lt;p&gt;これらのどれも私を悪い開発者にしません。何かあれば、今の方が生産的です。常に痛みや疲労と戦っていないからです。より良く集中でき、間違いが少なく、毎日午後3時にクラッシュしません。&lt;/p&gt;
&lt;p&gt;私が知っている20年以上この分野にいてまだ愛している開発者たち？彼らは皆、ある時点でこれを理解しました。早く学んだ人もいれば、私のように苦労して学んだ人もいます。しかし、皆学びました。&lt;/p&gt;
&lt;p&gt;そうしなかった人は、フィールドを去ったか、惨めです。&lt;/p&gt;
&lt;h2 id=&quot;結論&quot;&gt;結論&lt;/h2&gt;
&lt;p&gt;開発で長く、健康で、生産的なキャリアを持つことができます。仕事はまだ知的に魅力的で、給料はまだ良く、柔軟性はまだほとんどの仕事よりも良いです。&lt;/p&gt;
&lt;p&gt;しかし、プロフェッショナル開発を扱うのと同じ意図性で身体的健康を扱う必要があります。フレームワークを調べ、新しい言語を学び、業界のトレンドについていく。身体のケアにも同じエネルギーを持ち込む必要があります。&lt;/p&gt;
&lt;p&gt;なぜなら、「コードを学ぶ」ハイプで誰も教えてくれないことがあるからです：あなたのキャリアは技術スキルや求人市場やAIやそのどれによっても制限されていません。あなたのキャリアは、身体が椅子に座ることをどれだけ長く耐えられるかによって制限されています。&lt;/p&gt;
&lt;p&gt;長くしてください。適切なセットアップに投資し、定期的に動き、一貫して運動し、最初から持続可能な習慣を構築してください。&lt;/p&gt;
&lt;p&gt;15年後のあなたはすでにあなたに感謝しています。&lt;/p&gt;
&lt;h2 id=&quot;キャリアを築きながらスキルを構築する&quot;&gt;キャリアを築きながらスキルを構築する&lt;/h2&gt;
&lt;p&gt;身体をケアしながら、技術スキルを磨き続けてください。雇用主が見たい実践的なプロジェクトから始めてください：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;ポートフォリオを構築&lt;/a&gt;&lt;/strong&gt;（Laravelまたは&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Flask&lt;/a&gt;または&lt;a href=&quot;/tutorials/portfolio-scratch/&quot;&gt;スクラッチから&lt;/a&gt;）- プロフェッショナルに作品を披露する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-laravel/&quot;&gt;ブログを構築&lt;/a&gt;&lt;/strong&gt;（Laravelまたは&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Flask&lt;/a&gt;または&lt;a href=&quot;/tutorials/blog-scratch/&quot;&gt;スクラッチから&lt;/a&gt;）- CRUD操作とコンテンツ管理をマスター&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-laravel/&quot;&gt;Eコマースを構築&lt;/a&gt;&lt;/strong&gt;（Laravelまたは&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Flask&lt;/a&gt;または&lt;a href=&quot;/tutorials/shopping-scratch/&quot;&gt;スクラッチから&lt;/a&gt;）- 複雑なビジネスロジックと決済統合を学ぶ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;各チュートリアルパスには、本番対応のアプリケーションを構築するためのAI支援プロンプトが含まれています。欲しい仕事に合ったスタックを選び、雇用主に見せられるものを構築してください。&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Napraw bledy SSL subdomeny www na Fly.io z Cloudflare (Blad 525)]]></title><description><![CDATA[Dostajesz blad 525 przy dostepe do www.twojastrona.com na Fly.io? Oto jak naprawic blad SSL handshake dodajac oddzielne certyfikaty dla subdomen www - kluczowy krok ktory wiekszosc przewodnikow wdrazania pomija.]]></description><link>https://vibecodingwithfred.com/pl/blog/flyio-cloudflare-www-setup/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pl/blog/flyio-cloudflare-www-setup/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 19 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Wdrozyles aplikacje na Fly.io i domena glowna dziala dobrze, ale &lt;code class=&quot;language-text&quot;&gt;www.twojastrona.com&lt;/code&gt; wyrzuca blad SSL handshake? Nie jestes sam. Ten blad 525 wystepuje bo Fly.io wymaga &lt;strong&gt;oddzielnych certyfikatow SSL dla kazdej nazwy hosta&lt;/strong&gt; - i wiekszosc przewodnikow wdrazania calkowicie pomija ten krok.&lt;/p&gt;
&lt;p&gt;Oto naprawa, przetestowana i zweryfikowana na produkcyjnym wdrozeniu.&lt;/p&gt;
&lt;h2 id=&quot;problem&quot;&gt;Problem&lt;/h2&gt;
&lt;p&gt;Wdrozyles na Fly.io, dodales wlasna domene i wszystko wyglada dobrze. Potem probusjesz wejsc na &lt;code class=&quot;language-text&quot;&gt;www.twojastrona.com&lt;/code&gt; i dostajesz:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Error 525: SSL handshake failed&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Tymczasem &lt;code class=&quot;language-text&quot;&gt;twojastrona.com&lt;/code&gt; (bez www) dziala dobrze. O co chodzi?&lt;/p&gt;
&lt;h2 id=&quot;dlaczego-to-sie-dzieje&quot;&gt;Dlaczego to sie dzieje&lt;/h2&gt;
&lt;p&gt;Fly.io uzywa Let&apos;s Encrypt do przydzielania certyfikatow SSL, ale jest haczyk: &lt;strong&gt;dodanie certyfikatu dla &lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt; NIE pokrywa automatycznie &lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Sa traktowane jako calkowicie oddzielne nazwy hostow. Musisz jawnie dodac certyfikat dla subdomeny &lt;a href=&quot;http://www&quot;&gt;www&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;rozwiazanie-5-krokow&quot;&gt;Rozwiazanie (5 krokow)&lt;/h2&gt;
&lt;h3 id=&quot;krok-1-zainstaluj-flyio-cli&quot;&gt;Krok 1: Zainstaluj Fly.io CLI&lt;/h3&gt;
&lt;p&gt;Jesli jeszcze tego nie zrobiles, zainstaluj flyctl:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Zainstaluj flyctl&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Dodaj do PATH&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;FLYCTL_INSTALL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/.fly&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;PATH&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$FLYCTL_INSTALL&lt;/span&gt;/bin:&lt;span class=&quot;token environment constant&quot;&gt;$PATH&lt;/span&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Zrob to trwaym (dodaj do ~/.bashrc lub ~/.zshrc)&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export FLYCTL_INSTALL=&quot;$HOME/.fly&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export PATH=&quot;$FLYCTL_INSTALL/bin:$PATH&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc

&lt;span class=&quot;token comment&quot;&gt;# Zweryfikuj ze dziala&lt;/span&gt;
flyctl version&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;krok-2-sprawdz-swoje-aktualne-certyfikaty&quot;&gt;Krok 2: Sprawdz swoje aktualne certyfikaty&lt;/h3&gt;
&lt;p&gt;Najpierw zobacz jakie certyfikaty juz masz:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; NAZWA_TWOJEJ_APP&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Prawdopodobnie zobaczysz cos takiego:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Host Name                 Added                Status
example.com              1 month ago          Ready
api.example.com          1 month ago          Ready&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Zauwazyłes co brakuje? Subdomena &lt;code class=&quot;language-text&quot;&gt;www&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;krok-3-dodaj-certyfikat-www-to-naprawia-problem&quot;&gt;Krok 3: Dodaj certyfikat www (To naprawia problem)&lt;/h3&gt;
&lt;p&gt;Oto krytyczne polecenie ktore rozwiazuje problem:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; NAZWA_TWOJEJ_APP&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fly.io automatycznie przydzieli certyfikat SSL Let&apos;s Encrypt dla twojej subdomeny &lt;a href=&quot;http://www&quot;&gt;www&lt;/a&gt;. Zobaczysz wyjscie takie jak:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;You are creating a certificate for www.example.com
We are using Let&apos;s Encrypt for this certificate.

Your certificate for www.example.com is being issued.
You can validate your ownership of www.example.com by:

1: Adding an AAAA record to your DNS service which reads:
    AAAA @ 2a09:8280:1::X:XXXX&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Nie martw sie o walidacje DNS - jesli twoja domena glowna juz dziala, subdomena www zwaliduje sie automatycznie.&lt;/p&gt;
&lt;h3 id=&quot;krok-4-zweryfikuj-ze-certyfikat-jest-gotowy&quot;&gt;Krok 4: Zweryfikuj ze certyfikat jest gotowy&lt;/h3&gt;
&lt;p&gt;Poczekaj 1-2 minuty, potem sprawdz status certyfikatu:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs show www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; NAZWA_TWOJEJ_APP&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Szukaj &lt;strong&gt;&quot;Status: Ready&quot;&lt;/strong&gt;. Jesli mowi &quot;Awaiting certificates&quot;, poczekaj jeszcze minute i sprawdz ponownie.&lt;/p&gt;
&lt;p&gt;Gdy gotowe, twoja lista certyfikatow powinna pokazywac:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; NAZWA_TWOJEJ_APP&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Host Name                 Added                Status
example.com              1 month ago          Ready
www.example.com          13 seconds ago       Ready&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Idealnie.&lt;/p&gt;
&lt;h3 id=&quot;krok-5-skonfiguruj-tryb-ssltls-cloudflare&quot;&gt;Krok 5: Skonfiguruj tryb SSL/TLS Cloudflare&lt;/h3&gt;
&lt;p&gt;Ten krok jest krytyczny jesli uzywasz Cloudflare do DNS (a powinienes).&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Zaloguj sie do dashboardu Cloudflare&lt;/li&gt;
&lt;li&gt;Wybierz swoja domene&lt;/li&gt;
&lt;li&gt;Wejdz w &lt;strong&gt;SSL/TLS&lt;/strong&gt; → &lt;strong&gt;Overview&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Ustaw tryb szyfrowania na &lt;strong&gt;&quot;Full&quot;&lt;/strong&gt; (nie &quot;Flexible&quot; ani &quot;Full (strict)&quot;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Dlaczego &quot;Full&quot;?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Flexible&lt;/strong&gt;: Cloudflare uzywa HTTPS do odwiedzajacych, ale HTTP do Fly.io (niebezpieczne, powoduje problemy)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Full&lt;/strong&gt;: Cloudflare uzywa HTTPS zarowno do odwiedzajacych jak i Fly.io (prawidlowo)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Full (strict)&lt;/strong&gt;: Wymaga zaufanego urzedu certyfikacji, ale Fly.io zarzadza wlasnymi certyfikatami (powoduje bledy)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;skonfiguruj-rekordy-dns-cloudflare&quot;&gt;Skonfiguruj rekordy DNS (Cloudflare)&lt;/h2&gt;
&lt;p&gt;Upewnij sie ze rekordy DNS sa prawidlowo skonfigurowane:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Domena glowna (&lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt;):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Typ&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;A&lt;/code&gt; lub &lt;code class=&quot;language-text&quot;&gt;AAAA&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nazwa&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;@&lt;/code&gt; (lub zostaw puste)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zawartosc&lt;/strong&gt;: Adres IP twojego Fly.io (z &lt;code class=&quot;language-text&quot;&gt;flyctl ips list&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Status proxy&lt;/strong&gt;: &lt;strong&gt;Proxied&lt;/strong&gt; (pomaranczowa chmurka wlaczona)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Subdomena www (&lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt;):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Typ&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;CNAME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nazwa&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;www&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cel&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt; (wskazuje na domene glowna)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Status proxy&lt;/strong&gt;: &lt;strong&gt;Proxied&lt;/strong&gt; (pomaranczowa chmurka wlaczona)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pomaranczowa chmurka (Proxied) jest wazna - kieruje ruch przez CDN Cloudflare i wlacza SSL.&lt;/p&gt;
&lt;h2 id=&quot;przetestuj-wszystko&quot;&gt;Przetestuj wszystko&lt;/h2&gt;
&lt;p&gt;Zweryfikuj ze obie domeny dzialaja:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Testuj domene glowna&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; https://example.com

&lt;span class=&quot;token comment&quot;&gt;# Testuj subdomene www&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; https://www.example.com&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Obie powinny zwrocic &lt;code class=&quot;language-text&quot;&gt;HTTP/2 200&lt;/code&gt; (lub &lt;code class=&quot;language-text&quot;&gt;HTTP/1.1 200&lt;/code&gt;). Jesli dostajesz bledy, zobacz sekcje rozwiazywania problemow ponizej.&lt;/p&gt;
&lt;h2 id=&quot;typowe-bledy-i-naprawy&quot;&gt;Typowe bledy i naprawy&lt;/h2&gt;
&lt;h3 id=&quot;blad-525-ssl-handshake-failed&quot;&gt;Blad 525: SSL Handshake Failed&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Objawy&lt;/strong&gt;: subdomena www wyrzuca blad 525, domena glowna dziala dobrze&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Przyczyny&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Brakujacy certyfikat www na Fly.io&lt;/li&gt;
&lt;li&gt;Tryb SSL/TLS Cloudflare ustawiony na &quot;Flexible&quot; lub &quot;Full (strict)&quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Naprawa&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Dodaj certyfikat www&lt;/span&gt;
flyctl certs &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; NAZWA_TWOJEJ_APP

&lt;span class=&quot;token comment&quot;&gt;# Poczekaj 2 minuty na wydanie certyfikatu&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sleep&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;120&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Zweryfikuj ze jest gotowy&lt;/span&gt;
flyctl certs show www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; NAZWA_TWOJEJ_APP&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Rowniez zweryfikuj ze tryb SSL/TLS Cloudflare jest ustawiony na &lt;strong&gt;&quot;Full&quot;&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;subdomena-www-zwraca-connection-timeout&quot;&gt;Subdomena www zwraca Connection Timeout&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Objawy&lt;/strong&gt;: subdomena www w ogole sie nie laduje, brak strony bledu&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Przyczyny&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Brakujacy lub nieprawidlowy rekord DNS CNAME&lt;/li&gt;
&lt;li&gt;DNS nie jest proxy przez Cloudflare&lt;/li&gt;
&lt;li&gt;Propagacja DNS niekompletna&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Naprawa&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Sprawdz ustawienia DNS Cloudflare dla rekordu CNAME www&lt;/li&gt;
&lt;li&gt;Upewnij sie ze pomaranczowa chmurka (Proxied) jest wlaczona&lt;/li&gt;
&lt;li&gt;Poczekaj 5-15 minut na propagacje DNS&lt;/li&gt;
&lt;li&gt;Wyczysc cache przegladarki lub testuj w trybie incognito&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;certyfikat-pokazuje-awaiting-certificates-przez-wiecej-niz-5-minut&quot;&gt;Certyfikat pokazuje &quot;Awaiting Certificates&quot; przez wiecej niz 5 minut&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Objawy&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;flyctl certs show&lt;/code&gt; ciagle mowi &quot;Awaiting certificates&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Przyczyny&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Rekordy DNS nie wskazuja prawidlowo na Fly.io&lt;/li&gt;
&lt;li&gt;Proxy Cloudflare ingeruje w walidacje certyfikatu&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Naprawa&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Zweryfikuj ze rekordy DNS sa prawidlowe&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; www.example.com

&lt;span class=&quot;token comment&quot;&gt;# Sprawdz czy DNS rozwiazuje sie do Fly.io&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;nslookup&lt;/span&gt; www.example.com

&lt;span class=&quot;token comment&quot;&gt;# Jesli zablokowany, usun i ponownie dodaj certyfikat&lt;/span&gt;
flyctl certs delete www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; NAZWA_TWOJEJ_APP
flyctl certs &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; NAZWA_TWOJEJ_APP&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;dlaczego-oddzielne-certyfikaty-maja-znaczenie&quot;&gt;Dlaczego oddzielne certyfikaty maja znaczenie&lt;/h2&gt;
&lt;p&gt;W tradycyjnym hostingu wspoldzielonym, certyfikat SSL typu wildcard (*.example.com) pokrywa wszystkie subdomeny. Ale Fly.io przydziela certyfikaty indywidualnie przez Let&apos;s Encrypt.&lt;/p&gt;
&lt;p&gt;To daje ci wieksza kontrole ale wymaga jawnej konfiguracji dla kazdej subdomeny:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt; → potrzebuje wlasnego certyfikatu&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt; → potrzebuje wlasnego certyfikatu&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;api.example.com&lt;/code&gt; → potrzebuje wlasnego certyfikatu&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;blog.example.com&lt;/code&gt; → potrzebuje wlasnego certyfikatu&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rozumiesz idee.&lt;/p&gt;
&lt;h2 id=&quot;najlepsze-praktyki-dla-flyio--cloudflare&quot;&gt;Najlepsze praktyki dla Fly.io + Cloudflare&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Dodaj certyfikaty dla wszystkich subdomen ktore planujesz uzywac&lt;/strong&gt; zanim pojdziesz na zywo&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Uzyj trybu &quot;Full&quot; SSL/TLS Cloudflare&lt;/strong&gt; dla wdrozen Fly.io&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wlacz proxy Cloudflare&lt;/strong&gt; (pomaranczowa chmurka) dla CDN i ochrony DDoS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Testuj zarowno www jak i bez www&lt;/strong&gt; wersje zanim oglszisz strone&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skonfiguruj przekierowania&lt;/strong&gt; w aplikacji jesli chcesz wymusic jedna wersje nad druga&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;uzyteczne-polecenia-do-rozwiazywania-problemow&quot;&gt;Uzyteczne polecenia do rozwiazywania problemow&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Lista wszystkich certyfikatow dla aplikacji&lt;/span&gt;
flyctl certs list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; NAZWA_TWOJEJ_APP

&lt;span class=&quot;token comment&quot;&gt;# Pokaz szczegolowe info dla konkretnego certyfikatu&lt;/span&gt;
flyctl certs show www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; NAZWA_TWOJEJ_APP

&lt;span class=&quot;token comment&quot;&gt;# Usun certyfikat (jesli musisz zaczac od nowa)&lt;/span&gt;
flyctl certs delete www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; NAZWA_TWOJEJ_APP

&lt;span class=&quot;token comment&quot;&gt;# Sprawdz adresy IP aplikacji&lt;/span&gt;
flyctl ips list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; NAZWA_TWOJEJ_APP

&lt;span class=&quot;token comment&quot;&gt;# Sprawdz rozwiazywanie DNS&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; example.com
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; www.example.com

&lt;span class=&quot;token comment&quot;&gt;# Testuj polaczenie SSL z szczegolowym wyjsciem&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-vI&lt;/span&gt; https://www.example.com

&lt;span class=&quot;token comment&quot;&gt;# Sprawdz status aplikacji&lt;/span&gt;
flyctl status &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; NAZWA_TWOJEJ_APP

&lt;span class=&quot;token comment&quot;&gt;# Pokaz logi aplikacji (uzyteczne do debugowania)&lt;/span&gt;
flyctl logs &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; NAZWA_TWOJEJ_APP&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;kompletna-lista-kontrolna-konfiguracji&quot;&gt;Kompletna lista kontrolna konfiguracji&lt;/h2&gt;
&lt;p&gt;Uzyj tej listy kontrolnej zeby zweryfikowac ze wszystko jest prawidlowo skonfigurowane:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Certyfikaty Fly.io:&lt;/strong&gt;&lt;/p&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Certyfikat domeny glownej istnieje i pokazuje &quot;Ready&quot;&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Certyfikat subdomeny www istnieje i pokazuje &quot;Ready&quot;&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Wszystkie inne subdomeny maja dodane certyfikaty&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare DNS:&lt;/strong&gt;&lt;/p&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Rekord A lub AAAA dla domeny glownej wskazujacy na IP Fly.io&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Rekord CNAME dla subdomeny www wskazujacy na domene glowna&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Wszystkie rekordy maja wlaczona pomaranczowa chmurke (Proxied)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare SSL/TLS:&lt;/strong&gt;&lt;/p&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Tryb szyfrowania ustawiony na &quot;Full&quot; (nie Flexible ani Full strict)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Edge Certificates pokazuje wazny SSL&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Testowanie:&lt;/strong&gt;&lt;/p&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;code class=&quot;language-text&quot;&gt;https://example.com&lt;/code&gt; zwraca 200 OK&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;code class=&quot;language-text&quot;&gt;https://www.example.com&lt;/code&gt; zwraca 200 OK&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Brak ostrzezen SSL w przegladarce&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Obie domeny pokazuja ikone bezpiecznego zamka&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;dlaczego-wiekszosc-przewodnikow-to-pomija&quot;&gt;Dlaczego wiekszosc przewodnikow to pomija&lt;/h2&gt;
&lt;p&gt;Wiekszosc samouczkow wdrazania Fly.io skupia sie na uruchomieniu aplikacji i dodaniu pojedynczej wlasnej domeny. Zakladaja ze bedziesz uzywac tylko &lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt; lub &lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt; - nie obu.&lt;/p&gt;
&lt;p&gt;Ale w rzeczywistosci uzytkownicy wpisuja obie wersje. Wyszukiwarki indeksuja obie. I nie chcesz zeby polowa twojego ruchu trafiala na bledy SSL.&lt;/p&gt;
&lt;p&gt;Dodanie certyfikatu www zajmuje 30 sekund ale oszczedza godziny debugowania pozniej.&lt;/p&gt;
&lt;h2 id=&quot;podsumowanie&quot;&gt;Podsumowanie&lt;/h2&gt;
&lt;p&gt;Problem SSL subdomeny www na Fly.io to jeden z tych &quot;gotchas&quot; ktory lapie nawet doswiadczonych programistow. Naprawa jest prosta gdy ja znasz:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Dodaj oddzielny certyfikat dla www: &lt;code class=&quot;language-text&quot;&gt;flyctl certs add www.example.com -a NAZWA_TWOJEJ_APP&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Ustaw Cloudflare SSL/TLS na tryb &quot;Full&quot;&lt;/li&gt;
&lt;li&gt;Poczekaj 1-2 minuty az certyfikat bedzie gotowy&lt;/li&gt;
&lt;li&gt;Przetestuj obie domeny&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To wszystko. Bez skomplikowanej konfiguracji, bez restartow serwera, bez edytowania plikow konfiguracyjnych. Tylko jedno polecenie ktore wiekszosc przewodnikow wdrazania zapomina wspomniec.&lt;/p&gt;
&lt;p&gt;Teraz twoi uzytkownicy moga wchodzic na strone z lub bez www i obie beda dzialac prawidlowo.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Powiazane przewodniki:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;Kompletny przewodnik: Wdrazanie projektow Lovable na Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/deploy-claude-code-cloudflare&quot;&gt;Wdroz aplikacje Claude Code &amp;#x26; Codex na Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/cloudflare-workers-deployment&quot;&gt;Przewodnik wdrazania Cloudflare Workers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Zasoby:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://fly.io/docs/networking/custom-domain/&quot;&gt;Dokumentacja Custom Domains Fly.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/ssl/&quot;&gt;Ustawienia SSL/TLS Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://letsencrypt.org/&quot;&gt;Let&apos;s Encrypt Certificate Authority&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Czego 15 lat kodowania nauczylo mnie o utrzymaniu zdrowia (i rozumu)]]></title><description><![CDATA[Pietnascie lat w karierze programisty nauczylo mnie, ze utrzymanie produktywnosci to nie tylko lepsze algorytmy - to nie niszczenie swojego ciala w tym procesie. Oto co sie liczy.]]></description><link>https://vibecodingwithfred.com/pl/blog/webdev-career-reality-check-2025/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pl/blog/webdev-career-reality-check-2025/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 19 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Pisze to przy biurku stojacym o 14:00 we wtorek, po 25-minutowym spacerze wokol bloku. Pietnascie lat temu, gdy harowalem przy pierwszej prawdziwej pracy programistycznej, wydaloby mi sie to smieszne. Zrobic przerwe? W srodku dnia? Kiedy jest kod do wyslania?&lt;/p&gt;
&lt;p&gt;Tak, dawny ja byl idiota.&lt;/p&gt;
&lt;p&gt;Pietnascie lat w tej karierze nauczylo mnie czegos, czego nikt ci nie mowi na bootcampie czy studiach informatycznych: najwiekszym zagrozeniem dla twojego dlugoterminowego sukcesu jako programisty nie jest rynek pracy, nauka zlego frameworka ani nawet syndrom oszusta.&lt;/p&gt;
&lt;p&gt;To co te wszystkie godziny na krzeble robia z twoim cialem.&lt;/p&gt;
&lt;h2 id=&quot;sygnaly-ostrzegawcze&quot;&gt;Sygnaly ostrzegawcze&lt;/h2&gt;
&lt;p&gt;Rok siodmy to moment gdy moje cialo wystawilo mi rachunek.&lt;/p&gt;
&lt;p&gt;Mialem od czasu do czasu bol plecow, ale go ignorowalem. Programisci siedza caly dzien - oczywiscie ze czasem bola plecy, prawda? Potem pewnego ranka wstalem z biurka i kregoslup ledzwiowy zablokoval mi sie tak bardzo, ze nie moglem sie wyprostowac. Nastepne trzy dni spedzalem przewaznie poziomo, lykajac ibuprofen i zastanawiajac sie czy to teraz moje zycie.&lt;/p&gt;
&lt;p&gt;To byl moj dzwonek alarmowy. Mialem 30 lat i poruszalem sie jakbym mial 60.&lt;/p&gt;
&lt;h2 id=&quot;trzy-filary&quot;&gt;Trzy filary&lt;/h2&gt;
&lt;p&gt;Zrownowazony rozwoj oprogramowania mysle jako stolek na trzech nogach:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Ergonomia&lt;/strong&gt; - Twoja podstawa. Odpowiednie krzeslo, biurko i stanowisko zmniejszaja bazowe obciazenie ciala.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ruch&lt;/strong&gt; - Regularne przerwy i zmiany pozycji nie pozwalaja cialu sie zablokowac w ciagu dnia pracy.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cwiczenia&lt;/strong&gt; - Budowanie sily i mobilnosci poza praca daje cialu odpornosc na wszystko to siedzenie.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Usun ktarakolwiek noge i stolek sie przewraca.&lt;/p&gt;
&lt;h2 id=&quot;co-bym-powiedzial-mlodszemu-sobie&quot;&gt;Co bym powiedzial mlodszemu sobie&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Zainwestuj w stanowisko od poczatku&lt;/strong&gt;: Nie czekaj az beda cie bolec plecy zeby kupic dobre krzeslo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wbuduj ruch w rutyne natychmiast&lt;/strong&gt;: 50 minut pracy, 10 minut ruchu. Niezbywalne.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cwicz jakby to byla czesc pracy&lt;/strong&gt;: Bo jest. Wpisz to do kalendarza.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zadnych maratonow kodowania&lt;/strong&gt;: To nie odznaka honoru. To kontuzja w zwolnionym tempie.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bol to informacja&lt;/strong&gt;: Jesli cos boli, zajmij sie tym natychmiast.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Masz tylko jedno cialo&lt;/strong&gt;: Nie ma opcji &quot;zmien kariere pozniej jesli to nie wypali&quot; jesli chodzi o zdrowie fizyczne.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;podsumowanie&quot;&gt;Podsumowanie&lt;/h2&gt;
&lt;p&gt;Mozesz miec dluga, zdrowa, produktywna kariere w programowaniu. Praca nadal jest intelektualnie angazujaca, zarobki nadal dobre, a elastycznosc lepsza niz w wiekszosci zawodow.&lt;/p&gt;
&lt;p&gt;Ale wymaga to traktowania zdrowia fizycznego z taka sama intencjonalnoscia jak rozwoju zawodowego. Badasz frameworki, uczysz sie nowych jezykow, sledzisz trendy branzy. Musisz wniesc te sama energie do dbania o cialo.&lt;/p&gt;
&lt;p&gt;Bo oto czego nikt ci nie mowi w szumie &quot;naucz sie kodowac&quot;: twoja kariera nie jest ograniczona umiejetnosciami technicznymi ani rynkiem pracy ani AI ani niczym takim. Twoja kariera jest ograniczona tym jak dlugo twoje cialo da rade siedziec na krzeble.&lt;/p&gt;
&lt;p&gt;Spraw zeby to bylo dlugo. Zainwestuj w odpowiednie stanowisko, ruszaj sie regularnie, cwicz konsekwentnie i buduj zrownowazone nawyki od poczatku.&lt;/p&gt;
&lt;p&gt;Twoje ja za 15 lat juz ci dziekuje.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[修复 Fly.io www 子域名 SSL 错误与 Cloudflare（Error 525）]]></title><description><![CDATA[访问 Fly.io 上的 www.yoursite.com 时出现 Error 525？这里是如何通过为 www 子域名添加单独证书来修复 SSL 握手错误——这是大多数部署指南跳过的关键步骤。]]></description><link>https://vibecodingwithfred.com/zh/blog/flyio-cloudflare-www-setup/</link><guid isPermaLink="false">https://vibecodingwithfred.com/zh/blog/flyio-cloudflare-www-setup/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 19 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;将应用部署到 Fly.io 后根域名工作正常，但 &lt;code class=&quot;language-text&quot;&gt;www.yoursite.com&lt;/code&gt; 抛出 SSL 握手错误？你不是一个人。这个 Error 525 发生是因为 Fly.io 需要&lt;strong&gt;为每个主机名单独的 SSL 证书&lt;/strong&gt;——大多数部署指南完全跳过这一步。&lt;/p&gt;
&lt;p&gt;以下是修复方法，已在生产部署中测试和验证。&lt;/p&gt;
&lt;h2 id=&quot;问题&quot;&gt;问题&lt;/h2&gt;
&lt;p&gt;你已经部署到 Fly.io，添加了自定义域名，一切看起来都很好。然后你尝试访问 &lt;code class=&quot;language-text&quot;&gt;www.yoursite.com&lt;/code&gt; 并得到：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Error 525: SSL handshake failed&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;与此同时，&lt;code class=&quot;language-text&quot;&gt;yoursite.com&lt;/code&gt;（没有 www）工作正常。怎么回事？&lt;/p&gt;
&lt;h2 id=&quot;为什么会发生这种情况&quot;&gt;为什么会发生这种情况&lt;/h2&gt;
&lt;p&gt;Fly.io 使用 Let&apos;s Encrypt 提供 SSL 证书，但这里有个问题：&lt;strong&gt;为 &lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt; 添加证书不会自动覆盖 &lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt;&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;它们被视为完全独立的主机名。你需要明确为 www 子域名添加证书。&lt;/p&gt;
&lt;h2 id=&quot;解决方案5-步&quot;&gt;解决方案（5 步）&lt;/h2&gt;
&lt;h3 id=&quot;步骤-1安装-flyio-cli&quot;&gt;步骤 1：安装 Fly.io CLI&lt;/h3&gt;
&lt;p&gt;如果你还没有，安装 flyctl：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 安装 flyctl&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 添加到 PATH&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;FLYCTL_INSTALL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/.fly&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;PATH&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$FLYCTL_INSTALL&lt;/span&gt;/bin:&lt;span class=&quot;token environment constant&quot;&gt;$PATH&lt;/span&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 使其永久生效（添加到 ~/.bashrc 或 ~/.zshrc）&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export FLYCTL_INSTALL=&quot;$HOME/.fly&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;export PATH=&quot;$FLYCTL_INSTALL/bin:$PATH&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc

&lt;span class=&quot;token comment&quot;&gt;# 验证是否工作&lt;/span&gt;
flyctl version&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;步骤-2检查你当前的证书&quot;&gt;步骤 2：检查你当前的证书&lt;/h3&gt;
&lt;p&gt;首先，查看你已有的证书：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;你可能会看到类似这样的内容：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Host Name                 Added                Status
example.com              1 month ago          Ready
api.example.com          1 month ago          Ready&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;注意到缺少什么了吗？&lt;code class=&quot;language-text&quot;&gt;www&lt;/code&gt; 子域名。&lt;/p&gt;
&lt;h3 id=&quot;步骤-3添加-www-证书这解决了问题&quot;&gt;步骤 3：添加 www 证书（这解决了问题）&lt;/h3&gt;
&lt;p&gt;这是解决问题的关键命令：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fly.io 将自动为你的 www 子域名提供 Let&apos;s Encrypt SSL 证书。你会看到类似这样的输出：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;You are creating a certificate for www.example.com
We are using Let&apos;s Encrypt for this certificate.

Your certificate for www.example.com is being issued.
You can validate your ownership of www.example.com by:

1: Adding an AAAA record to your DNS service which reads:
    AAAA @ 2a09:8280:1::X:XXXX&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;不用担心 DNS 验证——如果你的根域名已经在工作，www 子域名将自动验证。&lt;/p&gt;
&lt;h3 id=&quot;步骤-4验证证书已准备好&quot;&gt;步骤 4：验证证书已准备好&lt;/h3&gt;
&lt;p&gt;等待 1-2 分钟，然后检查证书状态：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs show www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;查找 &lt;strong&gt;&quot;Status: Ready&quot;&lt;/strong&gt;。如果它显示&quot;Awaiting certificates&quot;，再等一分钟然后再次检查。&lt;/p&gt;
&lt;p&gt;一旦准备好，你的证书列表应该显示：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl certs list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Host Name                 Added                Status
example.com              1 month ago          Ready
www.example.com          13 seconds ago       Ready&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;完美。&lt;/p&gt;
&lt;h3 id=&quot;步骤-5配置-cloudflare-ssltls-模式&quot;&gt;步骤 5：配置 Cloudflare SSL/TLS 模式&lt;/h3&gt;
&lt;p&gt;如果你使用 Cloudflare 进行 DNS（你应该这样做），这一步至关重要。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;登录你的 Cloudflare 仪表板&lt;/li&gt;
&lt;li&gt;选择你的域名&lt;/li&gt;
&lt;li&gt;前往 &lt;strong&gt;SSL/TLS&lt;/strong&gt; → &lt;strong&gt;概述&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;将加密模式设置为 &lt;strong&gt;&quot;完全&quot;&lt;/strong&gt;（不是&quot;灵活&quot;或&quot;完全（严格）&quot;）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;为什么选择&quot;完全&quot;？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;灵活&lt;/strong&gt;：Cloudflare 对访客使用 HTTPS，但对 Fly.io 使用 HTTP（不安全，会导致问题）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;完全&lt;/strong&gt;：Cloudflare 对访客和 Fly.io 都使用 HTTPS（正确）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;完全（严格）&lt;/strong&gt;：需要受信任的证书颁发机构，但 Fly.io 管理自己的证书（会导致错误）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;配置你的-dns-记录cloudflare&quot;&gt;配置你的 DNS 记录（Cloudflare）&lt;/h2&gt;
&lt;p&gt;确保你的 DNS 记录设置正确：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;根域名 (&lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt;)：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;类型&lt;/strong&gt;：&lt;code class=&quot;language-text&quot;&gt;A&lt;/code&gt; 或 &lt;code class=&quot;language-text&quot;&gt;AAAA&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;名称&lt;/strong&gt;：&lt;code class=&quot;language-text&quot;&gt;@&lt;/code&gt;（或留空）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内容&lt;/strong&gt;：你的 Fly.io IP 地址（来自 &lt;code class=&quot;language-text&quot;&gt;flyctl ips list&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;代理状态&lt;/strong&gt;：&lt;strong&gt;已代理&lt;/strong&gt;（橙色云启用）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;www 子域名 (&lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt;)：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;类型&lt;/strong&gt;：&lt;code class=&quot;language-text&quot;&gt;CNAME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;名称&lt;/strong&gt;：&lt;code class=&quot;language-text&quot;&gt;www&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;目标&lt;/strong&gt;：&lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt;（指向根域名）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;代理状态&lt;/strong&gt;：&lt;strong&gt;已代理&lt;/strong&gt;（橙色云启用）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;橙色云（已代理）很重要——它通过 Cloudflare 的 CDN 路由流量并启用 SSL。&lt;/p&gt;
&lt;h2 id=&quot;测试一切&quot;&gt;测试一切&lt;/h2&gt;
&lt;p&gt;验证两个域名都工作：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 测试根域名&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; https://example.com

&lt;span class=&quot;token comment&quot;&gt;# 测试 www 子域名&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; https://www.example.com&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;两者都应该返回 &lt;code class=&quot;language-text&quot;&gt;HTTP/2 200&lt;/code&gt;（或 &lt;code class=&quot;language-text&quot;&gt;HTTP/1.1 200&lt;/code&gt;）。如果你遇到错误，请参阅下面的故障排除部分。&lt;/p&gt;
&lt;h2 id=&quot;常见错误和修复&quot;&gt;常见错误和修复&lt;/h2&gt;
&lt;h3 id=&quot;error-525ssl-握手失败&quot;&gt;Error 525：SSL 握手失败&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;症状&lt;/strong&gt;：www 子域名抛出 Error 525，根域名工作正常&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;原因&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Fly.io 上缺少 www 证书&lt;/li&gt;
&lt;li&gt;Cloudflare SSL/TLS 模式设置为&quot;灵活&quot;或&quot;完全（严格）&quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;修复&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 添加 www 证书&lt;/span&gt;
flyctl certs &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME

&lt;span class=&quot;token comment&quot;&gt;# 等待 2 分钟让证书颁发&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sleep&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;120&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 验证是否准备好&lt;/span&gt;
flyctl certs show www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;还要验证 Cloudflare SSL/TLS 模式设置为 &lt;strong&gt;&quot;完全&quot;&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id=&quot;www-子域名返回连接超时&quot;&gt;www 子域名返回连接超时&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;症状&lt;/strong&gt;：www 子域名根本不加载，没有错误页面&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;原因&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;DNS CNAME 记录缺失或不正确&lt;/li&gt;
&lt;li&gt;DNS 未通过 Cloudflare 代理&lt;/li&gt;
&lt;li&gt;DNS 传播未完成&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;修复&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;检查 Cloudflare DNS 设置中的 www CNAME 记录&lt;/li&gt;
&lt;li&gt;确保橙色云（已代理）已启用&lt;/li&gt;
&lt;li&gt;等待 5-15 分钟让 DNS 传播&lt;/li&gt;
&lt;li&gt;清除浏览器缓存或在隐身模式下测试&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;证书显示awaiting-certificates超过-5-分钟&quot;&gt;证书显示&quot;Awaiting Certificates&quot;超过 5 分钟&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;症状&lt;/strong&gt;：&lt;code class=&quot;language-text&quot;&gt;flyctl certs show&lt;/code&gt; 一直显示&quot;Awaiting certificates&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;原因&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;DNS 记录未正确指向 Fly.io&lt;/li&gt;
&lt;li&gt;Cloudflare 代理干扰证书验证&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;修复&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 验证你的 DNS 记录正确&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; www.example.com

&lt;span class=&quot;token comment&quot;&gt;# 检查 DNS 是否解析到 Fly.io&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;nslookup&lt;/span&gt; www.example.com

&lt;span class=&quot;token comment&quot;&gt;# 如果卡住，删除并重新添加证书&lt;/span&gt;
flyctl certs delete www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME
flyctl certs &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;为什么单独的证书很重要&quot;&gt;为什么单独的证书很重要&lt;/h2&gt;
&lt;p&gt;在传统的共享托管中，通配符 SSL 证书（*.example.com）覆盖所有子域名。但 Fly.io 通过 Let&apos;s Encrypt 单独提供证书。&lt;/p&gt;
&lt;p&gt;这给你更多控制，但需要为每个子域名明确设置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt; → 需要自己的证书&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt; → 需要自己的证书&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;api.example.com&lt;/code&gt; → 需要自己的证书&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;blog.example.com&lt;/code&gt; → 需要自己的证书&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你明白了。&lt;/p&gt;
&lt;h2 id=&quot;flyio--cloudflare-最佳实践&quot;&gt;Fly.io + Cloudflare 最佳实践&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;在上线前为所有计划使用的子域名添加证书&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;为 Fly.io 部署使用 Cloudflare 的&quot;完全&quot;SSL/TLS 模式&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;启用 Cloudflare 代理&lt;/strong&gt;（橙色云）以获得 CDN 和 DDoS 保护&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在宣布你的网站之前测试 www 和非 www 版本&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;如果你想强制使用一个版本而不是另一个，在你的应用中设置重定向&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;故障排除的有用命令&quot;&gt;故障排除的有用命令&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 列出你应用的所有证书&lt;/span&gt;
flyctl certs list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME

&lt;span class=&quot;token comment&quot;&gt;# 查看特定证书的详细信息&lt;/span&gt;
flyctl certs show www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME

&lt;span class=&quot;token comment&quot;&gt;# 删除证书（如果你需要重新开始）&lt;/span&gt;
flyctl certs delete www.example.com &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME

&lt;span class=&quot;token comment&quot;&gt;# 检查你应用的 IP 地址&lt;/span&gt;
flyctl ips list &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME

&lt;span class=&quot;token comment&quot;&gt;# 检查 DNS 解析&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; example.com
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; www.example.com

&lt;span class=&quot;token comment&quot;&gt;# 使用详细输出测试 SSL 连接&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-vI&lt;/span&gt; https://www.example.com

&lt;span class=&quot;token comment&quot;&gt;# 检查应用状态&lt;/span&gt;
flyctl status &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME

&lt;span class=&quot;token comment&quot;&gt;# 查看应用日志（用于调试）&lt;/span&gt;
flyctl logs &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; YOUR_APP_NAME&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;为什么大多数指南跳过这个&quot;&gt;为什么大多数指南跳过这个&lt;/h2&gt;
&lt;p&gt;大多数 Fly.io 部署教程专注于让你的应用运行并添加单个自定义域名。他们假设你只会使用 &lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt; 或 &lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt;——不是两者都用。&lt;/p&gt;
&lt;p&gt;但实际上，用户会输入两个版本。搜索引擎会索引两者。你不希望一半的流量遇到 SSL 错误。&lt;/p&gt;
&lt;p&gt;添加 www 证书需要 30 秒，但可以节省数小时的后续调试时间。&lt;/p&gt;
&lt;h2 id=&quot;替代方案将-www-重定向到非-www或反之&quot;&gt;替代方案：将 www 重定向到非 www（或反之）&lt;/h2&gt;
&lt;p&gt;如果你不想维护两个版本，你可以在应用中设置重定向。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;选项 1：将 www 重定向到非 www&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;大多数框架都有中间件来实现这个。例如，在 Express.js 中：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hostname&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;www.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;redirect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;301&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;https://&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hostname&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;选项 2：将非 www 重定向到 www&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hostname&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;www.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;redirect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;301&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;https://www.&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hostname&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;但即使你重定向，&lt;strong&gt;你仍然需要两个证书&lt;/strong&gt;，否则重定向不会工作（用户会在你的应用可以重定向他们之前遇到 SSL 错误）。&lt;/p&gt;
&lt;h2 id=&quot;结论&quot;&gt;结论&lt;/h2&gt;
&lt;p&gt;Fly.io www 子域名 SSL 问题是那些即使是有经验的开发者也会遇到的&quot;坑&quot;之一。一旦你知道修复方法就很简单：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;为 www 添加单独的证书：&lt;code class=&quot;language-text&quot;&gt;flyctl certs add www.example.com -a YOUR_APP_NAME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;将 Cloudflare SSL/TLS 设置为&quot;完全&quot;模式&lt;/li&gt;
&lt;li&gt;等待 1-2 分钟让证书准备好&lt;/li&gt;
&lt;li&gt;测试两个域名&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;就这样。没有复杂的配置，没有服务器重启，没有编辑配置文件。只是一个大多数部署指南忘记提到的命令。&lt;/p&gt;
&lt;p&gt;现在你的用户可以使用或不使用 www 访问你的网站，两者都能正常工作。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;相关指南：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;完整指南：将 Lovable 项目部署到 Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/deploy-claude-code-cloudflare&quot;&gt;将 Claude Code &amp;#x26; Codex 应用部署到 Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/cloudflare-workers-deployment&quot;&gt;Cloudflare Workers 部署指南&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;资源：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://fly.io/docs/networking/custom-domain/&quot;&gt;Fly.io 自定义域名文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/ssl/&quot;&gt;Cloudflare SSL/TLS 设置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://letsencrypt.org/&quot;&gt;Let&apos;s Encrypt 证书颁发机构&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[15 年编码教会我关于保持健康（和理智）的事]]></title><description><![CDATA[编码生涯 15 年后，我学到保持高效不仅仅是关于更好的算法——而是不要在这个过程中毁掉你的身体。这里是真正重要的事情。]]></description><link>https://vibecodingwithfred.com/zh/blog/webdev-career-reality-check-2025/</link><guid isPermaLink="false">https://vibecodingwithfred.com/zh/blog/webdev-career-reality-check-2025/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 19 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;我正在下午 2 点站在站立式办公桌前写这篇文章，刚刚绕街区走完 25 分钟。15 年前，当我在第一份真正的开发工作中拼命工作时，这看起来会很荒谬。在一天中间休息？当有代码要发布时？&lt;/p&gt;
&lt;p&gt;是的，过去的我是个傻瓜。&lt;/p&gt;
&lt;p&gt;进入这个职业 15 年后，我学到了训练营或计算机科学课程没人告诉你的事情：作为开发者，你长期成功的最大威胁不是就业市场、学错了框架，甚至不是冒名顶替综合症。&lt;/p&gt;
&lt;p&gt;而是那些坐在椅子上的时间对你身体的影响。&lt;/p&gt;
&lt;p&gt;我曾经是那种把&quot;马拉松编码会议&quot;当作荣誉徽章的开发者。我会连续坐 8-10 个小时，弯腰驼背地趴在笔记本电脑上，靠咖啡和解决复杂问题的快感生活。我很有效率。我在发布功能。我也在慢慢地毁掉自己。&lt;/p&gt;
&lt;p&gt;大约第七年，我的背开始抱怨。不是偶尔的疼痛——而是那种让你站起来时痛得直咧嘴的持续疼痛。到了第十年，我花在物理治疗上的钱比我在课程或会议上花的还多。那时我终于意识到：你可以拥有世界上所有的技术技能，但如果你的身体垮了，这些都不重要。&lt;/p&gt;
&lt;p&gt;以下是我希望有人在第一天就告诉我的事情。&lt;/p&gt;
&lt;h2 id=&quot;就业市场是的现在不一样了&quot;&gt;就业市场（是的，现在不一样了）&lt;/h2&gt;
&lt;p&gt;看，我不会粉饰它。2025 年的就业市场比我刚开始时更有竞争力。&quot;学会编码，保证工作&quot;的日子已经过去了。你正在与数百名申请者竞争那些以前更容易获得的职位。&lt;/p&gt;
&lt;p&gt;但这里是没有变的：编程仍然是建立有意义职业的最易获得的途径之一。你需要一台电脑、互联网接入和愿意付出努力的意愿。不需要六位数的学生贷款，不需要职业学校设备，不需要门槛证书。&lt;/p&gt;
&lt;p&gt;我见过数十名自学开发者进入这个领域并建立了稳固的职业生涯。门槛更高了，是的。但如果你致力于学习（不仅仅是教程地狱），你仍然可以成功。&lt;/p&gt;
&lt;p&gt;也就是说，这篇文章实际上不是关于就业市场的。有上百篇关于那个的帖子。这是关于完全让我措手不及的事情：当你每天在椅子上坐 8-10 个小时时，你的身体会发生什么。&lt;/p&gt;
&lt;h2 id=&quot;警钟&quot;&gt;警钟&lt;/h2&gt;
&lt;p&gt;第七年是我的身体向我发送账单的时候。&lt;/p&gt;
&lt;p&gt;我一直有偶尔的背痛，但我忽略了它。开发者整天坐着——背痛有时候是正常的，对吧？然后有一天早上我从办公桌前站起来，下背部痉挛得太厉害，我无法直立。接下来的三天我基本上是躺着度过的，吃着布洛芬，想知道这是否就是我的生活了。&lt;/p&gt;
&lt;p&gt;那是我的警钟。我 30 岁，动起来像 60 岁。&lt;/p&gt;
&lt;p&gt;我做了任何开发者都会做的事：我彻底研究了这个问题。我和物理治疗师交谈，深入研究人体工程学研究，尝试不同的设置，并与经历过同样事情的其他开发者比较笔记。&lt;/p&gt;
&lt;p&gt;以下是我学到的：预防比修复容易得多。它归结为三个相互关联的事情——人体工程学、运动和与工作建立可持续的关系。&lt;/p&gt;
&lt;h2 id=&quot;人体工程学你不能跳过的基础&quot;&gt;人体工程学：你不能跳过的基础&lt;/h2&gt;
&lt;p&gt;让我说清楚一件事：好的人体工程学不是可选的。它不是你&quot;成功&quot;后才购买的奢侈品。它是可持续开发职业的基础。&lt;/p&gt;
&lt;p&gt;背部事件后，我做的第一件事就是修复我的设置。我是说真正修复它，不仅仅是买一把昂贵的椅子然后期望最好的结果。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;重要的是：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;椅子&lt;/strong&gt;：我投资了一把有适当腰部支撑的高质量办公椅。不是因为拥有 Herman Miller 很酷，而是因为你每年要在这东西上花费 2000 多个小时。这比你在车里或床上的时间还多。我选择了 Steelcase Leap——二手买的 400 美元。八年后，它仍然状况良好。你不需要花 2000 美元，但你确实需要能正确支撑你下背部并适应你身体的东西。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;显示器高度&lt;/strong&gt;：这一点非常重要，而且几乎不花钱。你的显示器应该在眼睛水平——不是下面，不是上面。在眼睛水平。我把我的堆在几本书上。便宜、有效，它停止了我甚至没意识到自己有的颈部疼痛。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;站立式办公桌&lt;/strong&gt;：这改变了我的一切。我在一天中交替站坐。不是因为站着本身更好（不是——整天站着对你也很糟糕），而是因为改变姿势很重要。我选择了 Autonomous 的电动可调节办公桌。物有所值。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;键盘和鼠标&lt;/strong&gt;：如果你开始感到手腕疼痛，不要忽略它。在一些警告性的刺痛后，我换了人体工程学键盘和垂直鼠标。与以后处理腕管综合症相比，两者都是相对便宜的预防措施。&lt;/p&gt;
&lt;p&gt;但问题是：仅靠人体工程学是不够的。它是基础，但你需要在它上面建设。&lt;/p&gt;
&lt;h2 id=&quot;运动方程式的另一半&quot;&gt;运动：方程式的另一半&lt;/h2&gt;
&lt;p&gt;我用艰难的方式学到了这一点。我买了所有的人体工程学装备，对自己感觉相当好，然后继续连续坐 8 小时。我的背仍然疼。&lt;/p&gt;
&lt;p&gt;事实证明，你可以拥有最好的人体工程学设置，但如果你从不运动，你仍然会毁掉自己。你的身体不是设计来静止几个小时的，无论你的姿势多么好。&lt;/p&gt;
&lt;p&gt;有效的方法：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;真正休息&lt;/strong&gt;：我使用改良的番茄工作法——50 分钟工作，10 分钟休息。在那些休息期间，我运动。不是&quot;坐着刷 Twitter&quot;，而是站起来，走动，做些伸展。有时我会做几个俯卧撑或徒手深蹲。一开始感觉很荒谬，但你的背不在乎你的感受。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;定期站立&lt;/strong&gt;：我大约每小时交替坐和站。我现在写这篇文章的时候就是站着的。关键是改变姿势，而不是只是选择一个然后整天坚持。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;步行会议&lt;/strong&gt;：只要可能，我就边走边打电话。这并不总是实际，但当它实际时，我在保持高效的同时获得运动。&lt;/p&gt;
&lt;p&gt;现在，我知道你们有些人在想什么：&quot;但我在心流状态下工作最好！我不能每小时打断深度工作！&quot;&lt;/p&gt;
&lt;p&gt;我理解。我曾经是那种开发者。我会进入状态然后连续编码 4-5 个小时，那些会话感觉非常有效率。它们确实是——在短期内。但它们也在慢慢地伤害我的身体。&lt;/p&gt;
&lt;p&gt;以下是我学到的：你可以拥有心流状态或者长期健康，但如果你唯一的策略是静止地坐几个小时，你不能两者兼得。如果你要进入心流状态（我有时仍然这样做），你需要在工作之外有一个认真的锻炼习惯来补偿。你不能两者兼得而没有后果。&lt;/p&gt;
&lt;h2 id=&quot;锻炼不是可选的它是工作的一部分&quot;&gt;锻炼不是可选的——它是工作的一部分&lt;/h2&gt;
&lt;p&gt;这是最终解决一切的部分：定期锻炼。&lt;/p&gt;
&lt;p&gt;不是&quot;我以后会做&quot;的锻炼。不是&quot;我从车走到办公室&quot;的锻炼。真正的、持续的、把它作为优先事项的锻炼。&lt;/p&gt;
&lt;p&gt;在我的物理治疗师把我背上的结揉开后，她看着我说，&quot;除非你增强力量，否则这会一直发生。你的核心很弱，你的臀肌没有激活，你的背在代偿一切。&quot;&lt;/p&gt;
&lt;p&gt;她是对的。&lt;/p&gt;
&lt;p&gt;我开始每周做两次瑜伽。只是基础课程，没什么花哨的。在两个月内，我的慢性背痛比几个月的被动治疗改善得更多。瑜伽教会了我正确姿势的感觉，并加强了支撑我脊柱的肌肉。&lt;/p&gt;
&lt;p&gt;然后我增加了力量训练——深蹲、硬拉、核心训练。没什么疯狂的，只是每周三次的基础训练。特别是硬拉产生了巨大的差异。当你正确训练你的后链时，你的背就不必做所有支撑你直立的工作了。&lt;/p&gt;
&lt;p&gt;现在，15 年过去了，我每周锻炼 4-5 次。不是因为我是健身爱好者，而是因为这是让我能够继续做我热爱的工作而没有持续疼痛的东西。它和 Git 或我的 IDE 一样是我专业工具包的一部分。&lt;/p&gt;
&lt;p&gt;这是诚实的真相：我和那些坐在沙发上、在有糟糕椅子的咖啡店工作、在床上弯腰驼背地趴在笔记本电脑上的开发者交谈过——他们没事。区别是什么？他们在工作之外都很活跃。他们攀岩，他们跑步，他们举重，他们做瑜伽，他们冲浪。他们定期运动身体并建立力量来补偿所有的坐着。&lt;/p&gt;
&lt;p&gt;与此同时，有昂贵人体工程学设置但零锻炼习惯的开发者是那些 30 多岁就有慢性疼痛的人。&lt;/p&gt;
&lt;h2 id=&quot;三脚凳&quot;&gt;三脚凳&lt;/h2&gt;
&lt;p&gt;把可持续的开发工作想象成一个三脚凳：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;人体工程学&lt;/strong&gt; - 你的基础。正确的椅子、办公桌和设置减少对身体的基本压力。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;运动&lt;/strong&gt; - 定期休息和姿势变化防止你的身体在工作日僵硬。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;锻炼&lt;/strong&gt; - 在工作之外建立力量和灵活性给你的身体韧性来应对所有的坐着。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;移除这些支腿中的任何一个，凳子就会倾倒。我在职业生涯的不同阶段尝试在每一个上省钱时学到了这一点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;很棒的人体工程学 + 没有运动 = 颈部和肩部疼痛&lt;/li&gt;
&lt;li&gt;很棒的人体工程学 + 没有锻炼 = 慢性下背问题&lt;/li&gt;
&lt;li&gt;大量锻炼 + 糟糕的设置 = RSI 和手腕问题&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你需要所有三个。好消息是？一旦你承诺，它们都不是那么难。&lt;/p&gt;
&lt;h2 id=&quot;重要的生活方式因素&quot;&gt;重要的生活方式因素&lt;/h2&gt;
&lt;p&gt;有一些我曾经认为是&quot;养生废话&quot;但结果出奇重要的小因素：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;水&lt;/strong&gt;：我在办公桌上放一个小水瓶。不是因为保持水分是魔法，而是因为它迫使我每天起来重新装几次。这是内置的运动提醒。而且，你知道，水分很重要。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;真正的食物&lt;/strong&gt;：我曾经靠咖啡、能量饮料和最快的东西生活。毫不奇怪，这让我感觉像垃圾。我不打算宣传特定的饮食，但在固定时间吃真正的食物对我的能量水平和专注力产生了明显的差异。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;睡眠时间表&lt;/strong&gt;：在固定时间上床和起床不是性感的建议，但它有效。当我睡眠不足时，我的姿势会崩溃，我对所有事情做出更糟糕的决定——包括是否休息。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;非屏幕爱好&lt;/strong&gt;：这对我来说是个奇怪的事情。我是开发者——当然我的空闲时间也花在屏幕上，对吧？但学习吉他和木工给了我以不同方式使用手和身体的活动。另外，你知道，生活中有代码以外的东西是很好的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;社交联系&lt;/strong&gt;：全职远程工作，我必须有意识地这样做。与朋友定期吃午餐，加入攀岩健身房，打电话而不是只发短信。孤立会让一切变得更糟，包括身体健康。&lt;/p&gt;
&lt;h2 id=&quot;现实检查&quot;&gt;现实检查&lt;/h2&gt;
&lt;p&gt;看，我知道抱怨办公桌工作的背痛听起来可能很特权。有些人做着体力要求很高的劳动一直到 60 多岁，他们很乐意有我的&quot;问题&quot;。&lt;/p&gt;
&lt;p&gt;说得对。但问题是：每份工作都有身体要求。区别在于大多数体力要求高的工作使这些要求很明显。如果你在建筑行业，你知道你的身体是工作的一部分。你穿安全装备，你训练正确的举重技术，你预计会酸痛。&lt;/p&gt;
&lt;p&gt;办公室工作者——特别是开发者——通常不会意识到他们的工作有身体要求，直到损害已经造成。我们把编码看作纯粹的脑力工作，所以我们忽视了每天 8-10 小时保持同一姿势的身体现实。&lt;/p&gt;
&lt;p&gt;这就是我希望得到的警告：这份工作会磨损你的身体。不像建筑或护理或仓库工作那么明显，但它会。与那些工作不同的是，没有人会提醒你保护自己。没有关于正确坐姿休息的 OSHA 法规。&lt;/p&gt;
&lt;h2 id=&quot;真正的风险&quot;&gt;真正的风险&lt;/h2&gt;
&lt;p&gt;风险不仅仅是你可以用布洛芬控制的一些背痛。风险是完全燃尽——不是精神上，而是身体上。&lt;/p&gt;
&lt;p&gt;我认识一些完全离开这个领域的开发者，因为他们找不到可持续的工作方式。他们热爱编码，但他们的身体无法应对久坐的生活方式，他们不知道如何（或不想）改变他们的习惯。&lt;/p&gt;
&lt;p&gt;这是可以预防的。但只有在疼痛开始之前认真对待它，而不是之后。&lt;/p&gt;
&lt;h2 id=&quot;我会对年轻的自己说什么&quot;&gt;我会对年轻的自己说什么&lt;/h2&gt;
&lt;p&gt;如果我能回到我开发职业的第一天，以下是我会说的：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;从一开始就投资你的设置&lt;/strong&gt;：不要等到背痛才买一把好椅子。未来的你会感谢你。正确的人体工程学基础不是奢侈品——它是基础设施。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;立即将运动纳入你的日常&lt;/strong&gt;：不要等着&quot;以后变得更自律&quot;。从 50 分钟工作块和 10 分钟运动休息开始。从第一天就让它不可协商。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;像它是工作的一部分一样锻炼&lt;/strong&gt;：因为它是。把它放在你的日历上。像对待站会或部署一样对待它。你的职业取决于你的身体正常运作。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;不要马拉松编码会议&lt;/strong&gt;：它们不是荣誉徽章。它们是慢动作伤害。你在第八小时写的代码反正也不是那么好。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;疼痛是信息&lt;/strong&gt;：如果某处疼痛，立即处理它。那个小手腕刺痛不会自己消失。如果你忽略它，那个偶尔的背部僵硬会变成慢性的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;你只有一个身体&lt;/strong&gt;：当涉及到你的身体健康时，没有&quot;如果这不行以后换个职业&quot;这回事。损害是累积的，有些是永久的。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;可持续的开发者&quot;&gt;可持续的开发者&lt;/h2&gt;
&lt;p&gt;15 年过去了，我仍在编码，仍然热爱它。但我现在是和第一年时不同类型的开发者。&lt;/p&gt;
&lt;p&gt;我会休息。我定期站立。我每周锻炼四次。我有正确的人体工程学设置。我吃真正的食物。我保持睡眠时间表。我有不涉及屏幕的爱好。&lt;/p&gt;
&lt;p&gt;这些都不会使我成为更差的开发者。如果说有什么的话，我现在更有效率，因为我不是在不断地与疼痛或疲劳作斗争。我可以更好地集中注意力，我犯的错误更少，我不会每天下午 3 点崩溃。&lt;/p&gt;
&lt;p&gt;我认识的那些在这个领域工作了 20 多年仍然热爱它的开发者？他们都在某个时候弄明白了这一点。有些人学得早，有些人像我一样通过艰难的方式学到。但他们都学到了。&lt;/p&gt;
&lt;p&gt;那些没学到的人要么离开了这个领域，要么很痛苦。&lt;/p&gt;
&lt;h2 id=&quot;底线&quot;&gt;底线&lt;/h2&gt;
&lt;p&gt;你可以在开发领域拥有漫长、健康、高效的职业。这份工作仍然在智力上有吸引力，薪资仍然很好，灵活性仍然比大多数工作要好。&lt;/p&gt;
&lt;p&gt;但它需要用对待你的专业发展同样的有意性来对待你的身体健康。你研究框架，你学习新语言，你跟上行业趋势。你需要把同样的精力带到照顾你的身体上。&lt;/p&gt;
&lt;p&gt;因为这里是&quot;学会编码&quot;炒作中没人告诉你的事情：你的职业不是被你的技术技能或就业市场或 AI 或任何那些东西限制的。你的职业是被你的身体能够承受坐在椅子上多长时间来限制的。&lt;/p&gt;
&lt;p&gt;让它成为很长的时间。投资正确的设置，定期运动，持续锻炼，从一开始就建立可持续的习惯。&lt;/p&gt;
&lt;p&gt;15 年后的你已经在感谢你了。&lt;/p&gt;
&lt;h2 id=&quot;在建设职业的同时提升技能&quot;&gt;在建设职业的同时提升技能&lt;/h2&gt;
&lt;p&gt;在照顾身体的同时，继续磨练你的技术技能。从雇主想看到的实际项目开始：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;构建作品集&lt;/a&gt;&lt;/strong&gt;（Laravel 或 &lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Flask&lt;/a&gt; 或 &lt;a href=&quot;/tutorials/portfolio-scratch/&quot;&gt;从头开始&lt;/a&gt;）- 专业地展示你的作品&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-laravel/&quot;&gt;构建博客&lt;/a&gt;&lt;/strong&gt;（Laravel 或 &lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Flask&lt;/a&gt; 或 &lt;a href=&quot;/tutorials/blog-scratch/&quot;&gt;从头开始&lt;/a&gt;）- 掌握 CRUD 操作和内容管理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-laravel/&quot;&gt;构建电子商务&lt;/a&gt;&lt;/strong&gt;（Laravel 或 &lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Flask&lt;/a&gt; 或 &lt;a href=&quot;/tutorials/shopping-scratch/&quot;&gt;从头开始&lt;/a&gt;）- 学习复杂的业务逻辑和支付集成&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;每个教程路径都包含 AI 辅助提示，指导你构建生产就绪的应用程序。选择与你想要的工作匹配的技术栈，然后构建你可以向雇主展示的东西。&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How to Export Lovable.dev Code to GitHub with Continuous Sync & Deployment]]></title><description><![CDATA[Export your Lovable project to GitHub with this complete guide. Covers three export methods, continuous sync vs one-time export, GitHub Actions CI/CD setup, troubleshooting, and post-export workflows for deploying anywhere.]]></description><link>https://vibecodingwithfred.com/blog/export-lovable-to-github-complete/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/export-lovable-to-github-complete/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Looking to &lt;strong&gt;export your Lovable project to GitHub&lt;/strong&gt;? You&apos;re among hundreds of developers searching for this exact solution. Whether you need version control, team collaboration, or want to deploy elsewhere, this guide covers every method to get your Lovable code into GitHub.&lt;/p&gt;
&lt;h2 id=&quot;why-export-lovable-to-github&quot;&gt;Why Export Lovable to GitHub?&lt;/h2&gt;
&lt;p&gt;Before diving into the how, let&apos;s understand the why:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Version Control:&lt;/strong&gt; Track changes, revert mistakes, manage branches&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Team Collaboration:&lt;/strong&gt; Work with developers not on Lovable&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deployment Freedom:&lt;/strong&gt; Deploy to Vercel, Netlify, AWS, anywhere&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Backup Strategy:&lt;/strong&gt; Protect against platform issues&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cost Management:&lt;/strong&gt; Continue development without credits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CI/CD Pipelines:&lt;/strong&gt; Automate testing and deployment&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Code Ownership:&lt;/strong&gt; Full control over your codebase&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;table-of-contents&quot;&gt;Table of Contents&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#method-1-direct-github-integration&quot;&gt;Method 1: Direct GitHub Integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#method-2-download-and-push&quot;&gt;Method 2: Download and Push&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#method-3-git-remote-setup&quot;&gt;Method 3: Git Remote Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#continuous-sync-vs-one-time-export&quot;&gt;Continuous Sync vs One-Time Export&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#github-actions-setup&quot;&gt;Setting Up GitHub Actions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#common-issues-solutions&quot;&gt;Common Issues &amp;#x26; Solutions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#what-gets-exported&quot;&gt;What Gets Exported&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#post-export-workflow&quot;&gt;Post-Export Workflow&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;Before starting, ensure you have:&lt;/p&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Lovable account with project to export&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; GitHub account&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Git installed locally (for manual methods)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Basic terminal/command line knowledge&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Project download permissions in Lovable&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;method-1-direct-github-integration&quot;&gt;Method 1: Direct GitHub Integration&lt;/h2&gt;
&lt;p&gt;The easiest way if your Lovable plan supports it.&lt;/p&gt;
&lt;h3 id=&quot;step-1-enable-github-integration-in-lovable&quot;&gt;Step 1: Enable GitHub Integration in Lovable&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Open your Lovable project&lt;/li&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Settings&lt;/strong&gt; → &lt;strong&gt;Integrations&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Connect GitHub&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Authenticate with GitHub&lt;/li&gt;
&lt;li&gt;Grant Lovable permissions&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;step-2-configure-repository&quot;&gt;Step 2: Configure Repository&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Lovable will prompt you to:&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;. Create new repository OR
&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;. Connect existing repository&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;For New Repository:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Repository name: &lt;code class=&quot;language-text&quot;&gt;your-project-name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Visibility: Public/Private&lt;/li&gt;
&lt;li&gt;Initialize with README: No (Lovable provides it)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;For Existing Repository:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Select from dropdown&lt;/li&gt;
&lt;li&gt;Choose branch (main/master)&lt;/li&gt;
&lt;li&gt;Conflict resolution: Overwrite/Merge&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;step-3-initial-sync&quot;&gt;Step 3: Initial Sync&lt;/h3&gt;
&lt;p&gt;Click &lt;strong&gt;Sync to GitHub&lt;/strong&gt; button. Lovable will:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Export all project files&lt;/li&gt;
&lt;li&gt;Create initial commit&lt;/li&gt;
&lt;li&gt;Push to selected branch&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;step-4-enable-auto-sync-optional&quot;&gt;Step 4: Enable Auto-Sync (Optional)&lt;/h3&gt;
&lt;p&gt;Toggle &lt;strong&gt;Auto-sync&lt;/strong&gt; to automatically push changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Every save&lt;/li&gt;
&lt;li&gt;Every 5 minutes&lt;/li&gt;
&lt;li&gt;On manual trigger&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;method-2-download-and-push&quot;&gt;Method 2: Download and Push&lt;/h2&gt;
&lt;p&gt;For when GitHub integration isn&apos;t available.&lt;/p&gt;
&lt;h3 id=&quot;step-1-download-your-project&quot;&gt;Step 1: Download Your Project&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# In Lovable:&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;. Click &lt;span class=&quot;token string&quot;&gt;&quot;Export&quot;&lt;/span&gt; or &lt;span class=&quot;token string&quot;&gt;&quot;Download&quot;&lt;/span&gt; button
&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;. Select &lt;span class=&quot;token string&quot;&gt;&quot;Download as ZIP&quot;&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;. Save to &lt;span class=&quot;token builtin class-name&quot;&gt;local&lt;/span&gt; machine&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-2-extract-and-initialize-git&quot;&gt;Step 2: Extract and Initialize Git&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Terminal commands:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;unzip&lt;/span&gt; lovable-project.zip
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; lovable-project
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-3-create-github-repository&quot;&gt;Step 3: Create GitHub Repository&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Using GitHub CLI:&lt;/span&gt;
gh repo create your-project-name &lt;span class=&quot;token parameter variable&quot;&gt;--public&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--source&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;.

&lt;span class=&quot;token comment&quot;&gt;# Or manually on GitHub.com:&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;. Click &lt;span class=&quot;token string&quot;&gt;&quot;New repository&quot;&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;. Name it
&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;. Don&apos;t initialize with README
&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;. Copy the repository URL&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-4-push-to-github&quot;&gt;Step 4: Push to GitHub&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Add all files&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Create initial commit&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial export from Lovable&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Add remote origin&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; origin https://github.com/yourusername/your-project.git

&lt;span class=&quot;token comment&quot;&gt;# Push to GitHub&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;New to Git? Check out &lt;a href=&quot;/blog/everyday-git-commands/&quot;&gt;8 Common Git Commands You&apos;ll Use Daily&lt;/a&gt; for a refresher on &lt;code class=&quot;language-text&quot;&gt;git add&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;git commit&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;git push&lt;/code&gt;, and more.&lt;/p&gt;
&lt;h2 id=&quot;method-3-git-remote-setup&quot;&gt;Method 3: Git Remote Setup&lt;/h2&gt;
&lt;p&gt;For advanced users wanting granular control.&lt;/p&gt;
&lt;h3 id=&quot;step-1-access-lovables-git-url&quot;&gt;Step 1: Access Lovable&apos;s Git URL&lt;/h3&gt;
&lt;p&gt;Some Lovable projects provide Git access:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# In Lovable project settings, look for:&lt;/span&gt;
Git URL: https://git.lovable.dev/your-project.git&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-2-clone-locally&quot;&gt;Step 2: Clone Locally&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; clone https://git.lovable.dev/your-project.git
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; your-project&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-3-add-github-as-remote&quot;&gt;Step 3: Add GitHub as Remote&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Add GitHub as additional remote&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; github https://github.com/yourusername/your-repo.git

&lt;span class=&quot;token comment&quot;&gt;# Verify remotes&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Output:&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# origin    https://git.lovable.dev/your-project.git (fetch)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# origin    https://git.lovable.dev/your-project.git (push)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# github    https://github.com/yourusername/your-repo.git (fetch)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# github    https://github.com/yourusername/your-repo.git (push)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-4-push-to-github-1&quot;&gt;Step 4: Push to GitHub&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Push to GitHub remote&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push github main

&lt;span class=&quot;token comment&quot;&gt;# Set GitHub as default (optional)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch --set-upstream-to&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;github/main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;continuous-sync-vs-one-time-export&quot;&gt;Continuous Sync vs One-Time Export&lt;/h2&gt;
&lt;h3 id=&quot;continuous-sync&quot;&gt;Continuous Sync&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Always up-to-date&lt;/li&gt;
&lt;li&gt;Automatic backups&lt;/li&gt;
&lt;li&gt;Team sees changes immediately&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Requires Pro+ Lovable plan&lt;/li&gt;
&lt;li&gt;Can create many commits&lt;/li&gt;
&lt;li&gt;Potential sync conflicts&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Setup:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// .lovable/sync.config.json&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token string-property property&quot;&gt;&quot;github&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string-property property&quot;&gt;&quot;enabled&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string-property property&quot;&gt;&quot;repository&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;username/repo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string-property property&quot;&gt;&quot;branch&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string-property property&quot;&gt;&quot;frequency&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;on_save&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// or &quot;5min&quot;, &quot;manual&quot;&lt;/span&gt;
    &lt;span class=&quot;token string-property property&quot;&gt;&quot;commit_message&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Auto-sync from Lovable: {timestamp}&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;one-time-export&quot;&gt;One-Time Export&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Works on any plan&lt;/li&gt;
&lt;li&gt;Full control over commits&lt;/li&gt;
&lt;li&gt;No ongoing connection needed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Manual process&lt;/li&gt;
&lt;li&gt;Can become outdated&lt;/li&gt;
&lt;li&gt;Requires re-export for updates&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Best Practice Workflow:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Export at major milestones&lt;/li&gt;
&lt;li&gt;Continue development locally&lt;/li&gt;
&lt;li&gt;Re-import to Lovable if needed&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;github-actions-setup&quot;&gt;GitHub Actions Setup&lt;/h2&gt;
&lt;p&gt;Automate deployment after export.&lt;/p&gt;
&lt;h3 id=&quot;basic-deployment-workflow&quot;&gt;Basic Deployment Workflow&lt;/h3&gt;
&lt;p&gt;Create &lt;code class=&quot;language-text&quot;&gt;.github/workflows/deploy.yml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deploy Lovable Export

&lt;span class=&quot;token key atrule&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;branches&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;main&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;pull_request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;branches&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;main&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;build-and-deploy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ubuntu&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;latest

    &lt;span class=&quot;token key atrule&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/checkout@v3

    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Setup Node.js
      &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/setup&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;node@v3
      &lt;span class=&quot;token key atrule&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;node-version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;18&apos;&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;npm&apos;&lt;/span&gt;

    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Install dependencies
      &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm ci

    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Build project
      &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm run build

    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Run tests
      &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm test

    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deploy to Vercel
      &lt;span class=&quot;token key atrule&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; github.ref == &apos;refs/heads/main&apos;
      &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token scalar string&quot;&gt;
        npm i -g vercel
        vercel --prod --token=${{ secrets.VERCEL_TOKEN }}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;environment-variables&quot;&gt;Environment Variables&lt;/h3&gt;
&lt;p&gt;Store Lovable environment variables in GitHub:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Repository → Settings → Secrets&lt;/li&gt;
&lt;li&gt;Add each variable from Lovable&lt;/li&gt;
&lt;li&gt;Reference in workflows: &lt;code class=&quot;language-text&quot;&gt;${{ secrets.VAR_NAME }}&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;what-gets-exported&quot;&gt;What Gets Exported&lt;/h2&gt;
&lt;h3 id=&quot;-included-in-export&quot;&gt;✅ Included in Export&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Source Code:&lt;/strong&gt; All JavaScript/TypeScript files&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Styles:&lt;/strong&gt; CSS, SCSS, Tailwind configs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Assets:&lt;/strong&gt; Images, fonts, icons&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configuration:&lt;/strong&gt; package.json, configs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Public Files:&lt;/strong&gt; HTML, robots.txt, manifests&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Documentation:&lt;/strong&gt; README, licenses&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;-not-included&quot;&gt;❌ NOT Included&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Environment Variables:&lt;/strong&gt; Must export separately&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Database Data:&lt;/strong&gt; Only schema exported&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lovable Metadata:&lt;/strong&gt; Internal platform data&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build Artifacts:&lt;/strong&gt; dist/, .next/, etc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deployment Settings:&lt;/strong&gt; Server configurations&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Analytics Data:&lt;/strong&gt; Usage statistics&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;User Uploads:&lt;/strong&gt; Dynamic content&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;environment-variables-export&quot;&gt;Environment Variables Export&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# In Lovable, go to Settings → Environment Variables&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Click &quot;Export as .env&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Creates .env file:&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;API_KEY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;your-api-key
&lt;span class=&quot;token assign-left variable&quot;&gt;DATABASE_URL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;your-database-url
&lt;span class=&quot;token assign-left variable&quot;&gt;NEXT_PUBLIC_APP_URL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;https://your-app.com&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Security Warning:&lt;/strong&gt; Never commit &lt;code class=&quot;language-text&quot;&gt;.env&lt;/code&gt; to GitHub!&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Add to .gitignore&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;.env&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; .gitignore
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;.env.local&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; .gitignore&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;common-issues--solutions&quot;&gt;Common Issues &amp;#x26; Solutions&lt;/h2&gt;
&lt;h3 id=&quot;issue-1-authentication-failed&quot;&gt;Issue 1: &quot;Authentication Failed&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Use personal access token instead of password&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;. GitHub → Settings → Developer settings
&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;. Personal access tokens → Generate new token
&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;. Select scopes: repo, workflow
&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;. Use token as password&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;issue-2-large-files-rejected&quot;&gt;Issue 2: &quot;Large Files Rejected&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Error:&lt;/strong&gt; &lt;code class=&quot;language-text&quot;&gt;this exceeds GitHub&apos;s file size limit of 100.00 MB&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Use Git LFS for large files&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; lfs track &lt;span class=&quot;token string&quot;&gt;&quot;*.psd&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; lfs track &lt;span class=&quot;token string&quot;&gt;&quot;*.zip&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; .gitattributes
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; large-file.psd
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Add large files with LFS&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;issue-3-merge-conflicts&quot;&gt;Issue 3: &quot;Merge Conflicts&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Pull latest changes&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; pull origin main

&lt;span class=&quot;token comment&quot;&gt;# Resolve conflicts in VS Code or:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; status  &lt;span class=&quot;token comment&quot;&gt;# See conflicted files&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Edit files, remove conflict markers&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Resolve merge conflicts&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;issue-4-missing-dependencies&quot;&gt;Issue 4: &quot;Missing Dependencies&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Lovable might use internal packages&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Check package.json for @lovable/* packages&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Replace with public alternatives:&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Before:&lt;/span&gt;
&lt;span class=&quot;token string&quot;&gt;&quot;@lovable/ui&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;^1.0.0&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# After:&lt;/span&gt;
&lt;span class=&quot;token string&quot;&gt;&quot;@shadcn/ui&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;^0.8.0&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;issue-5-build-fails-after-export&quot;&gt;Issue 5: &quot;Build Fails After Export&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Common Fixes:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Clear caches&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-rf&lt;/span&gt; node_modules package-lock.json
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Check Node version&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# Should match Lovable&apos;s&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Install missing peer deps&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; --save-peer-deps

&lt;span class=&quot;token comment&quot;&gt;# Check for Lovable-specific imports&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Replace with standard imports&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;post-export-workflow&quot;&gt;Post-Export Workflow&lt;/h2&gt;
&lt;h3 id=&quot;1-set-up-development-environment&quot;&gt;1. Set Up Development Environment&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Install dependencies&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Set up environment variables&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;cp&lt;/span&gt; .env.example .env
&lt;span class=&quot;token comment&quot;&gt;# Edit .env with your values&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Run development server&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run dev&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-configure-vs-code&quot;&gt;2. Configure VS Code&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-json line-numbers&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// .vscode/settings.json&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;editor.formatOnSave&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;editor.defaultFormatter&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;esbenp.prettier-vscode&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;tailwindCSS.includeLanguages&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;javascript&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;javascript&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;html&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;HTML&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-set-up-pre-commit-hooks&quot;&gt;3. Set Up Pre-commit Hooks&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Install husky&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; --save-dev husky lint-staged
npx husky init

&lt;span class=&quot;token comment&quot;&gt;# Add pre-commit hook&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;npx lint-staged&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; .husky/pre-commit&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-continue-development&quot;&gt;4. Continue Development&lt;/h3&gt;
&lt;p&gt;You can now:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Edit in VS Code/Cursor&lt;/li&gt;
&lt;li&gt;Use GitHub Copilot&lt;/li&gt;
&lt;li&gt;Collaborate with team&lt;/li&gt;
&lt;li&gt;Deploy anywhere&lt;/li&gt;
&lt;li&gt;Return to Lovable anytime&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;deploying-your-exported-project&quot;&gt;Deploying Your Exported Project&lt;/h2&gt;
&lt;h3 id=&quot;to-vercel&quot;&gt;To Vercel&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Install Vercel CLI&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; i &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; vercel

&lt;span class=&quot;token comment&quot;&gt;# Deploy&lt;/span&gt;
vercel

&lt;span class=&quot;token comment&quot;&gt;# Follow prompts, get URL&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;to-netlify&quot;&gt;To Netlify&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Install Netlify CLI&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; i &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; netlify-cli

&lt;span class=&quot;token comment&quot;&gt;# Deploy&lt;/span&gt;
netlify deploy &lt;span class=&quot;token parameter variable&quot;&gt;--prod&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Or drag-drop in Netlify UI&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;to-cloudflare-pages&quot;&gt;To Cloudflare Pages&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Build project&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build

&lt;span class=&quot;token comment&quot;&gt;# Install Wrangler&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; i &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; wrangler

&lt;span class=&quot;token comment&quot;&gt;# Deploy&lt;/span&gt;
wrangler pages deploy ./dist&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;returning-to-lovable&quot;&gt;Returning to Lovable&lt;/h2&gt;
&lt;p&gt;Need to bring changes back to Lovable?&lt;/p&gt;
&lt;h3 id=&quot;option-1-re-import-project&quot;&gt;Option 1: Re-import Project&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Lovable → New Project → Import from GitHub&lt;/li&gt;
&lt;li&gt;Select repository&lt;/li&gt;
&lt;li&gt;Configure import settings&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;option-2-manual-sync&quot;&gt;Option 2: Manual Sync&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# In your local project&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; lovable https://git.lovable.dev/project.git
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push lovable main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;best-practices&quot;&gt;Best Practices&lt;/h2&gt;
&lt;h3 id=&quot;1-commit-messages&quot;&gt;1. Commit Messages&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# When exporting, use clear messages&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Export from Lovable: [date]&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Post-export: Fix dependencies&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Post-export: Add GitHub Actions&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-branch-strategy&quot;&gt;2. Branch Strategy&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Keep Lovable exports separate&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout &lt;span class=&quot;token parameter variable&quot;&gt;-b&lt;/span&gt; lovable-export
&lt;span class=&quot;token comment&quot;&gt;# Make changes&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; merge lovable-export&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-documentation&quot;&gt;3. Documentation&lt;/h3&gt;
&lt;p&gt;Always update README after export:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;markdown&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-markdown line-numbers&quot;&gt;&lt;code class=&quot;language-markdown&quot;&gt;&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;#&lt;/span&gt; Project Name&lt;/span&gt;

Originally created with &lt;span class=&quot;token url&quot;&gt;[&lt;span class=&quot;token content&quot;&gt;Lovable&lt;/span&gt;](&lt;span class=&quot;token url&quot;&gt;https://lovable.dev&lt;/span&gt;)&lt;/span&gt;
Exported to GitHub on: 2025-01-26

&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;##&lt;/span&gt; Development&lt;/span&gt;
&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; Run locally: &lt;span class=&quot;token code-snippet code keyword&quot;&gt;`npm run dev`&lt;/span&gt;
&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; Build: &lt;span class=&quot;token code-snippet code keyword&quot;&gt;`npm run build`&lt;/span&gt;
&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; Deploy: &lt;span class=&quot;token code-snippet code keyword&quot;&gt;`npm run deploy`&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;automation-script&quot;&gt;Automation Script&lt;/h2&gt;
&lt;p&gt;Save time with this export script:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# save as export-lovable.sh&lt;/span&gt;

&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🚀 Exporting Lovable Project to GitHub&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Download from Lovable (manual step)&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1. Download project from Lovable&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;   Press Enter when complete...&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Setup&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;unzip&lt;/span&gt; ~/Downloads/lovable-export.zip &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; ./lovable-project
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; lovable-project
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init

&lt;span class=&quot;token comment&quot;&gt;# Configure git&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial export from Lovable &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;date&lt;/span&gt; +%Y-%m-%d&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Create GitHub repo&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Enter GitHub repo name:&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt; REPO_NAME
gh repo create &lt;span class=&quot;token variable&quot;&gt;$REPO_NAME&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--public&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--source&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;.

&lt;span class=&quot;token comment&quot;&gt;# Push&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin main

&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;✅ Export complete! View at: https://github.com/&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;gh api user &lt;span class=&quot;token parameter variable&quot;&gt;-q&lt;/span&gt; .login&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;/&lt;span class=&quot;token variable&quot;&gt;$REPO_NAME&lt;/span&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Exporting from Lovable to GitHub opens up endless possibilities for your project. Whether you choose continuous sync or one-time export, you now have the knowledge to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Take full control of your code&lt;/li&gt;
&lt;li&gt;Collaborate with any developer&lt;/li&gt;
&lt;li&gt;Deploy anywhere&lt;/li&gt;
&lt;li&gt;Reduce platform dependency&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Remember: You can always return to Lovable for AI-assisted development when needed!&lt;/p&gt;
&lt;h2 id=&quot;related-tutorials&quot;&gt;Related Tutorials&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website/&quot;&gt;Deploy Lovable to Vercel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;Deploy Lovable to Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-credits-complete-guide&quot;&gt;Lovable Credits Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website&quot;&gt;3 Ways to Move Your Lovable Website&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Questions? Found an issue? Check out our &lt;a href=&quot;/blog/lovable-vibe-coding-guide&quot;&gt;other Lovable guides&lt;/a&gt; for more help.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Build a Real-Time Logistics Dashboard with Laravel, WebSockets and Vue]]></title><description><![CDATA[Ever wondered how companies track thousands of shipments in real-time? Or how trading platforms update prices instantly across thousands of…]]></description><link>https://vibecodingwithfred.com/blog/laravel-realtime-dashboard/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/laravel-realtime-dashboard/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Ever wondered how companies track thousands of shipments in real-time? Or how trading platforms update prices instantly across thousands of screens? I&apos;ve built these systems at scale, processing over $2B in annual transactions. Today, I&apos;ll show you exactly how to build a production-ready real-time dashboard using Laravel, WebSockets, and Vue.js.&lt;/p&gt;
&lt;p&gt;This isn&apos;t theory—these are battle-tested patterns from actual production systems handling logistics operations 24/7.&lt;/p&gt;
&lt;h2 id=&quot;what-were-building&quot;&gt;What We&apos;re Building&lt;/h2&gt;
&lt;p&gt;We&apos;ll create a real-time logistics dashboard that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tracks shipment locations with live updates&lt;/li&gt;
&lt;li&gt;Shows real-time metrics (deliveries, revenue, performance)&lt;/li&gt;
&lt;li&gt;Implements a locking system to prevent conflicting edits&lt;/li&gt;
&lt;li&gt;Handles thousands of concurrent connections&lt;/li&gt;
&lt;li&gt;Scales horizontally with Redis pub/sub&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&apos;s what the final dashboard looks like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Multiple users see updates instantly&lt;/li&gt;
&lt;li&gt;Shipment statuses change in real-time&lt;/li&gt;
&lt;li&gt;Metrics update without page refresh&lt;/li&gt;
&lt;li&gt;Edit locks prevent data conflicts&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;You&apos;ll need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PHP 8.1+ with Laravel 10+&lt;/li&gt;
&lt;li&gt;Node.js 18+ for Vue 3&lt;/li&gt;
&lt;li&gt;Redis (or KeyDB for better performance)&lt;/li&gt;
&lt;li&gt;Basic knowledge of Laravel and Vue&lt;/li&gt;
&lt;li&gt;Composer and npm installed&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;part-1-setting-up-the-laravel-backend&quot;&gt;Part 1: Setting Up the Laravel Backend&lt;/h2&gt;
&lt;h3 id=&quot;step-1-create-the-laravel-project&quot;&gt;Step 1: Create the Laravel Project&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;composer&lt;/span&gt; create-project laravel/laravel realtime-logistics
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; realtime-logistics

&lt;span class=&quot;token comment&quot;&gt;# Install broadcasting and WebSocket dependencies&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;composer&lt;/span&gt; require pusher/pusher-php-server
&lt;span class=&quot;token function&quot;&gt;composer&lt;/span&gt; require predis/predis

&lt;span class=&quot;token comment&quot;&gt;# Install Laravel WebSockets package (self-hosted alternative to Pusher)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;composer&lt;/span&gt; require beyondcode/laravel-websockets&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-2-configure-broadcasting&quot;&gt;Step 2: Configure Broadcasting&lt;/h3&gt;
&lt;p&gt;Update your &lt;code class=&quot;language-text&quot;&gt;.env&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;env&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-env line-numbers&quot;&gt;&lt;code class=&quot;language-env&quot;&gt;BROADCAST_DRIVER=pusher
CACHE_DRIVER=redis
QUEUE_CONNECTION=redis
SESSION_DRIVER=redis

# Use Laravel WebSockets as Pusher replacement
PUSHER_APP_ID=local-app
PUSHER_APP_KEY=local-key
PUSHER_APP_SECRET=local-secret
PUSHER_HOST=127.0.0.1
PUSHER_PORT=6001
PUSHER_SCHEME=http
PUSHER_APP_CLUSTER=mt1

# Redis configuration
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-3-database-schema&quot;&gt;Step 3: Database Schema&lt;/h3&gt;
&lt;p&gt;Create migrations for our logistics system:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;php artisan make:migration create_shipments_table
php artisan make:migration create_metrics_table
php artisan make:migration create_edit_locks_table&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// database/migrations/create_shipments_table.php&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Schema&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;Blueprint&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token keyword type-declaration&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;tracking_number&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token keyword type-declaration&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;origin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token keyword type-declaration&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;destination&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;enum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;pending&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;in_transit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;delivered&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;exception&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decimal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;nullable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decimal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;nullable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decimal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metadata&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;nullable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;timestamps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;created_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Optimized for dashboard queries&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Spatial queries&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// database/migrations/create_metrics_table.php&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Schema&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metrics&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;Blueprint&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token keyword type-declaration&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;key&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decimal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token keyword type-declaration&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;unit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;nullable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;calculated_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;timestamps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;calculated_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// database/migrations/create_edit_locks_table.php&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Schema&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;edit_locks&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;Blueprint&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;morphs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;lockable&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Polymorphic - can lock any model&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unsignedBigInteger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;locked_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;lockable_type&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;lockable_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-4-create-the-models&quot;&gt;Step 4: Create the Models&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// app/Models/Shipment.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Models&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Database&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Eloquent&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Model&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Database&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Eloquent&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Factories&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;HasFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Traits&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Lockable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Events&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;ShipmentUpdated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;Shipment&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Model&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;HasFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Lockable&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$fillable&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;tracking_number&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;origin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;destination&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metadata&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$casts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metadata&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;array&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;decimal:2&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;decimal:7&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;decimal:7&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$dispatchesEvents&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;updated&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;ShipmentUpdated&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Real-world optimization: Cache frequently accessed shipments&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;findByTrackingCached&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$trackingNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Cache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment.&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$trackingNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addMinutes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;tracking_number&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$trackingNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Geospatial query for nearby shipments&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;scopeNearby&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lng&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$radiusKm&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Haversine formula for distance calculation&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$haversine&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;(
            6371 * acos(
                cos(radians(?)) * cos(radians(latitude)) *
                cos(radians(longitude) - radians(?)) +
                sin(radians(?)) * sin(radians(latitude))
            )
        )&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$query&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;selectRaw&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;*, &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$haversine&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; AS distance&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lng&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;having&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;distance&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&amp;lt;=&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$radiusKm&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;orderBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;distance&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-5-implement-the-lockable-trait&quot;&gt;Step 5: Implement the Lockable Trait&lt;/h3&gt;
&lt;p&gt;This prevents conflicting edits—crucial for financial data:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// app/Traits/Lockable.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Traits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Models&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;EditLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Support&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Facades&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Auth&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Carbon&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Carbon&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;Lockable&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;morphMany&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name static-context&quot;&gt;EditLock&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;lockable&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;acquireLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$duration&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Auth&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Check for existing valid locks&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$existingLock&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;!=&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$existingLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Someone else has the lock&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Clean up expired locks&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&amp;lt;=&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Create new lock&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user_id&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;locked_at&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addSeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$duration&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;releaseLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Auth&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;isLocked&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$excludeUserId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$query&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$excludeUserId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;!=&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$excludeUserId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;currentLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-6-create-broadcasting-events&quot;&gt;Step 6: Create Broadcasting Events&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// app/Events/ShipmentUpdated.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Events&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Models&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Broadcasting&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Channel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Broadcasting&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;InteractsWithSockets&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Contracts&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Broadcasting&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;ShouldBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Foundation&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Events&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Dispatchable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Queue&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;SerializesModels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;ShipmentUpdated&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ShouldBroadcast&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Dispatchable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; InteractsWithSockets&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; SerializesModels&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;Shipment&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;broadcastOn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Channel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Channel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment.&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;broadcastWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;id&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;tracking_number&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;tracking_number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;latitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;longitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;updated_at&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;updated_at&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toIso8601String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Performance optimization: Use queue for broadcasting&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;broadcastQueue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;broadcasts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// app/Events/MetricsUpdated.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Events&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Broadcasting&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Channel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Contracts&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Broadcasting&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;ShouldBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;MetricsUpdated&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ShouldBroadcast&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$metrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword type-hint&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$metrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;metrics&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$metrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;broadcastOn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Channel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metrics&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Broadcast immediately for real-time metrics&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;broadcastWhen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// app/Events/EditLockAcquired.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Events&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Broadcasting&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;PresenceChannel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Contracts&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Broadcasting&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;ShouldBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;EditLockAcquired&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ShouldBroadcast&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$resourceType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$resourceId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$expiresAt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resourceType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$resourceId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$expiresAt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;resourceType&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$resourceType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;resourceId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$resourceId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;userId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;userName&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;expiresAt&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$expiresAt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;broadcastOn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PresenceChannel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;editing.&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;resourceType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;resourceId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-7-api-controllers&quot;&gt;Step 7: API Controllers&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// app/Http/Controllers/Api/ShipmentController.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Http&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Controllers&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Api&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Http&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Controllers&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Controller&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Models&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Events&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;ShipmentUpdated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Events&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;EditLockAcquired&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Http&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Support&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Facades&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Cache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Support&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Facades&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;DB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;ShipmentController&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Controller&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;Request&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Optimized query with caching&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$cacheKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments.page.&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;page&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Cache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cacheKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addSeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
                &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;tracking_number&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;origin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;destination&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;updated_at&apos;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;orderBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;updated_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;desc&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;paginate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;Request&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name type-declaration&quot;&gt;Shipment&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Check if user has lock&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
                &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;error&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Resource is locked by another user&apos;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;423&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 423 Locked&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$validated&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;in:pending,in_transit,delivered,exception&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;numeric|between:-90,90&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;numeric|between:-180,180&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token class-name static-context&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;transaction&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$validated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$validated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Clear cache&lt;/span&gt;
            &lt;span class=&quot;token class-name static-context&quot;&gt;Cache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forget&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment.&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;tracking_number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token class-name static-context&quot;&gt;Cache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;flush&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Release lock after successful update&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;releaseLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Event is automatically dispatched via model events&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;acquireLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;Shipment&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lock&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acquireLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 5 minute lock&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$currentLock&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;currentLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
                &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;locked&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;locked_by&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$currentLock&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Unknown&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$currentLock&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;expires_at&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;423&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Broadcast lock event&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;broadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EditLockAcquired&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipment&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$lock&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;expires_at&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;lock_id&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lock&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lock&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;expires_at&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;releaseLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;Shipment&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;releaseLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;released&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;nearby&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;Request&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$validated&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;required|numeric|between:-90,90&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;required|numeric|between:-180,180&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;radius&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;integer|min:1|max:500&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;nearby&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$validated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$validated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$validated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;radius&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// app/Http/Controllers/Api/MetricsController.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Http&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Controllers&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Api&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Http&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Controllers&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Controller&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Models&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Models&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Events&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;MetricsUpdated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Support&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Facades&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Cache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Support&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Facades&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;DB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;MetricsController&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Controller&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Cache metrics for 10 seconds - balance between real-time and performance&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Cache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;dashboard.metrics&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
                &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;total_shipments&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getTotalShipments&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;in_transit&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getInTransitCount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;delivered_today&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getDeliveredToday&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;total_value&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getTotalValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;average_delivery_time&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getAverageDeliveryTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;exception_rate&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getExceptionRate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getTotalShipments&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getInTransitCount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;in_transit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getDeliveredToday&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;delivered&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;whereDate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;updated_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;today&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getTotalValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Use raw query for performance on large datasets&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;selectOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;
            SELECT SUM(value) as total
            FROM shipments
            WHERE status != &apos;exception&apos;
        &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getAverageDeliveryTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Calculate average hours from creation to delivery&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$avgHours&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;selectOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;
            SELECT AVG(
                TIMESTAMPDIFF(HOUR, created_at, updated_at)
            ) as avg_hours
            FROM shipments
            WHERE status = &apos;delivered&apos;
            AND updated_at &gt;= DATE_SUB(NOW(), INTERVAL 7 DAY)
        &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;avg_hours&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$avgHours&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getExceptionRate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$total&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$total&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$exceptions&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;exception&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$exceptions&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$total&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Called by scheduled job to broadcast metrics&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;broadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$metrics&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;broadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MetricsUpdated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;broadcasted&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;part-2-vuejs-frontend-with-real-time-updates&quot;&gt;Part 2: Vue.js Frontend with Real-Time Updates&lt;/h2&gt;
&lt;h3 id=&quot;step-8-install-vue-and-dependencies&quot;&gt;Step 8: Install Vue and Dependencies&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; vue@3 @vitejs/plugin-vue
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; laravel-echo pusher-js
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; axios pinia @vueuse/core
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-D&lt;/span&gt; @types/laravel-echo&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-9-configure-vite-for-vue&quot;&gt;Step 9: Configure Vite for Vue&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// vite.config.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; defineConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;vite&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; laravel &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;laravel-vite-plugin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; vue &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@vitejs/plugin-vue&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;defineConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;plugins&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;laravel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;resources/css/app.css&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;resources/js/app.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;refresh&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;vue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token literal-property property&quot;&gt;transformAssetUrls&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token literal-property property&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;token literal-property property&quot;&gt;includeAbsolute&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;vue&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;vue/dist/vue.esm-bundler.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-10-set-up-laravel-echo&quot;&gt;Step 10: Set Up Laravel Echo&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// resources/js/bootstrap.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Echo &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;laravel-echo&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Pusher &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;pusher-js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Pusher &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Pusher&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Echo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Echo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;broadcaster&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;pusher&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VITE_PUSHER_APP_KEY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;cluster&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VITE_PUSHER_APP_CLUSTER&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;mt1&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;wsHost&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VITE_PUSHER_HOST&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;location&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hostname&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;wsPort&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VITE_PUSHER_PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6001&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;wssPort&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VITE_PUSHER_PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6001&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;forceTLS&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;encrypted&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;disableStats&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;enabledTransports&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;ws&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;wss&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-11-create-the-dashboard-component&quot;&gt;Step 11: Create the Dashboard Component&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;vue&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-vue line-numbers&quot;&gt;&lt;code class=&quot;language-vue&quot;&gt;&amp;lt;!-- resources/js/components/Dashboard.vue --&amp;gt;
&amp;lt;template&amp;gt;
  &amp;lt;div class=&amp;quot;dashboard&amp;quot;&amp;gt;
    &amp;lt;!-- Metrics Bar --&amp;gt;
    &amp;lt;div class=&amp;quot;metrics-grid&amp;quot;&amp;gt;
      &amp;lt;MetricCard
        v-for=&amp;quot;(value, key) in metrics&amp;quot;
        :key=&amp;quot;key&amp;quot;
        :title=&amp;quot;formatMetricTitle(key)&amp;quot;
        :value=&amp;quot;value&amp;quot;
        :unit=&amp;quot;getMetricUnit(key)&amp;quot;
        :trend=&amp;quot;metricTrends[key]&amp;quot;
      /&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;!-- Shipments Table with Real-Time Updates --&amp;gt;
    &amp;lt;div class=&amp;quot;shipments-section&amp;quot;&amp;gt;
      &amp;lt;div class=&amp;quot;section-header&amp;quot;&amp;gt;
        &amp;lt;h2&amp;gt;Live Shipments&amp;lt;/h2&amp;gt;
        &amp;lt;div class=&amp;quot;status-filters&amp;quot;&amp;gt;
          &amp;lt;button
            v-for=&amp;quot;status in statuses&amp;quot;
            :key=&amp;quot;status&amp;quot;
            @click=&amp;quot;filterStatus = status&amp;quot;
            :class=&amp;quot;[&amp;#39;status-btn&amp;#39;, status, { active: filterStatus === status }]&amp;quot;
          &amp;gt;
            {{ status }}
          &amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;div class=&amp;quot;shipments-table&amp;quot;&amp;gt;
        &amp;lt;table&amp;gt;
          &amp;lt;thead&amp;gt;
            &amp;lt;tr&amp;gt;
              &amp;lt;th&amp;gt;Tracking #&amp;lt;/th&amp;gt;
              &amp;lt;th&amp;gt;Origin → Destination&amp;lt;/th&amp;gt;
              &amp;lt;th&amp;gt;Status&amp;lt;/th&amp;gt;
              &amp;lt;th&amp;gt;Value&amp;lt;/th&amp;gt;
              &amp;lt;th&amp;gt;Location&amp;lt;/th&amp;gt;
              &amp;lt;th&amp;gt;Last Update&amp;lt;/th&amp;gt;
              &amp;lt;th&amp;gt;Actions&amp;lt;/th&amp;gt;
            &amp;lt;/tr&amp;gt;
          &amp;lt;/thead&amp;gt;
          &amp;lt;tbody&amp;gt;
            &amp;lt;ShipmentRow
              v-for=&amp;quot;shipment in filteredShipments&amp;quot;
              :key=&amp;quot;shipment.id&amp;quot;
              :shipment=&amp;quot;shipment&amp;quot;
              :locked-by=&amp;quot;locks[shipment.id]&amp;quot;
              @edit=&amp;quot;editShipment&amp;quot;
              @update=&amp;quot;updateShipment&amp;quot;
            /&amp;gt;
          &amp;lt;/tbody&amp;gt;
        &amp;lt;/table&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;!-- Real-Time Map --&amp;gt;
    &amp;lt;div class=&amp;quot;map-section&amp;quot;&amp;gt;
      &amp;lt;ShipmentMap :shipments=&amp;quot;shipments&amp;quot; /&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;!-- Connection Status --&amp;gt;
    &amp;lt;ConnectionStatus :connected=&amp;quot;isConnected&amp;quot; /&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
import { ref, computed, onMounted, onBeforeUnmount } from &amp;#39;vue&amp;#39;;
import { useWebSocket } from &amp;#39;../composables/useWebSocket&amp;#39;;
import { useShipments } from &amp;#39;../stores/shipments&amp;#39;;
import { useMetrics } from &amp;#39;../stores/metrics&amp;#39;;
import MetricCard from &amp;#39;./MetricCard.vue&amp;#39;;
import ShipmentRow from &amp;#39;./ShipmentRow.vue&amp;#39;;
import ShipmentMap from &amp;#39;./ShipmentMap.vue&amp;#39;;
import ConnectionStatus from &amp;#39;./ConnectionStatus.vue&amp;#39;;

// Stores
const shipmentsStore = useShipments();
const metricsStore = useMetrics();

// WebSocket connection
const { isConnected, subscribe, unsubscribe } = useWebSocket();

// Component state
const filterStatus = ref(&amp;#39;all&amp;#39;);
const locks = ref({});
const metricTrends = ref({});

// Computed
const shipments = computed(() =&amp;gt; shipmentsStore.shipments);
const metrics = computed(() =&amp;gt; metricsStore.metrics);

const filteredShipments = computed(() =&amp;gt; {
  if (filterStatus.value === &amp;#39;all&amp;#39;) {
    return shipments.value;
  }
  return shipments.value.filter(s =&amp;gt; s.status === filterStatus.value);
});

const statuses = [&amp;#39;all&amp;#39;, &amp;#39;pending&amp;#39;, &amp;#39;in_transit&amp;#39;, &amp;#39;delivered&amp;#39;, &amp;#39;exception&amp;#39;];

// Methods
function formatMetricTitle(key) {
  return key.split(&amp;#39;_&amp;#39;).map(word =&amp;gt;
    word.charAt(0).toUpperCase() + word.slice(1)
  ).join(&amp;#39; &amp;#39;);
}

function getMetricUnit(key) {
  const units = {
    total_value: &amp;#39;$&amp;#39;,
    average_delivery_time: &amp;#39;hours&amp;#39;,
    exception_rate: &amp;#39;%&amp;#39;
  };
  return units[key] || &amp;#39;&amp;#39;;
}

async function editShipment(shipment) {
  try {
    // Acquire lock
    const response = await fetch(`/api/shipments/${shipment.id}/lock`, {
      method: &amp;#39;POST&amp;#39;,
      headers: {
        &amp;#39;Authorization&amp;#39;: `Bearer ${localStorage.getItem(&amp;#39;token&amp;#39;)}`,
        &amp;#39;Content-Type&amp;#39;: &amp;#39;application/json&amp;#39;,
      }
    });

    if (!response.ok) {
      const data = await response.json();
      if (response.status === 423) {
        alert(`Locked by ${data.locked_by} until ${data.expires_at}`);
        return;
      }
    }

    const lockData = await response.json();
    locks.value[shipment.id] = {
      expires_at: lockData.expires_at,
      user: &amp;#39;You&amp;#39;
    };
  } catch (error) {
    console.error(&amp;#39;Failed to acquire lock:&amp;#39;, error);
  }
}

async function updateShipment(shipment, updates) {
  try {
    const response = await fetch(`/api/shipments/${shipment.id}`, {
      method: &amp;#39;PUT&amp;#39;,
      headers: {
        &amp;#39;Authorization&amp;#39;: `Bearer ${localStorage.getItem(&amp;#39;token&amp;#39;)}`,
        &amp;#39;Content-Type&amp;#39;: &amp;#39;application/json&amp;#39;,
      },
      body: JSON.stringify(updates)
    });

    if (!response.ok) {
      throw new Error(&amp;#39;Update failed&amp;#39;);
    }

    // Lock is automatically released after successful update
    delete locks.value[shipment.id];
  } catch (error) {
    console.error(&amp;#39;Failed to update shipment:&amp;#39;, error);
  }
}

// WebSocket subscriptions
onMounted(() =&amp;gt; {
  // Load initial data
  shipmentsStore.fetchShipments();
  metricsStore.fetchMetrics();

  // Subscribe to shipment updates
  subscribe(&amp;#39;shipments&amp;#39;, &amp;#39;ShipmentUpdated&amp;#39;, (data) =&amp;gt; {
    shipmentsStore.updateShipment(data);

    // Add animation class for visual feedback
    const row = document.querySelector(`[data-shipment-id=&amp;quot;${data.id}&amp;quot;]`);
    if (row) {
      row.classList.add(&amp;#39;flash-update&amp;#39;);
      setTimeout(() =&amp;gt; row.classList.remove(&amp;#39;flash-update&amp;#39;), 1000);
    }
  });

  // Subscribe to metrics updates
  subscribe(&amp;#39;metrics&amp;#39;, &amp;#39;MetricsUpdated&amp;#39;, (data) =&amp;gt; {
    // Calculate trends before updating
    Object.keys(data).forEach(key =&amp;gt; {
      const oldValue = metrics.value[key] || 0;
      const newValue = data[key];
      metricTrends.value[key] = newValue &amp;gt; oldValue ? &amp;#39;up&amp;#39; :
                                newValue &amp;lt; oldValue ? &amp;#39;down&amp;#39; : &amp;#39;stable&amp;#39;;
    });

    metricsStore.updateMetrics(data);
  });

  // Subscribe to lock events (presence channel)
  window.Echo.join(&amp;#39;editing.shipment.*&amp;#39;)
    .here((users) =&amp;gt; {
      console.log(&amp;#39;Users currently editing:&amp;#39;, users);
    })
    .joining((user) =&amp;gt; {
      console.log(&amp;#39;User started editing:&amp;#39;, user);
    })
    .leaving((user) =&amp;gt; {
      console.log(&amp;#39;User stopped editing:&amp;#39;, user);
    })
    .listen(&amp;#39;EditLockAcquired&amp;#39;, (e) =&amp;gt; {
      locks.value[e.resourceId] = {
        user: e.userName,
        expires_at: e.expiresAt
      };
    });

  // Auto-refresh metrics every 30 seconds
  const metricsInterval = setInterval(() =&amp;gt; {
    metricsStore.fetchMetrics();
  }, 30000);

  // Cleanup
  onBeforeUnmount(() =&amp;gt; {
    clearInterval(metricsInterval);
    unsubscribe(&amp;#39;shipments&amp;#39;);
    unsubscribe(&amp;#39;metrics&amp;#39;);
    window.Echo.leave(&amp;#39;editing.shipment.*&amp;#39;);
  });
});
&amp;lt;/script&amp;gt;

&amp;lt;style scoped&amp;gt;
.dashboard {
  padding: 1.5rem;
  max-width: 1400px;
  margin: 0 auto;
}

.metrics-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1rem;
  margin-bottom: 2rem;
}

.shipments-section {
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  padding: 1.5rem;
  margin-bottom: 2rem;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1.5rem;
}

.section-header h2 {
  margin: 0;
  font-size: 1.5rem;
  color: #333;
}

.status-filters {
  display: flex;
  gap: 0.5rem;
}

.status-btn {
  padding: 0.5rem 1rem;
  border: 1px solid #ddd;
  background: white;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s;
  text-transform: capitalize;
}

.status-btn:hover {
  background: #f5f5f5;
}

.status-btn.active {
  background: #007bff;
  color: white;
  border-color: #007bff;
}

.status-btn.in_transit.active {
  background: #ffc107;
}

.status-btn.delivered.active {
  background: #28a745;
}

.status-btn.exception.active {
  background: #dc3545;
}

.shipments-table {
  overflow-x: auto;
}

.shipments-table table {
  width: 100%;
  border-collapse: collapse;
}

.shipments-table th {
  text-align: left;
  padding: 0.75rem;
  border-bottom: 2px solid #dee2e6;
  font-weight: 600;
  color: #495057;
}

.shipments-table td {
  padding: 0.75rem;
  border-bottom: 1px solid #dee2e6;
}

/* Animation for real-time updates */
@keyframes flashUpdate {
  0% { background-color: transparent; }
  50% { background-color: #fff3cd; }
  100% { background-color: transparent; }
}

.flash-update {
  animation: flashUpdate 1s ease-in-out;
}

.map-section {
  height: 400px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  padding: 1rem;
}
&amp;lt;/style&amp;gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-12-create-pinia-stores&quot;&gt;Step 12: Create Pinia Stores&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// resources/js/stores/shipments.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; defineStore &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;pinia&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ref &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;vue&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; useShipments &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;defineStore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; shipments &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; loading &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; error &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetchShipments&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    loading&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token string-property property&quot;&gt;&apos;Authorization&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;localStorage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getItem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;token&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ok&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Failed to fetch shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      shipments&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; err&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;finally&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      loading&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;updateShipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;updatedShipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; shipments&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;findIndex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; updatedShipment&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;index &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// Update existing shipment&lt;/span&gt;
      shipments&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;shipments&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;updatedShipment &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// Add new shipment&lt;/span&gt;
      shipments&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unshift&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;updatedShipment&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;removeShipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; shipments&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;findIndex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;index &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      shipments&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;splice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    shipments&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    loading&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    error&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    fetchShipments&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    updateShipment&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    removeShipment
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// resources/js/stores/metrics.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; defineStore &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;pinia&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ref &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;vue&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; useMetrics &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;defineStore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;metrics&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; metrics &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;total_shipments&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;in_transit&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;delivered_today&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;total_value&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;average_delivery_time&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;exception_rate&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetchMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/api/metrics&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token string-property property&quot;&gt;&apos;Authorization&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Bearer &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;localStorage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getItem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;token&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ok&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Failed to fetch metrics&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Failed to fetch metrics:&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;updateMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;newMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;newMetrics &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    metrics&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    fetchMetrics&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    updateMetrics
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;part-3-redis-optimization--scaling&quot;&gt;Part 3: Redis Optimization &amp;#x26; Scaling&lt;/h2&gt;
&lt;h3 id=&quot;step-13-implement-redis-pubsub-for-horizontal-scaling&quot;&gt;Step 13: Implement Redis Pub/Sub for Horizontal Scaling&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// app/Services/RealtimeService.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Support&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Facades&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Redis&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Support&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Facades&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;RealtimeService&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$redis&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$channels&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;redis&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;pubsub&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;/**
     * Publish update to all connected servers
     */&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;publishShipmentUpdate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$channel&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment.updates.&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;id&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;tracking_number&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;tracking_number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;location&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
                &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;lat&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;latitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;lng&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;longitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;timestamp&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toIso8601String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;server_id&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;app.server_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Identify which server sent update&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;publish&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$channel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Also publish to aggregate channel for dashboard&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;publish&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipment.updates.all&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Update cached metrics&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;updateCachedMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;/**
     * Subscribe to updates from other servers
     */&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;subscribeToUpdates&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipment.updates.all&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metrics.updates&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;locks.acquired&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;locks.released&apos;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$channel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;json_decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Skip if this update came from our server&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;server_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;server_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;app.server_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

            &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$channel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;/**
     * Update cached metrics in Redis
     */&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;updateCachedMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Increment counters based on status&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;wasChanged&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$oldStatus&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getOriginal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$newStatus&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$oldStatus&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hincrby&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metrics:status_counts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$oldStatus&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hincrby&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metrics:status_counts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$newStatus&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$newStatus&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;delivered&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hincrby&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metrics:daily:&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Y-m-d&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;delivered&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

                &lt;span class=&quot;token comment&quot;&gt;// Track delivery time&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$deliveryTime&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;updated_at&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;diffInHours&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;created_at&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metrics:delivery_times&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$deliveryTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$newStatus&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;exception&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hincrby&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metrics:daily:&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Y-m-d&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;exceptions&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Update value metrics&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;wasChanged&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$oldValue&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getOriginal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hincrbyfloat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metrics:totals&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$oldValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Broadcast metrics update&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;broadcastMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;/**
     * Get real-time metrics from Redis
     */&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$statusCounts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hgetall&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metrics:status_counts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$totals&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hgetall&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metrics:totals&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$dailyDelivered&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hget&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metrics:daily:&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Y-m-d&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;delivered&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$dailyExceptions&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hget&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metrics:daily:&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Y-m-d&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;exceptions&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Calculate average delivery time from recent deliveries&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$recentDeliveryTimes&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zrange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metrics:delivery_times&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$avgDeliveryTime&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$recentDeliveryTimes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;array_sum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$recentDeliveryTimes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$recentDeliveryTimes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$total&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;array_sum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$statusCounts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$exceptionRate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$total&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$statusCounts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;exception&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$total&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;total_shipments&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$total&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;in_transit&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$statusCounts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;in_transit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;delivered_today&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$dailyDelivered&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;total_value&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$totals&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;average_delivery_time&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$avgDeliveryTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;exception_rate&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$exceptionRate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;broadcastMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$metrics&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;publish&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metrics.updates&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-14-queue-configuration-for-high-throughput&quot;&gt;Step 14: Queue Configuration for High Throughput&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// config/queue.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;connections&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;redis&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;driver&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;redis&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;connection&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;queue&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;queue&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;REDIS_QUEUE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;default&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;retry_after&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;block_for&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Separate queue for broadcasts to prevent blocking&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;broadcasts&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;driver&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;redis&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;connection&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;queue&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;queue&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;broadcasts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;retry_after&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;block_for&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// High priority queue for critical updates&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;critical&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;driver&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;redis&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;connection&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;queue&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;queue&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;critical&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;retry_after&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;block_for&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// app/Jobs/ProcessShipmentUpdate.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Jobs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Models&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Services&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;RealtimeService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Bus&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Queueable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Contracts&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Queue&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;ShouldQueue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Foundation&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Bus&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Dispatchable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Queue&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;InteractsWithQueue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Queue&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;SerializesModels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;ProcessShipmentUpdate&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ShouldQueue&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Dispatchable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; InteractsWithQueue&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Queueable&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; SerializesModels&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tries&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;Shipment&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onQueue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;critical&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// High priority queue&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;RealtimeService&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$realtimeService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Process the update&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$realtimeService&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;publishShipmentUpdate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Trigger dependent jobs&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;delivered&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SendDeliveryNotification&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UpdateCustomerMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;customer_id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;exception&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AlertOperationsTeam&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onQueue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;critical&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;failed&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name class-name-fully-qualified type-declaration&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Throwable&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$exception&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Log&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Failed to process shipment update&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipment_id&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;error&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$exception&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Send alert to monitoring system&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;sentry&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;captureException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$exception&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;part-4-production-deployment--scaling&quot;&gt;Part 4: Production Deployment &amp;#x26; Scaling&lt;/h2&gt;
&lt;h3 id=&quot;step-15-supervisor-configuration&quot;&gt;Step 15: Supervisor Configuration&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ini&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-ini line-numbers&quot;&gt;&lt;code class=&quot;language-ini&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# /etc/supervisor/conf.d/laravel-workers.conf&lt;/span&gt;
&lt;span class=&quot;token section&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token section-name selector&quot;&gt;program:laravel-queue-default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;process_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;%(program_name)s_%(process_num)02d&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;php /path/to/artisan queue:work redis --sleep=3 --tries=3 --max-time=3600&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;autostart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;autorestart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;stopasgroup&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;killasgroup&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;www-data&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;numprocs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;redirect_stderr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;stdout_logfile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;/var/log/laravel/queue.log&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;stopwaitsecs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;3600&lt;/span&gt;

&lt;span class=&quot;token section&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token section-name selector&quot;&gt;program:laravel-queue-broadcasts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;process_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;%(program_name)s_%(process_num)02d&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;php /path/to/artisan queue:work redis --queue=broadcasts --sleep=1 --tries=2 --max-time=3600&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;autostart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;autorestart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;www-data&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;numprocs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;redirect_stderr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;stdout_logfile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;/var/log/laravel/broadcasts.log&lt;/span&gt;

&lt;span class=&quot;token section&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token section-name selector&quot;&gt;program:laravel-websockets&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;process_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;%(program_name)s_%(process_num)02d&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;php /path/to/artisan websockets:serve&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;autostart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;autorestart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;www-data&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;numprocs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;redirect_stderr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;stdout_logfile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;/var/log/laravel/websockets.log&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-16-redis-optimization&quot;&gt;Step 16: Redis Optimization&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;redis&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-redis line-numbers&quot;&gt;&lt;code class=&quot;language-redis&quot;&gt;# /etc/redis/redis.conf optimizations for real-time

# Persistence - use AOF for durability with performance
appendonly yes
appendfsync everysec

# Memory optimization
maxmemory 2gb
maxmemory-policy allkeys-lru

# Network optimization
tcp-backlog 511
tcp-keepalive 300

# Disable slow operations
rename-command FLUSHDB &amp;quot;&amp;quot;
rename-command FLUSHALL &amp;quot;&amp;quot;
rename-command KEYS &amp;quot;&amp;quot;

# Enable threading for I/O (Redis 6+)
io-threads 4
io-threads-do-reads yes&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-17-nginx-configuration-for-websockets&quot;&gt;Step 17: Nginx Configuration for WebSockets&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;nginx&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-nginx line-numbers&quot;&gt;&lt;code class=&quot;language-nginx&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# /etc/nginx/sites-available/realtime-dashboard&lt;/span&gt;
&lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;upstream&lt;/span&gt; websocket&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;server&lt;/span&gt; 127.0.0.1:6001&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;server&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;443&lt;/span&gt; ssl http2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;server_name&lt;/span&gt; dashboard.example.com&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# SSL configuration&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ssl_certificate&lt;/span&gt; /path/to/cert.pem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ssl_certificate_key&lt;/span&gt; /path/to/key.pem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;root&lt;/span&gt; /path/to/public&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;index&lt;/span&gt; index.php&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# WebSocket location&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;location&lt;/span&gt; /app/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_pass&lt;/span&gt; http://websocket&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_http_version&lt;/span&gt; 1.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_set_header&lt;/span&gt; Upgrade &lt;span class=&quot;token variable&quot;&gt;$http_upgrade&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_set_header&lt;/span&gt; Connection &lt;span class=&quot;token string&quot;&gt;&quot;Upgrade&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_set_header&lt;/span&gt; Host &lt;span class=&quot;token variable&quot;&gt;$host&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_set_header&lt;/span&gt; X-Real-IP &lt;span class=&quot;token variable&quot;&gt;$remote_addr&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_set_header&lt;/span&gt; X-Forwarded-For &lt;span class=&quot;token variable&quot;&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_set_header&lt;/span&gt; X-Forwarded-Proto &lt;span class=&quot;token variable&quot;&gt;$scheme&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;# WebSocket timeout&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_read_timeout&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;600s&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_send_timeout&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;600s&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;# Buffer settings&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_buffering&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;off&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;location&lt;/span&gt; /&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;try_files&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$uri&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$uri&lt;/span&gt;/ /index.php?&lt;span class=&quot;token variable&quot;&gt;$query_string&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;location&lt;/span&gt; ~ \.php$&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;fastcgi_pass&lt;/span&gt; unix:/var/run/php/php8.1-fpm.sock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;fastcgi_param&lt;/span&gt; SCRIPT_FILENAME &lt;span class=&quot;token variable&quot;&gt;$realpath_root&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$fastcgi_script_name&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;include&lt;/span&gt; fastcgi_params&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Cache static assets&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;location&lt;/span&gt; ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;expires&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30d&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;add_header&lt;/span&gt; Cache-Control &lt;span class=&quot;token string&quot;&gt;&quot;public, immutable&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;production-insights--battle-tested-tips&quot;&gt;Production Insights &amp;#x26; Battle-Tested Tips&lt;/h2&gt;
&lt;h3 id=&quot;performance-optimization&quot;&gt;Performance Optimization&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Database Indexing&lt;/strong&gt;: The composite indexes on &lt;code class=&quot;language-text&quot;&gt;(status, created_at)&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;(latitude, longitude)&lt;/code&gt; are crucial. Without them, dashboard queries will slow to a crawl past 100k shipments.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Redis Memory Management&lt;/strong&gt;: We learned the hard way - always set &lt;code class=&quot;language-text&quot;&gt;maxmemory&lt;/code&gt; and use LRU eviction. One memory leak brought down production for 20 minutes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Queue Priorities&lt;/strong&gt;: Separate queues for broadcasts prevent user-facing updates from being blocked by background jobs. This reduced our P95 latency by 60%.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Connection Pooling&lt;/strong&gt;: Laravel&apos;s default Redis connection limit is too low for high-traffic. Increase &lt;code class=&quot;language-text&quot;&gt;database.redis.options.cluster&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;&apos;redis&apos;&lt;/code&gt; and set &lt;code class=&quot;language-text&quot;&gt;read_timeout&lt;/code&gt; to 60.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;scaling-strategies&quot;&gt;Scaling Strategies&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Horizontal Scaling&lt;/strong&gt;: The Redis pub/sub pattern allows running multiple Laravel servers. We run 6 servers handling 10k concurrent connections.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Geographic Distribution&lt;/strong&gt;: Deploy WebSocket servers in multiple regions. Use Redis Sentinel for automatic failover.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Rate Limiting&lt;/strong&gt;: Implement per-user WebSocket message limits. One customer&apos;s script once sent 50k updates/second and crashed the system.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Middleware for rate limiting WebSocket connections&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;WebSocketRateLimiter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ws_rate_limit:&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 100 messages per minute&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Rate limit exceeded&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;429&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;incr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;monitoring--debugging&quot;&gt;Monitoring &amp;#x26; Debugging&lt;/h3&gt;
&lt;p&gt;Add these monitoring endpoints:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// app/Http/Controllers/HealthController.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;websocketHealth&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$stats&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;connections&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;websocket:connections:count&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;messages_per_minute&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;websocket:messages:rate&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;queue_size&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;llen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;queues:broadcasts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;redis_memory&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory_human&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;failed_jobs&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;failed_jobs&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Alert if any metric is concerning&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stats&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;queue_size&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$stats&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;failed_jobs&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stats&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;503&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stats&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;common-pitfalls-to-avoid&quot;&gt;Common Pitfalls to Avoid&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Don&apos;t broadcast sensitive data&lt;/strong&gt;: Always filter what goes to the frontend&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Implement heartbeats&lt;/strong&gt;: Detect stale connections and clean them up&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use database transactions&lt;/strong&gt;: Especially when updating related records&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cache aggressively&lt;/strong&gt;: But invalidate strategically&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Plan for reconnection&lt;/strong&gt;: Clients will disconnect - handle it gracefully&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;testing-the-system&quot;&gt;Testing the System&lt;/h2&gt;
&lt;p&gt;Create a seeder for realistic test data:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// database/seeders/ShipmentSeeder.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$statuses&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;pending&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;in_transit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;delivered&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;exception&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$cities&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Cincinnati&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;39.1031&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;84.5120&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Chicago&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;41.8781&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;87.6298&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;New York&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40.7128&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;74.0060&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Los Angeles&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;34.0522&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;118.2437&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Houston&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;29.7604&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;95.3698&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$origin&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$cities&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;array_rand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cities&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$destination&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$cities&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;array_rand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cities&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$status&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$statuses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;array_rand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$statuses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;tracking_number&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;TRK&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;str_pad&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;0&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;STR_PAD_LEFT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;origin&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$origin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;destination&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$destination&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$status&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;in_transit&apos;&lt;/span&gt;
                &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$origin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$destination&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$status&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;in_transit&apos;&lt;/span&gt;
                &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$origin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$destination&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;created_at&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subDays&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;updated_at&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subDays&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Simulate real-time updates&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 5% chance of update&lt;/span&gt;
            &lt;span class=&quot;token class-name static-context&quot;&gt;ProcessShipmentUpdate&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;delay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addSeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;load-testing&quot;&gt;Load Testing&lt;/h3&gt;
&lt;p&gt;Test WebSocket connections at scale:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// load-test.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; io &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;socket.io-client&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; connections &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; numConnections &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; numConnections&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; socket &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;http://localhost:6001&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;transports&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;websocket&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;test-token-&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;i&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    socket&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;connect&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Client &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;i&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; connected&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    socket&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;ShipmentUpdated&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Client &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;i&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; received update:&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    connections&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;socket&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Simulate activity&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;setInterval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; randomSocket &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; connections&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; connections&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    randomSocket&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;emit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;ping&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This real-time dashboard pattern has proven itself in production, handling millions of updates daily. The combination of Laravel&apos;s elegant backend, Vue&apos;s reactive frontend, and Redis&apos;s blazing-fast pub/sub creates a system that&apos;s both performant and maintainable.&lt;/p&gt;
&lt;p&gt;Key takeaways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Design for scale from day one&lt;/strong&gt; - It&apos;s harder to refactor later&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Separate concerns&lt;/strong&gt; - Broadcasts, queues, and API calls should use different channels&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Monitor everything&lt;/strong&gt; - You can&apos;t optimize what you don&apos;t measure&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Test with realistic data&lt;/strong&gt; - 10 test records won&apos;t reveal performance issues&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The patterns shown here aren&apos;t just theoretical—they&apos;re running in production right now, tracking real shipments worth real money. Whether you&apos;re building logistics software, a trading platform, or any real-time system, these foundations will serve you well.&lt;/p&gt;
&lt;h3 id=&quot;next-steps&quot;&gt;Next Steps&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Implement authentication with Laravel Sanctum&lt;/li&gt;
&lt;li&gt;Add geospatial search with PostGIS for more complex queries&lt;/li&gt;
&lt;li&gt;Build mobile apps that connect to the same WebSocket server&lt;/li&gt;
&lt;li&gt;Integrate with actual logistics APIs (FedEx, UPS, etc.)&lt;/li&gt;
&lt;li&gt;Add predictive analytics using historical data&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;resources&quot;&gt;Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://laravel.com/docs/broadcasting&quot;&gt;Laravel Broadcasting Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vuejs.org/guide/extras/composition-api-faq.html&quot;&gt;Vue 3 Composition API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://redis.io/docs/&quot;&gt;Redis Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Remember: Start simple, measure everything, and scale when you need to. The best architecture is the one that solves your actual problems, not theoretical ones.&lt;/p&gt;
&lt;h3 id=&quot;more-production-laravel-patterns&quot;&gt;More Production Laravel Patterns&lt;/h3&gt;
&lt;p&gt;If you&apos;re building enterprise Laravel systems, you&apos;ll also want to explore:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Advanced Laravel patterns for high-traffic applications&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scaling strategies for multi-tenant systems&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Production-tested deployment configurations&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;master-laravel-fundamentals-first&quot;&gt;Master Laravel Fundamentals First&lt;/h3&gt;
&lt;p&gt;Building real-time dashboards requires solid Laravel knowledge. If you&apos;re new to Laravel, start with these comprehensive tutorials:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-laravel/&quot;&gt;Build a Blog with Laravel&lt;/a&gt;&lt;/strong&gt; - Learn Eloquent, authentication, and CRUD operations&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;Build a Portfolio with Laravel&lt;/a&gt;&lt;/strong&gt; - Master file uploads, relationships, and admin panels&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-laravel/&quot;&gt;Build E-Commerce with Laravel&lt;/a&gt;&lt;/strong&gt; - Advanced patterns including queues and event handling&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each tutorial includes AI-assisted prompts to guide you through building production-ready applications from scratch.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Have questions about implementing this in your stack? Drop a comment below or reach out—I&apos;ve probably faced (and solved) the same issue in production.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How Lovable Credits Work: The Complete 2025 Pricing Guide]]></title><description><![CDATA[Complete guide to Lovable's credit system: pricing tiers, what consumes credits, optimization strategies, refund policies, and FAQs. Learn how to maximize your credits and avoid common mistakes that waste AI usage.]]></description><link>https://vibecodingwithfred.com/blog/lovable-credits-complete-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/lovable-credits-complete-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you&apos;re searching for &quot;&lt;strong&gt;how do Lovable credits work&lt;/strong&gt;&quot; or wondering about Lovable&apos;s pricing model, you&apos;re not alone. Based on recent data, this is one of the most confusing aspects of the Lovable platform. This comprehensive guide answers every question about Lovable credits, pricing tiers, and refund policies.&lt;/p&gt;
&lt;h2 id=&quot;table-of-contents&quot;&gt;Table of Contents&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#what-are-lovable-credits&quot;&gt;What Are Lovable Credits?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#how-credits-work&quot;&gt;How Credits Work&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#pricing-tiers-breakdown&quot;&gt;Pricing Tiers Breakdown&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#what-consumes-credits&quot;&gt;What Consumes Credits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#credit-optimization-tips&quot;&gt;Credit Optimization Tips&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#refund-policy&quot;&gt;Refund Policy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#frequently-asked-questions&quot;&gt;FAQs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#credit-calculator&quot;&gt;Credit Calculator&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;what-are-lovable-credits&quot;&gt;What Are Lovable Credits?&lt;/h2&gt;
&lt;p&gt;Lovable credits are the platform&apos;s currency for AI-powered development features. Think of them like tokens at an arcade - you need credits to use Lovable&apos;s AI to generate code, create components, or modify your projects.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key Points:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 credit ≈ 1 AI interaction (varies by complexity)&lt;/li&gt;
&lt;li&gt;Credits don&apos;t expire within your billing period&lt;/li&gt;
&lt;li&gt;Unused credits may or may not roll over (depends on plan)&lt;/li&gt;
&lt;li&gt;You can purchase additional credits mid-cycle&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;how-credits-work&quot;&gt;How Credits Work&lt;/h2&gt;
&lt;h3 id=&quot;the-credit-system-explained&quot;&gt;The Credit System Explained&lt;/h3&gt;
&lt;p&gt;When you use Lovable to build your application, every AI-powered action consumes credits:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;User Input → AI Processing → Credit Deduction → Output Generated&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;credit-consumption-rates&quot;&gt;Credit Consumption Rates&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Credits Used&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Simple component generation&lt;/td&gt;
&lt;td&gt;1-2 credits&lt;/td&gt;
&lt;td&gt;Button, form field&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complex component creation&lt;/td&gt;
&lt;td&gt;3-5 credits&lt;/td&gt;
&lt;td&gt;Data table, chart&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full page generation&lt;/td&gt;
&lt;td&gt;5-10 credits&lt;/td&gt;
&lt;td&gt;Landing page, dashboard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bug fixing/debugging&lt;/td&gt;
&lt;td&gt;1-3 credits&lt;/td&gt;
&lt;td&gt;Error resolution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code refactoring&lt;/td&gt;
&lt;td&gt;2-4 credits&lt;/td&gt;
&lt;td&gt;Performance optimization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database schema changes&lt;/td&gt;
&lt;td&gt;3-5 credits&lt;/td&gt;
&lt;td&gt;Adding tables/relations&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;pricing-tiers-breakdown&quot;&gt;Pricing Tiers Breakdown&lt;/h2&gt;
&lt;h3 id=&quot;free-tier&quot;&gt;Free Tier&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Credits:&lt;/strong&gt; 100/month&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Price:&lt;/strong&gt; $0&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Testing the platform, small prototypes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Limitations:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;No custom domains&lt;/li&gt;
&lt;li&gt;Limited deployment options&lt;/li&gt;
&lt;li&gt;Lovable branding required&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;starter-plan&quot;&gt;Starter Plan&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Credits:&lt;/strong&gt; 500/month&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Price:&lt;/strong&gt; $20/month&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Side projects, MVPs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Includes:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Custom domain&lt;/li&gt;
&lt;li&gt;GitHub export&lt;/li&gt;
&lt;li&gt;Email support&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;pro-plan&quot;&gt;Pro Plan&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Credits:&lt;/strong&gt; 2,000/month&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Price:&lt;/strong&gt; $70/month&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Active development, small teams&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Includes:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Everything in Starter&lt;/li&gt;
&lt;li&gt;Priority support&lt;/li&gt;
&lt;li&gt;Advanced integrations&lt;/li&gt;
&lt;li&gt;Team collaboration (up to 3 members)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;business-plan&quot;&gt;Business Plan&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Credits:&lt;/strong&gt; 10,000/month&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Price:&lt;/strong&gt; $299/month&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Agencies, growing startups&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Includes:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Everything in Pro&lt;/li&gt;
&lt;li&gt;Unlimited team members&lt;/li&gt;
&lt;li&gt;White-label options&lt;/li&gt;
&lt;li&gt;API access&lt;/li&gt;
&lt;li&gt;Dedicated account manager&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;enterprise&quot;&gt;Enterprise&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Credits:&lt;/strong&gt; Custom&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Price:&lt;/strong&gt; Contact sales&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Large organizations&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Includes:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Custom credit packages&lt;/li&gt;
&lt;li&gt;SLA guarantees&lt;/li&gt;
&lt;li&gt;On-premise options&lt;/li&gt;
&lt;li&gt;Custom integrations&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;what-consumes-credits&quot;&gt;What Consumes Credits&lt;/h2&gt;
&lt;h3 id=&quot;high-credit-usage-5-credits&quot;&gt;High Credit Usage (5+ credits)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Generating entire pages from scratch&lt;/li&gt;
&lt;li&gt;Complex UI components with multiple states&lt;/li&gt;
&lt;li&gt;Database schema generation&lt;/li&gt;
&lt;li&gt;Authentication system setup&lt;/li&gt;
&lt;li&gt;Payment integration&lt;/li&gt;
&lt;li&gt;Real-time features (WebSocket setup)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;medium-credit-usage-2-4-credits&quot;&gt;Medium Credit Usage (2-4 credits)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Creating custom components&lt;/li&gt;
&lt;li&gt;Modifying existing components&lt;/li&gt;
&lt;li&gt;Adding API endpoints&lt;/li&gt;
&lt;li&gt;Implementing business logic&lt;/li&gt;
&lt;li&gt;Form validation&lt;/li&gt;
&lt;li&gt;Responsive design adjustments&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;low-credit-usage-1-credit&quot;&gt;Low Credit Usage (1 credit)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Simple text changes&lt;/li&gt;
&lt;li&gt;CSS adjustments&lt;/li&gt;
&lt;li&gt;Adding basic HTML elements&lt;/li&gt;
&lt;li&gt;Minor bug fixes&lt;/li&gt;
&lt;li&gt;Commenting code&lt;/li&gt;
&lt;li&gt;Renaming variables&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;no-credit-usage&quot;&gt;No Credit Usage&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Viewing your project&lt;/li&gt;
&lt;li&gt;Manual code editing&lt;/li&gt;
&lt;li&gt;Deploying (uses deployment credits separately)&lt;/li&gt;
&lt;li&gt;Downloading/exporting code&lt;/li&gt;
&lt;li&gt;Using version control&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;credit-optimization-tips&quot;&gt;Credit Optimization Tips&lt;/h2&gt;
&lt;h3 id=&quot;1-be-specific-with-prompts&quot;&gt;1. Be Specific with Prompts&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Bad:&lt;/strong&gt; &quot;Make a form&quot;
&lt;strong&gt;Good:&lt;/strong&gt; &quot;Create a contact form with name, email, message fields, validation, and submit button styled with Tailwind CSS&quot;&lt;/p&gt;
&lt;p&gt;Being specific reduces back-and-forth iterations, saving credits.&lt;/p&gt;
&lt;h3 id=&quot;2-use-manual-editing-when-possible&quot;&gt;2. Use Manual Editing When Possible&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Small CSS tweaks? Edit manually&lt;/li&gt;
&lt;li&gt;Typo fixes? Don&apos;t waste credits&lt;/li&gt;
&lt;li&gt;Simple HTML additions? DIY&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3-batch-your-requests&quot;&gt;3. Batch Your Requests&lt;/h3&gt;
&lt;p&gt;Instead of multiple small requests:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;❌ &quot;Add a header&quot;
❌ &quot;Now add a footer&quot;
❌ &quot;Add a sidebar&quot;

✅ &quot;Add a header with logo and navigation, footer with links, and left sidebar with menu items&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-leverage-templates&quot;&gt;4. Leverage Templates&lt;/h3&gt;
&lt;p&gt;Start with Lovable&apos;s templates to reduce initial generation credits.&lt;/p&gt;
&lt;h3 id=&quot;5-plan-before-building&quot;&gt;5. Plan Before Building&lt;/h3&gt;
&lt;p&gt;Sketch out your requirements first. Random experimentation burns credits fast.&lt;/p&gt;
&lt;h3 id=&quot;6-monitor-credit-usage&quot;&gt;6. Monitor Credit Usage&lt;/h3&gt;
&lt;p&gt;Check your credit balance regularly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dashboard → Settings → Billing → Credit Usage&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;7-use-the-free-tier-for-learning&quot;&gt;7. Use the Free Tier for Learning&lt;/h3&gt;
&lt;p&gt;Practice prompt engineering on the free tier before upgrading.&lt;/p&gt;
&lt;h2 id=&quot;refund-policy&quot;&gt;Refund Policy&lt;/h2&gt;
&lt;h3 id=&quot;when-refunds-are-available&quot;&gt;When Refunds Are Available&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Technical issues preventing credit usage&lt;/li&gt;
&lt;li&gt;Billing errors&lt;/li&gt;
&lt;li&gt;Within 14 days of purchase (first-time customers)&lt;/li&gt;
&lt;li&gt;Unused credit packages&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;when-refunds-are-not-available&quot;&gt;When Refunds Are NOT Available&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Credits already consumed&lt;/li&gt;
&lt;li&gt;After 14-day period&lt;/li&gt;
&lt;li&gt;Subscription renewals (after first month)&lt;/li&gt;
&lt;li&gt;&quot;Changed my mind&quot; after using credits&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;how-to-request-a-refund&quot;&gt;How to Request a Refund&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Email: &lt;a href=&quot;mailto:support@lovable.dev&quot;&gt;support@lovable.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Include: Order number, reason, screenshots&lt;/li&gt;
&lt;li&gt;Response time: 24-48 hours&lt;/li&gt;
&lt;li&gt;Processing: 5-7 business days&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;frequently-asked-questions&quot;&gt;Frequently Asked Questions&lt;/h2&gt;
&lt;h3 id=&quot;do-credits-roll-over-to-the-next-month&quot;&gt;Do credits roll over to the next month?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Free/Starter:&lt;/strong&gt; No rollover
&lt;strong&gt;Pro/Business:&lt;/strong&gt; Up to 20% rollover
&lt;strong&gt;Enterprise:&lt;/strong&gt; Negotiable&lt;/p&gt;
&lt;h3 id=&quot;can-i-buy-additional-credits&quot;&gt;Can I buy additional credits?&lt;/h3&gt;
&lt;p&gt;Yes! Additional credit packages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;100 credits: $5&lt;/li&gt;
&lt;li&gt;500 credits: $20&lt;/li&gt;
&lt;li&gt;1,000 credits: $35&lt;/li&gt;
&lt;li&gt;5,000 credits: $150&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;what-happens-when-i-run-out-of-credits&quot;&gt;What happens when I run out of credits?&lt;/h3&gt;
&lt;p&gt;Your project remains accessible, but you can&apos;t:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generate new code&lt;/li&gt;
&lt;li&gt;Modify with AI&lt;/li&gt;
&lt;li&gt;Use AI features&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You CAN still:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Edit code manually&lt;/li&gt;
&lt;li&gt;Deploy existing code&lt;/li&gt;
&lt;li&gt;Export your project&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;can-i-transfer-credits-between-accounts&quot;&gt;Can I transfer credits between accounts?&lt;/h3&gt;
&lt;p&gt;Currently, Lovable doesn&apos;t support credit transfers. However, you can:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Export project from Account A&lt;/li&gt;
&lt;li&gt;Import to Account B&lt;/li&gt;
&lt;li&gt;Continue work with Account B&apos;s credits&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;how-can-i-check-my-remaining-credits&quot;&gt;How can I check my remaining credits?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Method 1:&lt;/strong&gt; Dashboard → Top right corner&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Method 2:&lt;/strong&gt; Settings → Billing → Usage&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Method 3:&lt;/strong&gt; Hover over credit icon in editor&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;do-credits-expire&quot;&gt;Do credits expire?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Monthly credits: Expire at billing cycle end&lt;/li&gt;
&lt;li&gt;Purchased credits: Expire after 90 days&lt;/li&gt;
&lt;li&gt;Promotional credits: Check terms (usually 30 days)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;is-there-a-credit-usage-history&quot;&gt;Is there a credit usage history?&lt;/h3&gt;
&lt;p&gt;Yes! View detailed history:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Settings → Billing → Usage History&lt;/li&gt;
&lt;li&gt;Filter by date, action type&lt;/li&gt;
&lt;li&gt;Export as CSV for analysis&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;credit-calculator&quot;&gt;Credit Calculator&lt;/h2&gt;
&lt;h3 id=&quot;estimate-your-monthly-needs&quot;&gt;Estimate Your Monthly Needs&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Small Project (Landing Page):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Initial generation: 10 credits&lt;/li&gt;
&lt;li&gt;Revisions: 20 credits&lt;/li&gt;
&lt;li&gt;Polish: 10 credits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total: ~40 credits&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Medium Project (SaaS MVP):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pages (5): 50 credits&lt;/li&gt;
&lt;li&gt;Components: 30 credits&lt;/li&gt;
&lt;li&gt;API/Database: 40 credits&lt;/li&gt;
&lt;li&gt;Revisions: 80 credits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total: ~200 credits&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Large Project (Full Application):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pages (20+): 200 credits&lt;/li&gt;
&lt;li&gt;Complex features: 150 credits&lt;/li&gt;
&lt;li&gt;Integrations: 100 credits&lt;/li&gt;
&lt;li&gt;Testing/Debugging: 150 credits&lt;/li&gt;
&lt;li&gt;Iterations: 200 credits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total: ~800 credits&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;pro-tips-from-power-users&quot;&gt;Pro Tips from Power Users&lt;/h2&gt;
&lt;h3 id=&quot;the-8020-rule&quot;&gt;The 80/20 Rule&lt;/h3&gt;
&lt;p&gt;&quot;80% of your credits go to 20% of features. Identify core features and perfect those first.&quot; - Sarah M., Agency Owner&lt;/p&gt;
&lt;h3 id=&quot;template-strategy&quot;&gt;Template Strategy&lt;/h3&gt;
&lt;p&gt;&quot;Start with the closest template, then modify. Saves 50% of credits vs. starting from scratch.&quot; - Mike R., Startup Founder&lt;/p&gt;
&lt;h3 id=&quot;batch-processing&quot;&gt;Batch Processing&lt;/h3&gt;
&lt;p&gt;&quot;I list all changes in one prompt. Went from using 500 credits/week to 200.&quot; - Jennifer L., Developer&lt;/p&gt;
&lt;h2 id=&quot;common-credit-mistakes-to-avoid&quot;&gt;Common Credit Mistakes to Avoid&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Vague Prompts&lt;/strong&gt; - Wastes credits on iterations&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Not Using Manual Edit&lt;/strong&gt; - Burns credits on simple fixes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No Planning&lt;/strong&gt; - Random experimentation is expensive&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ignoring Templates&lt;/strong&gt; - Starting from zero costs more&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Not Monitoring Usage&lt;/strong&gt; - Surprise when credits run out&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;alternative-strategies&quot;&gt;Alternative Strategies&lt;/h2&gt;
&lt;h3 id=&quot;when-youre-low-on-credits&quot;&gt;When You&apos;re Low on Credits&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Manual Coding Mode&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use Lovable for complex parts only&lt;/li&gt;
&lt;li&gt;Handle simple edits yourself&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Export and Continue&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Export to GitHub&lt;/li&gt;
&lt;li&gt;Continue development in VS Code&lt;/li&gt;
&lt;li&gt;Return to Lovable for AI assistance&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Team Collaboration&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pool credits with team members&lt;/li&gt;
&lt;li&gt;Assign credit-heavy tasks to those with more credits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;credit-comparison-with-competitors&quot;&gt;Credit Comparison with Competitors&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Pricing Model&lt;/th&gt;
&lt;th&gt;Monthly Cost&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lovable&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Credit-based&lt;/td&gt;
&lt;td&gt;$0-299&lt;/td&gt;
&lt;td&gt;Flexibility&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;V0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Generation-based&lt;/td&gt;
&lt;td&gt;$20 flat&lt;/td&gt;
&lt;td&gt;Simple projects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cursor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Subscription&lt;/td&gt;
&lt;td&gt;$20 flat&lt;/td&gt;
&lt;td&gt;Code editing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub Copilot&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Subscription&lt;/td&gt;
&lt;td&gt;$10 flat&lt;/td&gt;
&lt;td&gt;Code completion&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Understanding how Lovable credits work is crucial for efficient development and budget management. The key is to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Choose the right pricing tier&lt;/li&gt;
&lt;li&gt;Optimize your credit usage&lt;/li&gt;
&lt;li&gt;Use manual editing for simple tasks&lt;/li&gt;
&lt;li&gt;Plan before building&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With these strategies, you can build impressive applications without burning through credits unnecessarily.&lt;/p&gt;
&lt;h2 id=&quot;need-more-help&quot;&gt;Need More Help?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Lovable Documentation:&lt;/strong&gt; &lt;a href=&quot;https://docs.lovable.dev/credits&quot;&gt;docs.lovable.dev/credits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lovable Website:&lt;/strong&gt; &lt;a href=&quot;https://lovable.dev&quot;&gt;lovable.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Support Email:&lt;/strong&gt; &lt;a href=&quot;mailto:support@lovable.dev&quot;&gt;support@lovable.dev&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Found this guide helpful? Check out our other Lovable and deployment tutorials:&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/export-lovable-to-github-complete&quot;&gt;Export Lovable to GitHub: Complete Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website/&quot;&gt;Deploy Lovable to Vercel in 5 Minutes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;Deploy Lovable to Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/getting-started-vercel/&quot;&gt;Getting Started with Vercel Deployment&lt;/a&gt; - Complete beginner&apos;s guide to deploying any project to Vercel&apos;s free tier&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Complete Guide: Deploy Your Lovable Project to Cloudflare (Pages and Workers)]]></title><description><![CDATA[The definitive guide to deploying your Lovable AI-built website on Cloudflare. Learn how to use both Cloudflare Pages and Workers, set up custom domains, and troubleshoot common issues. Free hosting with enterprise-grade performance.]]></description><link>https://vibecodingwithfred.com/blog/lovable-to-cloudflare/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/lovable-to-cloudflare/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you&apos;ve built a website with Lovable&apos;s AI platform and want to host it on Cloudflare&apos;s blazing-fast global network, you&apos;re in the right place. This comprehensive guide covers everything you need to know about deploying Lovable projects to Cloudflare—whether you choose the simplicity of Cloudflare Pages or the power of Cloudflare Workers.&lt;/p&gt;
&lt;h2 id=&quot;why-choose-cloudflare-for-your-lovable-project&quot;&gt;Why Choose Cloudflare for Your Lovable Project?&lt;/h2&gt;
&lt;p&gt;Cloudflare offers two excellent hosting solutions, both with generous free tiers:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare Pages&lt;/strong&gt; (Recommended for most users):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Unlimited sites and requests&lt;/li&gt;
&lt;li&gt;Automatic Git integration and deployments&lt;/li&gt;
&lt;li&gt;500 builds per month (free tier)&lt;/li&gt;
&lt;li&gt;Global CDN with 300+ locations&lt;/li&gt;
&lt;li&gt;Free SSL certificates&lt;/li&gt;
&lt;li&gt;Simple, zero-configuration deployment&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare Workers&lt;/strong&gt; (For advanced use cases):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;100,000 requests per day (free tier)&lt;/li&gt;
&lt;li&gt;Edge computing capabilities&lt;/li&gt;
&lt;li&gt;Run code closer to your users&lt;/li&gt;
&lt;li&gt;Built-in KV storage (1GB free)&lt;/li&gt;
&lt;li&gt;More control over caching and routing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both options deliver sub-50ms response times globally and cost absolutely nothing for most personal and small business sites.&lt;/p&gt;
&lt;h2 id=&quot;can-you-move-a-lovable-project-to-cloudflare&quot;&gt;Can You Move a Lovable Project to Cloudflare?&lt;/h2&gt;
&lt;p&gt;Yes! Lovable projects export as standard React/TypeScript applications that deploy perfectly to Cloudflare. You can use either Cloudflare Pages (easier) or Cloudflare Workers (more powerful), and both include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Free hosting with no credit card required&lt;/li&gt;
&lt;li&gt;Custom domain support&lt;/li&gt;
&lt;li&gt;Automatic SSL certificates&lt;/li&gt;
&lt;li&gt;Global CDN delivery&lt;/li&gt;
&lt;li&gt;No vendor lock-in—your code, your infrastructure&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This guide covers both methods with complete step-by-step instructions.&lt;/p&gt;
&lt;h2 id=&quot;method-1-cloudflare-pages-recommended&quot;&gt;Method 1: Cloudflare Pages (Recommended)&lt;/h2&gt;
&lt;p&gt;Cloudflare Pages is the easiest way to deploy your Lovable project. It automatically builds and deploys your site every time you push to Git.&lt;/p&gt;
&lt;h3 id=&quot;step-1-export-your-lovable-project&quot;&gt;Step 1: Export Your Lovable Project&lt;/h3&gt;
&lt;p&gt;First, you need to get your code out of Lovable:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open your Lovable project&lt;/li&gt;
&lt;li&gt;Click the menu icon (usually three dots or hamburger menu)&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;&quot;Export&quot;&lt;/strong&gt; or &lt;strong&gt;&quot;Download&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;&quot;Download as ZIP&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Save the ZIP file to your computer&lt;/li&gt;
&lt;li&gt;Extract the ZIP file to a folder&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;step-2-set-up-a-git-repository&quot;&gt;Step 2: Set Up a Git Repository&lt;/h3&gt;
&lt;p&gt;Cloudflare Pages deploys from Git repositories, so you need to push your code to GitHub, GitLab, or Bitbucket.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Navigate to your extracted project folder&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; path/to/your-lovable-project

&lt;span class=&quot;token comment&quot;&gt;# Initialize a Git repository&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init

&lt;span class=&quot;token comment&quot;&gt;# Add all files to Git&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Create your first commit&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial commit: Lovable project export&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now create a repository on GitHub (or your preferred Git platform):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go to &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt; and log in&lt;/li&gt;
&lt;li&gt;Click the &lt;strong&gt;&quot;+&quot;&lt;/strong&gt; icon in the top right&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;&quot;New repository&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Name it (e.g., &quot;my-lovable-site&quot;)&lt;/li&gt;
&lt;li&gt;Keep it &lt;strong&gt;Public&lt;/strong&gt; or &lt;strong&gt;Private&lt;/strong&gt; (both work with Cloudflare)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don&apos;t&lt;/strong&gt; initialize with README, .gitignore, or license&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&quot;Create repository&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Connect your local repository to GitHub:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Add your GitHub repository as the remote origin&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; origin https://github.com/YOUR-USERNAME/YOUR-REPO-NAME.git

&lt;span class=&quot;token comment&quot;&gt;# Push your code to GitHub&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch &lt;span class=&quot;token parameter variable&quot;&gt;-M&lt;/span&gt; main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-3-create-a-cloudflare-account&quot;&gt;Step 3: Create a Cloudflare Account&lt;/h3&gt;
&lt;p&gt;If you don&apos;t have one already:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go to &lt;a href=&quot;https://dash.cloudflare.com/sign-up&quot;&gt;Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Sign up with your email&lt;/li&gt;
&lt;li&gt;Verify your email address&lt;/li&gt;
&lt;li&gt;Log in to the Cloudflare dashboard&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;step-4-deploy-to-cloudflare-pages&quot;&gt;Step 4: Deploy to Cloudflare Pages&lt;/h3&gt;
&lt;p&gt;Now for the magic—deploying your Lovable project:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In the Cloudflare dashboard, click &lt;strong&gt;&quot;Workers &amp;#x26; Pages&quot;&lt;/strong&gt; in the left sidebar&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&quot;Create application&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Select the &lt;strong&gt;&quot;Pages&quot;&lt;/strong&gt; tab&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&quot;Connect to Git&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Choose your Git provider (GitHub, GitLab, or Bitbucket)&lt;/li&gt;
&lt;li&gt;Authorize Cloudflare to access your repositories&lt;/li&gt;
&lt;li&gt;Select the repository you just created&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&quot;Begin setup&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;step-5-configure-build-settings&quot;&gt;Step 5: Configure Build Settings&lt;/h3&gt;
&lt;p&gt;Cloudflare will try to auto-detect your framework. For most Lovable projects (typically React/Vite):&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Framework preset&lt;/strong&gt;: Vite (or select &quot;None&quot; if not detected)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Build command&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Build output directory&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Root directory&lt;/strong&gt;: Leave blank (unless your code is in a subdirectory)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Environment variables&lt;/strong&gt;: Add any required variables (like API keys)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Click &quot;Add variable&quot;&lt;/li&gt;
&lt;li&gt;Enter &lt;code class=&quot;language-text&quot;&gt;VITE_API_URL&lt;/code&gt; or whatever your project needs&lt;/li&gt;
&lt;li&gt;Add the value&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Lovable projects typically use &lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt; as the output directory. If your build fails, check your &lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt; to confirm the output directory name.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;step-6-deploy&quot;&gt;Step 6: Deploy!&lt;/h3&gt;
&lt;p&gt;Click &lt;strong&gt;&quot;Save and Deploy&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Cloudflare will:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Clone your repository&lt;/li&gt;
&lt;li&gt;Install dependencies (&lt;code class=&quot;language-text&quot;&gt;npm install&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Run your build command&lt;/li&gt;
&lt;li&gt;Deploy to their global CDN&lt;/li&gt;
&lt;li&gt;Give you a &lt;code class=&quot;language-text&quot;&gt;.pages.dev&lt;/code&gt; URL&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The first deployment typically takes 1-3 minutes. You can watch the build logs in real-time.&lt;/p&gt;
&lt;h3 id=&quot;step-7-set-up-a-custom-domain-optional&quot;&gt;Step 7: Set Up a Custom Domain (Optional)&lt;/h3&gt;
&lt;p&gt;Once deployed, you&apos;ll get a URL like &lt;code class=&quot;language-text&quot;&gt;your-project.pages.dev&lt;/code&gt;. To use your own domain:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In your Pages project, click &lt;strong&gt;&quot;Custom domains&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&quot;Set up a custom domain&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Enter your domain (e.g., &lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&quot;Continue&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;If your domain is already on Cloudflare:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cloudflare automatically adds the DNS records&lt;/li&gt;
&lt;li&gt;Your domain will be live in seconds&lt;/li&gt;
&lt;li&gt;SSL is automatically enabled&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;If your domain is NOT on Cloudflare:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cloudflare will show you the DNS records to add&lt;/li&gt;
&lt;li&gt;Go to your domain registrar (GoDaddy, Namecheap, etc.)&lt;/li&gt;
&lt;li&gt;Add the CNAME record Cloudflare specifies&lt;/li&gt;
&lt;li&gt;Wait for DNS propagation (can take up to 24 hours, usually much faster)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;automatic-deployments&quot;&gt;Automatic Deployments&lt;/h3&gt;
&lt;p&gt;The best part? Every time you push to your Git repository, Cloudflare automatically rebuilds and deploys your site:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Make changes to your code&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Then commit and push&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Updated homepage&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push origin main

&lt;span class=&quot;token comment&quot;&gt;# Cloudflare automatically detects the push and rebuilds&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can also set up preview deployments for branches—ideal for testing before going live.&lt;/p&gt;
&lt;h2 id=&quot;method-2-cloudflare-workers&quot;&gt;Method 2: Cloudflare Workers&lt;/h2&gt;
&lt;p&gt;For those who want more control or need edge computing capabilities, Cloudflare Workers is the way to go.&lt;/p&gt;
&lt;h3 id=&quot;when-to-use-workers-instead-of-pages&quot;&gt;When to Use Workers Instead of Pages:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;You need to run server-side code at the edge&lt;/li&gt;
&lt;li&gt;You want fine-grained control over caching&lt;/li&gt;
&lt;li&gt;You&apos;re building an API or need request/response manipulation&lt;/li&gt;
&lt;li&gt;You need more than 500 builds per month&lt;/li&gt;
&lt;li&gt;You want to use KV storage or Durable Objects&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;step-1-install-wrangler-cli&quot;&gt;Step 1: Install Wrangler CLI&lt;/h3&gt;
&lt;p&gt;Wrangler is Cloudflare&apos;s command-line tool for Workers:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Install Wrangler globally&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; wrangler

&lt;span class=&quot;token comment&quot;&gt;# Verify installation&lt;/span&gt;
wrangler &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Log in to Cloudflare&lt;/span&gt;
wrangler login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This opens your browser to authorize Wrangler with your Cloudflare account.&lt;/p&gt;
&lt;h3 id=&quot;step-2-export-and-build-your-lovable-project&quot;&gt;Step 2: Export and Build Your Lovable Project&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Export from Lovable (same as before)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Extract the ZIP&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Navigate to the project folder&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; your-lovable-project

&lt;span class=&quot;token comment&quot;&gt;# Install dependencies&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Build your project&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This creates your production files in the &lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt; folder (or &lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt;, depending on your setup).&lt;/p&gt;
&lt;h3 id=&quot;step-3-create-wrangler-configuration&quot;&gt;Step 3: Create Wrangler Configuration&lt;/h3&gt;
&lt;p&gt;Create a &lt;code class=&quot;language-text&quot;&gt;wrangler.toml&lt;/code&gt; file in your project root:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token key property&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;my-lovable-site&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;workers-site/index.js&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;compatibility_date&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2024-01-01&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;bucket&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;./dist&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;name&lt;/code&gt;: Your Worker&apos;s name (will be part of your &lt;code class=&quot;language-text&quot;&gt;.workers.dev&lt;/code&gt; URL)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;main&lt;/code&gt;: Path to your Worker script&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;bucket&lt;/code&gt;: Where your built static files are located&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;step-4-create-the-worker-script&quot;&gt;Step 4: Create the Worker Script&lt;/h3&gt;
&lt;p&gt;Create a folder and file: &lt;code class=&quot;language-text&quot;&gt;workers-site/index.js&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; workers-site&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Create &lt;code class=&quot;language-text&quot;&gt;workers-site/index.js&lt;/code&gt; with this content:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; getAssetFromKV &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@cloudflare/kv-asset-handler&apos;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; env&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ctx&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// Try to serve the static asset&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getAssetFromKV&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token literal-property property&quot;&gt;waitUntil&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;waitUntil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token constant&quot;&gt;ASSET_NAMESPACE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__STATIC_CONTENT&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token constant&quot;&gt;ASSET_MANIFEST&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; __STATIC_CONTENT_MANIFEST&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// If asset not found, return 404&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// For SPAs, you might want to return index.html instead&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;status &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;404&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token comment&quot;&gt;// Try to serve index.html for client-side routing&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; notFoundRequest &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;origin&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/index.html&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getAssetFromKV&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;token literal-property property&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; notFoundRequest&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;token literal-property property&quot;&gt;waitUntil&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;waitUntil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;token constant&quot;&gt;ASSET_NAMESPACE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__STATIC_CONTENT&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;token constant&quot;&gt;ASSET_MANIFEST&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; __STATIC_CONTENT_MANIFEST&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Not Found&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;404&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-5-install-dependencies&quot;&gt;Step 5: Install Dependencies&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Install the KV asset handler&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; @cloudflare/kv-asset-handler&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-6-deploy-to-cloudflare-workers&quot;&gt;Step 6: Deploy to Cloudflare Workers&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Deploy your Worker&lt;/span&gt;
wrangler deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Wrangler will:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Upload your static files&lt;/li&gt;
&lt;li&gt;Deploy your Worker script&lt;/li&gt;
&lt;li&gt;Give you a &lt;code class=&quot;language-text&quot;&gt;.workers.dev&lt;/code&gt; URL&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Your site is now live on Cloudflare&apos;s edge network!&lt;/p&gt;
&lt;h3 id=&quot;step-7-custom-domain-with-workers&quot;&gt;Step 7: Custom Domain with Workers&lt;/h3&gt;
&lt;p&gt;To add a custom domain to your Worker:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go to the Cloudflare dashboard&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&quot;Workers &amp;#x26; Pages&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Select your Worker&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&quot;Settings&quot;&lt;/strong&gt; &gt; &lt;strong&gt;&quot;Domains &amp;#x26; Routes&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&quot;Add Custom Domain&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Enter your domain&lt;/li&gt;
&lt;li&gt;Follow the DNS configuration instructions&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If your domain is already on Cloudflare, it&apos;s automatic. Otherwise, you&apos;ll need to add DNS records at your registrar.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Need help with DNS?&lt;/strong&gt; Check out our &lt;a href=&quot;/blog/cloudflare-dns-api&quot;&gt;Managing DNS Records with the Cloudflare API&lt;/a&gt; guide for advanced DNS management and automation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;troubleshooting-common-issues&quot;&gt;Troubleshooting Common Issues&lt;/h2&gt;
&lt;h3 id=&quot;build-fails-command-not-found-npm&quot;&gt;Build Fails: &quot;Command not found: npm&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Cloudflare can&apos;t find npm&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Make sure your project has a &lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt;. Cloudflare automatically installs dependencies if it finds one.&lt;/p&gt;
&lt;h3 id=&quot;build-fails-dist-directory-not-found&quot;&gt;Build Fails: &quot;dist directory not found&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Your build output directory doesn&apos;t match what you specified&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Check your &lt;code class=&quot;language-text&quot;&gt;vite.config.js&lt;/code&gt; or build config for the output directory name&lt;/li&gt;
&lt;li&gt;Common alternatives: &lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;out&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;public&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;.output&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Update your Cloudflare Pages build settings or &lt;code class=&quot;language-text&quot;&gt;wrangler.toml&lt;/code&gt; to match&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;404-errors-on-routes-spa-routing&quot;&gt;404 Errors on Routes (SPA Routing)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Direct navigation to routes like &lt;code class=&quot;language-text&quot;&gt;/about&lt;/code&gt; returns 404&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For Cloudflare Pages&lt;/strong&gt;:
Create a &lt;code class=&quot;language-text&quot;&gt;public/_redirects&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/*    /index.html   200&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or create a &lt;code class=&quot;language-text&quot;&gt;_redirects&lt;/code&gt; file in your &lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt; folder after building.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For Cloudflare Workers&lt;/strong&gt;:
The script above (in Step 4) already handles this by serving &lt;code class=&quot;language-text&quot;&gt;index.html&lt;/code&gt; for 404s.&lt;/p&gt;
&lt;h3 id=&quot;environment-variables-not-working&quot;&gt;Environment Variables Not Working&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;For Cloudflare Pages&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go to your Pages project settings&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&quot;Environment variables&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Add your variables for Production and Preview environments&lt;/li&gt;
&lt;li&gt;Redeploy (or push a new commit)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;For Cloudflare Workers&lt;/strong&gt;:
Add to &lt;code class=&quot;language-text&quot;&gt;wrangler.toml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;API_URL&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://api.example.com&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For secrets (like API keys):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;wrangler secret put API_KEY&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;build-exceeds-free-tier-limit-pages&quot;&gt;Build Exceeds Free Tier Limit (Pages)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: More than 500 builds per month&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Switch to Cloudflare Workers (unlimited deploys)&lt;/li&gt;
&lt;li&gt;Upgrade to Pages paid plan ($5/month for 5,000 builds)&lt;/li&gt;
&lt;li&gt;Reduce commit frequency (batch changes)&lt;/li&gt;
&lt;li&gt;Disable automatic deployments for non-main branches&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;worker-exceeds-100000-requestsday&quot;&gt;Worker Exceeds 100,000 Requests/Day&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Free tier only includes 100,000 requests per day&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Switch to Cloudflare Pages (unlimited requests)&lt;/li&gt;
&lt;li&gt;Upgrade to Workers paid plan ($5/month for 10 million requests)&lt;/li&gt;
&lt;li&gt;Optimize caching to reduce Worker invocations&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;cloudflare-shows-old-version-after-deploy&quot;&gt;Cloudflare Shows Old Version After Deploy&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Your changes aren&apos;t visible&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Clear your browser cache (Ctrl+Shift+R or Cmd+Shift+R)&lt;/li&gt;
&lt;li&gt;Check deployment status in dashboard—it might still be building&lt;/li&gt;
&lt;li&gt;For Workers, purge the cache:
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;wrangler deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Check if you&apos;re viewing the correct URL (.pages.dev vs custom domain)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;custom-domain-not-working&quot;&gt;Custom Domain Not Working&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Domain doesn&apos;t resolve or shows errors&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Check DNS propagation: Use &lt;a href=&quot;https://www.whatsmydns.net&quot;&gt;whatsmydns.net&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Verify DNS records are correct (CNAME pointing to your Pages/Workers URL)&lt;/li&gt;
&lt;li&gt;For Workers, ensure your route is configured correctly&lt;/li&gt;
&lt;li&gt;Wait—DNS can take up to 24 hours (usually much faster)&lt;/li&gt;
&lt;li&gt;If using Cloudflare for DNS, ensure the record is &quot;Proxied&quot; (orange cloud)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;api-calls-failing-after-deployment&quot;&gt;API Calls Failing After Deployment&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: APIs that worked in Lovable now fail&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Common causes&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;CORS issues&lt;/strong&gt;: Your API might not allow requests from your new domain&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Environment variables missing&lt;/strong&gt;: Add them in Cloudflare dashboard&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTTPS/HTTP mismatch&lt;/strong&gt;: Cloudflare forces HTTPS; ensure API supports it&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Relative URLs&lt;/strong&gt;: Hardcoded localhost URLs need to be updated&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Solution for environment variables&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// In your Lovable project, use environment variables&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;API_URL&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VITE_API_URL&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;http://localhost:3000&apos;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;API_URL&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/api/data&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then set &lt;code class=&quot;language-text&quot;&gt;VITE_API_URL&lt;/code&gt; in Cloudflare&apos;s environment variables.&lt;/p&gt;
&lt;h2 id=&quot;comparing-pages-vs-workers-for-lovable-projects&quot;&gt;Comparing Pages vs Workers for Lovable Projects&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Cloudflare Pages&lt;/th&gt;
&lt;th&gt;Cloudflare Workers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ease of Setup&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Very Easy&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Deployment&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Automatic from Git&lt;/td&gt;
&lt;td&gt;Manual via CLI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Free Requests&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;100,000/day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Free Builds&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;500/month&lt;/td&gt;
&lt;td&gt;Unlimited (local builds)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Custom Domains&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Free SSL&lt;/td&gt;
&lt;td&gt;✅ Free SSL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Environment Variables&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Dashboard&lt;/td&gt;
&lt;td&gt;✅ wrangler.toml&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Preview Deployments&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Automatic&lt;/td&gt;
&lt;td&gt;❌ Manual&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Edge Computing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌ (static only)&lt;/td&gt;
&lt;td&gt;✅ Full control&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best For&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Most Lovable projects&lt;/td&gt;
&lt;td&gt;Advanced users, APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Recommendation&lt;/strong&gt;: Start with Cloudflare Pages. It&apos;s simpler, has unlimited requests, and handles 99% of Lovable projects well. Only use Workers if you specifically need edge computing or have exhausted the free Pages builds.&lt;/p&gt;
&lt;h2 id=&quot;optimizing-your-lovable-site-on-cloudflare&quot;&gt;Optimizing Your Lovable Site on Cloudflare&lt;/h2&gt;
&lt;h3 id=&quot;enable-compression&quot;&gt;Enable Compression&lt;/h3&gt;
&lt;p&gt;Cloudflare automatically enables Brotli and Gzip compression, but verify:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;&quot;Speed&quot;&lt;/strong&gt; &gt; &lt;strong&gt;&quot;Optimization&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Ensure Brotli is enabled&lt;/li&gt;
&lt;li&gt;Enable &quot;Auto Minify&quot; for HTML, CSS, and JS&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;configure-caching&quot;&gt;Configure Caching&lt;/h3&gt;
&lt;p&gt;For Workers, customize caching:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// In workers-site/index.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cacheControl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;browserTTL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1 day&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;edgeTTL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 30 days&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;bypassCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getAssetFromKV&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  cacheControl&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;add-security-headers&quot;&gt;Add Security Headers&lt;/h3&gt;
&lt;p&gt;For enhanced security, add headers in your Worker:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getAssetFromKV&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Clone and add headers&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; newHeaders &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Headers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
newHeaders&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;X-Frame-Options&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;DENY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
newHeaders&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;X-Content-Type-Options&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;nosniff&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
newHeaders&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Referrer-Policy&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;strict-origin-when-cross-origin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;status&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; newHeaders&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;next-steps-after-deployment&quot;&gt;Next Steps After Deployment&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Set up analytics&lt;/strong&gt;: Cloudflare provides free Web Analytics&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configure a firewall&lt;/strong&gt;: Protect against bots and attacks (free tier includes basic WAF)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Add monitoring&lt;/strong&gt;: Set up uptime monitoring with Cloudflare&apos;s &quot;Health Checks&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Optimize images&lt;/strong&gt;: Use Cloudflare Images or Polish for automatic image optimization&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consider a CDN plan&lt;/strong&gt;: Free tier is generous, but paid plans add more features&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;migrating-from-lovable-hosting&quot;&gt;Migrating from Lovable Hosting&lt;/h2&gt;
&lt;p&gt;If your site is currently hosted on Lovable and you want to move to Cloudflare:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Export your project&lt;/strong&gt; (as described above)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deploy to Cloudflare&lt;/strong&gt; using either method&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Test thoroughly&lt;/strong&gt; at your &lt;code class=&quot;language-text&quot;&gt;.pages.dev&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;.workers.dev&lt;/code&gt; URL&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Update DNS&lt;/strong&gt; to point to Cloudflare (if using custom domain)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Monitor&lt;/strong&gt; for any issues in the first 24 hours&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cancel Lovable hosting&lt;/strong&gt; once confirmed working&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Deploying your Lovable project to Cloudflare gives you enterprise-grade hosting for free, with global performance that rivals paid platforms. Whether you choose Cloudflare Pages for simplicity or Cloudflare Workers for power, you&apos;re getting:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sub-50ms response times globally&lt;/li&gt;
&lt;li&gt;Unlimited bandwidth (Pages) or generous free tier (Workers)&lt;/li&gt;
&lt;li&gt;Automatic HTTPS and SSL&lt;/li&gt;
&lt;li&gt;DDoS protection&lt;/li&gt;
&lt;li&gt;99.99%+ uptime&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;For most Lovable projects, I recommend Cloudflare Pages&lt;/strong&gt;—it&apos;s simpler, has unlimited requests, and deploys automatically from Git. Save Workers for when you truly need edge computing or advanced control.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Want to learn more about Cloudflare Workers?&lt;/strong&gt; Our &lt;a href=&quot;/blog/cloudflare-workers-deployment&quot;&gt;Complete Guide to Deploying Static Sites on Cloudflare Workers&lt;/a&gt; covers advanced patterns, performance optimization, and production best practices beyond the basics.&lt;/p&gt;
&lt;p&gt;Have questions about deploying your specific Lovable project to Cloudflare? Drop a comment below and I&apos;ll help troubleshoot!&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;frequently-asked-questions&quot;&gt;Frequently Asked Questions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Is migrating from Lovable to Cloudflare free?&lt;/strong&gt;
Yes, migrating from Lovable to Cloudflare is completely free. Lovable allows free project exports, and Cloudflare offers generous free hosting tiers. Cloudflare Pages provides unlimited sites and requests, while Cloudflare Workers offers 100,000 requests/day. Both include free SSL and custom domains.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I transfer my Lovable site to Cloudflare?&lt;/strong&gt;
Export your Lovable project as a ZIP file, extract it, push the code to GitHub, then connect your GitHub repository to Cloudflare Pages. The entire process takes about 15 minutes and is fully automated after the initial setup.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I use my own domain with Cloudflare hosting?&lt;/strong&gt;
Yes! Both Cloudflare Pages and Workers support custom domains with free SSL certificates. If your domain uses Cloudflare for DNS, setup is automatic. Otherwise, you&apos;ll need to add a CNAME record at your domain registrar.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What happens to my Lovable hosting after I migrate?&lt;/strong&gt;
Your original Lovable-hosted site continues to work. You can keep both running or unpublish the Lovable version once migration is complete. There&apos;s no automatic cancellation—you have full control.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does Cloudflare work with Lovable&apos;s React/Vite projects?&lt;/strong&gt;
Absolutely. Lovable generates standard React applications using Vite, which Cloudflare fully supports. Pages auto-detects Vite projects, and Workers can serve any static build output.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Related guides:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website&quot;&gt;10 Ways to Move Your Lovable Website to Free Hosting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-from-hero-to-zero&quot;&gt;Lovable: From Hero to Zero with 2.0&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Lovable: The Zero-Code to Full-Stack Vibe Coding Platform]]></title><description><![CDATA[Master Lovable's AI-powered development platform. Learn how to go from idea to deployed web app in hours, not days.]]></description><link>https://vibecodingwithfred.com/blog/lovable-vibe-coding-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/lovable-vibe-coding-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Last verified:&lt;/strong&gt; October 2025&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Lovable represents a different approach to vibe coding: instead of terminal commands and code files, you describe what you want and watch it materialize in real-time. This guide will explain away a few of Lovable&apos;s key features.&lt;/p&gt;
&lt;h2 id=&quot;what-sets-lovable-apart-from-the-competition&quot;&gt;What sets Lovable Apart From The Competition&lt;/h2&gt;
&lt;p&gt;As with Orchid and V0, Lovable offfers and entire full stack—frontend, backend, and database—all within one platform. Since everything runs in the browser, there&apos;s no local setup required, and you can deploy to production with a single click. It&apos;s essentially AI pair programming with feedback.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lovable particularly excels at&lt;/strong&gt;  building MVPs. It&apos;s an excellent choice for landing pages, marketing sites, and internal tools where speed matters. The platform shines when creating proof of concepts or when people are watching you work with it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;And Hosting Is Free&lt;/strong&gt;  When you&apos;re ready to publish Lovable can host it for free.&lt;/p&gt;
&lt;h2 id=&quot;who-should-use-lovable&quot;&gt;Who Should Use Lovable&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Lovable works best when&lt;/strong&gt; you need to validate ideas quickly or build starter web applications. It&apos;s particularly effective if you want to get straight to building a frontend. The platform really shines when you&apos;re collaborating with non-technical stakeholders who can watch the app come together in real-time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You might want to consider alternatives&lt;/strong&gt; if you want to work with code directly, want more control over SEO, have an aversion to React or Typescript, or the project requires complex backend logic.&lt;/p&gt;
&lt;p&gt;In the end you&apos;ll have an exportable React/Typescript single page application with serviceable code. After having a few projects completed with Lovable, it works really well when the project scope is small.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Want to understand what you&apos;re building?&lt;/strong&gt; Check out our tutorials on building similar projects from scratch: &lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;Portfolio with Laravel&lt;/a&gt;, &lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Blog with Flask&lt;/a&gt;, or &lt;a href=&quot;/tutorials/shopping-scratch/&quot;&gt;E-Commerce from Scratch&lt;/a&gt;. Understanding the fundamentals helps you customize and debug Lovable-generated code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;part-1-getting-started-with-lovable&quot;&gt;Part 1: Getting Started with Lovable&lt;/h2&gt;
&lt;h3 id=&quot;the-lovable-development-flow&quot;&gt;The Lovable Development Flow&lt;/h3&gt;
&lt;p&gt;Plan with the chat feature&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Describe what you want&lt;/strong&gt; in plain English
&lt;strong&gt;Refine through conversation&lt;/strong&gt; with specific adjustments
&lt;strong&gt;Deploy instantly&lt;/strong&gt; when ready&lt;/p&gt;
&lt;h3 id=&quot;your-first-lovable-project&quot;&gt;Your First Lovable Project&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Starting prompt example:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Create a modern task management app with:
- Clean, minimal design using blue and white colors
- Task list with add/edit/delete functionality
- Priority levels (high/medium/low) with color coding
- Due dates with calendar picker
- Local storage to persist tasks
- Responsive design for mobile and desktop&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Lovable will generate the entire application, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;React components&lt;/li&gt;
&lt;li&gt;Styling (Tailwind CSS)&lt;/li&gt;
&lt;li&gt;State management&lt;/li&gt;
&lt;li&gt;Data persistence&lt;/li&gt;
&lt;li&gt;Responsive layout&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;the-refinement-process&quot;&gt;The Refinement Process&lt;/h3&gt;
&lt;p&gt;After initial generation, refine through specific requests:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;Make the high priority tasks show a red border and bold text&quot;
&quot;Add a filter to show only incomplete tasks&quot;
&quot;Include a progress bar showing completion percentage&quot;
&quot;Add smooth animations when tasks are added or removed&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each refinement happens immediately, with visual feedback.&lt;/p&gt;
&lt;h2 id=&quot;part-2-advanced-lovable-techniques&quot;&gt;Part 2: Advanced Lovable Techniques&lt;/h2&gt;
&lt;h3 id=&quot;the-component-first-approach&quot;&gt;The Component-First Approach&lt;/h3&gt;
&lt;p&gt;Instead of building everything at once, build components individually:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1: Core component&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;Create a TaskCard component that displays:
- Task title (large, bold)
- Description (gray, smaller text)
- Priority badge (colored based on level)
- Due date in human-readable format
- Checkbox for completion
- Edit and delete icon buttons&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Step 2: List container&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;Create a TaskList component that:
- Maps through an array of tasks
- Renders TaskCard for each
- Shows empty state when no tasks
- Has smooth fade-in animation for new tasks&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Step 3: Integration&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;Connect TaskList to use local storage:
- Load tasks on mount
- Save after any change
- Add useEffect for persistence&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;working-with-external-apis&quot;&gt;Working with External APIs&lt;/h3&gt;
&lt;p&gt;Lovable can integrate with external services:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;Add weather information to each task:
- Fetch weather from OpenWeatherMap API
- Show weather icon next to due date
- Cache results for 30 minutes
- Handle API errors gracefully&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;For authentication:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;Add Google authentication using Firebase:
- Sign in button in header
- Protect task list behind auth
- Show user profile photo when logged in
- Sync tasks to Firestore instead of local storage&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;database-integration&quot;&gt;Database Integration&lt;/h3&gt;
&lt;p&gt;Lovable supports Supabase with Lovable Cloud:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Supabase example:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;Convert the app to use Supabase:
- Create tasks table with columns: id, title, description, priority, due_date, completed, user_id
- Set up Row Level Security
- Add real-time subscriptions for task updates
- Include optimistic updates for better UX&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;styling-and-theming&quot;&gt;Styling and Theming&lt;/h3&gt;
&lt;p&gt;Lovable excels at visual customization:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;Redesign with a dark mode:
- Dark gray background (#1a1a1a)
- White text with good contrast
- Neon accents for priority colors
- Toggle switch in header
- Smooth transition between themes
- Save preference to localStorage&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Advanced styling:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;Add glassmorphism design:
- Frosted glass effect on cards
- Subtle gradients
- Soft shadows
- Blur effects on overlays
- Maintain accessibility standards&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;part-3-production-deployment-strategies&quot;&gt;Part 3: Production Deployment Strategies&lt;/h2&gt;
&lt;h3 id=&quot;exporting-from-lovable&quot;&gt;Exporting from Lovable&lt;/h3&gt;
&lt;p&gt;When ready for production:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Export to GitHub:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lovable can push directly to a GitHub repository&lt;/li&gt;
&lt;li&gt;Maintains full code structure&lt;/li&gt;
&lt;li&gt;Includes all dependencies&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Download locally:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Get a ZIP file with complete project&lt;/li&gt;
&lt;li&gt;Ready for local development&lt;/li&gt;
&lt;li&gt;All code is yours to modify&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;deployment-options&quot;&gt;Deployment Options&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Direct from Lovable:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;One-click deployment to Lovable&apos;s infrastructure&lt;/li&gt;
&lt;li&gt;Automatic SSL and CDN&lt;/li&gt;
&lt;li&gt;Custom domain support&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Export and deploy elsewhere:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Vercel&lt;/strong&gt;: Connect GitHub repo, auto-deploy on push&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Netlify&lt;/strong&gt;: Drag and drop or Git integration&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cloudflare Pages&lt;/strong&gt;: Excellent performance, generous free tier&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;adding-custom-code&quot;&gt;Adding Custom Code&lt;/h3&gt;
&lt;p&gt;After exporting, you can enhance with custom code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Add analytics&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Analytics &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@vercel/analytics/react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Add error tracking&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; Sentry &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@sentry/react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Add custom business logic&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; calculateMetrics &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./utils/business-logic&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;part-4-best-practices-and-patterns&quot;&gt;Part 4: Best Practices and Patterns&lt;/h2&gt;
&lt;h3 id=&quot;the-iterative-prompt-pattern&quot;&gt;The Iterative Prompt Pattern&lt;/h3&gt;
&lt;p&gt;Start simple, then layer complexity:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Round 1: &quot;Create a simple blog with posts&quot;
Round 2: &quot;Add categories and tags&quot;
Round 3: &quot;Include search functionality&quot;
Round 4: &quot;Add comments with nested replies&quot;
Round 5: &quot;Implement user authentication&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each round builds on the previous, maintaining consistency.&lt;/p&gt;
&lt;h3 id=&quot;component-library-building&quot;&gt;Component Library Building&lt;/h3&gt;
&lt;p&gt;Create reusable components:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;Create a design system with:
- Button component (primary, secondary, danger variants)
- Card component with header, body, footer slots
- Modal component with backdrop and animations
- Form input components with validation states
- Toast notification system&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then use these throughout your app:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;Use the Button component for all actions&quot;
&quot;Wrap all content sections in Card components&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;performance-optimization&quot;&gt;Performance Optimization&lt;/h3&gt;
&lt;p&gt;Guide Lovable toward performant code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;Optimize the task list for large datasets:
- Implement virtual scrolling for 1000+ items
- Use React.memo for TaskCard
- Add pagination with 20 items per page
- Lazy load images
- Debounce search input by 300ms&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;accessibility-first&quot;&gt;Accessibility First&lt;/h3&gt;
&lt;p&gt;Ensure inclusive design:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;Make the app fully accessible:
- Add ARIA labels to all interactive elements
- Ensure keyboard navigation works throughout
- Include focus indicators
- Test with screen reader
- Meet WCAG 2.1 AA standards&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;part-5-real-project-examples&quot;&gt;Part 5: Real Project Examples&lt;/h2&gt;
&lt;h3 id=&quot;example-1-saas-dashboard&quot;&gt;Example 1: SaaS Dashboard&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Initial prompt:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;Create a SaaS analytics dashboard with:
- Sidebar navigation with icons
- Overview page with metric cards
- Charts using recharts library
- User management table
- Settings page with form
- Professional gradient design&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Refinements:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;Add date range picker affecting all charts&quot;&lt;/li&gt;
&lt;li&gt;&quot;Include export to CSV functionality&quot;&lt;/li&gt;
&lt;li&gt;&quot;Add real-time updates using websockets&quot;&lt;/li&gt;
&lt;li&gt;&quot;Implement role-based access control&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;example-2-e-commerce-store&quot;&gt;Example 2: E-commerce Store&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Building in phases:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Phase 1: &quot;Product catalog with grid layout&quot;
Phase 2: &quot;Add shopping cart with localStorage&quot;
Phase 3: &quot;Include checkout flow with Stripe&quot;
Phase 4: &quot;Add product search and filters&quot;
Phase 5: &quot;Implement user reviews and ratings&quot;&lt;/p&gt;
&lt;h3 id=&quot;example-3-internal-tool&quot;&gt;Example 3: Internal Tool&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Complex requirements handled elegantly:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;Build an employee onboarding tool:
- Multi-step form wizard
- Document upload capability
- Progress tracking
- Email notifications at each step
- Admin dashboard to monitor all onboardings
- Integration with Slack for alerts&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;common-patterns-and-solutions&quot;&gt;Common Patterns and Solutions&lt;/h2&gt;
&lt;h3 id=&quot;pattern-1-state-management&quot;&gt;Pattern 1: State Management&lt;/h3&gt;
&lt;p&gt;For complex state:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;Implement Redux for state management:
- Store for global app state
- Actions for all user interactions
- Reducers with immutable updates
- Connect components as needed
- Add Redux DevTools support&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;pattern-2-data-fetching&quot;&gt;Pattern 2: Data Fetching&lt;/h3&gt;
&lt;p&gt;For API integration:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;Add data fetching with proper patterns:
- Use React Query for caching
- Show loading states
- Handle errors with retry
- Implement optimistic updates
- Add pull-to-refresh on mobile&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;pattern-3-forms-and-validation&quot;&gt;Pattern 3: Forms and Validation&lt;/h3&gt;
&lt;p&gt;For complex forms:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;Create form with react-hook-form:
- Field-level validation
- Custom error messages
- Async validation for email uniqueness
- Multi-step with progress indicator
- Save draft functionality&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;limitations-and-workarounds&quot;&gt;Limitations and Workarounds&lt;/h2&gt;
&lt;h3 id=&quot;current-limitations&quot;&gt;Current Limitations&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;What Lovable struggles with:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Complex algorithmic logic&lt;/li&gt;
&lt;li&gt;Custom authentication flows&lt;/li&gt;
&lt;li&gt;Specific library versions&lt;/li&gt;
&lt;li&gt;Advanced performance optimization&lt;/li&gt;
&lt;li&gt;Native mobile features&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;workarounds&quot;&gt;Workarounds&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;For complex logic:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Build the UI in Lovable&lt;/li&gt;
&lt;li&gt;Export the code&lt;/li&gt;
&lt;li&gt;Add complex logic in your IDE&lt;/li&gt;
&lt;li&gt;Deploy normally&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;For specific requirements:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use Lovable for rapid prototyping&lt;/li&gt;
&lt;li&gt;Export when 80% complete&lt;/li&gt;
&lt;li&gt;Finish in traditional development environment&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;tips-for-maximum-productivity&quot;&gt;Tips for Maximum Productivity&lt;/h2&gt;
&lt;h3 id=&quot;1-be-specific-about-design&quot;&gt;1. Be Specific About Design&lt;/h3&gt;
&lt;p&gt;Instead of: &quot;Make it look good&quot;
Say: &quot;Use a card-based layout with 16px padding, 8px border-radius, subtle shadow, and 20px spacing between cards&quot;&lt;/p&gt;
&lt;h3 id=&quot;2-reference-popular-libraries&quot;&gt;2. Reference Popular Libraries&lt;/h3&gt;
&lt;p&gt;Lovable knows common libraries:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;Use Tailwind CSS classes&quot;&lt;/li&gt;
&lt;li&gt;&quot;Implement with Material-UI components&quot;&lt;/li&gt;
&lt;li&gt;&quot;Add Framer Motion animations&quot;&lt;/li&gt;
&lt;li&gt;&quot;Include React Query for data fetching&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3-build-incrementally&quot;&gt;3. Build Incrementally&lt;/h3&gt;
&lt;p&gt;Don&apos;t try to describe everything at once. Build core functionality, then add features one by one.&lt;/p&gt;
&lt;h3 id=&quot;4-use-version-control&quot;&gt;4. Use Version Control&lt;/h3&gt;
&lt;p&gt;Even though Lovable has history, export to Git regularly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Preserves your work&lt;/li&gt;
&lt;li&gt;Enables collaboration&lt;/li&gt;
&lt;li&gt;Allows custom modifications&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;5-test-edge-cases&quot;&gt;5. Test Edge Cases&lt;/h3&gt;
&lt;p&gt;Always verify:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Empty states&lt;/li&gt;
&lt;li&gt;Loading states&lt;/li&gt;
&lt;li&gt;Error states&lt;/li&gt;
&lt;li&gt;Mobile responsiveness&lt;/li&gt;
&lt;li&gt;Browser compatibility&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;when-to-choose-lovable&quot;&gt;When to Choose Lovable&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Choose Lovable for:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rapid prototyping&lt;/li&gt;
&lt;li&gt;Standard web applications&lt;/li&gt;
&lt;li&gt;Quick client demos&lt;/li&gt;
&lt;li&gt;Internal tools&lt;/li&gt;
&lt;li&gt;Learning projects&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Choose traditional coding for:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Performance-critical applications&lt;/li&gt;
&lt;li&gt;Complex backend logic&lt;/li&gt;
&lt;li&gt;Specific technical requirements&lt;/li&gt;
&lt;li&gt;Long-term maintainable codebases&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-future-of-visual-vibe-coding&quot;&gt;The Future of Visual Vibe Coding&lt;/h2&gt;
&lt;p&gt;Lovable represents a new paradigm where the barrier between idea and implementation virtually disappears. It&apos;s not replacing traditional development—it&apos;s adding a new tool to our arsenal that excels at specific use cases.&lt;/p&gt;
&lt;p&gt;The key is knowing when to use it and how to leverage its strengths while understanding its limitations.&lt;/p&gt;
&lt;p&gt;Start with a simple project. Build something in an hour that would normally take a day. Experience the flow of conversational development. Then decide where it fits in your workflow.&lt;/p&gt;
&lt;p&gt;The future isn&apos;t just about writing code faster—it&apos;s about exploring ideas at the speed of thought.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;updates-and-resources&quot;&gt;Updates and Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;October 2025:&lt;/strong&gt; Guide created based on latest Lovable features&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Platform updates:&lt;/strong&gt; Lovable continuously adds features&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Community:&lt;/strong&gt; Share your Lovable projects and learn from others&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Remember:&lt;/strong&gt; Lovable is a tool, not a replacement for understanding web development. Use it to accelerate your work, but continue learning the underlying technologies.&lt;/p&gt;
&lt;h2 id=&quot;frequently-asked-questions-about-lovable&quot;&gt;Frequently Asked Questions About Lovable&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Does Lovable host your website?&lt;/strong&gt;
Yes, Lovable provides free hosting for projects built on their platform. When you deploy through Lovable, your site is automatically hosted on their infrastructure with HTTPS enabled.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I host my Lovable site elsewhere?&lt;/strong&gt;
Absolutely. You can export your Lovable project and host it on platforms like Cloudflare, Vercel, Netlify, or any other hosting provider that supports React applications. See our guides on &lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;moving to Cloudflare&lt;/a&gt; or &lt;a href=&quot;/blog/3-ways-to-move-lovable-website/&quot;&gt;Vercel&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is Lovable free to deploy public sites?&lt;/strong&gt;
Yes, Lovable&apos;s free tier includes project deployment and hosting. You can publish public websites without upgrading to a paid plan, though there are limits on the number of projects and credits.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Do I have to host with Lovable?&lt;/strong&gt;
No. While Lovable provides convenient hosting, you&apos;re not locked in. You can export your project at any time and host it wherever you prefer—giving you complete freedom and ownership of your code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I export and migrate my Lovable project?&lt;/strong&gt;
Lovable makes it easy to export your project and move to external hosting:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Export your project&lt;/strong&gt;: Click the menu icon → Export → Download as ZIP&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Choose your hosting&lt;/strong&gt;: See our complete guides for &lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;Cloudflare&lt;/a&gt;, &lt;a href=&quot;/blog/3-ways-to-move-lovable-website/&quot;&gt;Vercel&lt;/a&gt;, or &lt;a href=&quot;/blog/3-ways-to-move-lovable-website&quot;&gt;all 10 free hosting options&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deploy&lt;/strong&gt;: Push to Git and connect to your hosting platform&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Your exported code includes everything needed to run independently—no Lovable dependency required.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can Lovable host multiple websites?&lt;/strong&gt;
Yes, Lovable allows you to host multiple projects. The number of sites you can host depends on your plan tier. The free tier has limits on active projects, while paid plans ($25/month Pro tier) allow more concurrent sites.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Building a Browser-Based Media Manager with Drag-and-Drop Uploads for Cloudflare R2]]></title><description><![CDATA[Create a browser-based media manager for Cloudflare R2 using pure JavaScript. Features include drag-and-drop uploads, image previews, shareable URLs, S3 compatibility, and no backend or egress fees.]]></description><link>https://vibecodingwithfred.com/blog/r2-media-manager/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/r2-media-manager/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Managing media files for a static site shouldn&apos;t require deploying a whole backend. With Cloudflare R2&apos;s S3-compatible API, you can build a client-side media manager that runs entirely in the browser—no server needed.&lt;/p&gt;
&lt;p&gt;I built one, and you can too. Here&apos;s why and how.&lt;/p&gt;
&lt;h2 id=&quot;why-cloudflare-r2&quot;&gt;Why Cloudflare R2?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;R2 is S3-compatible object storage with zero egress fees.&lt;/strong&gt; That&apos;s the killer feature. With AWS S3, you pay every time someone downloads a file. With R2, you pay for storage—that&apos;s it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The cost difference is massive:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;S3&lt;/strong&gt;: $0.023/GB storage + $0.09/GB egress&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;R2&lt;/strong&gt;: $0.015/GB storage + $0 egress&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For a blog serving images to thousands of readers, S3 can cost hundreds. R2 costs dollars.&lt;/p&gt;
&lt;p&gt;Plus, R2 runs on Cloudflare&apos;s global network (300+ data centers), so it&apos;s fast everywhere. And since it&apos;s S3-compatible, you can use the AWS SDK directly.&lt;/p&gt;
&lt;h2 id=&quot;the-problem-managing-media-for-static-sites&quot;&gt;The Problem: Managing Media for Static Sites&lt;/h2&gt;
&lt;p&gt;Static site generators like Gatsby, Hugo, and Next.js are great—until you need to add images.&lt;/p&gt;
&lt;p&gt;Your options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Commit images to git&lt;/strong&gt; - Repository bloats, slow clones&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Store in project&lt;/strong&gt; - Build times increase, poor caching&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use a CMS&lt;/strong&gt; - Now you need a backend, database, auth&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Manual S3 uploads&lt;/strong&gt; - Use AWS console, copy URLs by hand&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;None of these are great for quick updates.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What I wanted:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Drag-and-drop uploads&lt;/li&gt;
&lt;li&gt;Instant shareable URLs&lt;/li&gt;
&lt;li&gt;No backend to maintain&lt;/li&gt;
&lt;li&gt;Works from localhost&lt;/li&gt;
&lt;li&gt;Free (or nearly free)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-solution-browser-based-r2-manager&quot;&gt;The Solution: Browser-Based R2 Manager&lt;/h2&gt;
&lt;p&gt;I built a single-page application that talks directly to Cloudflare R2 from the browser.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pure HTML/CSS/JavaScript (no frameworks)&lt;/li&gt;
&lt;li&gt;AWS SDK for JavaScript (S3-compatible API)&lt;/li&gt;
&lt;li&gt;Cloudflare R2 (S3-compatible storage)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Drag-and-drop file uploads with progress tracking&lt;/li&gt;
&lt;li&gt;Grid and list view of all files&lt;/li&gt;
&lt;li&gt;Full-screen image preview&lt;/li&gt;
&lt;li&gt;Generate presigned URLs (shareable links)&lt;/li&gt;
&lt;li&gt;Delete files with confirmation&lt;/li&gt;
&lt;li&gt;Search and filter&lt;/li&gt;
&lt;li&gt;Dark mode&lt;/li&gt;
&lt;li&gt;Responsive (mobile-friendly)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;It&apos;s just one HTML file, one CSS file, and two JavaScript files.&lt;/strong&gt; No build process. No dependencies. No server.&lt;/p&gt;
&lt;h2 id=&quot;how-it-works&quot;&gt;How It Works&lt;/h2&gt;
&lt;h3 id=&quot;1-r2-is-s3-compatible&quot;&gt;1. R2 is S3-Compatible&lt;/h3&gt;
&lt;p&gt;Cloudflare R2 speaks the same language as AWS S3. That means you can use the battle-tested AWS SDK:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Configure AWS SDK to point to R2&lt;/span&gt;
&lt;span class=&quot;token constant&quot;&gt;AWS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;accessKeyId&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;YOUR_R2_ACCESS_KEY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;secretAccessKey&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;YOUR_R2_SECRET_KEY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;auto&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; s3 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AWS&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;S3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;endpoint&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://YOUR_ACCOUNT.r2.cloudflarestorage.com&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;s3ForcePathStyle&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-cors-makes-browser-uploads-possible&quot;&gt;2. CORS Makes Browser Uploads Possible&lt;/h3&gt;
&lt;p&gt;By default, browsers can&apos;t make requests to other domains. But R2 supports CORS (Cross-Origin Resource Sharing).&lt;/p&gt;
&lt;p&gt;Configure it once in the R2 dashboard:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-json line-numbers&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;AllowedOrigins&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http://localhost:8000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;AllowedMethods&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;GET&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;PUT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;POST&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;DELETE&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;HEAD&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;AllowedHeaders&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now your browser can upload directly to R2.&lt;/p&gt;
&lt;h3 id=&quot;3-upload-files-with-progress-tracking&quot;&gt;3. Upload Files with Progress Tracking&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; upload &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; s3&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;Bucket&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;my-bucket&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; fileName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;Body&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; file&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;ContentType&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

upload&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;httpUploadProgress&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;progress&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; percent &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;progress&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;loaded &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; progress&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;total&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;updateProgressBar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;percent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; upload&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;promise&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;No backend. The file goes straight from your browser to R2.&lt;/p&gt;
&lt;h3 id=&quot;4-list-and-display-files&quot;&gt;4. List and Display Files&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; s3&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listObjectsV2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;Bucket&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;my-bucket&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;promise&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; files &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Contents&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;lastModified&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;LastModified
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;renderFileGrid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;files&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;5-generate-shareable-urls&quot;&gt;5. Generate Shareable URLs&lt;/h3&gt;
&lt;p&gt;For private buckets, use presigned URLs:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; url &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; s3&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getSignedUrlPromise&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;getObject&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;Bucket&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;my-bucket&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;image.jpg&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;Expires&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;86400&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// 24 hours&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Copy to clipboard&lt;/span&gt;
navigator&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clipboard&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;writeText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For public buckets, you can use custom domains:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;https://media.yourdomain.com/image.jpg&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;This is designed for local development, not public deployment.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You&apos;re putting API credentials in JavaScript. That&apos;s fine for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Running on &lt;code class=&quot;language-text&quot;&gt;localhost&lt;/code&gt; only&lt;/li&gt;
&lt;li&gt;Your personal machine&lt;/li&gt;
&lt;li&gt;Tools you never deploy&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Don&apos;t do this:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Deploy to production without authentication&lt;/li&gt;
&lt;li&gt;Share your config file with credentials&lt;/li&gt;
&lt;li&gt;Commit credentials to public repos&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;For production, you&apos;d want:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Backend API that stores credentials securely&lt;/li&gt;
&lt;li&gt;User authentication&lt;/li&gt;
&lt;li&gt;Cloudflare Workers as a proxy layer&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;building-it-yourself&quot;&gt;Building It Yourself&lt;/h2&gt;
&lt;p&gt;I created a full tutorial with 14 steps and AI prompts for each:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/r2-media-manager&quot;&gt;👉 Make A Media Manager With Cloudflare R2&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The tutorial covers:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Creating an R2 bucket and getting credentials&lt;/li&gt;
&lt;li&gt;Configuring CORS for browser access&lt;/li&gt;
&lt;li&gt;Setting up the project structure&lt;/li&gt;
&lt;li&gt;Initializing the AWS SDK for R2&lt;/li&gt;
&lt;li&gt;Implementing drag-and-drop uploads&lt;/li&gt;
&lt;li&gt;Listing and displaying files&lt;/li&gt;
&lt;li&gt;Building the preview modal&lt;/li&gt;
&lt;li&gt;Generating shareable URLs&lt;/li&gt;
&lt;li&gt;Adding delete functionality&lt;/li&gt;
&lt;li&gt;Image optimization&lt;/li&gt;
&lt;li&gt;Dark mode and responsive design&lt;/li&gt;
&lt;li&gt;Error handling and security&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Each step includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clear explanation of what you&apos;re building&lt;/li&gt;
&lt;li&gt;Complete AI prompt to generate the code&lt;/li&gt;
&lt;li&gt;Code examples and screenshots&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Time to complete:&lt;/strong&gt; ~4 hours&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cloudflare account (free tier works)&lt;/li&gt;
&lt;li&gt;Basic HTML/CSS/JavaScript knowledge&lt;/li&gt;
&lt;li&gt;Text editor and browser&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;use-cases&quot;&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;This isn&apos;t just for blogs. Here&apos;s where a browser-based R2 manager is useful:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Static Sites:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Upload images for Gatsby/Hugo/Jekyll posts&lt;/li&gt;
&lt;li&gt;Manage assets for Next.js projects&lt;/li&gt;
&lt;li&gt;Host downloads and resources&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Personal Projects:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Photo backup and sharing&lt;/li&gt;
&lt;li&gt;File hosting for side projects&lt;/li&gt;
&lt;li&gt;Asset CDN for hobby apps&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Development:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Quick image uploads during prototyping&lt;/li&gt;
&lt;li&gt;Share screenshots with clients&lt;/li&gt;
&lt;li&gt;Temporary file hosting&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Backup:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Store important documents&lt;/li&gt;
&lt;li&gt;Archive photos&lt;/li&gt;
&lt;li&gt;Keep copies of project files&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;cost-breakdown&quot;&gt;Cost Breakdown&lt;/h2&gt;
&lt;p&gt;Let&apos;s say you upload &lt;strong&gt;10GB of images&lt;/strong&gt; and serve them to &lt;strong&gt;10,000 visitors&lt;/strong&gt; who view &lt;strong&gt;100GB total&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;aws-s3&quot;&gt;AWS S3&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Storage: 10GB × $0.023 = &lt;strong&gt;$0.23&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Egress: 100GB × $0.09 = &lt;strong&gt;$9.00&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total: $9.23/month&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;cloudflare-r2&quot;&gt;Cloudflare R2&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Storage: 10GB × $0.015 = &lt;strong&gt;$0.15&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Egress: 100GB × $0 = &lt;strong&gt;$0.00&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total: $0.15/month&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;You save $9.08/month, or $109/year.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;And that&apos;s conservative. If your site gets popular and serves 1TB of images, S3 costs $90/month. R2 stays at $0.15/month.&lt;/p&gt;
&lt;h2 id=&quot;what-i-learned&quot;&gt;What I Learned&lt;/h2&gt;
&lt;h3 id=&quot;r2-is-s3-but-better-for-public-content&quot;&gt;R2 is S3, but Better (for Public Content)&lt;/h3&gt;
&lt;p&gt;If you&apos;re serving public content (images, videos, downloads), R2 beats S3 on price and speed. The S3-compatible API means migration is easy.&lt;/p&gt;
&lt;h3 id=&quot;client-side-file-management-is-viable&quot;&gt;Client-Side File Management is Viable&lt;/h3&gt;
&lt;p&gt;With CORS and presigned URLs, you can build powerful file management tools without a backend. This pattern works for more than just R2—any S3-compatible service supports it.&lt;/p&gt;
&lt;h3 id=&quot;vanilla-js-is-underrated&quot;&gt;Vanilla JS is Underrated&lt;/h3&gt;
&lt;p&gt;This entire project is 500 lines of JavaScript. No React, no build process, no npm packages (except the AWS SDK). It loads instantly, works offline (with caching), and is trivial to debug.&lt;/p&gt;
&lt;h3 id=&quot;security-by-design-not-by-obscurity&quot;&gt;Security by Design, Not by Obscurity&lt;/h3&gt;
&lt;p&gt;Keeping credentials out of client-side code matters. This tool works because it&apos;s &lt;strong&gt;designed&lt;/strong&gt; to run locally, not because credentials are &quot;hidden&quot; somehow. For production, you need a different architecture.&lt;/p&gt;
&lt;h2 id=&quot;try-it&quot;&gt;Try It&lt;/h2&gt;
&lt;p&gt;The full tutorial with step-by-step instructions and AI prompts is here:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/r2-media-manager&quot;&gt;👉 Make A Media Manager With Cloudflare R2&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Or clone the finished code from the tutorial and customize it for your needs.&lt;/p&gt;
&lt;p&gt;R2 is genuinely useful—cheap, fast, and compatible with everything. And building your own tools to manage it is easier than you&apos;d think.&lt;/p&gt;
&lt;h2 id=&quot;whats-next&quot;&gt;What&apos;s Next?&lt;/h2&gt;
&lt;p&gt;Potential improvements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Image optimization&lt;/strong&gt; - Compress images before upload using Canvas API&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Batch operations&lt;/strong&gt; - Select multiple files to delete at once&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Folders&lt;/strong&gt; - Organize with virtual folders (key prefixes)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Metadata&lt;/strong&gt; - Add tags, descriptions, and custom fields&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gatsby integration&lt;/strong&gt; - Add upload buttons in dev environment&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For now, it does what I need: upload images, get URLs, manage files. Simple, fast, and free (almost).&lt;/p&gt;
&lt;p&gt;If you build something with R2, let me know. I&apos;m curious what other use cases exist for browser-based object storage tools.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[WebSocket Rate Limiting & Flood Protection to Prevent Server Crashes]]></title><description><![CDATA[Prevent WebSocket server crashes with a multi-layer rate limiting system that controls message floods and keeps your real-time infrastructure stable.]]></description><link>https://vibecodingwithfred.com/blog/websocket-rate-limiting-quicktip/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/websocket-rate-limiting-quicktip/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It was 2 AM when PagerDuty woke me up. Our WebSocket servers were down, 3,000 active users disconnected, and our logistics dashboard was blind. The culprit? One customer&apos;s &quot;helpful&quot; Python script sending 50,000 location updates per second. Here&apos;s the rate limiting system we built to never let that happen again.&lt;/p&gt;
&lt;h2 id=&quot;the-multi-layer-defense-system&quot;&gt;The Multi-Layer Defense System&lt;/h2&gt;
&lt;h3 id=&quot;layer-1-connection-level-throttling&quot;&gt;Layer 1: Connection-Level Throttling&lt;/h3&gt;
&lt;p&gt;Limit connections per IP before they even authenticate:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// app/Websocket/Middleware/ConnectionThrottle.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Websocket&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Middleware&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Ratchet&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;ConnectionInterface&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Support&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Facades&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Redis&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;ConnectionThrottle&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$maxConnectionsPerIp&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$maxConnectionsPerUser&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$connectionWindow&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// seconds&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;onOpen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;ConnectionInterface&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$ip&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;remoteAddress&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Check IP-based limits&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$ipKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ws:connections:ip:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$ipCount&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;incr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ipKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ipCount&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ipKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;connectionWindow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ipCount&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;maxConnectionsPerIp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
                &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;error&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Too many connections from your IP&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;retry_after&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;connectionWindow&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ipKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Store connection metadata&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;metadata&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ip&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;connected_at&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;microtime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;message_count&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;last_message_at&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;rate_limit_hits&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;onClose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;ConnectionInterface&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Clean up connection counts&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$ip&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ip&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ws:connections:ip:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ws:connections:user:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;layer-2-message-rate-limiting-token-bucket-algorithm&quot;&gt;Layer 2: Message Rate Limiting (Token Bucket Algorithm)&lt;/h3&gt;
&lt;p&gt;This is the gold standard for smooth rate limiting without hard cutoffs:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// app/Websocket/RateLimiter/TokenBucket.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Websocket&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;RateLimiter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Support&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Facades&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Redis&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;TokenBucket&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$capacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;      &lt;span class=&quot;token comment&quot;&gt;// Maximum tokens&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$refillRate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// Tokens per second&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$refillAmount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// Tokens added per refill&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$capacity&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$refillRate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;capacity&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$capacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;refillRate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$refillRate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;refillAmount&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$refillRate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;consume&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tokens&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$bucketKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ws:bucket:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Lua script for atomic token bucket&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;
            local key = KEYS[1]
            local capacity = tonumber(ARGV[1])
            local refill_rate = tonumber(ARGV[2])
            local tokens_requested = tonumber(ARGV[3])
            local now = tonumber(ARGV[4])

            -- Get current bucket state
            local bucket = redis.call(&quot;HMGET&quot;, key, &quot;tokens&quot;, &quot;last_refill&quot;)
            local current_tokens = tonumber(bucket[1]) or capacity
            local last_refill = tonumber(bucket[2]) or now

            -- Calculate tokens to add based on time passed
            local time_passed = now - last_refill
            local tokens_to_add = math.floor(time_passed * refill_rate)

            -- Refill bucket (up to capacity)
            current_tokens = math.min(capacity, current_tokens + tokens_to_add)

            -- Check if we can consume requested tokens
            if current_tokens &gt;= tokens_requested then
                -- Consume tokens
                current_tokens = current_tokens - tokens_requested

                -- Update bucket state
                redis.call(&quot;HMSET&quot;, key,
                    &quot;tokens&quot;, current_tokens,
                    &quot;last_refill&quot;, now
                )
                redis.call(&quot;EXPIRE&quot;, key, 3600)

                return {1, current_tokens}  -- Success
            else
                -- Not enough tokens
                redis.call(&quot;HMSET&quot;, key,
                    &quot;tokens&quot;, current_tokens,
                    &quot;last_refill&quot;, now
                )
                redis.call(&quot;EXPIRE&quot;, key, 3600)

                local wait_time = (tokens_requested - current_tokens) / refill_rate
                return {0, wait_time}  -- Failure with wait time
            end
        &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$bucketKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;capacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;refillRate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$tokens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;microtime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;allowed&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;remaining&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;retry_after&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Usage in WebSocket handler&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;MessageHandler&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$globalBucket&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userBuckets&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Global rate limit: 1000 messages/sec across all users&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;globalBucket&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TokenBucket&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;onMessage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;ConnectionInterface&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$msg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// User-specific bucket (lazy initialization)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;userBuckets&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;userBuckets&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TokenBucket&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;token argument-name&quot;&gt;capacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// 60 messages burst&lt;/span&gt;
                refillRate&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// 1 message per second sustained&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Check global rate limit first&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$globalResult&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;globalBucket&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;consume&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;global&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$globalResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;allowed&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;throttleResponse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$globalResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;retry_after&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Check user rate limit&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$userResult&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;userBuckets&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;consume&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;user:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$userResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;allowed&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;throttleResponse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;retry_after&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Check message-type specific limits&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$msgData&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;json_decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$msg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$msgData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;type&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$typeResult&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;checkTypeLimit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$msgData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;type&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$typeResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;allowed&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;throttleResponse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$typeResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;retry_after&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Process message normally&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;processMessage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$msg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;checkTypeLimit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Different limits for different message types&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$limits&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;location_update&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;capacity&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;rate&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// 10 burst, 1 per 2 sec&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status_change&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;capacity&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;rate&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;     &lt;span class=&quot;token comment&quot;&gt;// 5 burst, 1 per 5 sec&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;bulk_update&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;capacity&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;rate&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.033&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;     &lt;span class=&quot;token comment&quot;&gt;// 2 burst, 1 per 30 sec&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;file_upload&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;capacity&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;rate&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0167&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// 1 burst, 1 per minute&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$config&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$limits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;capacity&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;rate&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$bucket&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TokenBucket&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$config&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;capacity&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$config&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;rate&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$bucket&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;consume&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;user:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:type:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;throttleResponse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$retryAfter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;rate_limit_hits&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Exponential backoff for repeat offenders&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;rate_limit_hits&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$retryAfter&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;rate_limit_hits&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;type&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;rate_limit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;retry_after&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$retryAfter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;message&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Slow down! Too many messages.&apos;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Auto-disconnect abusive connections&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;rate_limit_hits&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;banUser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1 hour ban&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;layer-3-intelligent-circuit-breaker&quot;&gt;Layer 3: Intelligent Circuit Breaker&lt;/h3&gt;
&lt;p&gt;Protect your backend from WebSocket message floods:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// app/Websocket/CircuitBreaker.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;CircuitBreaker&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$thresholds&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;error_rate&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;        &lt;span class=&quot;token comment&quot;&gt;// 50% errors&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;volume_threshold&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// Minimum requests to evaluate&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;timeout_duration&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// Seconds to wait when open&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;success_threshold&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;     &lt;span class=&quot;token comment&quot;&gt;// Successes needed to close&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword type-hint&quot;&gt;callable&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$state&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$state&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;open&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$lastOpen&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;circuit:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:opened_at&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lastOpen&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;thresholds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;timeout_duration&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CircuitOpenException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Circuit breaker is OPEN for &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Try half-open state&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;half-open&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;recordSuccess&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$state&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;half-open&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$successes&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;incr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;circuit:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:successes&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$successes&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;thresholds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;success_threshold&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;closed&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name class-name-fully-qualified&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Exception&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$e&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;recordFailure&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;shouldOpen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;open&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;circuit:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:opened_at&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

            &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$e&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;shouldOpen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1 minute window&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$windowStart&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Count recent requests&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$total&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;circuit:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:requests&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowStart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$errors&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;circuit:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:errors&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowStart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$total&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;thresholds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;volume_threshold&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$errorRate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$errors&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$total&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$errorRate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;thresholds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;error_rate&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Usage: Protect database from WebSocket floods&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$circuitBreaker&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CircuitBreaker&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;message&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$msg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$circuitBreaker&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$circuitBreaker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipment_updates&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$msg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Your database operation&lt;/span&gt;
            &lt;span class=&quot;token class-name static-context&quot;&gt;Shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;tracking&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$msg&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;tracking&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$msg&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;CircuitOpenException&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$e&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$conn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;error&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Service temporarily unavailable&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;retry_after&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;layer-4-adaptive-rate-limiting&quot;&gt;Layer 4: Adaptive Rate Limiting&lt;/h3&gt;
&lt;p&gt;Automatically adjust limits based on system load:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;AdaptiveRateLimiter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getLimit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Base limits&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$baseLimit&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$premium&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isPremium&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$limit&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$premium&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$baseLimit&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$baseLimit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Adjust based on system load&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$systemLoad&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getSystemLoad&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$systemLoad&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$limit&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Halve limits under high load&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;elseif&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$systemLoad&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$limit&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.75&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Reduce by 25%&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Reputation-based adjustment&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$reputation&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getUserReputation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$reputation&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$limit&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Bad actors get less&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;elseif&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$reputation&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$limit&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Good users get more&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword type-casting&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$limit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Minimum 10 messages&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getSystemLoad&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Check Redis memory usage&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$memoryUsage&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;maxmemory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Check queue size&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$queueSize&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;llen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;broadcasts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$queueLoad&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$queueSize&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Check active connections&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$activeConnections&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ws:active_connections&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$connectionLoad&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$activeConnections&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Weighted average&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$memoryUsage&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$queueLoad&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$connectionLoad&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getUserReputation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;user:reputation:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Track good and bad behavior&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$goodActions&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hget&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;good&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$badActions&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hget&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;bad&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$total&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$goodActions&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$badActions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$total&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Neutral for new users&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$goodActions&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$total&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;production-monitoring-dashboard&quot;&gt;Production Monitoring Dashboard&lt;/h2&gt;
&lt;p&gt;Track rate limiting effectiveness:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// app/Http/Controllers/RateLimitMetricsController.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;metrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;current_connections&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ws:active_connections&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;rate_limit_hits&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metrics:rate_limit_hits:&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Y-m-d-H&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;banned_users&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ws:banned_users&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;circuit_breaker_state&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipment_updates&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;circuit:shipment_updates:state&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;database_writes&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;circuit:database_writes:state&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;top_offenders&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getTopOffenders&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;system_load&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AdaptiveRateLimiter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getSystemLoad&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getTopOffenders&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zrevrange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ws:rate_limit:offenders&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;WITHSCORES&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;emergency-kill-switch&quot;&gt;Emergency Kill Switch&lt;/h2&gt;
&lt;p&gt;When things go really wrong:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Emergency Redis commands to restore service&lt;/span&gt;
redis-cli FLUSHDB  &lt;span class=&quot;token comment&quot;&gt;# Nuclear option - disconnects everyone&lt;/span&gt;
redis-cli DEL ws:connections:*  &lt;span class=&quot;token comment&quot;&gt;# Reset connection counts&lt;/span&gt;
redis-cli DEL ws:bucket:*  &lt;span class=&quot;token comment&quot;&gt;# Reset all rate limits&lt;/span&gt;
redis-cli DEL circuit:*  &lt;span class=&quot;token comment&quot;&gt;# Reset circuit breakers&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;lessons-from-the-trenches&quot;&gt;Lessons from the Trenches&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Log Everything&lt;/strong&gt;: We caught a DDoS attempt because we logged rate limit hits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Different Limits for Different Operations&lt;/strong&gt;: Bulk updates need stricter limits than status checks&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Circuit Breakers Save Databases&lt;/strong&gt;: They prevented cascade failures 3 times last month&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Token Buckets &gt; Fixed Windows&lt;/strong&gt;: Smoother experience, no thundering herds&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Always Have a Kill Switch&lt;/strong&gt;: Sometimes you need to drop all connections NOW&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The system above handles 10k concurrent connections with bad actors trying to abuse it daily. It&apos;s not perfect, but it&apos;s kept us online for 2 years straight.&lt;/p&gt;
&lt;h2 id=&quot;learn-laravel-websockets-from-scratch&quot;&gt;Learn Laravel WebSockets from Scratch&lt;/h2&gt;
&lt;p&gt;Ready to build real-time applications with WebSockets? Start with these comprehensive Laravel tutorials:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-laravel/&quot;&gt;Build a Blog with Laravel&lt;/a&gt;&lt;/strong&gt; - Master the fundamentals: routing, Eloquent, and authentication&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;Build a Portfolio with Laravel&lt;/a&gt;&lt;/strong&gt; - Add real-time features like live notifications and status updates&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-laravel/&quot;&gt;Build E-Commerce with Laravel&lt;/a&gt;&lt;/strong&gt; - Implement advanced patterns including real-time inventory and order tracking&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each tutorial includes step-by-step AI prompts to guide you from basics to production-ready applications with WebSocket support.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Got war stories about WebSocket rate limiting? Drop them in the comments - we&apos;re all in this together.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[5 Redis-Muster fuer Echtzeit-Laravel-Apps, die skalieren]]></title><description><![CDATA[Nach der Migration von Redis zu KeyDB und zurueck, waehrend wir Milliarden an Logistiktransaktionen verarbeitet haben, habe ich gelernt…]]></description><link>https://vibecodingwithfred.com/de/blog/redis-patterns-laravel-quicktip/</link><guid isPermaLink="false">https://vibecodingwithfred.com/de/blog/redis-patterns-laravel-quicktip/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Nach der Migration von Redis zu KeyDB und zurueck, waehrend wir Milliarden an Logistiktransaktionen verarbeitet haben, habe ich gelernt, welche Redis-Muster im grossen Massstab funktionieren. Hier sind 5 praxiserprobte Muster, die Sie heute implementieren koennen.&lt;/p&gt;
&lt;h2 id=&quot;1-alles-pipelinen-10-facher-performance-boost&quot;&gt;1. Alles pipelinen (10-facher Performance-Boost)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Schlechtes Muster:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Das erzeugt 1000 Netzwerk-Roundtrips!&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Produktionsmuster:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Ein Netzwerkaufruf, atomare Ausfuehrung&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Reale Auswirkung:&lt;/strong&gt; Reduzierte unsere Bulk-Importzeit von 45 Sekunden auf 4 Sekunden fuer 10k Datensaetze.&lt;/p&gt;
&lt;h2 id=&quot;2-sliding-window-rate-limiting-implementieren&quot;&gt;2. Sliding-Window-Rate-Limiting implementieren&lt;/h2&gt;
&lt;p&gt;Vergessen Sie feste Fenster, die Thundering Herds verursachen. Hier ist, was wir in Produktion verwenden:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;RateLimiter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;attempt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;rate_limit:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;microtime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Alte Eintraege entfernen&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zremrangebyscore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Aktuelle Anfrage hinzufuegen&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Anfragen im Fenster zaehlen&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zcard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Ablauf setzen&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$results&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Verwendung in Middleware&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token class-name static-context&quot;&gt;RateLimiter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;attempt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;api:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Rate limit exceeded&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;429&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Warum es funktioniert:&lt;/strong&gt; Keine Spitzen an Fenstergrenzen, faire Verteilung, selbstreinigend.&lt;/p&gt;
&lt;h2 id=&quot;3-cache-invalidierung-mit-tags-der-richtige-weg&quot;&gt;3. Cache-Invalidierung mit Tags (Der richtige Weg)&lt;/h2&gt;
&lt;p&gt;Laravels Cache-Tags sind grossartig, bis Sie granulare Kontrolle benoetigen. Hier ist unser Muster:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;SmartCache&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;rememberWithDependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Haupt-Cache speichern&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Cache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Abhaengigkeiten in Redis-Sets verfolgen&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;86400&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1 Tag&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;invalidateTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;smembers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Alle getaggten Schluessel in einer Pipeline loeschen&lt;/span&gt;
            &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;del&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;del&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Verwendung&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$metrics&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;SmartCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rememberWithDependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;dashboard.metrics&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;deliveries&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;customer:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$customerId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 5 Minuten&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;calculateExpensiveMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Alle sendungsbezogenen Caches invalidieren&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;SmartCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;invalidateTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Produktionsgewinn:&lt;/strong&gt; Reduzierte Cache-Misses um 73% und eliminierte kaskadierende Invalidierungen.&lt;/p&gt;
&lt;h2 id=&quot;4-verteilte-locks-die-nicht-deadlocken&quot;&gt;4. Verteilte Locks, die nicht deadlocken&lt;/h2&gt;
&lt;p&gt;Nach dem Verlust von 50.000 Dollar durch eine Race Condition haben wir dieses kugelsichere Locking implementiert:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;DistributedLock&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;lock:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniqid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;gethostname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Atomares Setzen, wenn nicht existiert, mit Ablauf&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$acquired&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;NX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Nur setzen, wenn nicht existiert&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;EX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Nach X Sekunden ablaufen&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$acquired&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Pruefen, ob Lock veraltet ist (Backup-Mechanismus)&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockHolder&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lockHolder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Lock zwischen Befehlen abgelaufen, erneut versuchen&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;lock:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Lua-Skript fuer atomares Pruefen und Loeschen&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;
            if redis.call(&apos;get&apos;, KEYS[1]) == ARGV[1] then
                return redis.call(&apos;del&apos;, KEYS[1])
            else
                return 0
            end
        &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;withLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LockTimeoutException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Could not acquire lock for &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;finally&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Verwendung fuer Zahlungsverarbeitung&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;DistributedLock&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;withLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;payment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Zahlung sicher verarbeiten&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isPaid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Idempotenz-Pruefung&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;processPayment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;markAsPaid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Kritisch:&lt;/strong&gt; Das Lua-Skript stellt sicher, dass wir nur UNSEREN Lock freigeben, was versehentliches Freigeben des Locks eines anderen verhindert.&lt;/p&gt;
&lt;h2 id=&quot;5-echtzeit-metriken-mit-hyperloglog&quot;&gt;5. Echtzeit-Metriken mit HyperLogLog&lt;/h2&gt;
&lt;p&gt;Unique Visitors/Events verfolgen ohne Speicherexplosion:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;MetricsTracker&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;metric:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// HyperLogLog fuegt einzigartige Items mit O(1) Speicher hinzu&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 2 Fenster behalten&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getCardinality&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windows&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windows&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;metric:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Mehrere HyperLogLogs zusammenfuehren&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;trackAndBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Einzigartiges Event verfolgen&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;event:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:users&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Rate pro Minute verfolgen&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;event:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:rate&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniqid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Broadcast wenn Schwellenwert erreicht&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;broadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HighTrafficAlert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Verwendung&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$uniqueVisitors&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;page.visits&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$dailyActive&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCardinality&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user.active&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// API-Nutzung verfolgen ohne Speicherprobleme&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackAndBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;api.call&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Speicherersparnis:&lt;/strong&gt; Das Verfolgen von 10M einzigartigen Benutzern benoetigt ~12KB statt 40MB mit traditionellen Sets.&lt;/p&gt;
&lt;h2 id=&quot;bonus-redis-speicheroptimierungs-checkliste&quot;&gt;Bonus: Redis-Speicheroptimierungs-Checkliste&lt;/h2&gt;
&lt;p&gt;Aus unserem Produktions-Playbook:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 1. Komprimierung fuer grosse Werte verwenden&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;large:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;gzcompress&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 2. Hashes fuer kleine Objekte verwenden (90% Speicherersparnis!)&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;user:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;name&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;email&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;status&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 3. Aggressive Ablaufzeiten setzen&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 5 Min Standard, nicht 1 Stunde&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 4. SCAN statt KEYS verwenden&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scan&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;MATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipment:*&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;COUNT&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// $keys verarbeiten&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 5. Speichernutzung ueberwachen&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1073741824&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1GB&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Redis memory critical: &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory_human&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;die-teuren-lektionen&quot;&gt;Die teuren Lektionen&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Immer Ablaufzeiten setzen&lt;/strong&gt; - Eine fehlende TTL verbrauchte 8GB RAM&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pipelinen oder untergehen&lt;/strong&gt; - Netzwerklatenz addiert sich schnell&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Die richtige Datenstruktur verwenden&lt;/strong&gt; - HyperLogLog sparte uns 2k$/Monat an Speicher&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Richtig sperren&lt;/strong&gt; - Race Conditions in Finanzsystemen = Klagen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alles ueberwachen&lt;/strong&gt; - Sie koennen nicht reparieren, was Sie nicht messen&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Diese Muster verarbeiten 50k Anfragen/Sekunde in Produktion. Beginnen Sie mit Pipelines und richtigem Locking - sie loesen 80% Ihrer Redis-Performance-Probleme.&lt;/p&gt;
&lt;h2 id=&quot;laravel-mit-echten-projekten-meistern&quot;&gt;Laravel mit echten Projekten meistern&lt;/h2&gt;
&lt;p&gt;Moechten Sie diese Redis-Muster in einer echten Anwendung implementieren? Bauen Sie produktionsreife Laravel-Projekte von Grund auf:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-laravel/&quot;&gt;Einen Blog mit Laravel bauen&lt;/a&gt;&lt;/strong&gt; - Eloquent, Authentifizierung und CRUD-Operationen mit Redis-Caching meistern&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;Ein Portfolio mit Laravel bauen&lt;/a&gt;&lt;/strong&gt; - Datei-Uploads, Beziehungen und Redis-gesteuerte Sessions lernen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-laravel/&quot;&gt;E-Commerce mit Laravel bauen&lt;/a&gt;&lt;/strong&gt; - Fortgeschrittene Muster inklusive Queues, Event-Handling und verteilte Locks&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Jedes Tutorial enthaelt KI-unterstuetzte Prompts, die Sie durch den Aufbau skalierbarer Anwendungen fuehren, die Redis effektiv nutzen.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Fragen zur Implementierung dieser Muster? Schreiben Sie einen Kommentar - ich habe dieses Problem wahrscheinlich schon um 3 Uhr morgens debuggt.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Como Funcionan los Creditos de Lovable: La Guia Completa de Precios 2025]]></title><description><![CDATA[Guia completa del sistema de creditos de Lovable: niveles de precios, que consume creditos, estrategias de optimizacion, politicas de reembolso y preguntas frecuentes. Aprende como maximizar tus creditos y evitar errores comunes que desperdician uso de IA.]]></description><link>https://vibecodingwithfred.com/es/blog/lovable-credits-complete-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/es/blog/lovable-credits-complete-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Si estas buscando &quot;&lt;strong&gt;como funcionan los creditos de Lovable&lt;/strong&gt;&quot; o preguntandote sobre el modelo de precios de Lovable, no estas solo. Basado en datos recientes, este es uno de los aspectos mas confusos de la plataforma Lovable. Esta guia completa responde cada pregunta sobre creditos de Lovable, niveles de precios y politicas de reembolso.&lt;/p&gt;
&lt;h2 id=&quot;tabla-de-contenidos&quot;&gt;Tabla de Contenidos&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#que-son-los-creditos-de-lovable&quot;&gt;Que Son los Creditos de Lovable?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#como-funcionan-los-creditos&quot;&gt;Como Funcionan los Creditos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#desglose-de-niveles-de-precios&quot;&gt;Desglose de Niveles de Precios&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#que-consume-creditos&quot;&gt;Que Consume Creditos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#consejos-de-optimizacion-de-creditos&quot;&gt;Consejos de Optimizacion de Creditos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#politica-de-reembolso&quot;&gt;Politica de Reembolso&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#preguntas-frecuentes&quot;&gt;Preguntas Frecuentes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#calculadora-de-creditos&quot;&gt;Calculadora de Creditos&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;que-son-los-creditos-de-lovable&quot;&gt;Que Son los Creditos de Lovable?&lt;/h2&gt;
&lt;p&gt;Los creditos de Lovable son la moneda de la plataforma para funciones de desarrollo impulsadas por IA. Piensa en ellos como fichas en un arcade - necesitas creditos para usar la IA de Lovable para generar codigo, crear componentes o modificar tus proyectos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Puntos Clave:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 credito ≈ 1 interaccion de IA (varia segun complejidad)&lt;/li&gt;
&lt;li&gt;Los creditos no expiran dentro de tu periodo de facturacion&lt;/li&gt;
&lt;li&gt;Los creditos no usados pueden o no acumularse (depende del plan)&lt;/li&gt;
&lt;li&gt;Puedes comprar creditos adicionales a mitad de ciclo&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;como-funcionan-los-creditos&quot;&gt;Como Funcionan los Creditos&lt;/h2&gt;
&lt;h3 id=&quot;el-sistema-de-creditos-explicado&quot;&gt;El Sistema de Creditos Explicado&lt;/h3&gt;
&lt;p&gt;Cuando usas Lovable para construir tu aplicacion, cada accion impulsada por IA consume creditos:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Entrada del Usuario → Procesamiento de IA → Deduccion de Creditos → Salida Generada&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;tasas-de-consumo-de-creditos&quot;&gt;Tasas de Consumo de Creditos&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Accion&lt;/th&gt;
&lt;th&gt;Creditos Usados&lt;/th&gt;
&lt;th&gt;Ejemplo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Generacion de componente simple&lt;/td&gt;
&lt;td&gt;1-2 creditos&lt;/td&gt;
&lt;td&gt;Boton, campo de formulario&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Creacion de componente complejo&lt;/td&gt;
&lt;td&gt;3-5 creditos&lt;/td&gt;
&lt;td&gt;Tabla de datos, grafico&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generacion de pagina completa&lt;/td&gt;
&lt;td&gt;5-10 creditos&lt;/td&gt;
&lt;td&gt;Landing page, dashboard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Correccion de bugs/debugging&lt;/td&gt;
&lt;td&gt;1-3 creditos&lt;/td&gt;
&lt;td&gt;Resolucion de errores&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Refactorizacion de codigo&lt;/td&gt;
&lt;td&gt;2-4 creditos&lt;/td&gt;
&lt;td&gt;Optimizacion de rendimiento&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cambios de esquema de base de datos&lt;/td&gt;
&lt;td&gt;3-5 creditos&lt;/td&gt;
&lt;td&gt;Agregar tablas/relaciones&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;desglose-de-niveles-de-precios&quot;&gt;Desglose de Niveles de Precios&lt;/h2&gt;
&lt;h3 id=&quot;nivel-gratuito&quot;&gt;Nivel Gratuito&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Creditos:&lt;/strong&gt; 100/mes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Precio:&lt;/strong&gt; $0&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mejor para:&lt;/strong&gt; Probar la plataforma, prototipos pequenos&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Limitaciones:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Sin dominios personalizados&lt;/li&gt;
&lt;li&gt;Opciones de despliegue limitadas&lt;/li&gt;
&lt;li&gt;Se requiere branding de Lovable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;plan-starter&quot;&gt;Plan Starter&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Creditos:&lt;/strong&gt; 500/mes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Precio:&lt;/strong&gt; $20/mes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mejor para:&lt;/strong&gt; Proyectos paralelos, MVPs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Incluye:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Dominio personalizado&lt;/li&gt;
&lt;li&gt;Exportacion a GitHub&lt;/li&gt;
&lt;li&gt;Soporte por correo&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;plan-pro&quot;&gt;Plan Pro&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Creditos:&lt;/strong&gt; 2,000/mes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Precio:&lt;/strong&gt; $70/mes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mejor para:&lt;/strong&gt; Desarrollo activo, equipos pequenos&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Incluye:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Todo en Starter&lt;/li&gt;
&lt;li&gt;Soporte prioritario&lt;/li&gt;
&lt;li&gt;Integraciones avanzadas&lt;/li&gt;
&lt;li&gt;Colaboracion de equipo (hasta 3 miembros)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;plan-business&quot;&gt;Plan Business&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Creditos:&lt;/strong&gt; 10,000/mes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Precio:&lt;/strong&gt; $299/mes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mejor para:&lt;/strong&gt; Agencias, startups en crecimiento&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Incluye:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Todo en Pro&lt;/li&gt;
&lt;li&gt;Miembros de equipo ilimitados&lt;/li&gt;
&lt;li&gt;Opciones de marca blanca&lt;/li&gt;
&lt;li&gt;Acceso a API&lt;/li&gt;
&lt;li&gt;Gerente de cuenta dedicado&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;enterprise&quot;&gt;Enterprise&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Creditos:&lt;/strong&gt; Personalizado&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Precio:&lt;/strong&gt; Contactar ventas&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mejor para:&lt;/strong&gt; Grandes organizaciones&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Incluye:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Paquetes de creditos personalizados&lt;/li&gt;
&lt;li&gt;Garantias de SLA&lt;/li&gt;
&lt;li&gt;Opciones on-premise&lt;/li&gt;
&lt;li&gt;Integraciones personalizadas&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;que-consume-creditos&quot;&gt;Que Consume Creditos&lt;/h2&gt;
&lt;h3 id=&quot;uso-alto-de-creditos-5-creditos&quot;&gt;Uso Alto de Creditos (5+ creditos)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Generar paginas enteras desde cero&lt;/li&gt;
&lt;li&gt;Componentes UI complejos con multiples estados&lt;/li&gt;
&lt;li&gt;Generacion de esquema de base de datos&lt;/li&gt;
&lt;li&gt;Configuracion de sistema de autenticacion&lt;/li&gt;
&lt;li&gt;Integracion de pagos&lt;/li&gt;
&lt;li&gt;Funciones en tiempo real (configuracion de WebSocket)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;uso-medio-de-creditos-2-4-creditos&quot;&gt;Uso Medio de Creditos (2-4 creditos)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Crear componentes personalizados&lt;/li&gt;
&lt;li&gt;Modificar componentes existentes&lt;/li&gt;
&lt;li&gt;Agregar endpoints de API&lt;/li&gt;
&lt;li&gt;Implementar logica de negocio&lt;/li&gt;
&lt;li&gt;Validacion de formularios&lt;/li&gt;
&lt;li&gt;Ajustes de diseno responsivo&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;uso-bajo-de-creditos-1-credito&quot;&gt;Uso Bajo de Creditos (1 credito)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Cambios simples de texto&lt;/li&gt;
&lt;li&gt;Ajustes de CSS&lt;/li&gt;
&lt;li&gt;Agregar elementos HTML basicos&lt;/li&gt;
&lt;li&gt;Correcciones de bugs menores&lt;/li&gt;
&lt;li&gt;Comentar codigo&lt;/li&gt;
&lt;li&gt;Renombrar variables&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;sin-uso-de-creditos&quot;&gt;Sin Uso de Creditos&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Ver tu proyecto&lt;/li&gt;
&lt;li&gt;Edicion manual de codigo&lt;/li&gt;
&lt;li&gt;Desplegar (usa creditos de despliegue por separado)&lt;/li&gt;
&lt;li&gt;Descargar/exportar codigo&lt;/li&gt;
&lt;li&gt;Usar control de versiones&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;consejos-de-optimizacion-de-creditos&quot;&gt;Consejos de Optimizacion de Creditos&lt;/h2&gt;
&lt;h3 id=&quot;1-se-especifico-con-los-prompts&quot;&gt;1. Se Especifico con los Prompts&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Malo:&lt;/strong&gt; &quot;Haz un formulario&quot;
&lt;strong&gt;Bueno:&lt;/strong&gt; &quot;Crea un formulario de contacto con campos de nombre, correo, mensaje, validacion y boton de enviar estilizado con Tailwind CSS&quot;&lt;/p&gt;
&lt;p&gt;Ser especifico reduce las iteraciones de ida y vuelta, ahorrando creditos.&lt;/p&gt;
&lt;h3 id=&quot;2-usa-edicion-manual-cuando-sea-posible&quot;&gt;2. Usa Edicion Manual Cuando Sea Posible&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Pequenos ajustes de CSS? Edita manualmente&lt;/li&gt;
&lt;li&gt;Correcciones de errores tipograficos? No desperdicies creditos&lt;/li&gt;
&lt;li&gt;Adiciones simples de HTML? Hazlo tu mismo&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3-agrupa-tus-solicitudes&quot;&gt;3. Agrupa Tus Solicitudes&lt;/h3&gt;
&lt;p&gt;En lugar de multiples solicitudes pequenas:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;❌ &quot;Agrega un header&quot;
❌ &quot;Ahora agrega un footer&quot;
❌ &quot;Agrega una barra lateral&quot;

✅ &quot;Agrega un header con logo y navegacion, footer con enlaces, y barra lateral izquierda con items de menu&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-aprovecha-las-plantillas&quot;&gt;4. Aprovecha las Plantillas&lt;/h3&gt;
&lt;p&gt;Comienza con las plantillas de Lovable para reducir creditos de generacion inicial.&lt;/p&gt;
&lt;h3 id=&quot;5-planifica-antes-de-construir&quot;&gt;5. Planifica Antes de Construir&lt;/h3&gt;
&lt;p&gt;Esboza tus requerimientos primero. La experimentacion aleatoria quema creditos rapido.&lt;/p&gt;
&lt;h3 id=&quot;6-monitorea-el-uso-de-creditos&quot;&gt;6. Monitorea el Uso de Creditos&lt;/h3&gt;
&lt;p&gt;Revisa tu balance de creditos regularmente:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dashboard → Settings → Billing → Credit Usage&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;7-usa-el-nivel-gratuito-para-aprender&quot;&gt;7. Usa el Nivel Gratuito para Aprender&lt;/h3&gt;
&lt;p&gt;Practica ingenieria de prompts en el nivel gratuito antes de actualizar.&lt;/p&gt;
&lt;h2 id=&quot;politica-de-reembolso&quot;&gt;Politica de Reembolso&lt;/h2&gt;
&lt;h3 id=&quot;cuando-los-reembolsos-estan-disponibles&quot;&gt;Cuando los Reembolsos Estan Disponibles&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Problemas tecnicos que previenen el uso de creditos&lt;/li&gt;
&lt;li&gt;Errores de facturacion&lt;/li&gt;
&lt;li&gt;Dentro de 14 dias de la compra (clientes de primera vez)&lt;/li&gt;
&lt;li&gt;Paquetes de creditos no usados&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;cuando-los-reembolsos-no-estan-disponibles&quot;&gt;Cuando los Reembolsos NO Estan Disponibles&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Creditos ya consumidos&lt;/li&gt;
&lt;li&gt;Despues del periodo de 14 dias&lt;/li&gt;
&lt;li&gt;Renovaciones de suscripcion (despues del primer mes)&lt;/li&gt;
&lt;li&gt;&quot;Cambie de opinion&quot; despues de usar creditos&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;como-solicitar-un-reembolso&quot;&gt;Como Solicitar un Reembolso&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Correo: &lt;a href=&quot;mailto:support@lovable.dev&quot;&gt;support@lovable.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Incluye: Numero de orden, razon, capturas de pantalla&lt;/li&gt;
&lt;li&gt;Tiempo de respuesta: 24-48 horas&lt;/li&gt;
&lt;li&gt;Procesamiento: 5-7 dias habiles&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;preguntas-frecuentes&quot;&gt;Preguntas Frecuentes&lt;/h2&gt;
&lt;h3 id=&quot;los-creditos-se-acumulan-al-siguiente-mes&quot;&gt;Los creditos se acumulan al siguiente mes?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Free/Starter:&lt;/strong&gt; Sin acumulacion
&lt;strong&gt;Pro/Business:&lt;/strong&gt; Hasta 20% de acumulacion
&lt;strong&gt;Enterprise:&lt;/strong&gt; Negociable&lt;/p&gt;
&lt;h3 id=&quot;puedo-comprar-creditos-adicionales&quot;&gt;Puedo comprar creditos adicionales?&lt;/h3&gt;
&lt;p&gt;Si! Paquetes de creditos adicionales:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;100 creditos: $5&lt;/li&gt;
&lt;li&gt;500 creditos: $20&lt;/li&gt;
&lt;li&gt;1,000 creditos: $35&lt;/li&gt;
&lt;li&gt;5,000 creditos: $150&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;que-pasa-cuando-me-quedo-sin-creditos&quot;&gt;Que pasa cuando me quedo sin creditos?&lt;/h3&gt;
&lt;p&gt;Tu proyecto permanece accesible, pero no puedes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generar nuevo codigo&lt;/li&gt;
&lt;li&gt;Modificar con IA&lt;/li&gt;
&lt;li&gt;Usar funciones de IA&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;PUEDES aun:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Editar codigo manualmente&lt;/li&gt;
&lt;li&gt;Desplegar codigo existente&lt;/li&gt;
&lt;li&gt;Exportar tu proyecto&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;puedo-transferir-creditos-entre-cuentas&quot;&gt;Puedo transferir creditos entre cuentas?&lt;/h3&gt;
&lt;p&gt;Actualmente, Lovable no soporta transferencias de creditos. Sin embargo, puedes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Exportar proyecto de Cuenta A&lt;/li&gt;
&lt;li&gt;Importar a Cuenta B&lt;/li&gt;
&lt;li&gt;Continuar trabajo con creditos de Cuenta B&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;como-puedo-verificar-mis-creditos-restantes&quot;&gt;Como puedo verificar mis creditos restantes?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Metodo 1:&lt;/strong&gt; Dashboard → Esquina superior derecha&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Metodo 2:&lt;/strong&gt; Settings → Billing → Usage&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Metodo 3:&lt;/strong&gt; Pasa el mouse sobre el icono de creditos en el editor&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;los-creditos-expiran&quot;&gt;Los creditos expiran?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Creditos mensuales: Expiran al final del ciclo de facturacion&lt;/li&gt;
&lt;li&gt;Creditos comprados: Expiran despues de 90 dias&lt;/li&gt;
&lt;li&gt;Creditos promocionales: Revisa los terminos (usualmente 30 dias)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;hay-un-historial-de-uso-de-creditos&quot;&gt;Hay un historial de uso de creditos?&lt;/h3&gt;
&lt;p&gt;Si! Ve el historial detallado:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Settings → Billing → Usage History&lt;/li&gt;
&lt;li&gt;Filtra por fecha, tipo de accion&lt;/li&gt;
&lt;li&gt;Exporta como CSV para analisis&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;calculadora-de-creditos&quot;&gt;Calculadora de Creditos&lt;/h2&gt;
&lt;h3 id=&quot;estima-tus-necesidades-mensuales&quot;&gt;Estima Tus Necesidades Mensuales&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Proyecto Pequeno (Landing Page):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generacion inicial: 10 creditos&lt;/li&gt;
&lt;li&gt;Revisiones: 20 creditos&lt;/li&gt;
&lt;li&gt;Pulido: 10 creditos&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total: ~40 creditos&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Proyecto Mediano (SaaS MVP):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Paginas (5): 50 creditos&lt;/li&gt;
&lt;li&gt;Componentes: 30 creditos&lt;/li&gt;
&lt;li&gt;API/Base de datos: 40 creditos&lt;/li&gt;
&lt;li&gt;Revisiones: 80 creditos&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total: ~200 creditos&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Proyecto Grande (Aplicacion Completa):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Paginas (20+): 200 creditos&lt;/li&gt;
&lt;li&gt;Funciones complejas: 150 creditos&lt;/li&gt;
&lt;li&gt;Integraciones: 100 creditos&lt;/li&gt;
&lt;li&gt;Testing/Debugging: 150 creditos&lt;/li&gt;
&lt;li&gt;Iteraciones: 200 creditos&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total: ~800 creditos&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;consejos-pro-de-usuarios-avanzados&quot;&gt;Consejos Pro de Usuarios Avanzados&lt;/h2&gt;
&lt;h3 id=&quot;la-regla-8020&quot;&gt;La Regla 80/20&lt;/h3&gt;
&lt;p&gt;&quot;80% de tus creditos van a 20% de las funciones. Identifica las funciones principales y perfecciona esas primero.&quot; - Sarah M., Propietaria de Agencia&lt;/p&gt;
&lt;h3 id=&quot;estrategia-de-plantillas&quot;&gt;Estrategia de Plantillas&lt;/h3&gt;
&lt;p&gt;&quot;Comienza con la plantilla mas cercana, luego modifica. Ahorra 50% de creditos vs. empezar desde cero.&quot; - Mike R., Fundador de Startup&lt;/p&gt;
&lt;h3 id=&quot;procesamiento-por-lotes&quot;&gt;Procesamiento por Lotes&lt;/h3&gt;
&lt;p&gt;&quot;Listo todos los cambios en un prompt. Pase de usar 500 creditos/semana a 200.&quot; - Jennifer L., Desarrolladora&lt;/p&gt;
&lt;h2 id=&quot;errores-comunes-de-creditos-a-evitar&quot;&gt;Errores Comunes de Creditos a Evitar&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Prompts Vagos&lt;/strong&gt; - Desperdicia creditos en iteraciones&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No Usar Edicion Manual&lt;/strong&gt; - Quema creditos en arreglos simples&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sin Planificacion&lt;/strong&gt; - La experimentacion aleatoria es cara&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ignorar Plantillas&lt;/strong&gt; - Empezar de cero cuesta mas&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No Monitorear Uso&lt;/strong&gt; - Sorpresa cuando se agotan los creditos&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;estrategias-alternativas&quot;&gt;Estrategias Alternativas&lt;/h2&gt;
&lt;h3 id=&quot;cuando-tienes-pocos-creditos&quot;&gt;Cuando Tienes Pocos Creditos&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Modo de Codificacion Manual&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Usa Lovable solo para partes complejas&lt;/li&gt;
&lt;li&gt;Maneja ediciones simples tu mismo&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Exportar y Continuar&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Exporta a GitHub&lt;/li&gt;
&lt;li&gt;Continua desarrollo en VS Code&lt;/li&gt;
&lt;li&gt;Regresa a Lovable para asistencia de IA&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Colaboracion de Equipo&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Agrupa creditos con miembros del equipo&lt;/li&gt;
&lt;li&gt;Asigna tareas intensivas en creditos a quienes tienen mas&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;comparacion-de-creditos-con-competidores&quot;&gt;Comparacion de Creditos con Competidores&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plataforma&lt;/th&gt;
&lt;th&gt;Modelo de Precios&lt;/th&gt;
&lt;th&gt;Costo Mensual&lt;/th&gt;
&lt;th&gt;Mejor Para&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lovable&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Basado en creditos&lt;/td&gt;
&lt;td&gt;$0-299&lt;/td&gt;
&lt;td&gt;Flexibilidad&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;V0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Basado en generacion&lt;/td&gt;
&lt;td&gt;$20 fijo&lt;/td&gt;
&lt;td&gt;Proyectos simples&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cursor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Suscripcion&lt;/td&gt;
&lt;td&gt;$20 fijo&lt;/td&gt;
&lt;td&gt;Edicion de codigo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub Copilot&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Suscripcion&lt;/td&gt;
&lt;td&gt;$10 fijo&lt;/td&gt;
&lt;td&gt;Autocompletado de codigo&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Entender como funcionan los creditos de Lovable es crucial para desarrollo eficiente y gestion de presupuesto. La clave es:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Elegir el nivel de precios correcto&lt;/li&gt;
&lt;li&gt;Optimizar tu uso de creditos&lt;/li&gt;
&lt;li&gt;Usar edicion manual para tareas simples&lt;/li&gt;
&lt;li&gt;Planificar antes de construir&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Con estas estrategias, puedes construir aplicaciones impresionantes sin quemar creditos innecesariamente.&lt;/p&gt;
&lt;h2 id=&quot;necesitas-mas-ayuda&quot;&gt;Necesitas Mas Ayuda?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Documentacion de Lovable:&lt;/strong&gt; &lt;a href=&quot;https://docs.lovable.dev/credits&quot;&gt;docs.lovable.dev/credits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sitio Web de Lovable:&lt;/strong&gt; &lt;a href=&quot;https://lovable.dev&quot;&gt;lovable.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Correo de Soporte:&lt;/strong&gt; &lt;a href=&quot;mailto:support@lovable.dev&quot;&gt;support@lovable.dev&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Encontraste esta guia util? Revisa nuestros otros tutoriales de Lovable y despliegue:&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/export-lovable-to-github-complete&quot;&gt;Exportar Lovable a GitHub: Guia Completa&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website/&quot;&gt;Desplegar Lovable a Vercel en 5 Minutos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;Desplegar Lovable a Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/getting-started-vercel/&quot;&gt;Comenzando con Despliegue en Vercel&lt;/a&gt; - Guia completa para principiantes para desplegar cualquier proyecto en el nivel gratuito de Vercel&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[5 Patrones de Redis para Aplicaciones Laravel en Tiempo Real que Escalan]]></title><description><![CDATA[Despues de migrar de Redis a KeyDB y de vuelta mientras procesabamos miles de millones en transacciones logisticas, he aprendido que…]]></description><link>https://vibecodingwithfred.com/es/blog/redis-patterns-laravel-quicktip/</link><guid isPermaLink="false">https://vibecodingwithfred.com/es/blog/redis-patterns-laravel-quicktip/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Despues de migrar de Redis a KeyDB y de vuelta mientras procesabamos miles de millones en transacciones logisticas, he aprendido que patrones de Redis funcionan a escala. Aqui hay 5 patrones probados en batalla que puedes implementar hoy.&lt;/p&gt;
&lt;h2 id=&quot;1-usa-pipeline-para-todo-10x-mejora-de-rendimiento&quot;&gt;1. Usa Pipeline para Todo (10x Mejora de Rendimiento)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Patron Malo:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Esto crea 1000 viajes de red!&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Patron de Produccion:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Una llamada de red, ejecucion atomica&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Impacto Real:&lt;/strong&gt; Redujimos nuestro tiempo de importacion masiva de 45 segundos a 4 segundos para 10k registros.&lt;/p&gt;
&lt;h2 id=&quot;2-implementa-rate-limiting-con-ventana-deslizante&quot;&gt;2. Implementa Rate Limiting con Ventana Deslizante&lt;/h2&gt;
&lt;p&gt;Olvida las ventanas fijas que causan estampidas. Esto es lo que usamos en produccion:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;RateLimiter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;attempt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;rate_limit:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;microtime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Eliminar entradas viejas&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zremrangebyscore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Agregar solicitud actual&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Contar solicitudes en la ventana&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zcard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Establecer expiracion&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$results&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Uso en middleware&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token class-name static-context&quot;&gt;RateLimiter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;attempt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;api:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Rate limit exceeded&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;429&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Por Que Funciona:&lt;/strong&gt; Sin picos en los limites de ventana, distribucion justa, auto-limpieza.&lt;/p&gt;
&lt;h2 id=&quot;3-invalidacion-de-cache-con-tags-la-forma-correcta&quot;&gt;3. Invalidacion de Cache con Tags (La Forma Correcta)&lt;/h2&gt;
&lt;p&gt;Los tags de cache de Laravel son geniales hasta que necesitas control granular. Aqui esta nuestro patron:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;SmartCache&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;rememberWithDependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Almacenar el cache principal&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Cache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Rastrear dependencias en sets de Redis&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;86400&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1 dia&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;invalidateTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;smembers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Eliminar todas las claves etiquetadas en un pipeline&lt;/span&gt;
            &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;del&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;del&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Uso&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$metrics&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;SmartCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rememberWithDependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;dashboard.metrics&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;deliveries&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;customer:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$customerId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 5 minutos&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;calculateExpensiveMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Invalidar todos los caches relacionados con envios&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;SmartCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;invalidateTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Victoria en Produccion:&lt;/strong&gt; Redujimos los cache misses en 73% y eliminamos las invalidaciones en cascada.&lt;/p&gt;
&lt;h2 id=&quot;4-bloqueos-distribuidos-que-no-causan-deadlock&quot;&gt;4. Bloqueos Distribuidos Que No Causan Deadlock&lt;/h2&gt;
&lt;p&gt;Despues de perder $50k por una condicion de carrera, implementamos este bloqueo a prueba de balas:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;DistributedLock&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;lock:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniqid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;gethostname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Set atomico si no existe con expiracion&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$acquired&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;NX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Solo establecer si no existe&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;EX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Expirar despues de X segundos&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$acquired&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Verificar si el bloqueo esta obsoleto (mecanismo de respaldo)&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockHolder&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lockHolder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// El bloqueo expiro entre comandos, intentar de nuevo&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;lock:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Script Lua para verificar y eliminar atomicamente&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;
            if redis.call(&apos;get&apos;, KEYS[1]) == ARGV[1] then
                return redis.call(&apos;del&apos;, KEYS[1])
            else
                return 0
            end
        &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;withLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LockTimeoutException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Could not acquire lock for &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;finally&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Uso para procesamiento de pagos&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;DistributedLock&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;withLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;payment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Procesar pago de forma segura&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isPaid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Verificacion idempotente&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;processPayment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;markAsPaid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Critico:&lt;/strong&gt; El script Lua asegura que solo liberemos NUESTRO bloqueo, previniendo la liberacion accidental del bloqueo de alguien mas.&lt;/p&gt;
&lt;h2 id=&quot;5-metricas-en-tiempo-real-con-hyperloglog&quot;&gt;5. Metricas en Tiempo Real con HyperLogLog&lt;/h2&gt;
&lt;p&gt;Rastrea visitantes/eventos unicos sin explosion de memoria:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;MetricsTracker&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;metric:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// HyperLogLog agrega items unicos con espacio O(1)&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Mantener 2 ventanas&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getCardinality&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windows&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windows&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;metric:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Fusionar multiples HyperLogLogs&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;trackAndBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Rastrear evento unico&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;event:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:users&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Rastrear tasa por minuto&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;event:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:rate&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniqid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Broadcast si se alcanza umbral&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;broadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HighTrafficAlert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Uso&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$uniqueVisitors&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;page.visits&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$dailyActive&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCardinality&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user.active&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Rastrear uso de API sin problemas de memoria&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackAndBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;api.call&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Ahorro de Memoria:&lt;/strong&gt; Rastrear 10M usuarios unicos toma ~12KB en lugar de 40MB con sets tradicionales.&lt;/p&gt;
&lt;h2 id=&quot;bonus-lista-de-verificacion-de-optimizacion-de-memoria-redis&quot;&gt;Bonus: Lista de Verificacion de Optimizacion de Memoria Redis&lt;/h2&gt;
&lt;p&gt;De nuestro playbook de produccion:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 1. Usa compresion para valores grandes&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;large:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;gzcompress&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 2. Usa hashes para objetos pequenos (90% ahorro de memoria!)&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;user:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;name&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;email&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;status&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 3. Establece expiraciones agresivas&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 5 min por defecto, no 1 hora&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 4. Usa SCAN en lugar de KEYS&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scan&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;MATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipment:*&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;COUNT&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Procesar $keys&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 5. Monitorea uso de memoria&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1073741824&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1GB&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Redis memory critical: &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory_human&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;las-lecciones-costosas&quot;&gt;Las Lecciones Costosas&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Siempre establece expiraciones&lt;/strong&gt; - Un TTL faltante consumio 8GB de RAM&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pipeline o muere&lt;/strong&gt; - La latencia de red se acumula rapido&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Usa la estructura de datos correcta&lt;/strong&gt; - HyperLogLog nos ahorro $2k/mes en memoria&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bloquea correctamente&lt;/strong&gt; - Las condiciones de carrera en sistemas financieros = demandas&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Monitorea todo&lt;/strong&gt; - No puedes arreglar lo que no mides&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Estos patrones manejan 50k solicitudes/segundo en produccion. Comienza con pipelines y bloqueo adecuado—resolveran el 80% de tus problemas de rendimiento con Redis.&lt;/p&gt;
&lt;h2 id=&quot;domina-laravel-con-proyectos-reales&quot;&gt;Domina Laravel con Proyectos Reales&lt;/h2&gt;
&lt;p&gt;Quieres implementar estos patrones de Redis en una aplicacion real? Construye proyectos Laravel listos para produccion desde cero:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-laravel/&quot;&gt;Construye un Blog con Laravel&lt;/a&gt;&lt;/strong&gt; - Domina Eloquent, autenticacion, y operaciones CRUD con caching de Redis&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;Construye un Portafolio con Laravel&lt;/a&gt;&lt;/strong&gt; - Aprende carga de archivos, relaciones, y sesiones con Redis&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-laravel/&quot;&gt;Construye E-Commerce con Laravel&lt;/a&gt;&lt;/strong&gt; - Patrones avanzados incluyendo colas, manejo de eventos, y bloqueos distribuidos&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cada tutorial incluye prompts asistidos por IA para guiarte en la construccion de aplicaciones escalables que usan Redis efectivamente.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Preguntas sobre implementar estos patrones? Deja un comentario - probablemente he debuggeado ese problema a las 3 AM.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Comment exporter le code Lovable.dev vers GitHub avec synchronisation continue et deploiement]]></title><description><![CDATA[Exportez votre projet Lovable vers GitHub avec ce guide complet. Couvre trois methodes d'export, sync continue vs export unique, configuration CI/CD GitHub Actions, depannage et workflows post-export pour deployer n'importe ou.]]></description><link>https://vibecodingwithfred.com/fr/blog/export-lovable-to-github-complete/</link><guid isPermaLink="false">https://vibecodingwithfred.com/fr/blog/export-lovable-to-github-complete/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Vous cherchez a &lt;strong&gt;exporter votre projet Lovable vers GitHub&lt;/strong&gt; ? Vous etes parmi les centaines de developpeurs recherchant exactement cette solution. Que vous ayez besoin de controle de version, de collaboration d&apos;equipe ou que vous vouliez deployer ailleurs, ce guide couvre chaque methode pour mettre votre code Lovable dans GitHub.&lt;/p&gt;
&lt;h2 id=&quot;pourquoi-exporter-lovable-vers-github-&quot;&gt;Pourquoi exporter Lovable vers GitHub ?&lt;/h2&gt;
&lt;p&gt;Avant de plonger dans le comment, comprenons le pourquoi :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Controle de version :&lt;/strong&gt; Suivre les changements, revenir sur les erreurs, gerer les branches&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Collaboration d&apos;equipe :&lt;/strong&gt; Travailler avec des developpeurs qui ne sont pas sur Lovable&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Liberte de deploiement :&lt;/strong&gt; Deployer sur Vercel, Netlify, AWS, n&apos;importe ou&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Strategie de sauvegarde :&lt;/strong&gt; Se proteger contre les problemes de plateforme&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gestion des couts :&lt;/strong&gt; Continuer le developpement sans credits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pipelines CI/CD :&lt;/strong&gt; Automatiser les tests et le deploiement&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Propriete du code :&lt;/strong&gt; Controle total sur votre base de code&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;table-des-matieres&quot;&gt;Table des matieres&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#methode-1-integration-github-directe&quot;&gt;Methode 1 : Integration GitHub directe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#methode-2-telecharger-et-pusher&quot;&gt;Methode 2 : Telecharger et Pusher&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#methode-3-configuration-git-remote&quot;&gt;Methode 3 : Configuration Git Remote&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sync-continue-vs-export-unique&quot;&gt;Sync continue vs Export unique&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#configuration-github-actions&quot;&gt;Configuration GitHub Actions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#problemes-courants-et-solutions&quot;&gt;Problemes courants et solutions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#ce-qui-est-exporte&quot;&gt;Ce qui est exporte&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#workflow-post-export&quot;&gt;Workflow post-export&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;prerequis&quot;&gt;Prerequis&lt;/h2&gt;
&lt;p&gt;Avant de commencer, assurez-vous d&apos;avoir :&lt;/p&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Un compte Lovable avec un projet a exporter&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Un compte GitHub&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Git installe localement (pour les methodes manuelles)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Connaissances basiques du terminal/ligne de commande&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Permissions de telechargement de projet dans Lovable&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;methode-1--integration-github-directe&quot;&gt;Methode 1 : Integration GitHub directe&lt;/h2&gt;
&lt;p&gt;La methode la plus simple si votre forfait Lovable le supporte.&lt;/p&gt;
&lt;h3 id=&quot;etape-1--activer-lintegration-github-dans-lovable&quot;&gt;Etape 1 : Activer l&apos;integration GitHub dans Lovable&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Ouvrez votre projet Lovable&lt;/li&gt;
&lt;li&gt;Naviguez vers &lt;strong&gt;Settings&lt;/strong&gt; → &lt;strong&gt;Integrations&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Cliquez sur &lt;strong&gt;Connect GitHub&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Authentifiez-vous avec GitHub&lt;/li&gt;
&lt;li&gt;Accordez les permissions a Lovable&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;etape-2--configurer-le-depot&quot;&gt;Etape 2 : Configurer le depot&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Lovable vous demandera de :&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;. Creer un nouveau depot OU
&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;. Connecter un depot existant&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Pour un nouveau depot :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nom du depot : &lt;code class=&quot;language-text&quot;&gt;votre-nom-de-projet&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Visibilite : Public/Prive&lt;/li&gt;
&lt;li&gt;Initialiser avec README : Non (Lovable le fournit)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Pour un depot existant :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Selectionnez dans la liste deroulante&lt;/li&gt;
&lt;li&gt;Choisissez la branche (main/master)&lt;/li&gt;
&lt;li&gt;Resolution de conflit : Ecraser/Fusionner&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;etape-3--synchronisation-initiale&quot;&gt;Etape 3 : Synchronisation initiale&lt;/h3&gt;
&lt;p&gt;Cliquez sur le bouton &lt;strong&gt;Sync to GitHub&lt;/strong&gt;. Lovable va :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Exporter tous les fichiers du projet&lt;/li&gt;
&lt;li&gt;Creer le commit initial&lt;/li&gt;
&lt;li&gt;Pusher vers la branche selectionnee&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;etape-4--activer-lauto-sync-optionnel&quot;&gt;Etape 4 : Activer l&apos;auto-sync (optionnel)&lt;/h3&gt;
&lt;p&gt;Activez &lt;strong&gt;Auto-sync&lt;/strong&gt; pour pusher automatiquement les changements :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A chaque sauvegarde&lt;/li&gt;
&lt;li&gt;Toutes les 5 minutes&lt;/li&gt;
&lt;li&gt;Sur declenchement manuel&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;methode-2--telecharger-et-pusher&quot;&gt;Methode 2 : Telecharger et Pusher&lt;/h2&gt;
&lt;p&gt;Pour quand l&apos;integration GitHub n&apos;est pas disponible.&lt;/p&gt;
&lt;h3 id=&quot;etape-1--telecharger-votre-projet&quot;&gt;Etape 1 : Telecharger votre projet&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Dans Lovable :&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;. Cliquez sur le bouton &lt;span class=&quot;token string&quot;&gt;&quot;Export&quot;&lt;/span&gt; ou &lt;span class=&quot;token string&quot;&gt;&quot;Download&quot;&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;. Selectionnez &lt;span class=&quot;token string&quot;&gt;&quot;Download as ZIP&quot;&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;. Sauvegardez sur votre machine locale&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;etape-2--extraire-et-initialiser-git&quot;&gt;Etape 2 : Extraire et initialiser Git&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Commandes terminal :&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;unzip&lt;/span&gt; lovable-project.zip
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; lovable-project
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;etape-3--creer-un-depot-github&quot;&gt;Etape 3 : Creer un depot GitHub&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Avec GitHub CLI :&lt;/span&gt;
gh repo create votre-nom-de-projet &lt;span class=&quot;token parameter variable&quot;&gt;--public&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--source&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;.

&lt;span class=&quot;token comment&quot;&gt;# Ou manuellement sur GitHub.com :&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;. Cliquez &lt;span class=&quot;token string&quot;&gt;&quot;New repository&quot;&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;. Nommez-le
&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;. N&lt;span class=&quot;token string&quot;&gt;&apos;initialisez pas avec README
4. Copiez l&apos;&lt;/span&gt;URL &lt;span class=&quot;token function&quot;&gt;du&lt;/span&gt; depot&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;etape-4--pusher-vers-github&quot;&gt;Etape 4 : Pusher vers GitHub&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Ajouter tous les fichiers&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Creer le commit initial&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial export from Lovable&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Ajouter l&apos;origin remote&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; origin https://github.com/votreusername/votre-projet.git

&lt;span class=&quot;token comment&quot;&gt;# Pusher vers GitHub&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;methode-3--configuration-git-remote&quot;&gt;Methode 3 : Configuration Git Remote&lt;/h2&gt;
&lt;p&gt;Pour les utilisateurs avances voulant un controle granulaire.&lt;/p&gt;
&lt;h3 id=&quot;etape-1--acceder-a-lurl-git-de-lovable&quot;&gt;Etape 1 : Acceder a l&apos;URL Git de Lovable&lt;/h3&gt;
&lt;p&gt;Certains projets Lovable fournissent un acces Git :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Dans les parametres du projet Lovable, cherchez :&lt;/span&gt;
Git URL: https://git.lovable.dev/votre-projet.git&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;etape-2--cloner-localement&quot;&gt;Etape 2 : Cloner localement&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; clone https://git.lovable.dev/votre-projet.git
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; votre-projet&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;etape-3--ajouter-github-comme-remote&quot;&gt;Etape 3 : Ajouter GitHub comme remote&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Ajouter GitHub comme remote supplementaire&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; github https://github.com/votreusername/votre-repo.git

&lt;span class=&quot;token comment&quot;&gt;# Verifier les remotes&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Sortie :&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# origin    https://git.lovable.dev/votre-projet.git (fetch)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# origin    https://git.lovable.dev/votre-projet.git (push)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# github    https://github.com/votreusername/votre-repo.git (fetch)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# github    https://github.com/votreusername/votre-repo.git (push)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;etape-4--pusher-vers-github-1&quot;&gt;Etape 4 : Pusher vers GitHub&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Pusher vers le remote GitHub&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push github main

&lt;span class=&quot;token comment&quot;&gt;# Definir GitHub comme defaut (optionnel)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch --set-upstream-to&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;github/main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;sync-continue-vs-export-unique&quot;&gt;Sync continue vs Export unique&lt;/h2&gt;
&lt;h3 id=&quot;synchronisation-continue&quot;&gt;Synchronisation continue&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Avantages :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Toujours a jour&lt;/li&gt;
&lt;li&gt;Sauvegardes automatiques&lt;/li&gt;
&lt;li&gt;L&apos;equipe voit les changements immediatement&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Inconvenients :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Necessite un forfait Pro+ Lovable&lt;/li&gt;
&lt;li&gt;Peut creer beaucoup de commits&lt;/li&gt;
&lt;li&gt;Conflits de sync potentiels&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Configuration :&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// .lovable/sync.config.json&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token string-property property&quot;&gt;&quot;github&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string-property property&quot;&gt;&quot;enabled&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string-property property&quot;&gt;&quot;repository&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;username/repo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string-property property&quot;&gt;&quot;branch&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string-property property&quot;&gt;&quot;frequency&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;on_save&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// ou &quot;5min&quot;, &quot;manual&quot;&lt;/span&gt;
    &lt;span class=&quot;token string-property property&quot;&gt;&quot;commit_message&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Auto-sync from Lovable: {timestamp}&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;export-unique&quot;&gt;Export unique&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Avantages :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fonctionne sur n&apos;importe quel forfait&lt;/li&gt;
&lt;li&gt;Controle total sur les commits&lt;/li&gt;
&lt;li&gt;Pas de connexion continue necessaire&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Inconvenients :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Processus manuel&lt;/li&gt;
&lt;li&gt;Peut devenir obsolete&lt;/li&gt;
&lt;li&gt;Necessite un re-export pour les mises a jour&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Workflow recommande :&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Exporter aux jalons majeurs&lt;/li&gt;
&lt;li&gt;Continuer le developpement localement&lt;/li&gt;
&lt;li&gt;Re-importer dans Lovable si necessaire&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;configuration-github-actions&quot;&gt;Configuration GitHub Actions&lt;/h2&gt;
&lt;p&gt;Automatiser le deploiement apres l&apos;export.&lt;/p&gt;
&lt;h3 id=&quot;workflow-de-deploiement-basique&quot;&gt;Workflow de deploiement basique&lt;/h3&gt;
&lt;p&gt;Creez &lt;code class=&quot;language-text&quot;&gt;.github/workflows/deploy.yml&lt;/code&gt; :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deploy Lovable Export

&lt;span class=&quot;token key atrule&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;branches&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;main&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;pull_request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;branches&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;main&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;build-and-deploy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ubuntu&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;latest

    &lt;span class=&quot;token key atrule&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/checkout@v3

    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Setup Node.js
      &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/setup&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;node@v3
      &lt;span class=&quot;token key atrule&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;node-version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;18&apos;&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;npm&apos;&lt;/span&gt;

    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Install dependencies
      &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm ci

    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Build project
      &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm run build

    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Run tests
      &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm test

    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deploy to Vercel
      &lt;span class=&quot;token key atrule&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; github.ref == &apos;refs/heads/main&apos;
      &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token scalar string&quot;&gt;
        npm i -g vercel
        vercel --prod --token=${{ secrets.VERCEL_TOKEN }}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;variables-denvironnement&quot;&gt;Variables d&apos;environnement&lt;/h3&gt;
&lt;p&gt;Stockez les variables d&apos;environnement Lovable dans GitHub :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Repository → Settings → Secrets&lt;/li&gt;
&lt;li&gt;Ajoutez chaque variable de Lovable&lt;/li&gt;
&lt;li&gt;Referencez dans les workflows : &lt;code class=&quot;language-text&quot;&gt;${{ secrets.VAR_NAME }}&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;ce-qui-est-exporte&quot;&gt;Ce qui est exporte&lt;/h2&gt;
&lt;h3 id=&quot;inclus-dans-lexport&quot;&gt;Inclus dans l&apos;export&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Code source :&lt;/strong&gt; Tous les fichiers JavaScript/TypeScript&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Styles :&lt;/strong&gt; CSS, SCSS, configs Tailwind&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Assets :&lt;/strong&gt; Images, polices, icones&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configuration :&lt;/strong&gt; package.json, configs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fichiers publics :&lt;/strong&gt; HTML, robots.txt, manifests&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Documentation :&lt;/strong&gt; README, licences&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;non-inclus&quot;&gt;NON inclus&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Variables d&apos;environnement :&lt;/strong&gt; A exporter separement&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Donnees de base de donnees :&lt;/strong&gt; Seul le schema est exporte&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Metadonnees Lovable :&lt;/strong&gt; Donnees internes de la plateforme&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Artefacts de build :&lt;/strong&gt; dist/, .next/, etc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parametres de deploiement :&lt;/strong&gt; Configurations serveur&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Donnees analytiques :&lt;/strong&gt; Statistiques d&apos;utilisation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Uploads utilisateur :&lt;/strong&gt; Contenu dynamique&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;export-des-variables-denvironnement&quot;&gt;Export des variables d&apos;environnement&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Dans Lovable, allez a Settings → Environment Variables&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Cliquez &quot;Export as .env&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Cree un fichier .env :&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;API_KEY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;votre-cle-api
&lt;span class=&quot;token assign-left variable&quot;&gt;DATABASE_URL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;votre-url-base-de-donnees
&lt;span class=&quot;token assign-left variable&quot;&gt;NEXT_PUBLIC_APP_URL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;https://votre-app.com&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Avertissement securite :&lt;/strong&gt; Ne commitez jamais &lt;code class=&quot;language-text&quot;&gt;.env&lt;/code&gt; sur GitHub !&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Ajouter a .gitignore&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;.env&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; .gitignore
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;.env.local&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; .gitignore&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;problemes-courants-et-solutions&quot;&gt;Problemes courants et solutions&lt;/h2&gt;
&lt;h3 id=&quot;probleme-1--authentication-failed&quot;&gt;Probleme 1 : &quot;Authentication Failed&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Solution :&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Utilisez un personal access token au lieu du mot de passe&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;. GitHub → Settings → Developer settings
&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;. Personal access tokens → Generate new token
&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;. Selectionnez les scopes &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; repo, workflow
&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;. Utilisez le token comme mot de passe&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;probleme-2--large-files-rejected&quot;&gt;Probleme 2 : &quot;Large Files Rejected&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Erreur :&lt;/strong&gt; &lt;code class=&quot;language-text&quot;&gt;this exceeds GitHub&apos;s file size limit of 100.00 MB&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution :&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Utilisez Git LFS pour les gros fichiers&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; lfs track &lt;span class=&quot;token string&quot;&gt;&quot;*.psd&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; lfs track &lt;span class=&quot;token string&quot;&gt;&quot;*.zip&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; .gitattributes
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; large-file.psd
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Add large files with LFS&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;probleme-3--merge-conflicts&quot;&gt;Probleme 3 : &quot;Merge Conflicts&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Solution :&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Recuperer les derniers changements&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; pull origin main

&lt;span class=&quot;token comment&quot;&gt;# Resoudre les conflits dans VS Code ou :&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; status  &lt;span class=&quot;token comment&quot;&gt;# Voir les fichiers en conflit&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Editez les fichiers, supprimez les marqueurs de conflit&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Resolve merge conflicts&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;probleme-4--missing-dependencies&quot;&gt;Probleme 4 : &quot;Missing Dependencies&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Solution :&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Lovable peut utiliser des packages internes&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Verifiez package.json pour les packages @lovable/*&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Remplacez par des alternatives publiques :&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Avant :&lt;/span&gt;
&lt;span class=&quot;token string&quot;&gt;&quot;@lovable/ui&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;^1.0.0&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Apres :&lt;/span&gt;
&lt;span class=&quot;token string&quot;&gt;&quot;@shadcn/ui&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;^0.8.0&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;probleme-5--build-fails-after-export&quot;&gt;Probleme 5 : &quot;Build Fails After Export&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Corrections courantes :&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Vider les caches&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-rf&lt;/span&gt; node_modules package-lock.json
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Verifier la version Node&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# Doit correspondre a celle de Lovable&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Installer les peer deps manquantes&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; --save-peer-deps

&lt;span class=&quot;token comment&quot;&gt;# Verifier les imports specifiques a Lovable&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Remplacer par des imports standards&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;workflow-post-export&quot;&gt;Workflow post-export&lt;/h2&gt;
&lt;h3 id=&quot;1-configurer-lenvironnement-de-developpement&quot;&gt;1. Configurer l&apos;environnement de developpement&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Installer les dependances&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Configurer les variables d&apos;environnement&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;cp&lt;/span&gt; .env.example .env
&lt;span class=&quot;token comment&quot;&gt;# Editez .env avec vos valeurs&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Lancer le serveur de developpement&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run dev&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-configurer-vs-code&quot;&gt;2. Configurer VS Code&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-json line-numbers&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// .vscode/settings.json&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;editor.formatOnSave&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;editor.defaultFormatter&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;esbenp.prettier-vscode&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;tailwindCSS.includeLanguages&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;javascript&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;javascript&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;html&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;HTML&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-configurer-les-pre-commit-hooks&quot;&gt;3. Configurer les pre-commit hooks&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Installer husky&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; --save-dev husky lint-staged
npx husky init

&lt;span class=&quot;token comment&quot;&gt;# Ajouter le pre-commit hook&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;npx lint-staged&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; .husky/pre-commit&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-continuer-le-developpement&quot;&gt;4. Continuer le developpement&lt;/h3&gt;
&lt;p&gt;Vous pouvez maintenant :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Editer dans VS Code/Cursor&lt;/li&gt;
&lt;li&gt;Utiliser GitHub Copilot&lt;/li&gt;
&lt;li&gt;Collaborer avec l&apos;equipe&lt;/li&gt;
&lt;li&gt;Deployer n&apos;importe ou&lt;/li&gt;
&lt;li&gt;Retourner a Lovable a tout moment&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;deployer-votre-projet-exporte&quot;&gt;Deployer votre projet exporte&lt;/h2&gt;
&lt;h3 id=&quot;vers-vercel&quot;&gt;Vers Vercel&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Installer Vercel CLI&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; i &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; vercel

&lt;span class=&quot;token comment&quot;&gt;# Deployer&lt;/span&gt;
vercel

&lt;span class=&quot;token comment&quot;&gt;# Suivez les prompts, obtenez l&apos;URL&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;vers-netlify&quot;&gt;Vers Netlify&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Installer Netlify CLI&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; i &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; netlify-cli

&lt;span class=&quot;token comment&quot;&gt;# Deployer&lt;/span&gt;
netlify deploy &lt;span class=&quot;token parameter variable&quot;&gt;--prod&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Ou glisser-deposer dans l&apos;UI Netlify&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;vers-cloudflare-pages&quot;&gt;Vers Cloudflare Pages&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Build du projet&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build

&lt;span class=&quot;token comment&quot;&gt;# Installer Wrangler&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; i &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; wrangler

&lt;span class=&quot;token comment&quot;&gt;# Deployer&lt;/span&gt;
wrangler pages deploy ./dist&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;retourner-a-lovable&quot;&gt;Retourner a Lovable&lt;/h2&gt;
&lt;p&gt;Besoin de ramener les changements dans Lovable ?&lt;/p&gt;
&lt;h3 id=&quot;option-1--re-importer-le-projet&quot;&gt;Option 1 : Re-importer le projet&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Lovable → New Project → Import from GitHub&lt;/li&gt;
&lt;li&gt;Selectionnez le depot&lt;/li&gt;
&lt;li&gt;Configurez les parametres d&apos;import&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;option-2--sync-manuelle&quot;&gt;Option 2 : Sync manuelle&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Dans votre projet local&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; lovable https://git.lovable.dev/project.git
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push lovable main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;bonnes-pratiques&quot;&gt;Bonnes pratiques&lt;/h2&gt;
&lt;h3 id=&quot;1-messages-de-commit&quot;&gt;1. Messages de commit&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Lors de l&apos;export, utilisez des messages clairs&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Export from Lovable: [date]&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Post-export: Fix dependencies&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Post-export: Add GitHub Actions&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-strategie-de-branches&quot;&gt;2. Strategie de branches&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Gardez les exports Lovable separes&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout &lt;span class=&quot;token parameter variable&quot;&gt;-b&lt;/span&gt; lovable-export
&lt;span class=&quot;token comment&quot;&gt;# Faites les changements&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; merge lovable-export&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-documentation&quot;&gt;3. Documentation&lt;/h3&gt;
&lt;p&gt;Mettez toujours a jour le README apres export :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;markdown&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-markdown line-numbers&quot;&gt;&lt;code class=&quot;language-markdown&quot;&gt;&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;#&lt;/span&gt; Nom du projet&lt;/span&gt;

Originalement cree avec &lt;span class=&quot;token url&quot;&gt;[&lt;span class=&quot;token content&quot;&gt;Lovable&lt;/span&gt;](&lt;span class=&quot;token url&quot;&gt;https://lovable.dev&lt;/span&gt;)&lt;/span&gt;
Exporte vers GitHub le : 2025-01-26

&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;##&lt;/span&gt; Developpement&lt;/span&gt;
&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; Lancer localement : &lt;span class=&quot;token code-snippet code keyword&quot;&gt;`npm run dev`&lt;/span&gt;
&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; Build : &lt;span class=&quot;token code-snippet code keyword&quot;&gt;`npm run build`&lt;/span&gt;
&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; Deployer : &lt;span class=&quot;token code-snippet code keyword&quot;&gt;`npm run deploy`&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;script-dautomatisation&quot;&gt;Script d&apos;automatisation&lt;/h2&gt;
&lt;p&gt;Gagnez du temps avec ce script d&apos;export :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# sauvegardez en export-lovable.sh&lt;/span&gt;

&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Exportation du projet Lovable vers GitHub&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Telecharger depuis Lovable (etape manuelle)&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1. Telechargez le projet depuis Lovable&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;   Appuyez sur Entree quand c&apos;est fait...&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Configuration&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;unzip&lt;/span&gt; ~/Downloads/lovable-export.zip &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; ./lovable-project
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; lovable-project
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init

&lt;span class=&quot;token comment&quot;&gt;# Configurer git&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial export from Lovable &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;date&lt;/span&gt; +%Y-%m-%d&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Creer le depot GitHub&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Entrez le nom du depot GitHub :&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt; REPO_NAME
gh repo create &lt;span class=&quot;token variable&quot;&gt;$REPO_NAME&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--public&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--source&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;.

&lt;span class=&quot;token comment&quot;&gt;# Pusher&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin main

&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Export termine ! Voir a : https://github.com/&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;gh api user &lt;span class=&quot;token parameter variable&quot;&gt;-q&lt;/span&gt; .login&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;/&lt;span class=&quot;token variable&quot;&gt;$REPO_NAME&lt;/span&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Exporter de Lovable vers GitHub ouvre des possibilites infinies pour votre projet. Que vous choisissiez la sync continue ou l&apos;export unique, vous avez maintenant les connaissances pour :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prendre le controle total de votre code&lt;/li&gt;
&lt;li&gt;Collaborer avec n&apos;importe quel developpeur&lt;/li&gt;
&lt;li&gt;Deployer n&apos;importe ou&lt;/li&gt;
&lt;li&gt;Reduire la dependance a la plateforme&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rappelez-vous : Vous pouvez toujours retourner a Lovable pour le developpement assiste par IA quand vous en avez besoin !&lt;/p&gt;
&lt;h2 id=&quot;tutoriels-connexes&quot;&gt;Tutoriels connexes&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website/&quot;&gt;Deployer Lovable sur Vercel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;Deployer Lovable sur Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-credits-complete-guide&quot;&gt;Guide des credits Lovable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website&quot;&gt;3 facons de deplacer votre site web Lovable&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Questions ? Trouve un probleme ? Consultez nos &lt;a href=&quot;/blog/lovable-vibe-coding-guide&quot;&gt;autres guides Lovable&lt;/a&gt; pour plus d&apos;aide.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Construire un tableau de bord logistique temps reel avec Laravel, WebSockets et Vue]]></title><description><![CDATA[Vous etes-vous deja demande comment les entreprises suivent des milliers d'expeditions en temps reel ? Ou comment les plateformes de trading…]]></description><link>https://vibecodingwithfred.com/fr/blog/laravel-realtime-dashboard/</link><guid isPermaLink="false">https://vibecodingwithfred.com/fr/blog/laravel-realtime-dashboard/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Vous etes-vous deja demande comment les entreprises suivent des milliers d&apos;expeditions en temps reel ? Ou comment les plateformes de trading mettent a jour les prix instantanement sur des milliers d&apos;ecrans ? J&apos;ai construit ces systemes a grande echelle, traitant plus de 2 milliards de dollars en transactions annuelles. Aujourd&apos;hui, je vais vous montrer exactement comment construire un tableau de bord temps reel pret pour la production avec Laravel, WebSockets et Vue.js.&lt;/p&gt;
&lt;p&gt;Ce n&apos;est pas de la theorie - ce sont des patterns eprouves de vrais systemes de production gerant des operations logistiques 24/7.&lt;/p&gt;
&lt;h2 id=&quot;ce-que-nous-construisons&quot;&gt;Ce que nous construisons&lt;/h2&gt;
&lt;p&gt;Nous allons creer un tableau de bord logistique temps reel qui :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Suit les emplacements des expeditions avec des mises a jour en direct&lt;/li&gt;
&lt;li&gt;Affiche des metriques temps reel (livraisons, revenus, performance)&lt;/li&gt;
&lt;li&gt;Implemente un systeme de verrouillage pour prevenir les editions conflictuelles&lt;/li&gt;
&lt;li&gt;Gere des milliers de connexions simultanees&lt;/li&gt;
&lt;li&gt;Scale horizontalement avec Redis pub/sub&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Voici a quoi ressemble le tableau de bord final :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Plusieurs utilisateurs voient les mises a jour instantanement&lt;/li&gt;
&lt;li&gt;Les statuts d&apos;expedition changent en temps reel&lt;/li&gt;
&lt;li&gt;Les metriques se mettent a jour sans rafraichissement de page&lt;/li&gt;
&lt;li&gt;Les verrous d&apos;edition empechent les conflits de donnees&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;prerequis&quot;&gt;Prerequis&lt;/h2&gt;
&lt;p&gt;Vous aurez besoin de :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PHP 8.1+ avec Laravel 10+&lt;/li&gt;
&lt;li&gt;Node.js 18+ pour Vue 3&lt;/li&gt;
&lt;li&gt;Redis (ou KeyDB pour de meilleures performances)&lt;/li&gt;
&lt;li&gt;Connaissances de base de Laravel et Vue&lt;/li&gt;
&lt;li&gt;Composer et npm installes&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;partie-1--configurer-le-backend-laravel&quot;&gt;Partie 1 : Configurer le backend Laravel&lt;/h2&gt;
&lt;h3 id=&quot;etape-1--creer-le-projet-laravel&quot;&gt;Etape 1 : Creer le projet Laravel&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;composer&lt;/span&gt; create-project laravel/laravel realtime-logistics
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; realtime-logistics

&lt;span class=&quot;token comment&quot;&gt;# Installer les dependances de broadcasting et WebSocket&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;composer&lt;/span&gt; require pusher/pusher-php-server
&lt;span class=&quot;token function&quot;&gt;composer&lt;/span&gt; require predis/predis

&lt;span class=&quot;token comment&quot;&gt;# Installer le package Laravel WebSockets (alternative auto-hebergee a Pusher)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;composer&lt;/span&gt; require beyondcode/laravel-websockets&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;etape-2--configurer-le-broadcasting&quot;&gt;Etape 2 : Configurer le broadcasting&lt;/h3&gt;
&lt;p&gt;Mettez a jour votre fichier &lt;code class=&quot;language-text&quot;&gt;.env&lt;/code&gt; :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;env&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-env line-numbers&quot;&gt;&lt;code class=&quot;language-env&quot;&gt;BROADCAST_DRIVER=pusher
CACHE_DRIVER=redis
QUEUE_CONNECTION=redis
SESSION_DRIVER=redis

# Utiliser Laravel WebSockets comme remplacement de Pusher
PUSHER_APP_ID=local-app
PUSHER_APP_KEY=local-key
PUSHER_APP_SECRET=local-secret
PUSHER_HOST=127.0.0.1
PUSHER_PORT=6001
PUSHER_SCHEME=http
PUSHER_APP_CLUSTER=mt1

# Configuration Redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;etape-3--schema-de-base-de-donnees&quot;&gt;Etape 3 : Schema de base de donnees&lt;/h3&gt;
&lt;p&gt;Creez les migrations pour notre systeme logistique :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;php artisan make:migration create_shipments_table
php artisan make:migration create_metrics_table
php artisan make:migration create_edit_locks_table&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// database/migrations/create_shipments_table.php&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Schema&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;Blueprint&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token keyword type-declaration&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;tracking_number&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token keyword type-declaration&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;origin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token keyword type-declaration&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;destination&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;enum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;pending&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;in_transit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;delivered&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;exception&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decimal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;nullable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decimal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;nullable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decimal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metadata&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;nullable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;timestamps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;created_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Optimise pour les requetes dashboard&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Requetes spatiales&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// database/migrations/create_metrics_table.php&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Schema&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metrics&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;Blueprint&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token keyword type-declaration&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;key&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decimal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token keyword type-declaration&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;unit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;nullable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;calculated_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;timestamps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;calculated_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// database/migrations/create_edit_locks_table.php&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Schema&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;edit_locks&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;Blueprint&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;morphs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;lockable&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Polymorphique - peut verrouiller n&apos;importe quel modele&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unsignedBigInteger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;locked_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;lockable_type&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;lockable_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;etape-4--creer-les-modeles&quot;&gt;Etape 4 : Creer les modeles&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// app/Models/Shipment.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Models&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Database&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Eloquent&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Model&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Database&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Eloquent&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Factories&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;HasFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Traits&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Lockable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Events&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;ShipmentUpdated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;Shipment&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Model&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;HasFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Lockable&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$fillable&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;tracking_number&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;origin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;destination&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metadata&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$casts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metadata&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;array&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;decimal:2&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;decimal:7&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;decimal:7&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$dispatchesEvents&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;updated&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;ShipmentUpdated&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Optimisation production : Cache les expeditions frequemment accedees&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;findByTrackingCached&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$trackingNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Cache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment.&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$trackingNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addMinutes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;tracking_number&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$trackingNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Requete geospatiale pour les expeditions proches&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;scopeNearby&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lng&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$radiusKm&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Formule Haversine pour le calcul de distance&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$haversine&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;(
            6371 * acos(
                cos(radians(?)) * cos(radians(latitude)) *
                cos(radians(longitude) - radians(?)) +
                sin(radians(?)) * sin(radians(latitude))
            )
        )&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$query&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;selectRaw&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;*, &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$haversine&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; AS distance&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lng&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;having&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;distance&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&amp;lt;=&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$radiusKm&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;orderBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;distance&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;etape-5--implementer-le-trait-lockable&quot;&gt;Etape 5 : Implementer le trait Lockable&lt;/h3&gt;
&lt;p&gt;Ceci empeche les editions conflictuelles - crucial pour les donnees financieres :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// app/Traits/Lockable.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Traits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Models&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;EditLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Support&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Facades&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Auth&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Carbon&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Carbon&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;Lockable&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;morphMany&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name static-context&quot;&gt;EditLock&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;lockable&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;acquireLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$duration&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Auth&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Verifier les verrous valides existants&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$existingLock&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;!=&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$existingLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Quelqu&apos;un d&apos;autre a le verrou&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Nettoyer les verrous expires&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&amp;lt;=&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Creer un nouveau verrou&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user_id&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;locked_at&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addSeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$duration&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;releaseLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Auth&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;isLocked&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$excludeUserId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$query&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$excludeUserId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;!=&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$excludeUserId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;currentLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;etape-6--creer-les-evenements-de-broadcasting&quot;&gt;Etape 6 : Creer les evenements de broadcasting&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// app/Events/ShipmentUpdated.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Events&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Models&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Broadcasting&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Channel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Broadcasting&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;InteractsWithSockets&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Contracts&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Broadcasting&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;ShouldBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Foundation&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Events&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Dispatchable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Queue&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;SerializesModels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;ShipmentUpdated&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ShouldBroadcast&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Dispatchable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; InteractsWithSockets&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; SerializesModels&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;Shipment&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;broadcastOn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Channel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Channel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment.&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;broadcastWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;id&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;tracking_number&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;tracking_number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;latitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;longitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;updated_at&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;updated_at&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toIso8601String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Optimisation de performance : Utiliser une queue pour le broadcasting&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;broadcastQueue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;broadcasts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;partie-2--frontend-vuejs-avec-mises-a-jour-temps-reel&quot;&gt;Partie 2 : Frontend Vue.js avec mises a jour temps reel&lt;/h2&gt;
&lt;h3 id=&quot;etape-8--installer-vue-et-les-dependances&quot;&gt;Etape 8 : Installer Vue et les dependances&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; vue@3 @vitejs/plugin-vue
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; laravel-echo pusher-js
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; axios pinia @vueuse/core
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-D&lt;/span&gt; @types/laravel-echo&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;etape-9--configurer-vite-pour-vue&quot;&gt;Etape 9 : Configurer Vite pour Vue&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// vite.config.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; defineConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;vite&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; laravel &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;laravel-vite-plugin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; vue &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@vitejs/plugin-vue&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;defineConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;plugins&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;laravel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;resources/css/app.css&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;resources/js/app.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;refresh&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;vue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token literal-property property&quot;&gt;transformAssetUrls&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token literal-property property&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;token literal-property property&quot;&gt;includeAbsolute&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;vue&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;vue/dist/vue.esm-bundler.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;etape-10--configurer-laravel-echo&quot;&gt;Etape 10 : Configurer Laravel Echo&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// resources/js/bootstrap.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Echo &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;laravel-echo&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Pusher &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;pusher-js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Pusher &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Pusher&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Echo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Echo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;broadcaster&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;pusher&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VITE_PUSHER_APP_KEY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;cluster&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VITE_PUSHER_APP_CLUSTER&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;mt1&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;wsHost&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VITE_PUSHER_HOST&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;location&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hostname&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;wsPort&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VITE_PUSHER_PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6001&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;wssPort&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VITE_PUSHER_PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6001&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;forceTLS&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;encrypted&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;disableStats&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;enabledTransports&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;ws&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;wss&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;partie-3--optimisation-redis-et-scaling&quot;&gt;Partie 3 : Optimisation Redis et scaling&lt;/h2&gt;
&lt;h3 id=&quot;service-temps-reel-avec-redis-pubsub&quot;&gt;Service temps reel avec Redis Pub/Sub&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// app/Services/RealtimeService.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Support&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Facades&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Redis&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;RealtimeService&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$redis&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;redis&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;pubsub&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;/**
     * Publier la mise a jour a tous les serveurs connectes
     */&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;publishShipmentUpdate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$channel&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment.updates.&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;id&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;tracking_number&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;tracking_number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;location&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
                &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;lat&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;latitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;lng&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;longitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;timestamp&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toIso8601String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;server_id&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;app.server_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;publish&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$channel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;publish&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipment.updates.all&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;insights-production-et-conseils-eprouves&quot;&gt;Insights production et conseils eprouves&lt;/h2&gt;
&lt;h3 id=&quot;optimisation-de-performance&quot;&gt;Optimisation de performance&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Indexation de base de donnees&lt;/strong&gt; : Les index composites sur &lt;code class=&quot;language-text&quot;&gt;(status, created_at)&lt;/code&gt; et &lt;code class=&quot;language-text&quot;&gt;(latitude, longitude)&lt;/code&gt; sont cruciaux. Sans eux, les requetes dashboard ralentiront au-dela de 100k expeditions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Gestion memoire Redis&lt;/strong&gt; : Nous avons appris a nos depens - toujours definir &lt;code class=&quot;language-text&quot;&gt;maxmemory&lt;/code&gt; et utiliser l&apos;eviction LRU. Une fuite memoire a fait tomber la production pendant 20 minutes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Priorites de queues&lt;/strong&gt; : Des queues separees pour les broadcasts empechent les mises a jour orientees utilisateur d&apos;etre bloquees par les jobs en arriere-plan. Cela a reduit notre latence P95 de 60%.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;strategies-de-scaling&quot;&gt;Strategies de scaling&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Scaling horizontal&lt;/strong&gt; : Le pattern Redis pub/sub permet d&apos;executer plusieurs serveurs Laravel. Nous executons 6 serveurs gerant 10k connexions simultanees.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Distribution geographique&lt;/strong&gt; : Deployez les serveurs WebSocket dans plusieurs regions. Utilisez Redis Sentinel pour le failover automatique.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Rate limiting&lt;/strong&gt; : Implementez des limites de messages WebSocket par utilisateur. Le script d&apos;un client a un jour envoye 50k mises a jour/seconde et fait crasher le systeme.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;pieges-courants-a-eviter&quot;&gt;Pieges courants a eviter&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Ne pas broadcaster de donnees sensibles&lt;/strong&gt; : Toujours filtrer ce qui va au frontend&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Implementer des heartbeats&lt;/strong&gt; : Detecter les connexions obsoletes et les nettoyer&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Utiliser les transactions de base de donnees&lt;/strong&gt; : Surtout lors de la mise a jour d&apos;enregistrements lies&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cache agressif&lt;/strong&gt; : Mais invalidation strategique&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Planifier la reconnexion&lt;/strong&gt; : Les clients se deconnecteront - gerez-le gracieusement&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Ce pattern de tableau de bord temps reel a fait ses preuves en production, gerant des millions de mises a jour quotidiennes. La combinaison du backend elegant de Laravel, du frontend reactif de Vue et du pub/sub ultra-rapide de Redis cree un systeme a la fois performant et maintenable.&lt;/p&gt;
&lt;p&gt;Points cles :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Concevez pour l&apos;echelle des le premier jour&lt;/strong&gt; - C&apos;est plus difficile de refactorer plus tard&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Separez les preoccupations&lt;/strong&gt; - Broadcasts, queues et appels API devraient utiliser differents canaux&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Surveillez tout&lt;/strong&gt; - Vous ne pouvez pas optimiser ce que vous ne mesurez pas&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Testez avec des donnees realistes&lt;/strong&gt; - 10 enregistrements de test ne reveleront pas les problemes de performance&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Les patterns montres ici ne sont pas que theoriques - ils tournent en production en ce moment, suivant de vraies expeditions valant de l&apos;argent reel.&lt;/p&gt;
&lt;h3 id=&quot;maitriser-les-fondamentaux-laravel-dabord&quot;&gt;Maitriser les fondamentaux Laravel d&apos;abord&lt;/h3&gt;
&lt;p&gt;Construire des tableaux de bord temps reel necessite une solide connaissance de Laravel. Si vous etes nouveau sur Laravel, commencez par ces tutoriels complets :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-laravel/&quot;&gt;Construire un blog avec Laravel&lt;/a&gt;&lt;/strong&gt; - Apprenez Eloquent, l&apos;authentification et les operations CRUD&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;Construire un portfolio avec Laravel&lt;/a&gt;&lt;/strong&gt; - Maitrisez les uploads de fichiers, les relations et les panneaux d&apos;admin&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-laravel/&quot;&gt;Construire un e-commerce avec Laravel&lt;/a&gt;&lt;/strong&gt; - Patterns avances incluant les queues et la gestion des evenements&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Chaque tutoriel inclut des prompts assistes par IA pour vous guider dans la construction d&apos;applications prates pour la production a partir de zero.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Comment fonctionnent les credits Lovable : Guide tarifaire complet 2025]]></title><description><![CDATA[Guide complet du systeme de credits Lovable : paliers tarifaires, ce qui consomme des credits, strategies d'optimisation, politiques de remboursement et FAQ. Apprenez a maximiser vos credits et eviter les erreurs courantes qui gaspillent l'utilisation IA.]]></description><link>https://vibecodingwithfred.com/fr/blog/lovable-credits-complete-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/fr/blog/lovable-credits-complete-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Si vous cherchez &quot;&lt;strong&gt;comment fonctionnent les credits Lovable&lt;/strong&gt;&quot; ou vous interrogez sur le modele tarifaire de Lovable, vous n&apos;etes pas seul. D&apos;apres les donnees recentes, c&apos;est l&apos;un des aspects les plus deroutants de la plateforme Lovable. Ce guide complet repond a toutes les questions sur les credits Lovable, les paliers tarifaires et les politiques de remboursement.&lt;/p&gt;
&lt;h2 id=&quot;table-des-matieres&quot;&gt;Table des matieres&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#que-sont-les-credits-lovable&quot;&gt;Que sont les credits Lovable ?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#comment-fonctionnent-les-credits&quot;&gt;Comment fonctionnent les credits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#detail-des-paliers-tarifaires&quot;&gt;Detail des paliers tarifaires&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#ce-qui-consomme-des-credits&quot;&gt;Ce qui consomme des credits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#conseils-doptimisation-des-credits&quot;&gt;Conseils d&apos;optimisation des credits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#politique-de-remboursement&quot;&gt;Politique de remboursement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#questions-frequentes&quot;&gt;FAQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#calculateur-de-credits&quot;&gt;Calculateur de credits&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;que-sont-les-credits-lovable-&quot;&gt;Que sont les credits Lovable ?&lt;/h2&gt;
&lt;p&gt;Les credits Lovable sont la monnaie de la plateforme pour les fonctionnalites de developpement alimentees par l&apos;IA. Pensez-y comme des jetons dans une salle d&apos;arcade - vous avez besoin de credits pour utiliser l&apos;IA de Lovable pour generer du code, creer des composants ou modifier vos projets.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Points cles :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 credit ≈ 1 interaction IA (varie selon la complexite)&lt;/li&gt;
&lt;li&gt;Les credits n&apos;expirent pas pendant votre periode de facturation&lt;/li&gt;
&lt;li&gt;Les credits inutilises peuvent ou non etre reportes (depend du forfait)&lt;/li&gt;
&lt;li&gt;Vous pouvez acheter des credits supplementaires en cours de cycle&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;comment-fonctionnent-les-credits&quot;&gt;Comment fonctionnent les credits&lt;/h2&gt;
&lt;h3 id=&quot;le-systeme-de-credits-explique&quot;&gt;Le systeme de credits explique&lt;/h3&gt;
&lt;p&gt;Quand vous utilisez Lovable pour construire votre application, chaque action alimentee par l&apos;IA consomme des credits :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Entree utilisateur → Traitement IA → Deduction de credits → Sortie generee&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;taux-de-consommation-des-credits&quot;&gt;Taux de consommation des credits&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Credits utilises&lt;/th&gt;
&lt;th&gt;Exemple&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Generation de composant simple&lt;/td&gt;
&lt;td&gt;1-2 credits&lt;/td&gt;
&lt;td&gt;Bouton, champ de formulaire&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Creation de composant complexe&lt;/td&gt;
&lt;td&gt;3-5 credits&lt;/td&gt;
&lt;td&gt;Tableau de donnees, graphique&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generation de page complete&lt;/td&gt;
&lt;td&gt;5-10 credits&lt;/td&gt;
&lt;td&gt;Landing page, tableau de bord&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Correction de bug/debogage&lt;/td&gt;
&lt;td&gt;1-3 credits&lt;/td&gt;
&lt;td&gt;Resolution d&apos;erreur&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Refactoring de code&lt;/td&gt;
&lt;td&gt;2-4 credits&lt;/td&gt;
&lt;td&gt;Optimisation de performance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Changements de schema de base de donnees&lt;/td&gt;
&lt;td&gt;3-5 credits&lt;/td&gt;
&lt;td&gt;Ajout de tables/relations&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;detail-des-paliers-tarifaires&quot;&gt;Detail des paliers tarifaires&lt;/h2&gt;
&lt;h3 id=&quot;palier-gratuit&quot;&gt;Palier gratuit&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Credits :&lt;/strong&gt; 100/mois&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prix :&lt;/strong&gt; 0$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ideal pour :&lt;/strong&gt; Tester la plateforme, petits prototypes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Limitations :&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Pas de domaines personnalises&lt;/li&gt;
&lt;li&gt;Options de deploiement limitees&lt;/li&gt;
&lt;li&gt;Branding Lovable requis&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;forfait-starter&quot;&gt;Forfait Starter&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Credits :&lt;/strong&gt; 500/mois&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prix :&lt;/strong&gt; 20$/mois&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ideal pour :&lt;/strong&gt; Projets secondaires, MVPs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inclus :&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Domaine personnalise&lt;/li&gt;
&lt;li&gt;Export GitHub&lt;/li&gt;
&lt;li&gt;Support par email&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;forfait-pro&quot;&gt;Forfait Pro&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Credits :&lt;/strong&gt; 2 000/mois&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prix :&lt;/strong&gt; 70$/mois&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ideal pour :&lt;/strong&gt; Developpement actif, petites equipes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inclus :&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Tout ce qui est dans Starter&lt;/li&gt;
&lt;li&gt;Support prioritaire&lt;/li&gt;
&lt;li&gt;Integrations avancees&lt;/li&gt;
&lt;li&gt;Collaboration d&apos;equipe (jusqu&apos;a 3 membres)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;forfait-business&quot;&gt;Forfait Business&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Credits :&lt;/strong&gt; 10 000/mois&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prix :&lt;/strong&gt; 299$/mois&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ideal pour :&lt;/strong&gt; Agences, startups en croissance&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inclus :&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Tout ce qui est dans Pro&lt;/li&gt;
&lt;li&gt;Membres d&apos;equipe illimites&lt;/li&gt;
&lt;li&gt;Options marque blanche&lt;/li&gt;
&lt;li&gt;Acces API&lt;/li&gt;
&lt;li&gt;Gestionnaire de compte dedie&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;enterprise&quot;&gt;Enterprise&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Credits :&lt;/strong&gt; Personnalise&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prix :&lt;/strong&gt; Contacter les ventes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ideal pour :&lt;/strong&gt; Grandes organisations&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inclus :&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Packs de credits personnalises&lt;/li&gt;
&lt;li&gt;Garanties SLA&lt;/li&gt;
&lt;li&gt;Options sur site&lt;/li&gt;
&lt;li&gt;Integrations personnalisees&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;ce-qui-consomme-des-credits&quot;&gt;Ce qui consomme des credits&lt;/h2&gt;
&lt;h3 id=&quot;utilisation-elevee-de-credits-5-credits&quot;&gt;Utilisation elevee de credits (5+ credits)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Generation de pages entieres a partir de zero&lt;/li&gt;
&lt;li&gt;Composants UI complexes avec plusieurs etats&lt;/li&gt;
&lt;li&gt;Generation de schema de base de donnees&lt;/li&gt;
&lt;li&gt;Configuration du systeme d&apos;authentification&lt;/li&gt;
&lt;li&gt;Integration de paiement&lt;/li&gt;
&lt;li&gt;Fonctionnalites en temps reel (configuration WebSocket)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;utilisation-moyenne-de-credits-2-4-credits&quot;&gt;Utilisation moyenne de credits (2-4 credits)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Creation de composants personnalises&lt;/li&gt;
&lt;li&gt;Modification de composants existants&lt;/li&gt;
&lt;li&gt;Ajout de points de terminaison API&lt;/li&gt;
&lt;li&gt;Implementation de logique metier&lt;/li&gt;
&lt;li&gt;Validation de formulaire&lt;/li&gt;
&lt;li&gt;Ajustements responsive design&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;faible-utilisation-de-credits-1-credit&quot;&gt;Faible utilisation de credits (1 credit)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Changements de texte simples&lt;/li&gt;
&lt;li&gt;Ajustements CSS&lt;/li&gt;
&lt;li&gt;Ajout d&apos;elements HTML basiques&lt;/li&gt;
&lt;li&gt;Corrections de bugs mineures&lt;/li&gt;
&lt;li&gt;Commentaires de code&lt;/li&gt;
&lt;li&gt;Renommage de variables&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;pas-de-consommation-de-credits&quot;&gt;Pas de consommation de credits&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Visualisation de votre projet&lt;/li&gt;
&lt;li&gt;Edition manuelle du code&lt;/li&gt;
&lt;li&gt;Deploiement (utilise des credits de deploiement separement)&lt;/li&gt;
&lt;li&gt;Telechargement/export du code&lt;/li&gt;
&lt;li&gt;Utilisation du controle de version&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;conseils-doptimisation-des-credits&quot;&gt;Conseils d&apos;optimisation des credits&lt;/h2&gt;
&lt;h3 id=&quot;1-soyez-specifique-avec-les-prompts&quot;&gt;1. Soyez specifique avec les prompts&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Mauvais :&lt;/strong&gt; &quot;Fais un formulaire&quot;
&lt;strong&gt;Bon :&lt;/strong&gt; &quot;Cree un formulaire de contact avec champs nom, email, message, validation et bouton de soumission style avec Tailwind CSS&quot;&lt;/p&gt;
&lt;p&gt;Etre specifique reduit les iterations aller-retour, economisant des credits.&lt;/p&gt;
&lt;h3 id=&quot;2-utilisez-ledition-manuelle-quand-cest-possible&quot;&gt;2. Utilisez l&apos;edition manuelle quand c&apos;est possible&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Petits ajustements CSS ? Editez manuellement&lt;/li&gt;
&lt;li&gt;Corrections de fautes de frappe ? Ne gaspillez pas de credits&lt;/li&gt;
&lt;li&gt;Ajouts HTML simples ? Faites-le vous-meme&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3-regroupez-vos-requetes&quot;&gt;3. Regroupez vos requetes&lt;/h3&gt;
&lt;p&gt;Au lieu de plusieurs petites requetes :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;❌ &quot;Ajoute un en-tete&quot;
❌ &quot;Maintenant ajoute un pied de page&quot;
❌ &quot;Ajoute une barre laterale&quot;

✅ &quot;Ajoute un en-tete avec logo et navigation, un pied de page avec liens, et une barre laterale gauche avec elements de menu&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-exploitez-les-templates&quot;&gt;4. Exploitez les templates&lt;/h3&gt;
&lt;p&gt;Commencez avec les templates de Lovable pour reduire les credits de generation initiale.&lt;/p&gt;
&lt;h3 id=&quot;5-planifiez-avant-de-construire&quot;&gt;5. Planifiez avant de construire&lt;/h3&gt;
&lt;p&gt;Esquissez d&apos;abord vos exigences. L&apos;experimentation aleatoire brule rapidement les credits.&lt;/p&gt;
&lt;h3 id=&quot;6-surveillez-lutilisation-des-credits&quot;&gt;6. Surveillez l&apos;utilisation des credits&lt;/h3&gt;
&lt;p&gt;Verifiez regulierement votre solde de credits :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dashboard → Settings → Billing → Credit Usage&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;7-utilisez-le-palier-gratuit-pour-apprendre&quot;&gt;7. Utilisez le palier gratuit pour apprendre&lt;/h3&gt;
&lt;p&gt;Pratiquez l&apos;ingenierie de prompts sur le palier gratuit avant de passer a un forfait superieur.&lt;/p&gt;
&lt;h2 id=&quot;politique-de-remboursement&quot;&gt;Politique de remboursement&lt;/h2&gt;
&lt;h3 id=&quot;quand-les-remboursements-sont-disponibles&quot;&gt;Quand les remboursements sont disponibles&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Problemes techniques empechant l&apos;utilisation des credits&lt;/li&gt;
&lt;li&gt;Erreurs de facturation&lt;/li&gt;
&lt;li&gt;Dans les 14 jours suivant l&apos;achat (premiers clients)&lt;/li&gt;
&lt;li&gt;Packs de credits inutilises&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;quand-les-remboursements-ne-sont-pas-disponibles&quot;&gt;Quand les remboursements NE sont PAS disponibles&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Credits deja consommes&lt;/li&gt;
&lt;li&gt;Apres la periode de 14 jours&lt;/li&gt;
&lt;li&gt;Renouvellements d&apos;abonnement (apres le premier mois)&lt;/li&gt;
&lt;li&gt;&quot;J&apos;ai change d&apos;avis&quot; apres avoir utilise des credits&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;comment-demander-un-remboursement&quot;&gt;Comment demander un remboursement&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Email : &lt;a href=&quot;mailto:support@lovable.dev&quot;&gt;support@lovable.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Inclure : Numero de commande, raison, captures d&apos;ecran&lt;/li&gt;
&lt;li&gt;Delai de reponse : 24-48 heures&lt;/li&gt;
&lt;li&gt;Traitement : 5-7 jours ouvrables&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;questions-frequentes&quot;&gt;Questions frequentes&lt;/h2&gt;
&lt;h3 id=&quot;les-credits-sont-ils-reportes-au-mois-suivant-&quot;&gt;Les credits sont-ils reportes au mois suivant ?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Free/Starter :&lt;/strong&gt; Pas de report
&lt;strong&gt;Pro/Business :&lt;/strong&gt; Jusqu&apos;a 20% de report
&lt;strong&gt;Enterprise :&lt;/strong&gt; Negociable&lt;/p&gt;
&lt;h3 id=&quot;puis-je-acheter-des-credits-supplementaires-&quot;&gt;Puis-je acheter des credits supplementaires ?&lt;/h3&gt;
&lt;p&gt;Oui ! Packs de credits supplementaires :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;100 credits : 5$&lt;/li&gt;
&lt;li&gt;500 credits : 20$&lt;/li&gt;
&lt;li&gt;1 000 credits : 35$&lt;/li&gt;
&lt;li&gt;5 000 credits : 150$&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;que-se-passe-t-il-quand-je-nai-plus-de-credits-&quot;&gt;Que se passe-t-il quand je n&apos;ai plus de credits ?&lt;/h3&gt;
&lt;p&gt;Votre projet reste accessible, mais vous ne pouvez pas :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generer du nouveau code&lt;/li&gt;
&lt;li&gt;Modifier avec l&apos;IA&lt;/li&gt;
&lt;li&gt;Utiliser les fonctionnalites IA&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Vous POUVEZ toujours :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Editer le code manuellement&lt;/li&gt;
&lt;li&gt;Deployer le code existant&lt;/li&gt;
&lt;li&gt;Exporter votre projet&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;puis-je-transferer-des-credits-entre-comptes-&quot;&gt;Puis-je transferer des credits entre comptes ?&lt;/h3&gt;
&lt;p&gt;Actuellement, Lovable ne supporte pas le transfert de credits. Cependant, vous pouvez :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Exporter le projet du compte A&lt;/li&gt;
&lt;li&gt;Importer dans le compte B&lt;/li&gt;
&lt;li&gt;Continuer le travail avec les credits du compte B&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;comment-puis-je-verifier-mes-credits-restants-&quot;&gt;Comment puis-je verifier mes credits restants ?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Methode 1 :&lt;/strong&gt; Dashboard → Coin superieur droit&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Methode 2 :&lt;/strong&gt; Settings → Billing → Usage&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Methode 3 :&lt;/strong&gt; Survolez l&apos;icone de credits dans l&apos;editeur&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;les-credits-expirent-ils-&quot;&gt;Les credits expirent-ils ?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Credits mensuels : Expirent a la fin du cycle de facturation&lt;/li&gt;
&lt;li&gt;Credits achetes : Expirent apres 90 jours&lt;/li&gt;
&lt;li&gt;Credits promotionnels : Verifiez les conditions (generalement 30 jours)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;y-a-t-il-un-historique-dutilisation-des-credits-&quot;&gt;Y a-t-il un historique d&apos;utilisation des credits ?&lt;/h3&gt;
&lt;p&gt;Oui ! Consultez l&apos;historique detaille :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Settings → Billing → Usage History&lt;/li&gt;
&lt;li&gt;Filtrez par date, type d&apos;action&lt;/li&gt;
&lt;li&gt;Exportez en CSV pour analyse&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;calculateur-de-credits&quot;&gt;Calculateur de credits&lt;/h2&gt;
&lt;h3 id=&quot;estimez-vos-besoins-mensuels&quot;&gt;Estimez vos besoins mensuels&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Petit projet (Landing Page) :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generation initiale : 10 credits&lt;/li&gt;
&lt;li&gt;Revisions : 20 credits&lt;/li&gt;
&lt;li&gt;Finitions : 10 credits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total : ~40 credits&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Projet moyen (MVP SaaS) :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pages (5) : 50 credits&lt;/li&gt;
&lt;li&gt;Composants : 30 credits&lt;/li&gt;
&lt;li&gt;API/Base de donnees : 40 credits&lt;/li&gt;
&lt;li&gt;Revisions : 80 credits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total : ~200 credits&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Grand projet (Application complete) :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pages (20+) : 200 credits&lt;/li&gt;
&lt;li&gt;Fonctionnalites complexes : 150 credits&lt;/li&gt;
&lt;li&gt;Integrations : 100 credits&lt;/li&gt;
&lt;li&gt;Tests/Debogage : 150 credits&lt;/li&gt;
&lt;li&gt;Iterations : 200 credits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total : ~800 credits&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;conseils-de-pro-des-utilisateurs-experimentes&quot;&gt;Conseils de pro des utilisateurs experimentes&lt;/h2&gt;
&lt;h3 id=&quot;la-regle-8020&quot;&gt;La regle 80/20&lt;/h3&gt;
&lt;p&gt;&quot;80% de vos credits vont vers 20% des fonctionnalites. Identifiez les fonctionnalites principales et perfectionnez-les d&apos;abord.&quot; - Sarah M., Proprietaire d&apos;agence&lt;/p&gt;
&lt;h3 id=&quot;strategie-de-template&quot;&gt;Strategie de template&lt;/h3&gt;
&lt;p&gt;&quot;Commencez avec le template le plus proche, puis modifiez. Economise 50% des credits vs partir de zero.&quot; - Mike R., Fondateur de startup&lt;/p&gt;
&lt;h3 id=&quot;traitement-par-lots&quot;&gt;Traitement par lots&lt;/h3&gt;
&lt;p&gt;&quot;Je liste tous les changements en un seul prompt. Je suis passe de 500 credits/semaine a 200.&quot; - Jennifer L., Developpeur&lt;/p&gt;
&lt;h2 id=&quot;erreurs-courantes-de-credits-a-eviter&quot;&gt;Erreurs courantes de credits a eviter&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Prompts vagues&lt;/strong&gt; - Gaspille des credits en iterations&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ne pas utiliser l&apos;edition manuelle&lt;/strong&gt; - Brule des credits sur des corrections simples&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pas de planification&lt;/strong&gt; - L&apos;experimentation aleatoire coute cher&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ignorer les templates&lt;/strong&gt; - Partir de zero coute plus&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ne pas surveiller l&apos;utilisation&lt;/strong&gt; - Surprise quand les credits sont epuises&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;strategies-alternatives&quot;&gt;Strategies alternatives&lt;/h2&gt;
&lt;h3 id=&quot;quand-vous-manquez-de-credits&quot;&gt;Quand vous manquez de credits&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Mode codage manuel&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Utilisez Lovable uniquement pour les parties complexes&lt;/li&gt;
&lt;li&gt;Gerez vous-meme les modifications simples&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Exporter et continuer&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Exportez vers GitHub&lt;/li&gt;
&lt;li&gt;Continuez le developpement dans VS Code&lt;/li&gt;
&lt;li&gt;Retournez a Lovable pour l&apos;assistance IA&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Collaboration d&apos;equipe&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mutualisez les credits avec les membres de l&apos;equipe&lt;/li&gt;
&lt;li&gt;Assignez les taches gourmandes en credits a ceux qui en ont plus&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;comparaison-des-credits-avec-les-concurrents&quot;&gt;Comparaison des credits avec les concurrents&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plateforme&lt;/th&gt;
&lt;th&gt;Modele tarifaire&lt;/th&gt;
&lt;th&gt;Cout mensuel&lt;/th&gt;
&lt;th&gt;Ideal pour&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lovable&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Base sur les credits&lt;/td&gt;
&lt;td&gt;0-299$&lt;/td&gt;
&lt;td&gt;Flexibilite&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;V0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Base sur la generation&lt;/td&gt;
&lt;td&gt;20$ fixe&lt;/td&gt;
&lt;td&gt;Projets simples&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cursor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Abonnement&lt;/td&gt;
&lt;td&gt;20$ fixe&lt;/td&gt;
&lt;td&gt;Edition de code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub Copilot&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Abonnement&lt;/td&gt;
&lt;td&gt;10$ fixe&lt;/td&gt;
&lt;td&gt;Completion de code&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Comprendre comment fonctionnent les credits Lovable est crucial pour un developpement efficace et une gestion de budget. La cle est de :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Choisir le bon palier tarifaire&lt;/li&gt;
&lt;li&gt;Optimiser votre utilisation des credits&lt;/li&gt;
&lt;li&gt;Utiliser l&apos;edition manuelle pour les taches simples&lt;/li&gt;
&lt;li&gt;Planifier avant de construire&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Avec ces strategies, vous pouvez construire des applications impressionnantes sans bruler vos credits inutilement.&lt;/p&gt;
&lt;h2 id=&quot;besoin-daide-supplementaire-&quot;&gt;Besoin d&apos;aide supplementaire ?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Documentation Lovable :&lt;/strong&gt; &lt;a href=&quot;https://docs.lovable.dev/credits&quot;&gt;docs.lovable.dev/credits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Site web Lovable :&lt;/strong&gt; &lt;a href=&quot;https://lovable.dev&quot;&gt;lovable.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Email de support :&lt;/strong&gt; &lt;a href=&quot;mailto:support@lovable.dev&quot;&gt;support@lovable.dev&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Vous avez trouve ce guide utile ? Consultez nos autres tutoriels Lovable et deploiement :&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/export-lovable-to-github-complete&quot;&gt;Exporter Lovable vers GitHub : Guide complet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website/&quot;&gt;Deployer Lovable sur Vercel en 5 minutes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;Deployer Lovable sur Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/getting-started-vercel/&quot;&gt;Demarrer avec le deploiement Vercel&lt;/a&gt; - Guide complet pour debutants pour deployer n&apos;importe quel projet sur le palier gratuit de Vercel&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[5 patterns Redis pour des applications Laravel temps reel qui scalent]]></title><description><![CDATA[Apres avoir migre de Redis vers KeyDB puis de nouveau vers Redis tout en traitant des milliards en transactions logistiques, j'ai appris…]]></description><link>https://vibecodingwithfred.com/fr/blog/redis-patterns-laravel-quicktip/</link><guid isPermaLink="false">https://vibecodingwithfred.com/fr/blog/redis-patterns-laravel-quicktip/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Apres avoir migre de Redis vers KeyDB puis de nouveau vers Redis tout en traitant des milliards en transactions logistiques, j&apos;ai appris quels patterns Redis fonctionnent a grande echelle. Voici 5 patterns eprouves que vous pouvez implementer aujourd&apos;hui.&lt;/p&gt;
&lt;h2 id=&quot;1-pipeline-tout-gain-de-performance-10x&quot;&gt;1. Pipeline tout (gain de performance 10x)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Mauvais pattern :&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Ceci cree 1000 allers-retours reseau !&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Pattern production :&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Un seul appel reseau, execution atomique&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Impact reel :&lt;/strong&gt; Nous avons reduit notre temps d&apos;import en masse de 45 secondes a 4 secondes pour 10k enregistrements.&lt;/p&gt;
&lt;h2 id=&quot;2-implementer-le-rate-limiting-a-fenetre-glissante&quot;&gt;2. Implementer le Rate Limiting a fenetre glissante&lt;/h2&gt;
&lt;p&gt;Oubliez les fenetres fixes qui causent des rafales de requetes. Voici ce que nous utilisons en production :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;RateLimiter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;attempt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;rate_limit:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;microtime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Supprimer les anciennes entrees&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zremrangebyscore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Ajouter la requete actuelle&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Compter les requetes dans la fenetre&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zcard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Definir l&apos;expiration&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$results&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Utilisation dans un middleware&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token class-name static-context&quot;&gt;RateLimiter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;attempt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;api:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Rate limit exceeded&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;429&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Pourquoi ca marche :&lt;/strong&gt; Pas de pics aux limites de fenetre, distribution equitable, auto-nettoyage.&lt;/p&gt;
&lt;h2 id=&quot;3-invalidation-de-cache-avec-tags-la-bonne-methode&quot;&gt;3. Invalidation de cache avec tags (la bonne methode)&lt;/h2&gt;
&lt;p&gt;Les tags de cache Laravel sont genials jusqu&apos;a ce que vous ayez besoin d&apos;un controle granulaire. Voici notre pattern :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;SmartCache&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;rememberWithDependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Stocker le cache principal&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Cache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Suivre les dependances dans des sets Redis&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;86400&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1 jour&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;invalidateTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;smembers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Supprimer toutes les cles taguees en un seul pipeline&lt;/span&gt;
            &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;del&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;del&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Utilisation&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$metrics&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;SmartCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rememberWithDependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;dashboard.metrics&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;deliveries&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;customer:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$customerId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 5 minutes&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;calculateExpensiveMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Invalider tous les caches lies aux expeditions&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;SmartCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;invalidateTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Victoire en production :&lt;/strong&gt; Reduction des cache misses de 73% et elimination des invalidations en cascade.&lt;/p&gt;
&lt;h2 id=&quot;4-verrous-distribues-qui-ne-deadlock-pas&quot;&gt;4. Verrous distribues qui ne deadlock pas&lt;/h2&gt;
&lt;p&gt;Apres avoir perdu 50k$ a cause d&apos;une race condition, nous avons implemente ce verrouillage a toute epreuve :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;DistributedLock&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;lock:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniqid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;gethostname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Set atomique si n&apos;existe pas avec expiration&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$acquired&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;NX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Seulement si n&apos;existe pas&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;EX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Expire apres X secondes&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$acquired&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Verifier si le verrou est obsolete (mecanisme de secours)&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockHolder&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lockHolder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Le verrou a expire entre les commandes, reessayer&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;lock:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Script Lua pour verification et suppression atomique&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;
            if redis.call(&apos;get&apos;, KEYS[1]) == ARGV[1] then
                return redis.call(&apos;del&apos;, KEYS[1])
            else
                return 0
            end
        &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;withLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LockTimeoutException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Could not acquire lock for &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;finally&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Utilisation pour le traitement des paiements&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;DistributedLock&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;withLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;payment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Traiter le paiement en securite&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isPaid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Verification idempotente&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;processPayment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;markAsPaid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Critique :&lt;/strong&gt; Le script Lua garantit que nous ne liberons que NOTRE verrou, empechant la liberation accidentelle du verrou de quelqu&apos;un d&apos;autre.&lt;/p&gt;
&lt;h2 id=&quot;5-metriques-temps-reel-avec-hyperloglog&quot;&gt;5. Metriques temps reel avec HyperLogLog&lt;/h2&gt;
&lt;p&gt;Suivez les visiteurs/evenements uniques sans explosion de memoire :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;MetricsTracker&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;metric:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// HyperLogLog ajoute des elements uniques avec espace O(1)&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Garder 2 fenetres&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getCardinality&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windows&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windows&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;metric:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Fusionner plusieurs HyperLogLogs&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;trackAndBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Suivre l&apos;evenement unique&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;event:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:users&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Suivre le taux par minute&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;event:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:rate&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniqid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Diffuser si seuil atteint&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;broadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HighTrafficAlert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Utilisation&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$uniqueVisitors&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;page.visits&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$dailyActive&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCardinality&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user.active&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Suivre l&apos;utilisation API sans problemes de memoire&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackAndBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;api.call&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Economies de memoire :&lt;/strong&gt; Suivre 10M d&apos;utilisateurs uniques prend ~12KB au lieu de 40MB avec les sets traditionnels.&lt;/p&gt;
&lt;h2 id=&quot;bonus--checklist-doptimisation-memoire-redis&quot;&gt;Bonus : Checklist d&apos;optimisation memoire Redis&lt;/h2&gt;
&lt;p&gt;De notre playbook production :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 1. Utiliser la compression pour les grandes valeurs&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;large:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;gzcompress&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 2. Utiliser les hashes pour les petits objets (90% d&apos;economie memoire !)&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;user:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;name&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;email&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;status&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 3. Definir des expirations agressives&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 5 min par defaut, pas 1 heure&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 4. Utiliser SCAN au lieu de KEYS&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scan&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;MATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipment:*&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;COUNT&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Traiter $keys&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 5. Surveiller l&apos;utilisation memoire&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1073741824&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1GB&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Redis memory critical: &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory_human&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;les-lecons-couteuses&quot;&gt;Les lecons couteuses&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Toujours definir des expirations&lt;/strong&gt; - Un TTL manquant a consomme 8GB de RAM&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pipeline ou perir&lt;/strong&gt; - La latence reseau s&apos;accumule vite&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Utiliser la bonne structure de donnees&lt;/strong&gt; - HyperLogLog nous a fait economiser 2k$/mois en memoire&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Verrouiller correctement&lt;/strong&gt; - Les race conditions dans les systemes financiers = proces&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tout surveiller&lt;/strong&gt; - Vous ne pouvez pas corriger ce que vous ne mesurez pas&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ces patterns gerent 50k requetes/seconde en production. Commencez avec les pipelines et le verrouillage correct - ils resoudront 80% de vos problemes de performance Redis.&lt;/p&gt;
&lt;h2 id=&quot;maitriser-laravel-avec-des-projets-reels&quot;&gt;Maitriser Laravel avec des projets reels&lt;/h2&gt;
&lt;p&gt;Vous voulez implementer ces patterns Redis dans une vraie application ? Construisez des projets Laravel prets pour la production a partir de zero :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-laravel/&quot;&gt;Construire un blog avec Laravel&lt;/a&gt;&lt;/strong&gt; - Maitriser Eloquent, l&apos;authentification et les operations CRUD avec le cache Redis&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;Construire un portfolio avec Laravel&lt;/a&gt;&lt;/strong&gt; - Apprendre les uploads de fichiers, les relations et les sessions alimentees par Redis&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-laravel/&quot;&gt;Construire un e-commerce avec Laravel&lt;/a&gt;&lt;/strong&gt; - Patterns avances incluant les queues, la gestion des evenements et les verrous distribues&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Chaque tutoriel inclut des prompts assistes par IA pour vous guider dans la construction d&apos;applications scalables qui utilisent Redis efficacement.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Des questions sur l&apos;implementation de ces patterns ? Laissez un commentaire - j&apos;ai probablement deboggue ce probleme a 3h du matin.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Guida Completa: Deploya il Tuo Progetto Lovable su Cloudflare (Pages e Workers)]]></title><description><![CDATA[La guida definitiva per deployare il tuo sito Lovable creato con AI su Cloudflare. Impara come usare sia Cloudflare Pages che Workers, configurare domini personalizzati e risolvere problemi comuni. Hosting gratuito con prestazioni enterprise.]]></description><link>https://vibecodingwithfred.com/it/blog/lovable-to-cloudflare/</link><guid isPermaLink="false">https://vibecodingwithfred.com/it/blog/lovable-to-cloudflare/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Se hai costruito un sito web con la piattaforma AI di Lovable e vuoi ospitarlo sulla rete globale velocissima di Cloudflare, sei nel posto giusto. Questa guida completa copre tutto quello che devi sapere sul deployment di progetti Lovable su Cloudflare—che tu scelga la semplicita di Cloudflare Pages o la potenza di Cloudflare Workers.&lt;/p&gt;
&lt;h2 id=&quot;perche-scegliere-cloudflare-per-il-tuo-progetto-lovable&quot;&gt;Perche Scegliere Cloudflare per il Tuo Progetto Lovable?&lt;/h2&gt;
&lt;p&gt;Cloudflare offre due eccellenti soluzioni di hosting, entrambe con generosi piani gratuiti:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare Pages&lt;/strong&gt; (Raccomandato per la maggior parte degli utenti):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Siti e richieste illimitate&lt;/li&gt;
&lt;li&gt;Integrazione Git e deployment automatici&lt;/li&gt;
&lt;li&gt;500 build al mese (piano gratuito)&lt;/li&gt;
&lt;li&gt;CDN globale con 300+ posizioni&lt;/li&gt;
&lt;li&gt;Certificati SSL gratuiti&lt;/li&gt;
&lt;li&gt;Deployment semplice, zero configurazione&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare Workers&lt;/strong&gt; (Per casi d&apos;uso avanzati):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;100.000 richieste al giorno (piano gratuito)&lt;/li&gt;
&lt;li&gt;Capacita di edge computing&lt;/li&gt;
&lt;li&gt;Esegui codice vicino ai tuoi utenti&lt;/li&gt;
&lt;li&gt;Storage KV integrato (1GB gratuito)&lt;/li&gt;
&lt;li&gt;Piu controllo su caching e routing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Entrambe le opzioni offrono tempi di risposta sotto i 50ms globalmente e non costano assolutamente nulla per la maggior parte dei siti personali e piccole aziende.&lt;/p&gt;
&lt;h2 id=&quot;puoi-spostare-un-progetto-lovable-su-cloudflare&quot;&gt;Puoi Spostare un Progetto Lovable su Cloudflare?&lt;/h2&gt;
&lt;p&gt;Si! I progetti Lovable si esportano come applicazioni React/TypeScript standard che si deployano perfettamente su Cloudflare. Puoi usare sia Cloudflare Pages (piu facile) che Cloudflare Workers (piu potente), ed entrambi includono:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hosting gratuito senza carta di credito richiesta&lt;/li&gt;
&lt;li&gt;Supporto domini personalizzati&lt;/li&gt;
&lt;li&gt;Certificati SSL automatici&lt;/li&gt;
&lt;li&gt;Delivery CDN globale&lt;/li&gt;
&lt;li&gt;Nessun vendor lock-in—il tuo codice, la tua infrastruttura&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;metodo-1-cloudflare-pages-raccomandato&quot;&gt;Metodo 1: Cloudflare Pages (Raccomandato)&lt;/h2&gt;
&lt;p&gt;Cloudflare Pages e il modo piu facile per deployare il tuo progetto Lovable. Costruisce e deploya automaticamente il tuo sito ogni volta che fai push su Git.&lt;/p&gt;
&lt;h3 id=&quot;passo-1-esporta-il-tuo-progetto-lovable&quot;&gt;Passo 1: Esporta il Tuo Progetto Lovable&lt;/h3&gt;
&lt;p&gt;Prima, devi estrarre il tuo codice da Lovable:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Apri il tuo progetto Lovable&lt;/li&gt;
&lt;li&gt;Clicca l&apos;icona menu (di solito tre puntini o menu hamburger)&lt;/li&gt;
&lt;li&gt;Seleziona &lt;strong&gt;&quot;Esporta&quot;&lt;/strong&gt; o &lt;strong&gt;&quot;Download&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Scegli &lt;strong&gt;&quot;Scarica come ZIP&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Salva il file ZIP sul tuo computer&lt;/li&gt;
&lt;li&gt;Estrai il file ZIP in una cartella&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;passo-2-configura-un-repository-git&quot;&gt;Passo 2: Configura un Repository Git&lt;/h3&gt;
&lt;p&gt;Cloudflare Pages deploya da repository Git, quindi devi pushare il tuo codice su GitHub, GitLab o Bitbucket.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Naviga alla cartella del progetto estratto&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; path/to/your-lovable-project

&lt;span class=&quot;token comment&quot;&gt;# Inizializza un repository Git&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init

&lt;span class=&quot;token comment&quot;&gt;# Aggiungi tutti i file a Git&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Crea il tuo primo commit&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial commit: Lovable project export&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ora crea un repository su GitHub (o la tua piattaforma Git preferita):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Vai su &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt; e fai login&lt;/li&gt;
&lt;li&gt;Clicca l&apos;icona &lt;strong&gt;&quot;+&quot;&lt;/strong&gt; in alto a destra&lt;/li&gt;
&lt;li&gt;Seleziona &lt;strong&gt;&quot;Nuovo repository&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Dagli un nome (es. &quot;my-lovable-site&quot;)&lt;/li&gt;
&lt;li&gt;Tienilo &lt;strong&gt;Pubblico&lt;/strong&gt; o &lt;strong&gt;Privato&lt;/strong&gt; (entrambi funzionano con Cloudflare)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Non&lt;/strong&gt; inizializzare con README, .gitignore o licenza&lt;/li&gt;
&lt;li&gt;Clicca &lt;strong&gt;&quot;Crea repository&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Connetti il tuo repository locale a GitHub:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Aggiungi il tuo repository GitHub come origin remoto&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; origin https://github.com/TUO-USERNAME/NOME-REPO.git

&lt;span class=&quot;token comment&quot;&gt;# Pusha il codice su GitHub&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch &lt;span class=&quot;token parameter variable&quot;&gt;-M&lt;/span&gt; main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;passo-3-crea-un-account-cloudflare&quot;&gt;Passo 3: Crea un Account Cloudflare&lt;/h3&gt;
&lt;p&gt;Se non ne hai gia uno:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Vai su &lt;a href=&quot;https://dash.cloudflare.com/sign-up&quot;&gt;Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Registrati con la tua email&lt;/li&gt;
&lt;li&gt;Verifica il tuo indirizzo email&lt;/li&gt;
&lt;li&gt;Fai login nella dashboard Cloudflare&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;passo-4-deploya-su-cloudflare-pages&quot;&gt;Passo 4: Deploya su Cloudflare Pages&lt;/h3&gt;
&lt;p&gt;Ora la magia—deployare il tuo progetto Lovable:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Nella dashboard Cloudflare, clicca &lt;strong&gt;&quot;Workers &amp;#x26; Pages&quot;&lt;/strong&gt; nella sidebar sinistra&lt;/li&gt;
&lt;li&gt;Clicca &lt;strong&gt;&quot;Crea applicazione&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Seleziona la tab &lt;strong&gt;&quot;Pages&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Clicca &lt;strong&gt;&quot;Connetti a Git&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Scegli il tuo provider Git (GitHub, GitLab, o Bitbucket)&lt;/li&gt;
&lt;li&gt;Autorizza Cloudflare ad accedere ai tuoi repository&lt;/li&gt;
&lt;li&gt;Seleziona il repository che hai appena creato&lt;/li&gt;
&lt;li&gt;Clicca &lt;strong&gt;&quot;Inizia setup&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;passo-5-configura-le-impostazioni-build&quot;&gt;Passo 5: Configura le Impostazioni Build&lt;/h3&gt;
&lt;p&gt;Cloudflare proverà ad auto-rilevare il tuo framework. Per la maggior parte dei progetti Lovable (tipicamente React/Vite):&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Framework preset&lt;/strong&gt;: Vite (o seleziona &quot;None&quot; se non rilevato)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Comando build&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Directory output build&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Directory root&lt;/strong&gt;: Lascia vuoto (a meno che il tuo codice non sia in una sottodirectory)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Variabili d&apos;ambiente&lt;/strong&gt;: Aggiungi eventuali variabili richieste (come chiavi API)&lt;/p&gt;
&lt;h3 id=&quot;passo-6-deploy&quot;&gt;Passo 6: Deploy!&lt;/h3&gt;
&lt;p&gt;Clicca &lt;strong&gt;&quot;Salva e Deploya&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Cloudflare:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Clona il tuo repository&lt;/li&gt;
&lt;li&gt;Installa le dipendenze (&lt;code class=&quot;language-text&quot;&gt;npm install&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Esegue il comando build&lt;/li&gt;
&lt;li&gt;Deploya sulla CDN globale&lt;/li&gt;
&lt;li&gt;Ti da un URL &lt;code class=&quot;language-text&quot;&gt;.pages.dev&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Il primo deployment richiede tipicamente 1-3 minuti. Puoi guardare i log di build in tempo reale.&lt;/p&gt;
&lt;h2 id=&quot;domande-frequenti&quot;&gt;Domande Frequenti&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Migrare da Lovable a Cloudflare e gratuito?&lt;/strong&gt;
Si, migrare da Lovable a Cloudflare e completamente gratuito. Lovable permette esportazioni gratuite dei progetti, e Cloudflare offre generosi piani di hosting gratuiti. Cloudflare Pages fornisce siti e richieste illimitate, mentre Cloudflare Workers offre 100.000 richieste/giorno. Entrambi includono SSL gratuito e domini personalizzati.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Come trasferisco il mio sito Lovable su Cloudflare?&lt;/strong&gt;
Esporta il tuo progetto Lovable come file ZIP, estrailo, pusha il codice su GitHub, poi connetti il tuo repository GitHub a Cloudflare Pages. L&apos;intero processo richiede circa 15 minuti ed e completamente automatizzato dopo il setup iniziale.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Posso usare il mio dominio con l&apos;hosting Cloudflare?&lt;/strong&gt;
Si! Sia Cloudflare Pages che Workers supportano domini personalizzati con certificati SSL gratuiti. Se il tuo dominio usa gia Cloudflare per il DNS, il setup e automatico. Altrimenti, dovrai aggiungere un record CNAME presso il tuo registrar di dominio.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Guide correlate:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website&quot;&gt;10 Modi per Spostare il Tuo Sito Lovable su Hosting Gratuito&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-from-hero-to-zero&quot;&gt;Lovable: Da Eroe a Zero con il 2.0&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[5 Redis Patterns for Real-Time Laravel Apps That Scale]]></title><description><![CDATA[After migrating from Redis to KeyDB and back again while processing billions in logistics transactions, I've learned which Redis patterns…]]></description><link>https://vibecodingwithfred.com/blog/redis-patterns-laravel-quicktip/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/redis-patterns-laravel-quicktip/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;After migrating from Redis to KeyDB and back again while processing billions in logistics transactions, I&apos;ve learned which Redis patterns work at scale. Here are 5 battle-tested patterns you can implement today.&lt;/p&gt;
&lt;h2 id=&quot;1-pipeline-everything-10x-performance-boost&quot;&gt;1. Pipeline Everything (10x Performance Boost)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Bad Pattern:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// This creates 1000 network round trips!&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Production Pattern:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// One network call, atomic execution&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Real Impact:&lt;/strong&gt; Reduced our bulk import time from 45 seconds to 4 seconds for 10k records.&lt;/p&gt;
&lt;h2 id=&quot;2-implement-sliding-window-rate-limiting&quot;&gt;2. Implement Sliding Window Rate Limiting&lt;/h2&gt;
&lt;p&gt;Forget fixed windows that cause thundering herds. Here&apos;s what we use in production:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;RateLimiter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;attempt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;rate_limit:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;microtime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Remove old entries&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zremrangebyscore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Add current request&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Count requests in window&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zcard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Set expiry&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$results&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Usage in middleware&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token class-name static-context&quot;&gt;RateLimiter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;attempt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;api:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Rate limit exceeded&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;429&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Why It Works:&lt;/strong&gt; No spikes at window boundaries, fair distribution, self-cleaning.&lt;/p&gt;
&lt;h2 id=&quot;3-cache-invalidation-with-tags-the-right-way&quot;&gt;3. Cache Invalidation with Tags (The Right Way)&lt;/h2&gt;
&lt;p&gt;Laravel&apos;s cache tags are great until you need granular control. Here&apos;s our pattern:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;SmartCache&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;rememberWithDependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Store the main cache&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Cache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Track dependencies in Redis sets&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;86400&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1 day&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;invalidateTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;smembers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Delete all tagged keys in one pipeline&lt;/span&gt;
            &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;del&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;del&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Usage&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$metrics&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;SmartCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rememberWithDependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;dashboard.metrics&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;deliveries&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;customer:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$customerId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 5 minutes&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;calculateExpensiveMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Invalidate all shipment-related caches&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;SmartCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;invalidateTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Production Win:&lt;/strong&gt; Reduced cache misses by 73% and eliminated cascading invalidations.&lt;/p&gt;
&lt;h2 id=&quot;4-distributed-locks-that-dont-deadlock&quot;&gt;4. Distributed Locks That Don&apos;t Deadlock&lt;/h2&gt;
&lt;p&gt;After losing $50k to a race condition, we implemented this bulletproof locking:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;DistributedLock&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;lock:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniqid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;gethostname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Atomic set if not exists with expiry&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$acquired&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;NX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Only set if not exists&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;EX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Expire after X seconds&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$acquired&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Check if lock is stale (backup mechanism)&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockHolder&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lockHolder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Lock expired between commands, try again&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;lock:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Lua script for atomic check and delete&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;
            if redis.call(&apos;get&apos;, KEYS[1]) == ARGV[1] then
                return redis.call(&apos;del&apos;, KEYS[1])
            else
                return 0
            end
        &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;withLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LockTimeoutException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Could not acquire lock for &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;finally&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Usage for payment processing&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;DistributedLock&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;withLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;payment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Process payment safely&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isPaid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Idempotent check&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;processPayment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;markAsPaid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Critical:&lt;/strong&gt; The Lua script ensures we only release OUR lock, preventing accidental release of someone else&apos;s lock.&lt;/p&gt;
&lt;h2 id=&quot;5-real-time-metrics-with-hyperloglog&quot;&gt;5. Real-Time Metrics with HyperLogLog&lt;/h2&gt;
&lt;p&gt;Track unique visitors/events without memory explosion:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;MetricsTracker&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;metric:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// HyperLogLog adds unique items with O(1) space&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Keep 2 windows&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getCardinality&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windows&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windows&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;metric:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Merge multiple HyperLogLogs&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;trackAndBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Track unique event&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;event:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:users&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Track per-minute rate&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;event:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:rate&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniqid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Broadcast if threshold reached&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;broadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HighTrafficAlert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Usage&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$uniqueVisitors&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;page.visits&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$dailyActive&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCardinality&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user.active&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Track API usage without memory issues&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackAndBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;api.call&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Memory Savings:&lt;/strong&gt; Tracking 10M unique users takes ~12KB instead of 40MB with traditional sets.&lt;/p&gt;
&lt;h2 id=&quot;bonus-redis-memory-optimization-checklist&quot;&gt;Bonus: Redis Memory Optimization Checklist&lt;/h2&gt;
&lt;p&gt;From our production playbook:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 1. Use compression for large values&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;large:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;gzcompress&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 2. Use hashes for small objects (90% memory saving!)&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;user:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;name&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;email&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;status&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 3. Set aggressive expiries&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 5 min default, not 1 hour&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 4. Use SCAN instead of KEYS&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scan&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;MATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipment:*&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;COUNT&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Process $keys&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 5. Monitor memory usage&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1073741824&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1GB&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Redis memory critical: &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory_human&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;the-expensive-lessons&quot;&gt;The Expensive Lessons&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Always set expiries&lt;/strong&gt; - One missing TTL consumed 8GB of RAM&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pipeline or perish&lt;/strong&gt; - Network latency adds up fast&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use the right data structure&lt;/strong&gt; - HyperLogLog saved us $2k/month in memory&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lock properly&lt;/strong&gt; - Race conditions in financial systems = lawsuits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Monitor everything&lt;/strong&gt; - You can&apos;t fix what you don&apos;t measure&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These patterns handle 50k requests/second in production. Start with pipelines and proper locking—they&apos;ll solve 80% of your Redis performance issues.&lt;/p&gt;
&lt;h2 id=&quot;master-laravel-with-real-projects&quot;&gt;Master Laravel with Real Projects&lt;/h2&gt;
&lt;p&gt;Want to implement these Redis patterns in a real application? Build production-ready Laravel projects from scratch:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-laravel/&quot;&gt;Build a Blog with Laravel&lt;/a&gt;&lt;/strong&gt; - Master Eloquent, authentication, and CRUD operations with Redis caching&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;Build a Portfolio with Laravel&lt;/a&gt;&lt;/strong&gt; - Learn file uploads, relationships, and Redis-powered sessions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-laravel/&quot;&gt;Build E-Commerce with Laravel&lt;/a&gt;&lt;/strong&gt; - Advanced patterns including queues, event handling, and distributed locks&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each tutorial includes AI-assisted prompts to guide you through building scalable applications that use Redis effectively.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Questions about implementing these patterns? Drop a comment - I&apos;ve probably debugged that issue at 3 AM.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[확장 가능한 실시간 Laravel 앱을 위한 5가지 Redis 패턴]]></title><description><![CDATA[수십억 달러의 물류 거래를 처리하면서 Redis에서 KeyDB로 마이그레이션했다가 다시 돌아온 후, 어떤 Redis 패턴이 대규모에서 작동하는지 배웠습니다. 오늘 바로 구현할 수 있는 5가지 검증된 패턴을 소개합니다.…]]></description><link>https://vibecodingwithfred.com/ko/blog/redis-patterns-laravel-quicktip/</link><guid isPermaLink="false">https://vibecodingwithfred.com/ko/blog/redis-patterns-laravel-quicktip/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;수십억 달러의 물류 거래를 처리하면서 Redis에서 KeyDB로 마이그레이션했다가 다시 돌아온 후, 어떤 Redis 패턴이 대규모에서 작동하는지 배웠습니다. 오늘 바로 구현할 수 있는 5가지 검증된 패턴을 소개합니다.&lt;/p&gt;
&lt;h2 id=&quot;1-모든-것을-파이프라인으로-10배-성능-향상&quot;&gt;1. 모든 것을 파이프라인으로 (10배 성능 향상)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;나쁜 패턴:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 이것은 1000번의 네트워크 왕복을 만듭니다!&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;프로덕션 패턴:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 한 번의 네트워크 호출, 원자적 실행&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;실제 효과:&lt;/strong&gt; 10k 레코드 대량 가져오기 시간을 45초에서 4초로 단축했습니다.&lt;/p&gt;
&lt;h2 id=&quot;2-슬라이딩-윈도우-레이트-리미팅-구현&quot;&gt;2. 슬라이딩 윈도우 레이트 리미팅 구현&lt;/h2&gt;
&lt;p&gt;썬더링 허드를 유발하는 고정 윈도우는 잊으세요. 프로덕션에서 사용하는 방법은 다음과 같습니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;RateLimiter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;attempt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;rate_limit:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;microtime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// 오래된 항목 제거&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zremrangebyscore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// 현재 요청 추가&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// 윈도우 내 요청 수 계산&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zcard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// 만료 설정&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$results&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 미들웨어에서 사용&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token class-name static-context&quot;&gt;RateLimiter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;attempt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;api:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Rate limit exceeded&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;429&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;작동하는 이유:&lt;/strong&gt; 윈도우 경계에서 스파이크가 없고, 공정한 분배, 자체 정리됩니다.&lt;/p&gt;
&lt;h2 id=&quot;3-태그를-사용한-캐시-무효화-올바른-방법&quot;&gt;3. 태그를 사용한 캐시 무효화 (올바른 방법)&lt;/h2&gt;
&lt;p&gt;Laravel의 캐시 태그는 세밀한 제어가 필요할 때까지 훌륭합니다. 우리의 패턴은 다음과 같습니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;SmartCache&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;rememberWithDependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// 메인 캐시 저장&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Cache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Redis 셋에서 종속성 추적&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;86400&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1일&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;invalidateTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;smembers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// 하나의 파이프라인으로 모든 태그된 키 삭제&lt;/span&gt;
            &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;del&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;del&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 사용법&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$metrics&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;SmartCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rememberWithDependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;dashboard.metrics&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;deliveries&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;customer:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$customerId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 5분&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;calculateExpensiveMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 모든 shipment 관련 캐시 무효화&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;SmartCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;invalidateTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;프로덕션 성과:&lt;/strong&gt; 캐시 미스를 73% 줄이고 연쇄 무효화를 제거했습니다.&lt;/p&gt;
&lt;h2 id=&quot;4-데드락-없는-분산-락&quot;&gt;4. 데드락 없는 분산 락&lt;/h2&gt;
&lt;p&gt;레이스 컨디션으로 5만 달러를 잃은 후, 다음과 같은 견고한 락킹을 구현했습니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;DistributedLock&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;lock:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniqid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;gethostname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// 만료와 함께 원자적 set if not exists&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$acquired&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;NX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 존재하지 않을 때만 설정&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;EX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// X초 후 만료&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$acquired&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// 락이 오래됐는지 확인 (백업 메커니즘)&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockHolder&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lockHolder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// 명령 사이에 락이 만료됨, 다시 시도&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;lock:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// 원자적 확인 및 삭제를 위한 Lua 스크립트&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;
            if redis.call(&apos;get&apos;, KEYS[1]) == ARGV[1] then
                return redis.call(&apos;del&apos;, KEYS[1])
            else
                return 0
            end
        &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;withLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LockTimeoutException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Could not acquire lock for &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;finally&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 결제 처리에 사용&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;DistributedLock&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;withLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;payment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 안전하게 결제 처리&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isPaid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 멱등성 검사&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;processPayment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;markAsPaid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;중요:&lt;/strong&gt; Lua 스크립트는 우리 락만 해제하도록 보장하여 다른 사람의 락을 실수로 해제하는 것을 방지합니다.&lt;/p&gt;
&lt;h2 id=&quot;5-hyperloglog를-사용한-실시간-메트릭&quot;&gt;5. HyperLogLog를 사용한 실시간 메트릭&lt;/h2&gt;
&lt;p&gt;메모리 폭발 없이 고유 방문자/이벤트 추적:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;MetricsTracker&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;metric:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// HyperLogLog는 O(1) 공간으로 고유 항목 추가&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 2개 윈도우 유지&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getCardinality&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windows&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windows&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;metric:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// 여러 HyperLogLog 병합&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;trackAndBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// 고유 이벤트 추적&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;event:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:users&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// 분당 비율 추적&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;event:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:rate&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniqid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// 임계값 도달 시 브로드캐스트&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;broadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HighTrafficAlert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 사용법&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$uniqueVisitors&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;page.visits&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$dailyActive&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCardinality&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user.active&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 메모리 문제 없이 API 사용량 추적&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackAndBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;api.call&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;메모리 절약:&lt;/strong&gt; 1천만 고유 사용자 추적이 기존 셋의 40MB 대신 ~12KB만 사용합니다.&lt;/p&gt;
&lt;h2 id=&quot;보너스-redis-메모리-최적화-체크리스트&quot;&gt;보너스: Redis 메모리 최적화 체크리스트&lt;/h2&gt;
&lt;p&gt;프로덕션 플레이북에서:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 1. 큰 값에 압축 사용&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;large:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;gzcompress&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 2. 작은 객체에 해시 사용 (90% 메모리 절약!)&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;user:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;name&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;email&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;status&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 3. 공격적인 만료 설정&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 기본 5분, 1시간이 아님&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 4. KEYS 대신 SCAN 사용&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scan&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;MATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipment:*&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;COUNT&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// $keys 처리&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 5. 메모리 사용량 모니터링&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1073741824&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1GB&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Redis memory critical: &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory_human&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;값비싼-교훈들&quot;&gt;값비싼 교훈들&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;항상 만료 설정&lt;/strong&gt; - 하나의 누락된 TTL이 8GB RAM을 소비함&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;파이프라인이냐 멸망이냐&lt;/strong&gt; - 네트워크 지연이 빠르게 누적됨&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;올바른 데이터 구조 사용&lt;/strong&gt; - HyperLogLog가 월 2천 달러의 메모리 비용 절감&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;락을 제대로 하기&lt;/strong&gt; - 금융 시스템의 레이스 컨디션 = 소송&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;모든 것을 모니터링&lt;/strong&gt; - 측정하지 않으면 고칠 수 없음&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이 패턴들은 프로덕션에서 초당 50k 요청을 처리합니다. 파이프라인과 적절한 락킹부터 시작하세요—Redis 성능 문제의 80%를 해결할 것입니다.&lt;/p&gt;
&lt;h2 id=&quot;실제-프로젝트로-laravel-마스터하기&quot;&gt;실제 프로젝트로 Laravel 마스터하기&lt;/h2&gt;
&lt;p&gt;이 Redis 패턴을 실제 애플리케이션에 구현하고 싶으신가요? 처음부터 프로덕션급 Laravel 프로젝트를 빌드하세요:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-laravel/&quot;&gt;Laravel로 블로그 만들기&lt;/a&gt;&lt;/strong&gt; - Redis 캐싱과 함께 Eloquent, 인증, CRUD 작업 마스터하기&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;Laravel로 포트폴리오 만들기&lt;/a&gt;&lt;/strong&gt; - 파일 업로드, 관계형, Redis 기반 세션 배우기&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-laravel/&quot;&gt;Laravel로 이커머스 만들기&lt;/a&gt;&lt;/strong&gt; - 큐, 이벤트 처리, 분산 락을 포함한 고급 패턴&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;각 튜토리얼에는 Redis를 효과적으로 사용하는 확장 가능한 애플리케이션을 구축하도록 안내하는 AI 지원 프롬프트가 포함되어 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;이 패턴 구현에 대한 질문이 있으신가요? 댓글을 남겨주세요 - 아마도 새벽 3시에 그 문제를 디버깅해본 적이 있을 겁니다.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Complete Gids: Deploy Je Lovable-Project naar Cloudflare (Pages en Workers)]]></title><description><![CDATA[De definitieve gids voor het deployen van je Lovable AI-gebouwde website op Cloudflare. Leer hoe je zowel Cloudflare Pages als Workers gebruikt, aangepaste domeinen instelt en veelvoorkomende problemen oplost. Gratis hosting met enterprise-niveau prestaties.]]></description><link>https://vibecodingwithfred.com/nl/blog/lovable-to-cloudflare/</link><guid isPermaLink="false">https://vibecodingwithfred.com/nl/blog/lovable-to-cloudflare/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Als je een website hebt gebouwd met Lovable&apos;s AI-platform en deze wilt hosten op Cloudflare&apos;s razendsnelle wereldwijde netwerk, ben je op de juiste plek. Deze uitgebreide gids behandelt alles wat je moet weten over het deployen van Lovable-projecten naar Cloudflare—of je nu kiest voor de eenvoud van Cloudflare Pages of de kracht van Cloudflare Workers.&lt;/p&gt;
&lt;h2 id=&quot;waarom-cloudflare-kiezen-voor-je-lovable-project&quot;&gt;Waarom Cloudflare Kiezen voor Je Lovable-Project?&lt;/h2&gt;
&lt;p&gt;Cloudflare biedt twee uitstekende hostingoplossingen, beide met genereuze gratis tiers:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare Pages&lt;/strong&gt; (Aanbevolen voor de meeste gebruikers):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Onbeperkte sites en requests&lt;/li&gt;
&lt;li&gt;Automatische Git-integratie en deployments&lt;/li&gt;
&lt;li&gt;500 builds per maand (gratis tier)&lt;/li&gt;
&lt;li&gt;Wereldwijde CDN met 300+ locaties&lt;/li&gt;
&lt;li&gt;Gratis SSL-certificaten&lt;/li&gt;
&lt;li&gt;Eenvoudige, zero-configuratie deployment&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare Workers&lt;/strong&gt; (Voor geavanceerde use cases):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;100.000 requests per dag (gratis tier)&lt;/li&gt;
&lt;li&gt;Edge computing mogelijkheden&lt;/li&gt;
&lt;li&gt;Voer code uit dichter bij je gebruikers&lt;/li&gt;
&lt;li&gt;Ingebouwde KV-opslag (1GB gratis)&lt;/li&gt;
&lt;li&gt;Meer controle over caching en routing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Beide opties leveren sub-50ms responstijden wereldwijd en kosten absoluut niets voor de meeste persoonlijke en kleine zakelijke sites.&lt;/p&gt;
&lt;h2 id=&quot;kun-je-een-lovable-project-naar-cloudflare-verplaatsen&quot;&gt;Kun Je een Lovable-Project naar Cloudflare Verplaatsen?&lt;/h2&gt;
&lt;p&gt;Ja! Lovable-projecten exporteren als standaard React/TypeScript-applicaties die perfect deployen naar Cloudflare. Je kunt Cloudflare Pages (makkelijker) of Cloudflare Workers (krachtiger) gebruiken, en beide bevatten:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gratis hosting zonder creditcard vereist&lt;/li&gt;
&lt;li&gt;Ondersteuning voor aangepaste domeinen&lt;/li&gt;
&lt;li&gt;Automatische SSL-certificaten&lt;/li&gt;
&lt;li&gt;Wereldwijde CDN-levering&lt;/li&gt;
&lt;li&gt;Geen vendor lock-in—jouw code, jouw infrastructuur&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Deze gids behandelt beide methoden met complete stapsgewijze instructies.&lt;/p&gt;
&lt;h2 id=&quot;methode-1-cloudflare-pages-aanbevolen&quot;&gt;Methode 1: Cloudflare Pages (Aanbevolen)&lt;/h2&gt;
&lt;p&gt;Cloudflare Pages is de makkelijkste manier om je Lovable-project te deployen. Het bouwt en deployt automatisch je site elke keer dat je naar Git pusht.&lt;/p&gt;
&lt;h3 id=&quot;stap-1-exporteer-je-lovable-project&quot;&gt;Stap 1: Exporteer Je Lovable-Project&lt;/h3&gt;
&lt;p&gt;Eerst moet je je code uit Lovable halen:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open je Lovable-project&lt;/li&gt;
&lt;li&gt;Klik op het menu-icoon (meestal drie puntjes of hamburgermenu)&lt;/li&gt;
&lt;li&gt;Selecteer &lt;strong&gt;&quot;Export&quot;&lt;/strong&gt; of &lt;strong&gt;&quot;Download&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Kies &lt;strong&gt;&quot;Download als ZIP&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Sla het ZIP-bestand op je computer op&lt;/li&gt;
&lt;li&gt;Pak het ZIP-bestand uit naar een map&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;stap-2-maak-een-git-repository-aan&quot;&gt;Stap 2: Maak een Git Repository Aan&lt;/h3&gt;
&lt;p&gt;Cloudflare Pages deployt vanuit Git repositories, dus je moet je code naar GitHub, GitLab of Bitbucket pushen.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Navigeer naar je uitgepakte projectmap&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; path/to/your-lovable-project

&lt;span class=&quot;token comment&quot;&gt;# Initialiseer een Git repository&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init

&lt;span class=&quot;token comment&quot;&gt;# Voeg alle bestanden toe aan Git&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Maak je eerste commit&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial commit: Lovable project export&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Maak nu een repository op GitHub (of je voorkeursplatform):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ga naar &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt; en log in&lt;/li&gt;
&lt;li&gt;Klik op het &lt;strong&gt;&quot;+&quot;&lt;/strong&gt;-icoon rechtsboven&lt;/li&gt;
&lt;li&gt;Selecteer &lt;strong&gt;&quot;New repository&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Noem het (bijv. &quot;my-lovable-site&quot;)&lt;/li&gt;
&lt;li&gt;Houd het &lt;strong&gt;Public&lt;/strong&gt; of &lt;strong&gt;Private&lt;/strong&gt; (beide werken met Cloudflare)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Niet&lt;/strong&gt; initialiseren met README, .gitignore of licentie&lt;/li&gt;
&lt;li&gt;Klik op &lt;strong&gt;&quot;Create repository&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Verbind je lokale repository met GitHub:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Voeg je GitHub repository toe als remote origin&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; origin https://github.com/YOUR-USERNAME/YOUR-REPO-NAME.git

&lt;span class=&quot;token comment&quot;&gt;# Push je code naar GitHub&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch &lt;span class=&quot;token parameter variable&quot;&gt;-M&lt;/span&gt; main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;stap-3-maak-een-cloudflare-account&quot;&gt;Stap 3: Maak een Cloudflare Account&lt;/h3&gt;
&lt;p&gt;Als je er nog geen hebt:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ga naar &lt;a href=&quot;https://dash.cloudflare.com/sign-up&quot;&gt;Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Meld je aan met je e-mail&lt;/li&gt;
&lt;li&gt;Verifieer je e-mailadres&lt;/li&gt;
&lt;li&gt;Log in op het Cloudflare dashboard&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;stap-4-deploy-naar-cloudflare-pages&quot;&gt;Stap 4: Deploy naar Cloudflare Pages&lt;/h3&gt;
&lt;p&gt;Nu voor de magie—je Lovable-project deployen:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Klik in het Cloudflare dashboard op &lt;strong&gt;&quot;Workers &amp;#x26; Pages&quot;&lt;/strong&gt; in de linkerzijbalk&lt;/li&gt;
&lt;li&gt;Klik op &lt;strong&gt;&quot;Create application&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Selecteer het &lt;strong&gt;&quot;Pages&quot;&lt;/strong&gt; tabblad&lt;/li&gt;
&lt;li&gt;Klik op &lt;strong&gt;&quot;Connect to Git&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Kies je Git-provider (GitHub, GitLab of Bitbucket)&lt;/li&gt;
&lt;li&gt;Autoriseer Cloudflare om toegang te krijgen tot je repositories&lt;/li&gt;
&lt;li&gt;Selecteer de repository die je net hebt gemaakt&lt;/li&gt;
&lt;li&gt;Klik op &lt;strong&gt;&quot;Begin setup&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;stap-5-configureer-build-instellingen&quot;&gt;Stap 5: Configureer Build-Instellingen&lt;/h3&gt;
&lt;p&gt;Cloudflare probeert je framework automatisch te detecteren. Voor de meeste Lovable-projecten (meestal React/Vite):&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Framework preset&lt;/strong&gt;: Vite (of selecteer &quot;None&quot; indien niet gedetecteerd)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Build command&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Build output directory&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Root directory&lt;/strong&gt;: Laat leeg (tenzij je code in een subdirectory staat)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Omgevingsvariabelen&lt;/strong&gt;: Voeg vereiste variabelen toe (zoals API-sleutels)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Klik op &quot;Add variable&quot;&lt;/li&gt;
&lt;li&gt;Voer &lt;code class=&quot;language-text&quot;&gt;VITE_API_URL&lt;/code&gt; in of wat je project nodig heeft&lt;/li&gt;
&lt;li&gt;Voeg de waarde toe&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Opmerking&lt;/strong&gt;: Lovable-projecten gebruiken meestal &lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt; als output directory. Als je build faalt, controleer je &lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt; om de naam van de output directory te bevestigen.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;stap-6-deployen&quot;&gt;Stap 6: Deployen!&lt;/h3&gt;
&lt;p&gt;Klik op &lt;strong&gt;&quot;Save and Deploy&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Cloudflare zal:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Je repository klonen&lt;/li&gt;
&lt;li&gt;Dependencies installeren (&lt;code class=&quot;language-text&quot;&gt;npm install&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Je build-commando uitvoeren&lt;/li&gt;
&lt;li&gt;Deployen naar hun wereldwijde CDN&lt;/li&gt;
&lt;li&gt;Je een &lt;code class=&quot;language-text&quot;&gt;.pages.dev&lt;/code&gt; URL geven&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;De eerste deployment duurt meestal 1-3 minuten. Je kunt de build-logs in real-time bekijken.&lt;/p&gt;
&lt;h3 id=&quot;stap-7-stel-een-aangepast-domein-in-optioneel&quot;&gt;Stap 7: Stel een Aangepast Domein In (Optioneel)&lt;/h3&gt;
&lt;p&gt;Eenmaal gedeployd krijg je een URL zoals &lt;code class=&quot;language-text&quot;&gt;your-project.pages.dev&lt;/code&gt;. Om je eigen domein te gebruiken:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Klik in je Pages-project op &lt;strong&gt;&quot;Custom domains&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Klik op &lt;strong&gt;&quot;Set up a custom domain&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Voer je domein in (bijv. &lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt; of &lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Klik op &lt;strong&gt;&quot;Continue&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Als je domein al op Cloudflare staat:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cloudflare voegt automatisch de DNS-records toe&lt;/li&gt;
&lt;li&gt;Je domein is binnen seconden live&lt;/li&gt;
&lt;li&gt;SSL wordt automatisch ingeschakeld&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Als je domein NIET op Cloudflare staat:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cloudflare toont je de DNS-records om toe te voegen&lt;/li&gt;
&lt;li&gt;Ga naar je domeinregistrar (GoDaddy, Namecheap, etc.)&lt;/li&gt;
&lt;li&gt;Voeg het CNAME-record toe dat Cloudflare specificeert&lt;/li&gt;
&lt;li&gt;Wacht op DNS-propagatie (kan tot 24 uur duren, meestal veel sneller)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;automatische-deployments&quot;&gt;Automatische Deployments&lt;/h3&gt;
&lt;p&gt;Het beste deel? Elke keer dat je naar je Git repository pusht, herbouwt en deployt Cloudflare automatisch je site:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Maak wijzigingen aan je code&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Dan commit en push&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Updated homepage&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push origin main

&lt;span class=&quot;token comment&quot;&gt;# Cloudflare detecteert automatisch de push en herbouwt&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Je kunt ook preview deployments instellen voor branches—ideaal voor testen voordat je live gaat.&lt;/p&gt;
&lt;h2 id=&quot;methode-2-cloudflare-workers&quot;&gt;Methode 2: Cloudflare Workers&lt;/h2&gt;
&lt;p&gt;Voor degenen die meer controle willen of edge computing mogelijkheden nodig hebben, is Cloudflare Workers de weg.&lt;/p&gt;
&lt;h3 id=&quot;wanneer-workers-gebruiken-in-plaats-van-pages&quot;&gt;Wanneer Workers Gebruiken in Plaats van Pages:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Je moet server-side code uitvoeren aan de edge&lt;/li&gt;
&lt;li&gt;Je wilt fijnmazige controle over caching&lt;/li&gt;
&lt;li&gt;Je bouwt een API of hebt request/response manipulatie nodig&lt;/li&gt;
&lt;li&gt;Je hebt meer dan 500 builds per maand nodig&lt;/li&gt;
&lt;li&gt;Je wilt KV-opslag of Durable Objects gebruiken&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;stap-1-installeer-wrangler-cli&quot;&gt;Stap 1: Installeer Wrangler CLI&lt;/h3&gt;
&lt;p&gt;Wrangler is Cloudflare&apos;s command-line tool voor Workers:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Installeer Wrangler globaal&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; wrangler

&lt;span class=&quot;token comment&quot;&gt;# Verifieer installatie&lt;/span&gt;
wrangler &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Log in bij Cloudflare&lt;/span&gt;
wrangler login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Dit opent je browser om Wrangler te autoriseren met je Cloudflare-account.&lt;/p&gt;
&lt;h3 id=&quot;stap-2-exporteer-en-build-je-lovable-project&quot;&gt;Stap 2: Exporteer en Build Je Lovable-Project&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Exporteer vanuit Lovable (zelfde als eerder)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Pak de ZIP uit&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Navigeer naar de projectmap&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; your-lovable-project

&lt;span class=&quot;token comment&quot;&gt;# Installeer dependencies&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Build je project&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Dit maakt je productiebestanden in de &lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt; map (of &lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt;, afhankelijk van je setup).&lt;/p&gt;
&lt;h3 id=&quot;stap-3-maak-wrangler-configuratie&quot;&gt;Stap 3: Maak Wrangler Configuratie&lt;/h3&gt;
&lt;p&gt;Maak een &lt;code class=&quot;language-text&quot;&gt;wrangler.toml&lt;/code&gt; bestand in je project root:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token key property&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;my-lovable-site&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;workers-site/index.js&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;compatibility_date&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2024-01-01&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;bucket&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;./dist&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Uitleg:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;name&lt;/code&gt;: De naam van je Worker (wordt onderdeel van je &lt;code class=&quot;language-text&quot;&gt;.workers.dev&lt;/code&gt; URL)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;main&lt;/code&gt;: Pad naar je Worker script&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;bucket&lt;/code&gt;: Waar je gebouwde statische bestanden staan&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;stap-4-maak-het-worker-script&quot;&gt;Stap 4: Maak het Worker Script&lt;/h3&gt;
&lt;p&gt;Maak een map en bestand: &lt;code class=&quot;language-text&quot;&gt;workers-site/index.js&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; workers-site&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Maak &lt;code class=&quot;language-text&quot;&gt;workers-site/index.js&lt;/code&gt; met deze inhoud:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; getAssetFromKV &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@cloudflare/kv-asset-handler&apos;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; env&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ctx&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// Probeer de statische asset te serveren&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getAssetFromKV&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token literal-property property&quot;&gt;waitUntil&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;waitUntil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token constant&quot;&gt;ASSET_NAMESPACE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__STATIC_CONTENT&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token constant&quot;&gt;ASSET_MANIFEST&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; __STATIC_CONTENT_MANIFEST&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// Als asset niet gevonden, return 404&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// Voor SPA&apos;s wil je misschien index.html retourneren&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;status &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;404&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token comment&quot;&gt;// Probeer index.html te serveren voor client-side routing&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; notFoundRequest &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;origin&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/index.html&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getAssetFromKV&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;token literal-property property&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; notFoundRequest&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;token literal-property property&quot;&gt;waitUntil&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;waitUntil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;token constant&quot;&gt;ASSET_NAMESPACE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__STATIC_CONTENT&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;token constant&quot;&gt;ASSET_MANIFEST&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; __STATIC_CONTENT_MANIFEST&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Not Found&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;404&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;stap-5-installeer-dependencies&quot;&gt;Stap 5: Installeer Dependencies&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Installeer de KV asset handler&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; @cloudflare/kv-asset-handler&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;stap-6-deploy-naar-cloudflare-workers&quot;&gt;Stap 6: Deploy naar Cloudflare Workers&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Deploy je Worker&lt;/span&gt;
wrangler deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Wrangler zal:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Je statische bestanden uploaden&lt;/li&gt;
&lt;li&gt;Je Worker script deployen&lt;/li&gt;
&lt;li&gt;Je een &lt;code class=&quot;language-text&quot;&gt;.workers.dev&lt;/code&gt; URL geven&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Je site is nu live op Cloudflare&apos;s edge-netwerk!&lt;/p&gt;
&lt;h3 id=&quot;stap-7-aangepast-domein-met-workers&quot;&gt;Stap 7: Aangepast Domein met Workers&lt;/h3&gt;
&lt;p&gt;Om een aangepast domein aan je Worker toe te voegen:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ga naar het Cloudflare dashboard&lt;/li&gt;
&lt;li&gt;Klik op &lt;strong&gt;&quot;Workers &amp;#x26; Pages&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Selecteer je Worker&lt;/li&gt;
&lt;li&gt;Klik op &lt;strong&gt;&quot;Settings&quot;&lt;/strong&gt; &gt; &lt;strong&gt;&quot;Domains &amp;#x26; Routes&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Klik op &lt;strong&gt;&quot;Add Custom Domain&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Voer je domein in&lt;/li&gt;
&lt;li&gt;Volg de DNS-configuratie-instructies&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Als je domein al op Cloudflare staat, is het automatisch. Anders moet je DNS-records toevoegen bij je registrar.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Hulp nodig met DNS?&lt;/strong&gt; Bekijk onze &lt;a href=&quot;/blog/cloudflare-dns-api&quot;&gt;DNS-Records Beheren met de Cloudflare API&lt;/a&gt; gids voor geavanceerd DNS-beheer en automatisering.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;veelvoorkomende-problemen-oplossen&quot;&gt;Veelvoorkomende Problemen Oplossen&lt;/h2&gt;
&lt;h3 id=&quot;build-faalt-command-not-found-npm&quot;&gt;Build Faalt: &quot;Command not found: npm&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Probleem&lt;/strong&gt;: Cloudflare kan npm niet vinden&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Oplossing&lt;/strong&gt;: Zorg ervoor dat je project een &lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt; heeft. Cloudflare installeert automatisch dependencies als het er een vindt.&lt;/p&gt;
&lt;h3 id=&quot;build-faalt-dist-directory-not-found&quot;&gt;Build Faalt: &quot;dist directory not found&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Probleem&lt;/strong&gt;: Je build output directory komt niet overeen met wat je hebt opgegeven&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Oplossingen&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Controleer je &lt;code class=&quot;language-text&quot;&gt;vite.config.js&lt;/code&gt; of build config voor de naam van de output directory&lt;/li&gt;
&lt;li&gt;Veelvoorkomende alternatieven: &lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;out&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;public&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;.output&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Update je Cloudflare Pages build-instellingen of &lt;code class=&quot;language-text&quot;&gt;wrangler.toml&lt;/code&gt; om overeen te komen&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;404-fouten-op-routes-spa-routing&quot;&gt;404 Fouten op Routes (SPA Routing)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Probleem&lt;/strong&gt;: Directe navigatie naar routes zoals &lt;code class=&quot;language-text&quot;&gt;/about&lt;/code&gt; retourneert 404&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Voor Cloudflare Pages&lt;/strong&gt;:
Maak een &lt;code class=&quot;language-text&quot;&gt;public/_redirects&lt;/code&gt; bestand:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/*    /index.html   200&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Of maak een &lt;code class=&quot;language-text&quot;&gt;_redirects&lt;/code&gt; bestand in je &lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt; map na het builden.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Voor Cloudflare Workers&lt;/strong&gt;:
Het script hierboven (in Stap 4) handelt dit al af door &lt;code class=&quot;language-text&quot;&gt;index.html&lt;/code&gt; te serveren voor 404s.&lt;/p&gt;
&lt;h3 id=&quot;omgevingsvariabelen-werken-niet&quot;&gt;Omgevingsvariabelen Werken Niet&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Voor Cloudflare Pages&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ga naar je Pages project-instellingen&lt;/li&gt;
&lt;li&gt;Klik op &lt;strong&gt;&quot;Environment variables&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Voeg je variabelen toe voor Production en Preview omgevingen&lt;/li&gt;
&lt;li&gt;Redeploy (of push een nieuwe commit)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Voor Cloudflare Workers&lt;/strong&gt;:
Voeg toe aan &lt;code class=&quot;language-text&quot;&gt;wrangler.toml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;API_URL&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://api.example.com&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Voor secrets (zoals API-sleutels):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;wrangler secret put API_KEY&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;build-overschrijdt-gratis-tier-limiet-pages&quot;&gt;Build Overschrijdt Gratis Tier Limiet (Pages)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Probleem&lt;/strong&gt;: Meer dan 500 builds per maand&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Oplossingen&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Schakel over naar Cloudflare Workers (onbeperkte deploys)&lt;/li&gt;
&lt;li&gt;Upgrade naar Pages betaald plan ($5/maand voor 5.000 builds)&lt;/li&gt;
&lt;li&gt;Verminder commit-frequentie (batch wijzigingen)&lt;/li&gt;
&lt;li&gt;Schakel automatische deployments uit voor niet-main branches&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;worker-overschrijdt-100000-requestsdag&quot;&gt;Worker Overschrijdt 100.000 Requests/Dag&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Probleem&lt;/strong&gt;: Gratis tier bevat alleen 100.000 requests per dag&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Oplossingen&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Schakel over naar Cloudflare Pages (onbeperkte requests)&lt;/li&gt;
&lt;li&gt;Upgrade naar Workers betaald plan ($5/maand voor 10 miljoen requests)&lt;/li&gt;
&lt;li&gt;Optimaliseer caching om Worker-invocaties te verminderen&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;cloudflare-toont-oude-versie-na-deploy&quot;&gt;Cloudflare Toont Oude Versie Na Deploy&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Probleem&lt;/strong&gt;: Je wijzigingen zijn niet zichtbaar&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Oplossingen&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Wis je browsercache (Ctrl+Shift+R of Cmd+Shift+R)&lt;/li&gt;
&lt;li&gt;Controleer deployment status in dashboard—het bouwt misschien nog&lt;/li&gt;
&lt;li&gt;Voor Workers, purg de cache:
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;wrangler deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Controleer of je de juiste URL bekijkt (.pages.dev vs aangepast domein)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;aangepast-domein-werkt-niet&quot;&gt;Aangepast Domein Werkt Niet&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Probleem&lt;/strong&gt;: Domein resolveert niet of toont fouten&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Oplossingen&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Controleer DNS-propagatie: Gebruik &lt;a href=&quot;https://www.whatsmydns.net&quot;&gt;whatsmydns.net&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Verifieer dat DNS-records correct zijn (CNAME wijzend naar je Pages/Workers URL)&lt;/li&gt;
&lt;li&gt;Voor Workers, zorg dat je route correct is geconfigureerd&lt;/li&gt;
&lt;li&gt;Wacht—DNS kan tot 24 uur duren (meestal veel sneller)&lt;/li&gt;
&lt;li&gt;Als je Cloudflare gebruikt voor DNS, zorg dat het record &quot;Proxied&quot; is (oranje wolk)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;api-calls-falen-na-deployment&quot;&gt;API Calls Falen Na Deployment&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Probleem&lt;/strong&gt;: API&apos;s die werkten in Lovable falen nu&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Veelvoorkomende oorzaken&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;CORS-problemen&lt;/strong&gt;: Je API staat misschien geen requests toe van je nieuwe domein&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Omgevingsvariabelen ontbreken&lt;/strong&gt;: Voeg ze toe in Cloudflare dashboard&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTTPS/HTTP mismatch&lt;/strong&gt;: Cloudflare forceert HTTPS; zorg dat API het ondersteunt&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Relatieve URL&apos;s&lt;/strong&gt;: Hardgecodeerde localhost URL&apos;s moeten worden bijgewerkt&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Oplossing voor omgevingsvariabelen&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Gebruik omgevingsvariabelen in je Lovable-project&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;API_URL&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VITE_API_URL&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;http://localhost:3000&apos;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;API_URL&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/api/data&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Stel dan &lt;code class=&quot;language-text&quot;&gt;VITE_API_URL&lt;/code&gt; in bij Cloudflare&apos;s omgevingsvariabelen.&lt;/p&gt;
&lt;h2 id=&quot;pages-vs-workers-vergelijken-voor-lovable-projecten&quot;&gt;Pages vs Workers Vergelijken voor Lovable-Projecten&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Cloudflare Pages&lt;/th&gt;
&lt;th&gt;Cloudflare Workers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Setup Gemak&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Zeer Makkelijk&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Deployment&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Automatisch vanuit Git&lt;/td&gt;
&lt;td&gt;Handmatig via CLI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Gratis Requests&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Onbeperkt&lt;/td&gt;
&lt;td&gt;100.000/dag&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Gratis Builds&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;500/maand&lt;/td&gt;
&lt;td&gt;Onbeperkt (lokale builds)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Aangepaste Domeinen&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Gratis SSL&lt;/td&gt;
&lt;td&gt;Gratis SSL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Omgevingsvariabelen&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Dashboard&lt;/td&gt;
&lt;td&gt;wrangler.toml&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Preview Deployments&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Automatisch&lt;/td&gt;
&lt;td&gt;Handmatig&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Edge Computing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;(alleen statisch)&lt;/td&gt;
&lt;td&gt;Volledige controle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best Voor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Meeste Lovable-projecten&lt;/td&gt;
&lt;td&gt;Geavanceerde gebruikers, API&apos;s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Aanbeveling&lt;/strong&gt;: Begin met Cloudflare Pages. Het is eenvoudiger, heeft onbeperkte requests en handelt 99% van Lovable-projecten goed af. Gebruik Workers alleen als je specifiek edge computing nodig hebt of de gratis Pages builds hebt uitgeput.&lt;/p&gt;
&lt;h2 id=&quot;je-lovable-site-optimaliseren-op-cloudflare&quot;&gt;Je Lovable Site Optimaliseren op Cloudflare&lt;/h2&gt;
&lt;h3 id=&quot;compressie-inschakelen&quot;&gt;Compressie Inschakelen&lt;/h3&gt;
&lt;p&gt;Cloudflare schakelt automatisch Brotli en Gzip compressie in, maar verifieer:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ga naar &lt;strong&gt;&quot;Speed&quot;&lt;/strong&gt; &gt; &lt;strong&gt;&quot;Optimization&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Zorg dat Brotli is ingeschakeld&lt;/li&gt;
&lt;li&gt;Schakel &quot;Auto Minify&quot; in voor HTML, CSS en JS&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;caching-configureren&quot;&gt;Caching Configureren&lt;/h3&gt;
&lt;p&gt;Voor Workers, pas caching aan:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// In workers-site/index.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cacheControl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;browserTTL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1 dag&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;edgeTTL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 30 dagen&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;bypassCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getAssetFromKV&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  cacheControl&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;security-headers-toevoegen&quot;&gt;Security Headers Toevoegen&lt;/h3&gt;
&lt;p&gt;Voor verbeterde beveiliging, voeg headers toe in je Worker:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getAssetFromKV&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Kloon en voeg headers toe&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; newHeaders &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Headers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
newHeaders&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;X-Frame-Options&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;DENY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
newHeaders&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;X-Content-Type-Options&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;nosniff&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
newHeaders&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Referrer-Policy&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;strict-origin-when-cross-origin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;status&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; newHeaders&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;volgende-stappen-na-deployment&quot;&gt;Volgende Stappen Na Deployment&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Stel analytics in&lt;/strong&gt;: Cloudflare biedt gratis Web Analytics&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configureer een firewall&lt;/strong&gt;: Bescherm tegen bots en aanvallen (gratis tier bevat basis WAF)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Voeg monitoring toe&lt;/strong&gt;: Stel uptime monitoring in met Cloudflare&apos;s &quot;Health Checks&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Optimaliseer afbeeldingen&lt;/strong&gt;: Gebruik Cloudflare Images of Polish voor automatische afbeeldingsoptimalisatie&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Overweeg een CDN-plan&lt;/strong&gt;: Gratis tier is genereus, maar betaalde plannen voegen meer features toe&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;migreren-van-lovable-hosting&quot;&gt;Migreren van Lovable Hosting&lt;/h2&gt;
&lt;p&gt;Als je site momenteel op Lovable wordt gehost en je naar Cloudflare wilt verhuizen:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Exporteer je project&lt;/strong&gt; (zoals hierboven beschreven)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deploy naar Cloudflare&lt;/strong&gt; met een van beide methoden&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Test grondig&lt;/strong&gt; op je &lt;code class=&quot;language-text&quot;&gt;.pages.dev&lt;/code&gt; of &lt;code class=&quot;language-text&quot;&gt;.workers.dev&lt;/code&gt; URL&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Update DNS&lt;/strong&gt; om naar Cloudflare te wijzen (bij gebruik van aangepast domein)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Monitor&lt;/strong&gt; voor problemen in de eerste 24 uur&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Annuleer Lovable hosting&lt;/strong&gt; zodra bevestigd werkend&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;conclusie&quot;&gt;Conclusie&lt;/h2&gt;
&lt;p&gt;Je Lovable-project naar Cloudflare deployen geeft je enterprise-niveau hosting gratis, met wereldwijde prestaties die rivaliseren met betaalde platforms. Of je nu kiest voor Cloudflare Pages voor eenvoud of Cloudflare Workers voor kracht, je krijgt:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sub-50ms responstijden wereldwijd&lt;/li&gt;
&lt;li&gt;Onbeperkte bandbreedte (Pages) of genereuze gratis tier (Workers)&lt;/li&gt;
&lt;li&gt;Automatische HTTPS en SSL&lt;/li&gt;
&lt;li&gt;DDoS-bescherming&lt;/li&gt;
&lt;li&gt;99,99%+ uptime&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Voor de meeste Lovable-projecten raad ik Cloudflare Pages aan&lt;/strong&gt;—het is eenvoudiger, heeft onbeperkte requests en deployt automatisch vanuit Git. Bewaar Workers voor wanneer je echt edge computing of geavanceerde controle nodig hebt.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wil je meer leren over Cloudflare Workers?&lt;/strong&gt; Onze &lt;a href=&quot;/blog/cloudflare-workers-deployment&quot;&gt;Complete Gids voor het Deployen van Statische Sites op Cloudflare Workers&lt;/a&gt; behandelt geavanceerde patronen, prestatieoptimalisatie en productie best practices voorbij de basis.&lt;/p&gt;
&lt;p&gt;Heb je vragen over het deployen van je specifieke Lovable-project naar Cloudflare? Laat een reactie achter en ik help met troubleshooten!&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;veelgestelde-vragen&quot;&gt;Veelgestelde Vragen&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Is migreren van Lovable naar Cloudflare gratis?&lt;/strong&gt;
Ja, migreren van Lovable naar Cloudflare is volledig gratis. Lovable staat gratis project-exports toe en Cloudflare biedt genereuze gratis hosting tiers. Cloudflare Pages biedt onbeperkte sites en requests, terwijl Cloudflare Workers 100.000 requests/dag biedt. Beide bevatten gratis SSL en aangepaste domeinen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hoe verplaats ik mijn Lovable-site naar Cloudflare?&lt;/strong&gt;
Exporteer je Lovable-project als ZIP-bestand, pak het uit, push de code naar GitHub en verbind dan je GitHub repository met Cloudflare Pages. Het hele proces duurt ongeveer 15 minuten en is volledig geautomatiseerd na de initiële setup.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kan ik mijn eigen domein gebruiken met Cloudflare hosting?&lt;/strong&gt;
Ja! Zowel Cloudflare Pages als Workers ondersteunen aangepaste domeinen met gratis SSL-certificaten. Als je domein Cloudflare gebruikt voor DNS, is setup automatisch. Anders moet je een CNAME-record toevoegen bij je domeinregistrar.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wat gebeurt er met mijn Lovable hosting nadat ik migreer?&lt;/strong&gt;
Je oorspronkelijke Lovable-gehoste site blijft werken. Je kunt beide draaiende houden of de Lovable-versie unpublishen zodra migratie voltooid is. Er is geen automatische annulering—je hebt volledige controle.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Werkt Cloudflare met Lovable&apos;s React/Vite-projecten?&lt;/strong&gt;
Absoluut. Lovable genereert standaard React-applicaties met Vite, die Cloudflare volledig ondersteunt. Pages detecteert automatisch Vite-projecten en Workers kan elke statische build-output serveren.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Gerelateerde gidsen:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website&quot;&gt;10 Manieren om Je Lovable-Website te Verplaatsen naar Gratis Hosting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-from-hero-to-zero&quot;&gt;Lovable: Van Held naar Nul met 2.0&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[5 Redis Patronen voor Real-Time Laravel Apps Die Schalen]]></title><description><![CDATA[Na het migreren van Redis naar KeyDB en weer terug terwijl we miljarden aan logistieke transacties verwerkten, heb ik geleerd welke Redis…]]></description><link>https://vibecodingwithfred.com/nl/blog/redis-patterns-laravel-quicktip/</link><guid isPermaLink="false">https://vibecodingwithfred.com/nl/blog/redis-patterns-laravel-quicktip/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Na het migreren van Redis naar KeyDB en weer terug terwijl we miljarden aan logistieke transacties verwerkten, heb ik geleerd welke Redis patronen werken op schaal. Hier zijn 5 beproefde patronen die je vandaag kunt implementeren.&lt;/p&gt;
&lt;h2 id=&quot;1-pipeline-alles-10x-prestatieverbetering&quot;&gt;1. Pipeline Alles (10x Prestatieverbetering)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Slecht Patroon:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Dit creëert 1000 netwerk round trips!&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Productie Patroon:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Eén netwerkaanroep, atomische uitvoering&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Echte Impact:&lt;/strong&gt; Verminderde onze bulk import tijd van 45 seconden naar 4 seconden voor 10k records.&lt;/p&gt;
&lt;h2 id=&quot;2-implementeer-sliding-window-rate-limiting&quot;&gt;2. Implementeer Sliding Window Rate Limiting&lt;/h2&gt;
&lt;p&gt;Vergeet fixed windows die thundering herds veroorzaken. Dit is wat we in productie gebruiken:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;RateLimiter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;attempt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;rate_limit:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;microtime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Verwijder oude entries&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zremrangebyscore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Voeg huidige request toe&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Tel requests in window&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zcard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Stel expiry in&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$results&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Gebruik in middleware&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token class-name static-context&quot;&gt;RateLimiter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;attempt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;api:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Rate limit exceeded&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;429&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Waarom Het Werkt:&lt;/strong&gt; Geen pieken bij window-grenzen, eerlijke verdeling, zelfreinigend.&lt;/p&gt;
&lt;h2 id=&quot;3-cache-invalidatie-met-tags-de-juiste-manier&quot;&gt;3. Cache Invalidatie met Tags (De Juiste Manier)&lt;/h2&gt;
&lt;p&gt;Laravel&apos;s cache tags zijn geweldig totdat je granulaire controle nodig hebt. Dit is ons patroon:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;SmartCache&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;rememberWithDependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Sla de hoofdcache op&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Cache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Volg dependencies in Redis sets&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;86400&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1 dag&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;invalidateTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;smembers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Verwijder alle getagde keys in één pipeline&lt;/span&gt;
            &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;del&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;del&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Gebruik&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$metrics&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;SmartCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rememberWithDependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;dashboard.metrics&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;deliveries&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;customer:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$customerId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 5 minuten&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;calculateExpensiveMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Invalideer alle shipment-gerelateerde caches&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;SmartCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;invalidateTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Productie Winst:&lt;/strong&gt; Verminderde cache misses met 73% en elimineerde cascaderende invalidaties.&lt;/p&gt;
&lt;h2 id=&quot;4-gedistribueerde-locks-die-niet-deadlocken&quot;&gt;4. Gedistribueerde Locks Die Niet Deadlocken&lt;/h2&gt;
&lt;p&gt;Na het verliezen van $50k door een race condition, implementeerden we dit kogelvrije locking:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;DistributedLock&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;lock:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniqid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;gethostname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Atomische set if not exists met expiry&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$acquired&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;NX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Alleen zetten als niet bestaat&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;EX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Verloopt na X seconden&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$acquired&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Controleer of lock stale is (backup mechanisme)&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockHolder&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lockHolder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Lock verlopen tussen commando&apos;s, probeer opnieuw&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;lock:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Lua script voor atomische check en delete&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;
            if redis.call(&apos;get&apos;, KEYS[1]) == ARGV[1] then
                return redis.call(&apos;del&apos;, KEYS[1])
            else
                return 0
            end
        &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;withLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LockTimeoutException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Could not acquire lock for &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;finally&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Gebruik voor betalingsverwerking&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;DistributedLock&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;withLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;payment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Verwerk betaling veilig&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isPaid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Idempotente check&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;processPayment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;markAsPaid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Kritiek:&lt;/strong&gt; Het Lua script zorgt ervoor dat we alleen ONZE lock vrijgeven, waardoor we voorkomen dat we per ongeluk iemand anders&apos; lock vrijgeven.&lt;/p&gt;
&lt;h2 id=&quot;5-real-time-metrics-met-hyperloglog&quot;&gt;5. Real-Time Metrics met HyperLogLog&lt;/h2&gt;
&lt;p&gt;Volg unieke bezoekers/events zonder geheugenexplosie:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;MetricsTracker&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;metric:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// HyperLogLog voegt unieke items toe met O(1) ruimte&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Bewaar 2 windows&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getCardinality&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windows&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windows&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;metric:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Merge meerdere HyperLogLogs&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;trackAndBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Volg uniek event&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;event:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:users&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Volg per-minuut rate&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;event:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:rate&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniqid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Broadcast als drempel bereikt&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;broadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HighTrafficAlert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Gebruik&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$uniqueVisitors&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;page.visits&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$dailyActive&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCardinality&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user.active&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Volg API-gebruik zonder geheugenproblemen&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackAndBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;api.call&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Geheugenbesparing:&lt;/strong&gt; Het volgen van 10M unieke gebruikers kost ~12KB in plaats van 40MB met traditionele sets.&lt;/p&gt;
&lt;h2 id=&quot;bonus-redis-geheugenoptimalisatie-checklist&quot;&gt;Bonus: Redis Geheugenoptimalisatie Checklist&lt;/h2&gt;
&lt;p&gt;Uit ons productie playbook:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 1. Gebruik compressie voor grote waarden&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;large:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;gzcompress&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 2. Gebruik hashes voor kleine objecten (90% geheugenbesparing!)&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;user:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;name&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;email&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;status&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 3. Stel agressieve expiries in&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 5 min standaard, niet 1 uur&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 4. Gebruik SCAN in plaats van KEYS&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scan&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;MATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipment:*&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;COUNT&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Verwerk $keys&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 5. Monitor geheugengebruik&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1073741824&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1GB&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Redis memory critical: &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory_human&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;de-dure-lessen&quot;&gt;De Dure Lessen&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Altijd expiries instellen&lt;/strong&gt; - Eén ontbrekende TTL consumeerde 8GB RAM&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pipeline of perish&lt;/strong&gt; - Netwerklatentie stapelt snel op&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gebruik de juiste datastructuur&lt;/strong&gt; - HyperLogLog bespaarde ons $2k/maand aan geheugen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lock correct&lt;/strong&gt; - Race conditions in financiële systemen = rechtszaken&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Monitor alles&lt;/strong&gt; - Je kunt niet fixen wat je niet meet&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Deze patronen verwerken 50k requests/seconde in productie. Begin met pipelines en correct locken—ze lossen 80% van je Redis prestatieproblemen op.&lt;/p&gt;
&lt;h2 id=&quot;beheers-laravel-met-echte-projecten&quot;&gt;Beheers Laravel met Echte Projecten&lt;/h2&gt;
&lt;p&gt;Wil je deze Redis patronen implementeren in een echte applicatie? Bouw productie-klare Laravel projecten vanaf nul:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-laravel/&quot;&gt;Bouw een Blog met Laravel&lt;/a&gt;&lt;/strong&gt; - Beheers Eloquent, authenticatie en CRUD operaties met Redis caching&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;Bouw een Portfolio met Laravel&lt;/a&gt;&lt;/strong&gt; - Leer bestandsuploads, relaties en Redis-powered sessies&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-laravel/&quot;&gt;Bouw E-Commerce met Laravel&lt;/a&gt;&lt;/strong&gt; - Geavanceerde patronen inclusief queues, event handling en gedistribueerde locks&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Elke tutorial bevat AI-geassisteerde prompts om je te begeleiden bij het bouwen van schaalbare applicaties die Redis effectief gebruiken.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Vragen over het implementeren van deze patronen? Laat een reactie achter - ik heb dat probleem waarschijnlijk al om 3 uur &apos;s nachts gedebugd.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Zbuduj dashboard logistyczny w czasie rzeczywistym z Laravel, WebSockets i Vue]]></title><description><![CDATA[Czy kiedykolwiek zastanawiales sie jak firmy sledza tysiace przesylek w czasie rzeczywistym? Albo jak platformy tradingowe aktualizuja ceny…]]></description><link>https://vibecodingwithfred.com/pl/blog/laravel-realtime-dashboard/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pl/blog/laravel-realtime-dashboard/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Czy kiedykolwiek zastanawiales sie jak firmy sledza tysiace przesylek w czasie rzeczywistym? Albo jak platformy tradingowe aktualizuja ceny natychmiast na tysiacach ekranow? Budowalem te systemy w skali, przetwarzajac ponad 2 miliardy dolarow rocznych transakcji. Dzisiaj pokaze ci dokladnie jak zbudowac gotowy do produkcji dashboard w czasie rzeczywistym uzywajac Laravel, WebSockets i Vue.js.&lt;/p&gt;
&lt;p&gt;To nie jest teoria - to sprawdzone w boju wzory z rzeczywistych systemow produkcyjnych obslugujacych operacje logistyczne 24/7.&lt;/p&gt;
&lt;h2 id=&quot;co-budujemy&quot;&gt;Co budujemy&lt;/h2&gt;
&lt;p&gt;Stworzymy dashboard logistyczny w czasie rzeczywistym ktory:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sledzi lokalizacje przesylek z aktualizacjami na zywo&lt;/li&gt;
&lt;li&gt;Pokazuje metryki w czasie rzeczywistym (dostawy, przychod, wydajnosc)&lt;/li&gt;
&lt;li&gt;Implementuje system blokad zeby zapobiec konfliktowym edycjom&lt;/li&gt;
&lt;li&gt;Obsluguje tysiace jednoczesnych polaczen&lt;/li&gt;
&lt;li&gt;Skaluje sie horyzontalnie z Redis pub/sub&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Oto jak wyglada finalny dashboard:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wielu uzytkownikow widzi aktualizacje natychmiast&lt;/li&gt;
&lt;li&gt;Statusy przesylek zmieniaja sie w czasie rzeczywistym&lt;/li&gt;
&lt;li&gt;Metryki aktualizuja sie bez odswiezania strony&lt;/li&gt;
&lt;li&gt;Blokady edycji zapobiegaja konfliktom danych&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;wymagania-wstepne&quot;&gt;Wymagania wstepne&lt;/h2&gt;
&lt;p&gt;Bedziesz potrzebowal:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PHP 8.1+ z Laravel 10+&lt;/li&gt;
&lt;li&gt;Node.js 18+ dla Vue 3&lt;/li&gt;
&lt;li&gt;Redis (lub KeyDB dla lepszej wydajnosci)&lt;/li&gt;
&lt;li&gt;Podstawowa znajomosc Laravel i Vue&lt;/li&gt;
&lt;li&gt;Zainstalowane Composer i npm&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;czesc-1-konfiguracja-backendu-laravel&quot;&gt;Czesc 1: Konfiguracja backendu Laravel&lt;/h2&gt;
&lt;h3 id=&quot;krok-1-utworz-projekt-laravel&quot;&gt;Krok 1: Utworz projekt Laravel&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;composer&lt;/span&gt; create-project laravel/laravel realtime-logistics
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; realtime-logistics

&lt;span class=&quot;token comment&quot;&gt;# Zainstaluj zaleznosci broadcasting i WebSocket&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;composer&lt;/span&gt; require pusher/pusher-php-server
&lt;span class=&quot;token function&quot;&gt;composer&lt;/span&gt; require predis/predis

&lt;span class=&quot;token comment&quot;&gt;# Zainstaluj pakiet Laravel WebSockets (samodzielna alternatywa dla Pusher)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;composer&lt;/span&gt; require beyondcode/laravel-websockets&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;krok-2-skonfiguruj-broadcasting&quot;&gt;Krok 2: Skonfiguruj Broadcasting&lt;/h3&gt;
&lt;p&gt;Zaktualizuj plik &lt;code class=&quot;language-text&quot;&gt;.env&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;env&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-env line-numbers&quot;&gt;&lt;code class=&quot;language-env&quot;&gt;BROADCAST_DRIVER=pusher
CACHE_DRIVER=redis
QUEUE_CONNECTION=redis
SESSION_DRIVER=redis

# Uzyj Laravel WebSockets jako zamiennika Pusher
PUSHER_APP_ID=local-app
PUSHER_APP_KEY=local-key
PUSHER_APP_SECRET=local-secret
PUSHER_HOST=127.0.0.1
PUSHER_PORT=6001
PUSHER_SCHEME=http
PUSHER_APP_CLUSTER=mt1

# Konfiguracja Redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;krok-3-schemat-bazy-danych&quot;&gt;Krok 3: Schemat bazy danych&lt;/h3&gt;
&lt;p&gt;Utworz migracje dla naszego systemu logistycznego:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;php artisan make:migration create_shipments_table
php artisan make:migration create_metrics_table
php artisan make:migration create_edit_locks_table&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// database/migrations/create_shipments_table.php&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Schema&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;Blueprint&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token keyword type-declaration&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;tracking_number&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token keyword type-declaration&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;origin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token keyword type-declaration&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;destination&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;enum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;pending&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;in_transit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;delivered&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;exception&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decimal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;nullable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decimal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;nullable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decimal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metadata&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;nullable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;timestamps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;created_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Optymalizacja dla zapytan dashboardu&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Zapytania przestrzenne&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// database/migrations/create_metrics_table.php&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Schema&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metrics&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;Blueprint&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token keyword type-declaration&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;key&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decimal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token keyword type-declaration&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;unit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;nullable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;calculated_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;timestamps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;calculated_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// database/migrations/create_edit_locks_table.php&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Schema&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;edit_locks&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;Blueprint&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;morphs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;lockable&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Polimorficzne - moze blokowac dowolny model&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unsignedBigInteger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;locked_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;lockable_type&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;lockable_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;krok-4-utworz-modele&quot;&gt;Krok 4: Utworz modele&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// app/Models/Shipment.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Models&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Database&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Eloquent&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Model&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Database&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Eloquent&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Factories&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;HasFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Traits&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Lockable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Events&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;ShipmentUpdated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;Shipment&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Model&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;HasFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Lockable&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$fillable&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;tracking_number&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;origin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;destination&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metadata&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$casts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;metadata&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;array&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;decimal:2&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;decimal:7&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;decimal:7&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$dispatchesEvents&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;updated&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;ShipmentUpdated&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Optymalizacja swiata rzeczywistego: Cache&apos;uj czesto odwiedzane przesylki&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;findByTrackingCached&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$trackingNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Cache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment.&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$trackingNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addMinutes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;tracking_number&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$trackingNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Zapytanie geoprzestrzenne dla poblizkich przesylek&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;scopeNearby&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lng&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$radiusKm&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Wzor Haversine do obliczania odleglosci&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$haversine&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;(
            6371 * acos(
                cos(radians(?)) * cos(radians(latitude)) *
                cos(radians(longitude) - radians(?)) +
                sin(radians(?)) * sin(radians(latitude))
            )
        )&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$query&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;selectRaw&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;*, &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$haversine&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; AS distance&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lng&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;having&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;distance&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&amp;lt;=&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$radiusKm&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;orderBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;distance&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;krok-5-zaimplementuj-trait-lockable&quot;&gt;Krok 5: Zaimplementuj trait Lockable&lt;/h3&gt;
&lt;p&gt;To zapobiega konfliktowym edycjom - kluczowe dla danych finansowych:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// app/Traits/Lockable.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Traits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Models&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;EditLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Support&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Facades&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Auth&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Carbon&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Carbon&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;Lockable&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;morphMany&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name static-context&quot;&gt;EditLock&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;lockable&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;acquireLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$duration&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Auth&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Sprawdz istniejace wazne blokady&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$existingLock&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;!=&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$existingLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Ktos inny ma blokade&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Wyczysc wygasle blokady&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&amp;lt;=&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Utworz nowa blokade&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user_id&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;locked_at&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addSeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$duration&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;releaseLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Auth&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;isLocked&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$excludeUserId&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$query&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$excludeUserId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user_id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;!=&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$excludeUserId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;currentLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;locks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;expires_at&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;krok-6-utworz-eventy-broadcastingu&quot;&gt;Krok 6: Utworz eventy broadcastingu&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// app/Events/ShipmentUpdated.php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Events&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Models&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Broadcasting&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Channel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Broadcasting&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;InteractsWithSockets&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Contracts&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Broadcasting&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;ShouldBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Foundation&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Events&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Dispatchable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;Queue&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;SerializesModels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;ShipmentUpdated&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ShouldBroadcast&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Dispatchable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; InteractsWithSockets&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; SerializesModels&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name type-declaration&quot;&gt;Shipment&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;broadcastOn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Channel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Channel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment.&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;broadcastWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;id&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;tracking_number&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;tracking_number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;latitude&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;latitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;longitude&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;longitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;value&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;updated_at&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;updated_at&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toIso8601String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Optymalizacja wydajnosci: Uzyj kolejki do broadcastingu&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;broadcastQueue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;broadcasts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ten artykul jest obszerny i zawiera pelna implementacje dashboardu w czasie rzeczywistym. Pelna wersja w jezyku angielskim zawiera:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kompletna implementacje Vue.js frontendu z aktualizacjami w czasie rzeczywistym&lt;/li&gt;
&lt;li&gt;Konfiguracje Pinia stores&lt;/li&gt;
&lt;li&gt;Optymalizacje Redis i skalowanie&lt;/li&gt;
&lt;li&gt;Konfiguracje kolejek dla wysokiej przepustowosci&lt;/li&gt;
&lt;li&gt;Wdrozenie produkcyjne z Supervisor&lt;/li&gt;
&lt;li&gt;Optymalizacje Redis&lt;/li&gt;
&lt;li&gt;Konfiguracje Nginx dla WebSockets&lt;/li&gt;
&lt;li&gt;Wskazowki i spostrzezenia produkcyjne&lt;/li&gt;
&lt;li&gt;Strategie skalowania&lt;/li&gt;
&lt;li&gt;Monitorowanie i debugowanie&lt;/li&gt;
&lt;li&gt;Testowanie systemu&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;podsumowanie&quot;&gt;Podsumowanie&lt;/h2&gt;
&lt;p&gt;Ten wzor dashboardu w czasie rzeczywistym sprawdzil sie w produkcji, obslugujac miliony aktualizacji dziennie. Kombinacja eleganckiego backendu Laravel, reaktywnego frontendu Vue i blyskawiocznego Redis pub/sub tworzy system ktory jest zarowno wydajny jak i latwy w utrzymaniu.&lt;/p&gt;
&lt;p&gt;Kluczowe wnioski:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Projektuj pod skale od pierwszego dnia&lt;/strong&gt; - Trudniej refaktoryzowac pozniej&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Oddziel odpowiedzialnosci&lt;/strong&gt; - Broadcasty, kolejki i wywolania API powinny uzywac roznych kanalow&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Monitoruj wszystko&lt;/strong&gt; - Nie mozesz optymalizowac czegos czego nie mierzysz&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Testuj z realistycznymi danymi&lt;/strong&gt; - 10 rekordow testowych nie ujawni problemow wydajnosciowych&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Wzory pokazane tutaj nie sa tylko teoretyczne - dzialaja w produkcji wlasnie teraz, sledzac prawdziwe przesylki warte prawdziwe pieniadze.&lt;/p&gt;
&lt;h3 id=&quot;opanuj-najpierw-podstawy-laravel&quot;&gt;Opanuj najpierw podstawy Laravel&lt;/h3&gt;
&lt;p&gt;Budowanie dashboardow w czasie rzeczywistym wymaga solidnej znajomosci Laravel. Jesli jestes nowy w Laravel, zacznij od tych kompleksowych samouczkow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-laravel/&quot;&gt;Zbuduj bloga z Laravel&lt;/a&gt;&lt;/strong&gt; - Naucz sie Eloquent, uwierzytelniania i operacji CRUD&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;Zbuduj portfolio z Laravel&lt;/a&gt;&lt;/strong&gt; - Opanuj przesylanie plikow, relacje i panele administracyjne&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-laravel/&quot;&gt;Zbuduj e-commerce z Laravel&lt;/a&gt;&lt;/strong&gt; - Zaawansowane wzory wlaczajac kolejki i obsluge zdarzen&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Kazdy samouczek zawiera prompty wspomagane przez AI ktore przeprowadza cie przez budowanie gotowych do produkcji aplikacji od zera.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Masz pytania o implementacje tego w twoim stacku? Zostaw komentarz - prawdopodobnie stalem przed (i rozwiazalem) ten sam problem w produkcji.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Jak dzialaja kredyty Lovable: Kompletny przewodnik cenowy 2025]]></title><description><![CDATA[Kompletny przewodnik po systemie kredytow Lovable: poziomy cenowe, co zuzywa kredyty, strategie optymalizacji, polityka zwrotow i FAQ.]]></description><link>https://vibecodingwithfred.com/pl/blog/lovable-credits-complete-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pl/blog/lovable-credits-complete-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;czym-sa-kredyty-lovable&quot;&gt;Czym sa kredyty Lovable?&lt;/h2&gt;
&lt;p&gt;Kredyty Lovable to waluta platformy dla funkcji rozwojowych zasilanych AI. Pomysl o nich jak o zetonach w salonie gier - potrzebujesz kredytow zeby uzywac AI Lovable do generowania kodu, tworzenia komponentow lub modyfikowania projektow.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kluczowe punkty:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 kredyt = okolo 1 interakcji AI (zalezy od zlozonosci)&lt;/li&gt;
&lt;li&gt;Kredyty nie wygasaja w ramach okresu rozliczeniowego&lt;/li&gt;
&lt;li&gt;Niewykorzystane kredyty moga lub nie przenosic sie (zalezy od planu)&lt;/li&gt;
&lt;li&gt;Mozesz kupic dodatkowe kredyty w trakcie cyklu&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;jak-dzialaja-kredyty&quot;&gt;Jak dzialaja kredyty&lt;/h2&gt;
&lt;h3 id=&quot;stawki-zuzycia-kredytow&quot;&gt;Stawki zuzycia kredytow&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Akcja&lt;/th&gt;
&lt;th&gt;Uzyte kredyty&lt;/th&gt;
&lt;th&gt;Przyklad&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Prosta generacja komponentu&lt;/td&gt;
&lt;td&gt;1-2 kredyty&lt;/td&gt;
&lt;td&gt;Przycisk, pole formularza&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tworzenie zlozonego komponentu&lt;/td&gt;
&lt;td&gt;3-5 kredytow&lt;/td&gt;
&lt;td&gt;Tabela danych, wykres&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generacja pelnej strony&lt;/td&gt;
&lt;td&gt;5-10 kredytow&lt;/td&gt;
&lt;td&gt;Landing page, dashboard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Naprawianie bledow/debugowanie&lt;/td&gt;
&lt;td&gt;1-3 kredyty&lt;/td&gt;
&lt;td&gt;Rozwiazywanie bledow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Refaktoryzacja kodu&lt;/td&gt;
&lt;td&gt;2-4 kredyty&lt;/td&gt;
&lt;td&gt;Optymalizacja wydajnosci&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;podzial-poziomow-cenowych&quot;&gt;Podzial poziomow cenowych&lt;/h2&gt;
&lt;h3 id=&quot;darmowy-tier&quot;&gt;Darmowy tier&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Kredyty:&lt;/strong&gt; 100/miesiac&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cena:&lt;/strong&gt; 0$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Najlepszy dla:&lt;/strong&gt; Testowanie platformy, male prototypy&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;plan-starter&quot;&gt;Plan Starter&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Kredyty:&lt;/strong&gt; 500/miesiac&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cena:&lt;/strong&gt; 20$/miesiac&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Najlepszy dla:&lt;/strong&gt; Projekty poboczne, MVP&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;plan-pro&quot;&gt;Plan Pro&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Kredyty:&lt;/strong&gt; 2000/miesiac&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cena:&lt;/strong&gt; 70$/miesiac&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Najlepszy dla:&lt;/strong&gt; Aktywny rozwoj, male zespoly&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;plan-business&quot;&gt;Plan Business&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Kredyty:&lt;/strong&gt; 10000/miesiac&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cena:&lt;/strong&gt; 299$/miesiac&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Najlepszy dla:&lt;/strong&gt; Agencje, rosnace startupy&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;co-zuzywa-kredyty&quot;&gt;Co zuzywa kredyty&lt;/h2&gt;
&lt;h3 id=&quot;wysokie-zuzycie-kredytow-5&quot;&gt;Wysokie zuzycie kredytow (5+)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Generowanie calych stron od zera&lt;/li&gt;
&lt;li&gt;Zlozone komponenty UI z wieloma stanami&lt;/li&gt;
&lt;li&gt;Generowanie schematu bazy danych&lt;/li&gt;
&lt;li&gt;Konfiguracja systemu uwierzytelniania&lt;/li&gt;
&lt;li&gt;Integracja platnosci&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;srednie-zuzycie-kredytow-2-4&quot;&gt;Srednie zuzycie kredytow (2-4)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Tworzenie niestandardowych komponentow&lt;/li&gt;
&lt;li&gt;Modyfikowanie istniejacych komponentow&lt;/li&gt;
&lt;li&gt;Dodawanie endpointow API&lt;/li&gt;
&lt;li&gt;Implementacja logiki biznesowej&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;niskie-zuzycie-kredytow-1-kredyt&quot;&gt;Niskie zuzycie kredytow (1 kredyt)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Proste zmiany tekstu&lt;/li&gt;
&lt;li&gt;Korekty CSS&lt;/li&gt;
&lt;li&gt;Dodawanie podstawowych elementow HTML&lt;/li&gt;
&lt;li&gt;Drobne poprawki bledow&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;bez-zuzycia-kredytow&quot;&gt;Bez zuzycia kredytow&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Przegladanie projektu&lt;/li&gt;
&lt;li&gt;Reczna edycja kodu&lt;/li&gt;
&lt;li&gt;Wdrazanie (uzywa oddzielnych kredytow)&lt;/li&gt;
&lt;li&gt;Pobieranie/eksport kodu&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;wskazowki-optymalizacji-kredytow&quot;&gt;Wskazowki optymalizacji kredytow&lt;/h2&gt;
&lt;h3 id=&quot;1-badz-konkretny-w-promptach&quot;&gt;1. Badz konkretny w promptach&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Zle:&lt;/strong&gt; &quot;Zrob formularz&quot;
&lt;strong&gt;Dobrze:&lt;/strong&gt; &quot;Utworz formularz kontaktowy z polami imie, email, wiadomosc, walidacja i przyciskiem wyslij stylizowanym Tailwind CSS&quot;&lt;/p&gt;
&lt;p&gt;Bycie konkretnym redukuje iteracje tam i z powrotem, oszczedzajac kredyty.&lt;/p&gt;
&lt;h3 id=&quot;2-uzywaj-recznej-edycji-gdy-to-mozliwe&quot;&gt;2. Uzywaj recznej edycji gdy to mozliwe&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Male poprawki CSS? Edytuj recznie&lt;/li&gt;
&lt;li&gt;Poprawki literowek? Nie marnuj kredytow&lt;/li&gt;
&lt;li&gt;Proste dodatki HTML? Zrob sam&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3-grupuj-zadania&quot;&gt;3. Grupuj zadania&lt;/h3&gt;
&lt;p&gt;Zamiast wielu malych zadan:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;X &quot;Dodaj naglowek&quot;
X &quot;Teraz dodaj stopke&quot;
X &quot;Dodaj pasek boczny&quot;

OK &quot;Dodaj naglowek z logo i nawigacja, stopke z linkami i lewy pasek boczny z elementami menu&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-wykorzystuj-szablony&quot;&gt;4. Wykorzystuj szablony&lt;/h3&gt;
&lt;p&gt;Zacznij od szablonow Lovable zeby zmniejszyc poczatkowe kredyty generacji.&lt;/p&gt;
&lt;h3 id=&quot;5-planuj-przed-budowaniem&quot;&gt;5. Planuj przed budowaniem&lt;/h3&gt;
&lt;p&gt;Naszkicuj wymagania najpierw. Losowe eksperymentowanie szybko pali kredyty.&lt;/p&gt;
&lt;h2 id=&quot;polityka-zwrotow&quot;&gt;Polityka zwrotow&lt;/h2&gt;
&lt;h3 id=&quot;kiedy-zwroty-sa-dostepne&quot;&gt;Kiedy zwroty sa dostepne&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Problemy techniczne uniemozliwiajace uzycie kredytow&lt;/li&gt;
&lt;li&gt;Bledy rozliczeniowe&lt;/li&gt;
&lt;li&gt;W ciagu 14 dni od zakupu (nowi klienci)&lt;/li&gt;
&lt;li&gt;Niewykorzystane pakiety kredytow&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;kiedy-zwroty-nie-sa-dostepne&quot;&gt;Kiedy zwroty NIE sa dostepne&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Kredyty juz zuzyte&lt;/li&gt;
&lt;li&gt;Po 14-dniowym okresie&lt;/li&gt;
&lt;li&gt;Odnowienia subskrypcji (po pierwszym miesiacu)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;czesto-zadawane-pytania&quot;&gt;Czesto zadawane pytania&lt;/h2&gt;
&lt;h3 id=&quot;czy-kredyty-przechodza-na-nastepny-miesiac&quot;&gt;Czy kredyty przechodza na nastepny miesiac?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Darmowy/Starter:&lt;/strong&gt; Bez przenoszenia
&lt;strong&gt;Pro/Business:&lt;/strong&gt; Do 20% przenoszenia
&lt;strong&gt;Enterprise:&lt;/strong&gt; Do negocjacji&lt;/p&gt;
&lt;h3 id=&quot;czy-moge-kupic-dodatkowe-kredyty&quot;&gt;Czy moge kupic dodatkowe kredyty?&lt;/h3&gt;
&lt;p&gt;Tak! Dodatkowe pakiety kredytow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;100 kredytow: 5$&lt;/li&gt;
&lt;li&gt;500 kredytow: 20$&lt;/li&gt;
&lt;li&gt;1000 kredytow: 35$&lt;/li&gt;
&lt;li&gt;5000 kredytow: 150$&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;co-sie-dzieje-gdy-skonczy-mi-sie-kredyty&quot;&gt;Co sie dzieje gdy skonczy mi sie kredyty?&lt;/h3&gt;
&lt;p&gt;Twoj projekt pozostaje dostepny, ale nie mozesz:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generowac nowego kodu&lt;/li&gt;
&lt;li&gt;Modyfikowac za pomoca AI&lt;/li&gt;
&lt;li&gt;Uzywac funkcji AI&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mozesz nadal:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Edytowac kod recznie&lt;/li&gt;
&lt;li&gt;Wdrazac istniejacy kod&lt;/li&gt;
&lt;li&gt;Eksportowac projekt&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;czy-kredyty-wygasaja&quot;&gt;Czy kredyty wygasaja?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Miesieczne kredyty: Wygasaja na koniec cyklu rozliczeniowego&lt;/li&gt;
&lt;li&gt;Zakupione kredyty: Wygasaja po 90 dniach&lt;/li&gt;
&lt;li&gt;Kredyty promocyjne: Sprawdz warunki (zwykle 30 dni)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;kalkulator-kredytow&quot;&gt;Kalkulator kredytow&lt;/h2&gt;
&lt;h3 id=&quot;oszacuj-miesieczne-potrzeby&quot;&gt;Oszacuj miesieczne potrzeby&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Maly projekt (Landing Page):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Poczatkowa generacja: 10 kredytow&lt;/li&gt;
&lt;li&gt;Rewizje: 20 kredytow&lt;/li&gt;
&lt;li&gt;Dopracowanie: 10 kredytow&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lacznie: ~40 kredytow&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Sredni projekt (SaaS MVP):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Strony (5): 50 kredytow&lt;/li&gt;
&lt;li&gt;Komponenty: 30 kredytow&lt;/li&gt;
&lt;li&gt;API/Baza danych: 40 kredytow&lt;/li&gt;
&lt;li&gt;Rewizje: 80 kredytow&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lacznie: ~200 kredytow&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Duzy projekt (Pelna aplikacja):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Strony (20+): 200 kredytow&lt;/li&gt;
&lt;li&gt;Zlozone funkcje: 150 kredytow&lt;/li&gt;
&lt;li&gt;Integracje: 100 kredytow&lt;/li&gt;
&lt;li&gt;Testowanie/Debugowanie: 150 kredytow&lt;/li&gt;
&lt;li&gt;Iteracje: 200 kredytow&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lacznie: ~800 kredytow&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;typowe-bledy-z-kredytami-do-unikania&quot;&gt;Typowe bledy z kredytami do unikania&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Niejasne prompty&lt;/strong&gt; - Marnuje kredyty na iteracje&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nieuzywanie recznej edycji&lt;/strong&gt; - Pali kredyty na proste poprawki&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Brak planowania&lt;/strong&gt; - Losowe eksperymentowanie jest drogie&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ignorowanie szablonow&lt;/strong&gt; - Zaczynanie od zera kosztuje wiecej&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Niemonitorowanie zuzycia&lt;/strong&gt; - Niespodzianka gdy skonczy sie kredyty&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;podsumowanie&quot;&gt;Podsumowanie&lt;/h2&gt;
&lt;p&gt;Zrozumienie jak dzialaja kredyty Lovable jest kluczowe dla efektywnego rozwoju i zarzadzania budzetem. Kluczem jest:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wybrac odpowiedni poziom cenowy&lt;/li&gt;
&lt;li&gt;Optymalizowac zuzycie kredytow&lt;/li&gt;
&lt;li&gt;Uzywac recznej edycji do prostych zadan&lt;/li&gt;
&lt;li&gt;Planowac przed budowaniem&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dzieki tym strategiom mozesz budowac imponujace aplikacje bez niepotrzebnego przepalania kredytow.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[5 wzorow Redis dla aplikacji Laravel w czasie rzeczywistym ktore skaluja sie]]></title><description><![CDATA[Po migracji z Redis do KeyDB i z powrotem podczas przetwarzania miliardow w transakcjach logistycznych, nauczylem sie ktore wzory Redis…]]></description><link>https://vibecodingwithfred.com/pl/blog/redis-patterns-laravel-quicktip/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pl/blog/redis-patterns-laravel-quicktip/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Po migracji z Redis do KeyDB i z powrotem podczas przetwarzania miliardow w transakcjach logistycznych, nauczylem sie ktore wzory Redis dzialaja w skali. Oto 5 sprawdzonych w boju wzorow ktore mozesz wdrozyc dzisiaj.&lt;/p&gt;
&lt;h2 id=&quot;1-pipeline-wszystko-10x-wzrost-wydajnosci&quot;&gt;1. Pipeline wszystko (10x wzrost wydajnosci)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Zly wzor:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// To tworzy 1000 polaczen sieciowych!&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Wzor produkcyjny:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Jedno polaczenie sieciowe, atomowe wykonanie&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Rzeczywisty wplyw:&lt;/strong&gt; Zredukowalismy czas masowego importu z 45 sekund do 4 sekund dla 10k rekordow.&lt;/p&gt;
&lt;h2 id=&quot;2-implementuj-ograniczanie-predkosci-z-oknem-przesuwnym&quot;&gt;2. Implementuj ograniczanie predkosci z oknem przesuwnym&lt;/h2&gt;
&lt;p&gt;Zapomnij o stalych oknach ktore powoduja lawinowe obciazenia. Oto czego uzywamy w produkcji:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;RateLimiter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;attempt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;rate_limit:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;microtime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Usun stare wpisy&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zremrangebyscore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Dodaj aktualne zadanie&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Policz zadania w oknie&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zcard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Ustaw wygasniecie&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$results&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Uzycie w middleware&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token class-name static-context&quot;&gt;RateLimiter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;attempt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;api:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Rate limit exceeded&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;429&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Dlaczego to dziala:&lt;/strong&gt; Brak skokow na granicach okien, sprawiedliwa dystrybucja, samoczyszczenie.&lt;/p&gt;
&lt;h2 id=&quot;3-uniewaznanie-cache-z-tagami-wlasciwy-sposob&quot;&gt;3. Uniewaznanie cache z tagami (Wlasciwy sposob)&lt;/h2&gt;
&lt;p&gt;Tagi cache Laravel sa swietne dopoki nie potrzebujesz szczegolowej kontroli. Oto nasz wzor:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;SmartCache&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;rememberWithDependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Zapisz glowny cache&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Cache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Sledz zaleznosci w Redis sets&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;86400&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1 dzien&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;invalidateTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;smembers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Usun wszystkie otagowane klucze w jednym pipeline&lt;/span&gt;
            &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;del&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;del&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Uzycie&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$metrics&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;SmartCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rememberWithDependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;dashboard.metrics&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;deliveries&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;customer:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$customerId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 5 minut&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;calculateExpensiveMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Uniewaznic wszystkie cache zwiazane z przesylkami&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;SmartCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;invalidateTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Zysk produkcyjny:&lt;/strong&gt; Zredukowalismy brakujace trafienia cache o 73% i wyeliminowalismy kaskadowe uniewaznenia.&lt;/p&gt;
&lt;h2 id=&quot;4-blokady-rozproszone-ktore-nie-deadlockuja&quot;&gt;4. Blokady rozproszone ktore nie deadlockuja&lt;/h2&gt;
&lt;p&gt;Po stracie 50 tysiecy dolarow przez race condition, wdrozylismy te kuloodporne blokady:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;DistributedLock&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;lock:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniqid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;gethostname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Atomowe ustawienie jesli nie istnieje z wygasaniem&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$acquired&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;NX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Tylko ustaw jesli nie istnieje&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;EX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Wygasa po X sekundach&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$acquired&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Sprawdz czy blokada jest przestarzala (mechanizm zapasowy)&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockHolder&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lockHolder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Blokada wygasla miedzy poleceniami, sprobuj ponownie&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;lock:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Skrypt Lua dla atomowego sprawdzenia i usuniecia&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;
            if redis.call(&apos;get&apos;, KEYS[1]) == ARGV[1] then
                return redis.call(&apos;del&apos;, KEYS[1])
            else
                return 0
            end
        &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;withLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LockTimeoutException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Could not acquire lock for &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;finally&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Uzycie do przetwarzania platnosci&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;DistributedLock&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;withLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;payment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Przetwarzaj platnosc bezpiecznie&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isPaid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Idempotentne sprawdzenie&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;processPayment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;markAsPaid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Krytyczne:&lt;/strong&gt; Skrypt Lua zapewnia ze zwalniamy tylko NASZA blokade, zapobiegajac przypadkowemu zwolnieniu blokady kogos innego.&lt;/p&gt;
&lt;h2 id=&quot;5-metryki-w-czasie-rzeczywistym-z-hyperloglog&quot;&gt;5. Metryki w czasie rzeczywistym z HyperLogLog&lt;/h2&gt;
&lt;p&gt;Sledz unikalnych odwiedzajacych/zdarzenia bez wybuchu pamieci:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;MetricsTracker&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;metric:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// HyperLogLog dodaje unikalne elementy z przestrzenia O(1)&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Zachowaj 2 okna&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getCardinality&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windows&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windows&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;metric:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Polacz wiele HyperLogLog&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;trackAndBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Sledz unikalne zdarzenie&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;event:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:users&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Sledz czestotliwosc na minute&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;event:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:rate&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniqid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Rozglos jesli przekroczono prog&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;broadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HighTrafficAlert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Uzycie&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$uniqueVisitors&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;page.visits&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$dailyActive&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCardinality&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user.active&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Sledz uzycie API bez problemow z pamiecia&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackAndBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;api.call&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Oszczednosci pamieci:&lt;/strong&gt; Sledzenie 10M unikalnych uzytkownikow zajmuje ~12KB zamiast 40MB z tradycyjnymi setami.&lt;/p&gt;
&lt;h2 id=&quot;bonus-lista-kontrolna-optymalizacji-pamieci-redis&quot;&gt;Bonus: Lista kontrolna optymalizacji pamieci Redis&lt;/h2&gt;
&lt;p&gt;Z naszego podrecznika produkcyjnego:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 1. Uzyj kompresji dla duzych wartosci&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;large:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;gzcompress&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 2. Uzyj hashow dla malych obiektow (90% oszczednosci pamieci!)&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;user:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;name&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;email&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;status&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 3. Ustaw agresywne wygasanie&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 5 min domyslnie, nie 1 godzina&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 4. Uzyj SCAN zamiast KEYS&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scan&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;MATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipment:*&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;COUNT&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Przetwarzaj $keys&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 5. Monitoruj uzycie pamieci&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1073741824&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1GB&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Redis memory critical: &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory_human&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;drogie-lekcje&quot;&gt;Drogie lekcje&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Zawsze ustawiaj wygasanie&lt;/strong&gt; - Jeden brakujacy TTL skonsumowa 8GB RAM&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pipeline albo przepadnij&lt;/strong&gt; - Opoznienie sieci sumuje sie szybko&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Uzyj wlasciwej struktury danych&lt;/strong&gt; - HyperLogLog oszczedzil nam 2 tys. dolarow miesiecznie na pamieci&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Blokuj prawidlowo&lt;/strong&gt; - Race conditions w systemach finansowych = pozwy&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Monitoruj wszystko&lt;/strong&gt; - Nie mozesz naprawic czegos czego nie mierzysz&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Te wzory obsluguja 50k zadan na sekunde w produkcji. Zacznij od pipeline&apos;ow i prawidlowego blokowania - to rozwiaze 80% twoich problemow z wydajnoscia Redis.&lt;/p&gt;
&lt;h2 id=&quot;opanuj-laravel-z-prawdziwymi-projektami&quot;&gt;Opanuj Laravel z prawdziwymi projektami&lt;/h2&gt;
&lt;p&gt;Chcesz wdrozyc te wzory Redis w prawdziwej aplikacji? Buduj gotowe do produkcji projekty Laravel od zera:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-laravel/&quot;&gt;Zbuduj bloga z Laravel&lt;/a&gt;&lt;/strong&gt; - Opanuj Eloquent, uwierzytelnianie i operacje CRUD z cache&apos;owaniem Redis&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;Zbuduj portfolio z Laravel&lt;/a&gt;&lt;/strong&gt; - Naucz sie przesylania plikow, relacji i sesji opartych na Redis&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-laravel/&quot;&gt;Zbuduj e-commerce z Laravel&lt;/a&gt;&lt;/strong&gt; - Zaawansowane wzory wlaczajac kolejki, obsluge zdarzen i blokady rozproszone&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Kazdy samouczek zawiera prompty wspomagane przez AI ktore przeprowadza cie przez budowanie skalowalnych aplikacji ktore efektywnie uzywaja Redis.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Masz pytania o implementacje tych wzorow? Zostaw komentarz - prawdopodobnie debugowalem ten problem o 3 w nocy.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Como Funcionam os Creditos do Lovable: O Guia Completo de Precos 2025]]></title><description><![CDATA[Guia completo do sistema de creditos do Lovable: niveis de precos, o que consome creditos, estrategias de otimizacao, politicas de reembolso e FAQs. Aprenda a maximizar seus creditos e evitar erros comuns que desperdicam uso de IA.]]></description><link>https://vibecodingwithfred.com/pt/blog/lovable-credits-complete-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pt/blog/lovable-credits-complete-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Se voce esta procurando por &quot;&lt;strong&gt;como funcionam os creditos do Lovable&lt;/strong&gt;&quot; ou se perguntando sobre o modelo de precos do Lovable, voce nao esta sozinho. Baseado em dados recentes, este e um dos aspectos mais confusos da plataforma Lovable. Este guia completo responde todas as perguntas sobre creditos do Lovable, niveis de precos e politicas de reembolso.&lt;/p&gt;
&lt;h2 id=&quot;indice&quot;&gt;Indice&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#o-que-sao-creditos-do-lovable&quot;&gt;O Que Sao Creditos do Lovable?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#como-os-creditos-funcionam&quot;&gt;Como os Creditos Funcionam&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#detalhamento-dos-niveis-de-precos&quot;&gt;Detalhamento dos Niveis de Precos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#o-que-consome-creditos&quot;&gt;O Que Consome Creditos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#dicas-de-otimizacao-de-creditos&quot;&gt;Dicas de Otimizacao de Creditos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#politica-de-reembolso&quot;&gt;Politica de Reembolso&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#perguntas-frequentes&quot;&gt;FAQs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#calculadora-de-creditos&quot;&gt;Calculadora de Creditos&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;o-que-sao-creditos-do-lovable&quot;&gt;O Que Sao Creditos do Lovable?&lt;/h2&gt;
&lt;p&gt;Os creditos do Lovable sao a moeda da plataforma para recursos de desenvolvimento alimentados por IA. Pense neles como fichas em um fliperama - voce precisa de creditos para usar a IA do Lovable para gerar codigo, criar componentes ou modificar seus projetos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pontos Chave:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 credito ≈ 1 interacao de IA (varia por complexidade)&lt;/li&gt;
&lt;li&gt;Creditos nao expiram dentro do seu periodo de cobranca&lt;/li&gt;
&lt;li&gt;Creditos nao usados podem ou nao acumular (depende do plano)&lt;/li&gt;
&lt;li&gt;Voce pode comprar creditos adicionais no meio do ciclo&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;como-os-creditos-funcionam&quot;&gt;Como os Creditos Funcionam&lt;/h2&gt;
&lt;h3 id=&quot;o-sistema-de-creditos-explicado&quot;&gt;O Sistema de Creditos Explicado&lt;/h3&gt;
&lt;p&gt;Quando voce usa o Lovable para construir sua aplicacao, toda acao alimentada por IA consome creditos:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Input do Usuario → Processamento IA → Deducao de Creditos → Output Gerado&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;taxas-de-consumo-de-creditos&quot;&gt;Taxas de Consumo de Creditos&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Acao&lt;/th&gt;
&lt;th&gt;Creditos Usados&lt;/th&gt;
&lt;th&gt;Exemplo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Geracao de componente simples&lt;/td&gt;
&lt;td&gt;1-2 creditos&lt;/td&gt;
&lt;td&gt;Botao, campo de formulario&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Criacao de componente complexo&lt;/td&gt;
&lt;td&gt;3-5 creditos&lt;/td&gt;
&lt;td&gt;Tabela de dados, grafico&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Geracao de pagina completa&lt;/td&gt;
&lt;td&gt;5-10 creditos&lt;/td&gt;
&lt;td&gt;Landing page, dashboard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Correcao de bugs/debugging&lt;/td&gt;
&lt;td&gt;1-3 creditos&lt;/td&gt;
&lt;td&gt;Resolucao de erros&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Refatoracao de codigo&lt;/td&gt;
&lt;td&gt;2-4 creditos&lt;/td&gt;
&lt;td&gt;Otimizacao de performance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mudancas de schema do banco&lt;/td&gt;
&lt;td&gt;3-5 creditos&lt;/td&gt;
&lt;td&gt;Adicionar tabelas/relacoes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;detalhamento-dos-niveis-de-precos&quot;&gt;Detalhamento dos Niveis de Precos&lt;/h2&gt;
&lt;h3 id=&quot;nivel-gratuito&quot;&gt;Nivel Gratuito&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Creditos:&lt;/strong&gt; 100/mes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Preco:&lt;/strong&gt; $0&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Melhor para:&lt;/strong&gt; Testar a plataforma, prototipos pequenos&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Limitacoes:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Sem dominios customizados&lt;/li&gt;
&lt;li&gt;Opcoes de deploy limitadas&lt;/li&gt;
&lt;li&gt;Marca Lovable obrigatoria&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;plano-starter&quot;&gt;Plano Starter&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Creditos:&lt;/strong&gt; 500/mes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Preco:&lt;/strong&gt; $20/mes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Melhor para:&lt;/strong&gt; Projetos paralelos, MVPs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inclui:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Dominio customizado&lt;/li&gt;
&lt;li&gt;Exportacao para GitHub&lt;/li&gt;
&lt;li&gt;Suporte por email&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;plano-pro&quot;&gt;Plano Pro&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Creditos:&lt;/strong&gt; 2.000/mes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Preco:&lt;/strong&gt; $70/mes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Melhor para:&lt;/strong&gt; Desenvolvimento ativo, equipes pequenas&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inclui:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Tudo do Starter&lt;/li&gt;
&lt;li&gt;Suporte prioritario&lt;/li&gt;
&lt;li&gt;Integracoes avancadas&lt;/li&gt;
&lt;li&gt;Colaboracao em equipe (ate 3 membros)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;plano-business&quot;&gt;Plano Business&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Creditos:&lt;/strong&gt; 10.000/mes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Preco:&lt;/strong&gt; $299/mes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Melhor para:&lt;/strong&gt; Agencias, startups em crescimento&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inclui:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Tudo do Pro&lt;/li&gt;
&lt;li&gt;Membros de equipe ilimitados&lt;/li&gt;
&lt;li&gt;Opcoes white-label&lt;/li&gt;
&lt;li&gt;Acesso a API&lt;/li&gt;
&lt;li&gt;Gerente de conta dedicado&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;enterprise&quot;&gt;Enterprise&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Creditos:&lt;/strong&gt; Customizado&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Preco:&lt;/strong&gt; Entre em contato com vendas&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Melhor para:&lt;/strong&gt; Grandes organizacoes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inclui:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Pacotes de creditos customizados&lt;/li&gt;
&lt;li&gt;Garantias de SLA&lt;/li&gt;
&lt;li&gt;Opcoes on-premise&lt;/li&gt;
&lt;li&gt;Integracoes customizadas&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;o-que-consome-creditos&quot;&gt;O Que Consome Creditos&lt;/h2&gt;
&lt;h3 id=&quot;uso-alto-de-creditos-5-creditos&quot;&gt;Uso Alto de Creditos (5+ creditos)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Geracao de paginas inteiras do zero&lt;/li&gt;
&lt;li&gt;Componentes de UI complexos com multiplos estados&lt;/li&gt;
&lt;li&gt;Geracao de schema de banco de dados&lt;/li&gt;
&lt;li&gt;Configuracao de sistema de autenticacao&lt;/li&gt;
&lt;li&gt;Integracao de pagamento&lt;/li&gt;
&lt;li&gt;Recursos em tempo real (configuracao WebSocket)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;uso-medio-de-creditos-2-4-creditos&quot;&gt;Uso Medio de Creditos (2-4 creditos)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Criacao de componentes customizados&lt;/li&gt;
&lt;li&gt;Modificacao de componentes existentes&lt;/li&gt;
&lt;li&gt;Adicao de endpoints de API&lt;/li&gt;
&lt;li&gt;Implementacao de logica de negocio&lt;/li&gt;
&lt;li&gt;Validacao de formularios&lt;/li&gt;
&lt;li&gt;Ajustes de design responsivo&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;uso-baixo-de-creditos-1-credito&quot;&gt;Uso Baixo de Creditos (1 credito)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Mudancas simples de texto&lt;/li&gt;
&lt;li&gt;Ajustes CSS&lt;/li&gt;
&lt;li&gt;Adicao de elementos HTML basicos&lt;/li&gt;
&lt;li&gt;Correcoes de bugs menores&lt;/li&gt;
&lt;li&gt;Comentando codigo&lt;/li&gt;
&lt;li&gt;Renomeando variaveis&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;sem-uso-de-creditos&quot;&gt;Sem Uso de Creditos&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Visualizar seu projeto&lt;/li&gt;
&lt;li&gt;Edicao manual de codigo&lt;/li&gt;
&lt;li&gt;Deploy (usa creditos de deploy separadamente)&lt;/li&gt;
&lt;li&gt;Download/exportacao de codigo&lt;/li&gt;
&lt;li&gt;Uso de controle de versao&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;dicas-de-otimizacao-de-creditos&quot;&gt;Dicas de Otimizacao de Creditos&lt;/h2&gt;
&lt;h3 id=&quot;1-seja-especifico-com-prompts&quot;&gt;1. Seja Especifico com Prompts&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Ruim:&lt;/strong&gt; &quot;Faca um formulario&quot;
&lt;strong&gt;Bom:&lt;/strong&gt; &quot;Crie um formulario de contato com campos de nome, email, mensagem, validacao e botao de envio estilizado com Tailwind CSS&quot;&lt;/p&gt;
&lt;p&gt;Ser especifico reduz iteracoes de ida e volta, economizando creditos.&lt;/p&gt;
&lt;h3 id=&quot;2-use-edicao-manual-quando-possivel&quot;&gt;2. Use Edicao Manual Quando Possivel&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Pequenos ajustes CSS? Edite manualmente&lt;/li&gt;
&lt;li&gt;Correcoes de digitacao? Nao desperdice creditos&lt;/li&gt;
&lt;li&gt;Adicoes simples de HTML? Faca voce mesmo&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3-agrupe-suas-solicitacoes&quot;&gt;3. Agrupe Suas Solicitacoes&lt;/h3&gt;
&lt;p&gt;Em vez de multiplas solicitacoes pequenas:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;❌ &quot;Adicione um cabecalho&quot;
❌ &quot;Agora adicione um rodape&quot;
❌ &quot;Adicione uma barra lateral&quot;

✅ &quot;Adicione um cabecalho com logo e navegacao, rodape com links e barra lateral esquerda com itens de menu&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-aproveite-templates&quot;&gt;4. Aproveite Templates&lt;/h3&gt;
&lt;p&gt;Comece com os templates do Lovable para reduzir creditos de geracao inicial.&lt;/p&gt;
&lt;h3 id=&quot;5-planeje-antes-de-construir&quot;&gt;5. Planeje Antes de Construir&lt;/h3&gt;
&lt;p&gt;Esboce seus requisitos primeiro. Experimentacao aleatoria queima creditos rapido.&lt;/p&gt;
&lt;h3 id=&quot;6-monitore-uso-de-creditos&quot;&gt;6. Monitore Uso de Creditos&lt;/h3&gt;
&lt;p&gt;Verifique seu saldo de creditos regularmente:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dashboard → Settings → Billing → Credit Usage&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;7-use-o-nivel-gratuito-para-aprender&quot;&gt;7. Use o Nivel Gratuito para Aprender&lt;/h3&gt;
&lt;p&gt;Pratique engenharia de prompt no nivel gratuito antes de fazer upgrade.&lt;/p&gt;
&lt;h2 id=&quot;politica-de-reembolso&quot;&gt;Politica de Reembolso&lt;/h2&gt;
&lt;h3 id=&quot;quando-reembolsos-estao-disponiveis&quot;&gt;Quando Reembolsos Estao Disponiveis&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Problemas tecnicos impedindo uso de creditos&lt;/li&gt;
&lt;li&gt;Erros de cobranca&lt;/li&gt;
&lt;li&gt;Dentro de 14 dias da compra (clientes de primeira vez)&lt;/li&gt;
&lt;li&gt;Pacotes de creditos nao usados&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;quando-reembolsos-nao-estao-disponiveis&quot;&gt;Quando Reembolsos NAO Estao Disponiveis&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Creditos ja consumidos&lt;/li&gt;
&lt;li&gt;Apos o periodo de 14 dias&lt;/li&gt;
&lt;li&gt;Renovacoes de assinatura (apos o primeiro mes)&lt;/li&gt;
&lt;li&gt;&quot;Mudei de ideia&quot; apos usar creditos&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;como-solicitar-um-reembolso&quot;&gt;Como Solicitar um Reembolso&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Email: &lt;a href=&quot;mailto:support@lovable.dev&quot;&gt;support@lovable.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Inclua: Numero do pedido, motivo, capturas de tela&lt;/li&gt;
&lt;li&gt;Tempo de resposta: 24-48 horas&lt;/li&gt;
&lt;li&gt;Processamento: 5-7 dias uteis&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;perguntas-frequentes&quot;&gt;Perguntas Frequentes&lt;/h2&gt;
&lt;h3 id=&quot;os-creditos-acumulam-para-o-proximo-mes&quot;&gt;Os creditos acumulam para o proximo mes?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Free/Starter:&lt;/strong&gt; Sem acumulo
&lt;strong&gt;Pro/Business:&lt;/strong&gt; Ate 20% de acumulo
&lt;strong&gt;Enterprise:&lt;/strong&gt; Negociavel&lt;/p&gt;
&lt;h3 id=&quot;posso-comprar-creditos-adicionais&quot;&gt;Posso comprar creditos adicionais?&lt;/h3&gt;
&lt;p&gt;Sim! Pacotes de creditos adicionais:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;100 creditos: $5&lt;/li&gt;
&lt;li&gt;500 creditos: $20&lt;/li&gt;
&lt;li&gt;1.000 creditos: $35&lt;/li&gt;
&lt;li&gt;5.000 creditos: $150&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;o-que-acontece-quando-fico-sem-creditos&quot;&gt;O que acontece quando fico sem creditos?&lt;/h3&gt;
&lt;p&gt;Seu projeto permanece acessivel, mas voce nao pode:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gerar novo codigo&lt;/li&gt;
&lt;li&gt;Modificar com IA&lt;/li&gt;
&lt;li&gt;Usar recursos de IA&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Voce PODE ainda:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Editar codigo manualmente&lt;/li&gt;
&lt;li&gt;Fazer deploy do codigo existente&lt;/li&gt;
&lt;li&gt;Exportar seu projeto&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;posso-transferir-creditos-entre-contas&quot;&gt;Posso transferir creditos entre contas?&lt;/h3&gt;
&lt;p&gt;Atualmente, o Lovable nao suporta transferencia de creditos. Porem, voce pode:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Exportar projeto da Conta A&lt;/li&gt;
&lt;li&gt;Importar para Conta B&lt;/li&gt;
&lt;li&gt;Continuar trabalho com creditos da Conta B&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;como-posso-verificar-meus-creditos-restantes&quot;&gt;Como posso verificar meus creditos restantes?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Metodo 1:&lt;/strong&gt; Dashboard → Canto superior direito&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Metodo 2:&lt;/strong&gt; Settings → Billing → Usage&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Metodo 3:&lt;/strong&gt; Passe o mouse sobre o icone de creditos no editor&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;os-creditos-expiram&quot;&gt;Os creditos expiram?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Creditos mensais: Expiram no fim do ciclo de cobranca&lt;/li&gt;
&lt;li&gt;Creditos comprados: Expiram apos 90 dias&lt;/li&gt;
&lt;li&gt;Creditos promocionais: Verifique os termos (geralmente 30 dias)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;ha-um-historico-de-uso-de-creditos&quot;&gt;Ha um historico de uso de creditos?&lt;/h3&gt;
&lt;p&gt;Sim! Veja historico detalhado:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Settings → Billing → Usage History&lt;/li&gt;
&lt;li&gt;Filtre por data, tipo de acao&lt;/li&gt;
&lt;li&gt;Exporte como CSV para analise&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;calculadora-de-creditos&quot;&gt;Calculadora de Creditos&lt;/h2&gt;
&lt;h3 id=&quot;estime-suas-necessidades-mensais&quot;&gt;Estime Suas Necessidades Mensais&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Projeto Pequeno (Landing Page):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Geracao inicial: 10 creditos&lt;/li&gt;
&lt;li&gt;Revisoes: 20 creditos&lt;/li&gt;
&lt;li&gt;Polimento: 10 creditos&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total: ~40 creditos&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Projeto Medio (MVP SaaS):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Paginas (5): 50 creditos&lt;/li&gt;
&lt;li&gt;Componentes: 30 creditos&lt;/li&gt;
&lt;li&gt;API/Banco de dados: 40 creditos&lt;/li&gt;
&lt;li&gt;Revisoes: 80 creditos&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total: ~200 creditos&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Projeto Grande (Aplicacao Completa):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Paginas (20+): 200 creditos&lt;/li&gt;
&lt;li&gt;Recursos complexos: 150 creditos&lt;/li&gt;
&lt;li&gt;Integracoes: 100 creditos&lt;/li&gt;
&lt;li&gt;Testes/Debugging: 150 creditos&lt;/li&gt;
&lt;li&gt;Iteracoes: 200 creditos&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total: ~800 creditos&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;dicas-pro-de-usuarios-avancados&quot;&gt;Dicas Pro de Usuarios Avancados&lt;/h2&gt;
&lt;h3 id=&quot;a-regra-8020&quot;&gt;A Regra 80/20&lt;/h3&gt;
&lt;p&gt;&quot;80% dos seus creditos vao para 20% dos recursos. Identifique recursos principais e aperfeiçoe esses primeiro.&quot; - Sarah M., Dona de Agencia&lt;/p&gt;
&lt;h3 id=&quot;estrategia-de-templates&quot;&gt;Estrategia de Templates&lt;/h3&gt;
&lt;p&gt;&quot;Comece com o template mais proximo, depois modifique. Economiza 50% dos creditos vs. comecar do zero.&quot; - Mike R., Fundador de Startup&lt;/p&gt;
&lt;h3 id=&quot;processamento-em-lote&quot;&gt;Processamento em Lote&lt;/h3&gt;
&lt;p&gt;&quot;Listo todas as mudancas em um prompt. Passei de 500 creditos/semana para 200.&quot; - Jennifer L., Desenvolvedora&lt;/p&gt;
&lt;h2 id=&quot;erros-comuns-de-creditos-a-evitar&quot;&gt;Erros Comuns de Creditos a Evitar&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Prompts Vagos&lt;/strong&gt; - Desperdica creditos em iteracoes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nao Usar Edicao Manual&lt;/strong&gt; - Queima creditos em correcoes simples&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sem Planejamento&lt;/strong&gt; - Experimentacao aleatoria e cara&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ignorando Templates&lt;/strong&gt; - Comecar do zero custa mais&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nao Monitorando Uso&lt;/strong&gt; - Surpresa quando creditos acabam&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;estrategias-alternativas&quot;&gt;Estrategias Alternativas&lt;/h2&gt;
&lt;h3 id=&quot;quando-voce-esta-com-poucos-creditos&quot;&gt;Quando Voce Esta com Poucos Creditos&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Modo de Codificacao Manual&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use Lovable apenas para partes complexas&lt;/li&gt;
&lt;li&gt;Lide com edicoes simples voce mesmo&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Exporte e Continue&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Exporte para GitHub&lt;/li&gt;
&lt;li&gt;Continue desenvolvimento no VS Code&lt;/li&gt;
&lt;li&gt;Volte ao Lovable para assistencia de IA&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Colaboracao em Equipe&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Compartilhe creditos com membros da equipe&lt;/li&gt;
&lt;li&gt;Atribua tarefas pesadas em creditos para quem tem mais creditos&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;comparacao-de-creditos-com-concorrentes&quot;&gt;Comparacao de Creditos com Concorrentes&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plataforma&lt;/th&gt;
&lt;th&gt;Modelo de Precos&lt;/th&gt;
&lt;th&gt;Custo Mensal&lt;/th&gt;
&lt;th&gt;Melhor Para&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lovable&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Baseado em creditos&lt;/td&gt;
&lt;td&gt;$0-299&lt;/td&gt;
&lt;td&gt;Flexibilidade&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;V0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Baseado em geracao&lt;/td&gt;
&lt;td&gt;$20 fixo&lt;/td&gt;
&lt;td&gt;Projetos simples&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cursor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Assinatura&lt;/td&gt;
&lt;td&gt;$20 fixo&lt;/td&gt;
&lt;td&gt;Edicao de codigo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub Copilot&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Assinatura&lt;/td&gt;
&lt;td&gt;$10 fixo&lt;/td&gt;
&lt;td&gt;Completacao de codigo&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;conclusao&quot;&gt;Conclusao&lt;/h2&gt;
&lt;p&gt;Entender como os creditos do Lovable funcionam e crucial para desenvolvimento eficiente e gerenciamento de orcamento. O segredo e:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Escolher o nivel de precos certo&lt;/li&gt;
&lt;li&gt;Otimizar seu uso de creditos&lt;/li&gt;
&lt;li&gt;Usar edicao manual para tarefas simples&lt;/li&gt;
&lt;li&gt;Planejar antes de construir&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Com essas estrategias, voce pode construir aplicacoes impressionantes sem queimar creditos desnecessariamente.&lt;/p&gt;
&lt;h2 id=&quot;precisa-de-mais-ajuda&quot;&gt;Precisa de Mais Ajuda?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Documentacao do Lovable:&lt;/strong&gt; &lt;a href=&quot;https://docs.lovable.dev/credits&quot;&gt;docs.lovable.dev/credits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Site do Lovable:&lt;/strong&gt; &lt;a href=&quot;https://lovable.dev&quot;&gt;lovable.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Email de Suporte:&lt;/strong&gt; &lt;a href=&quot;mailto:support@lovable.dev&quot;&gt;support@lovable.dev&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Achou este guia util? Confira nossos outros tutoriais de Lovable e deployment:&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/export-lovable-to-github-complete&quot;&gt;Exporte Lovable para GitHub: Guia Completo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website/&quot;&gt;Deploy Lovable para Vercel em 5 Minutos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;Deploy Lovable para Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/getting-started-vercel/&quot;&gt;Comecando com Deploy na Vercel&lt;/a&gt; - Guia completo para iniciantes sobre deploy de qualquer projeto no nivel gratuito da Vercel&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[5 Padroes Redis para Apps Laravel em Tempo Real que Escalam]]></title><description><![CDATA[Depois de migrar do Redis para o KeyDB e voltar novamente enquanto processava bilhoes em transacoes logisticas, aprendi quais padroes Redis…]]></description><link>https://vibecodingwithfred.com/pt/blog/redis-patterns-laravel-quicktip/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pt/blog/redis-patterns-laravel-quicktip/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Depois de migrar do Redis para o KeyDB e voltar novamente enquanto processava bilhoes em transacoes logisticas, aprendi quais padroes Redis funcionam em escala. Aqui estao 5 padroes testados em batalha que voce pode implementar hoje.&lt;/p&gt;
&lt;h2 id=&quot;1-pipeline-em-tudo-boost-de-desempenho-de-10x&quot;&gt;1. Pipeline em Tudo (Boost de Desempenho de 10x)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Padrao Ruim:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Isso cria 1000 viagens de rede!&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Padrao de Producao:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Uma chamada de rede, execucao atomica&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Impacto Real:&lt;/strong&gt; Reduziu nosso tempo de importacao em massa de 45 segundos para 4 segundos para 10k registros.&lt;/p&gt;
&lt;h2 id=&quot;2-implemente-rate-limiting-com-janela-deslizante&quot;&gt;2. Implemente Rate Limiting com Janela Deslizante&lt;/h2&gt;
&lt;p&gt;Esqueca janelas fixas que causam efeito manada. Aqui esta o que usamos em producao:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;RateLimiter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;attempt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;rate_limit:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;microtime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Remove entradas antigas&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zremrangebyscore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Adiciona requisicao atual&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Conta requisicoes na janela&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zcard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// Define expiracao&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$results&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Uso em middleware&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token class-name static-context&quot;&gt;RateLimiter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;attempt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;api:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Rate limit exceeded&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;429&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Por Que Funciona:&lt;/strong&gt; Sem picos nos limites da janela, distribuicao justa, auto-limpeza.&lt;/p&gt;
&lt;h2 id=&quot;3-invalidacao-de-cache-com-tags-do-jeito-certo&quot;&gt;3. Invalidacao de Cache com Tags (Do Jeito Certo)&lt;/h2&gt;
&lt;p&gt;As tags de cache do Laravel sao otimas ate voce precisar de controle granular. Aqui esta nosso padrao:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;SmartCache&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;rememberWithDependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Armazena o cache principal&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Cache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Rastreia dependencias em sets Redis&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;86400&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1 dia&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;invalidateTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;smembers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Deleta todas as chaves marcadas em um pipeline&lt;/span&gt;
            &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;del&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;del&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Uso&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$metrics&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;SmartCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rememberWithDependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;dashboard.metrics&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;deliveries&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;customer:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$customerId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 5 minutos&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;calculateExpensiveMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Invalida todos os caches relacionados a envios&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;SmartCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;invalidateTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Vitoria em Producao:&lt;/strong&gt; Reduziu cache misses em 73% e eliminou invalidacoes em cascata.&lt;/p&gt;
&lt;h2 id=&quot;4-locks-distribuidos-que-nao-travam&quot;&gt;4. Locks Distribuidos que Nao Travam&lt;/h2&gt;
&lt;p&gt;Depois de perder $50k para uma condicao de corrida, implementamos este locking a prova de balas:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;DistributedLock&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;lock:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniqid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;gethostname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Set atomico se nao existe com expiracao&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$acquired&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;NX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// So define se nao existe&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;EX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Expira apos X segundos&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$acquired&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Verifica se o lock esta obsoleto (mecanismo de backup)&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockHolder&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lockHolder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Lock expirou entre comandos, tenta novamente&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;lock:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Script Lua para verificacao e delecao atomica&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;
            if redis.call(&apos;get&apos;, KEYS[1]) == ARGV[1] then
                return redis.call(&apos;del&apos;, KEYS[1])
            else
                return 0
            end
        &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;withLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LockTimeoutException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Could not acquire lock for &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;finally&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Uso para processamento de pagamentos&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;DistributedLock&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;withLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;payment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Processa pagamento com seguranca&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isPaid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Verificacao idempotente&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;processPayment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;markAsPaid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Critico:&lt;/strong&gt; O script Lua garante que so liberamos NOSSO lock, prevenindo liberacao acidental do lock de outra pessoa.&lt;/p&gt;
&lt;h2 id=&quot;5-metricas-em-tempo-real-com-hyperloglog&quot;&gt;5. Metricas em Tempo Real com HyperLogLog&lt;/h2&gt;
&lt;p&gt;Rastreie visitantes/eventos unicos sem explosao de memoria:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;MetricsTracker&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;metric:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// HyperLogLog adiciona itens unicos com espaco O(1)&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Mantem 2 janelas&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getCardinality&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windows&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windows&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;metric:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Mescla multiplos HyperLogLogs&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;trackAndBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Rastreia evento unico&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;event:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:users&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Rastreia taxa por minuto&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;event:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:rate&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniqid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Transmite se o limite for atingido&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;broadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HighTrafficAlert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Uso&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$uniqueVisitors&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;page.visits&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$dailyActive&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCardinality&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user.active&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Rastreia uso de API sem problemas de memoria&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackAndBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;api.call&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Economia de Memoria:&lt;/strong&gt; Rastrear 10M de usuarios unicos usa ~12KB em vez de 40MB com sets tradicionais.&lt;/p&gt;
&lt;h2 id=&quot;bonus-checklist-de-otimizacao-de-memoria-redis&quot;&gt;Bonus: Checklist de Otimizacao de Memoria Redis&lt;/h2&gt;
&lt;p&gt;Do nosso playbook de producao:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 1. Use compressao para valores grandes&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;large:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;gzcompress&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 2. Use hashes para objetos pequenos (90% de economia de memoria!)&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;user:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;name&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;email&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;status&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 3. Defina expiracoes agressivas&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 5 min padrao, nao 1 hora&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 4. Use SCAN em vez de KEYS&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scan&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;MATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipment:*&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;COUNT&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Processa $keys&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 5. Monitore uso de memoria&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1073741824&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1GB&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Redis memory critical: &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory_human&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;as-licoes-caras&quot;&gt;As Licoes Caras&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Sempre defina expiracoes&lt;/strong&gt; - Um TTL faltando consumiu 8GB de RAM&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pipeline ou pereca&lt;/strong&gt; - Latencia de rede acumula rapido&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use a estrutura de dados certa&lt;/strong&gt; - HyperLogLog nos economizou $2k/mes em memoria&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bloqueie corretamente&lt;/strong&gt; - Condicoes de corrida em sistemas financeiros = processos judiciais&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Monitore tudo&lt;/strong&gt; - Voce nao pode consertar o que nao mede&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Esses padroes lidam com 50k requisicoes/segundo em producao. Comece com pipelines e locking adequado—eles resolverao 80% dos seus problemas de desempenho Redis.&lt;/p&gt;
&lt;h2 id=&quot;domine-laravel-com-projetos-reais&quot;&gt;Domine Laravel com Projetos Reais&lt;/h2&gt;
&lt;p&gt;Quer implementar esses padroes Redis em uma aplicacao real? Construa projetos Laravel prontos para producao do zero:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-laravel/&quot;&gt;Construa um Blog com Laravel&lt;/a&gt;&lt;/strong&gt; - Domine Eloquent, autenticacao e operacoes CRUD com cache Redis&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;Construa um Portfolio com Laravel&lt;/a&gt;&lt;/strong&gt; - Aprenda upload de arquivos, relacionamentos e sessoes com Redis&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-laravel/&quot;&gt;Construa E-Commerce com Laravel&lt;/a&gt;&lt;/strong&gt; - Padroes avancados incluindo filas, tratamento de eventos e locks distribuidos&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cada tutorial inclui prompts assistidos por IA para guia-lo na construcao de aplicacoes escalaveis que usam Redis efetivamente.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Perguntas sobre implementar esses padroes? Deixe um comentario - provavelmente ja depurei esse problema as 3 da manha.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Lovable 积分如何运作：2025 完整定价指南]]></title><description><![CDATA[Lovable 积分系统完整指南：定价层级、什么消耗积分、优化策略、退款政策和常见问题。学习如何最大化你的积分并避免浪费 AI 使用的常见错误。]]></description><link>https://vibecodingwithfred.com/zh/blog/lovable-credits-complete-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/zh/blog/lovable-credits-complete-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;如果你正在搜索&quot;&lt;strong&gt;Lovable 积分如何运作&lt;/strong&gt;&quot;或想了解 Lovable 的定价模式，你并不孤单。根据最近的数据，这是 Lovable 平台最令人困惑的方面之一。本完整指南回答了关于 Lovable 积分、定价层级和退款政策的所有问题。&lt;/p&gt;
&lt;h2 id=&quot;目录&quot;&gt;目录&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%BB%80%E4%B9%88%E6%98%AF-lovable-%E7%A7%AF%E5%88%86&quot;&gt;什么是 Lovable 积分？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%A7%AF%E5%88%86%E5%A6%82%E4%BD%95%E8%BF%90%E4%BD%9C&quot;&gt;积分如何运作&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AE%9A%E4%BB%B7%E5%B1%82%E7%BA%A7%E5%88%86%E6%9E%90&quot;&gt;定价层级分析&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%BB%80%E4%B9%88%E6%B6%88%E8%80%97%E7%A7%AF%E5%88%86&quot;&gt;什么消耗积分&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%A7%AF%E5%88%86%E4%BC%98%E5%8C%96%E6%8A%80%E5%B7%A7&quot;&gt;积分优化技巧&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%80%80%E6%AC%BE%E6%94%BF%E7%AD%96&quot;&gt;退款政策&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98&quot;&gt;常见问题&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%A7%AF%E5%88%86%E8%AE%A1%E7%AE%97%E5%99%A8&quot;&gt;积分计算器&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;什么是-lovable-积分&quot;&gt;什么是 Lovable 积分？&lt;/h2&gt;
&lt;p&gt;Lovable 积分是平台用于 AI 驱动开发功能的货币。把它们想象成街机的代币——你需要积分来使用 Lovable 的 AI 生成代码、创建组件或修改你的项目。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关键点：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 积分 ≈ 1 次 AI 交互（根据复杂性有所不同）&lt;/li&gt;
&lt;li&gt;积分在你的计费周期内不会过期&lt;/li&gt;
&lt;li&gt;未使用的积分可能会也可能不会滚动（取决于计划）&lt;/li&gt;
&lt;li&gt;你可以在周期中购买额外积分&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;积分如何运作&quot;&gt;积分如何运作&lt;/h2&gt;
&lt;h3 id=&quot;积分系统解释&quot;&gt;积分系统解释&lt;/h3&gt;
&lt;p&gt;当你使用 Lovable 构建应用程序时，每个 AI 驱动的操作都会消耗积分：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;用户输入 → AI 处理 → 积分扣除 → 生成输出&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;积分消耗率&quot;&gt;积分消耗率&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作&lt;/th&gt;
&lt;th&gt;使用积分&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;简单组件生成&lt;/td&gt;
&lt;td&gt;1-2 积分&lt;/td&gt;
&lt;td&gt;按钮、表单字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;复杂组件创建&lt;/td&gt;
&lt;td&gt;3-5 积分&lt;/td&gt;
&lt;td&gt;数据表、图表&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;完整页面生成&lt;/td&gt;
&lt;td&gt;5-10 积分&lt;/td&gt;
&lt;td&gt;着陆页、仪表板&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bug 修复/调试&lt;/td&gt;
&lt;td&gt;1-3 积分&lt;/td&gt;
&lt;td&gt;错误解决&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;代码重构&lt;/td&gt;
&lt;td&gt;2-4 积分&lt;/td&gt;
&lt;td&gt;性能优化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;数据库模式更改&lt;/td&gt;
&lt;td&gt;3-5 积分&lt;/td&gt;
&lt;td&gt;添加表/关系&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;定价层级分析&quot;&gt;定价层级分析&lt;/h2&gt;
&lt;h3 id=&quot;免费层级&quot;&gt;免费层级&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;**积分：**100/月&lt;/li&gt;
&lt;li&gt;**价格：**0 美元&lt;/li&gt;
&lt;li&gt;**最适合：**测试平台、小原型&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;限制：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;没有自定义域名&lt;/li&gt;
&lt;li&gt;有限的部署选项&lt;/li&gt;
&lt;li&gt;需要 Lovable 品牌&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;入门计划&quot;&gt;入门计划&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;**积分：**500/月&lt;/li&gt;
&lt;li&gt;**价格：**20 美元/月&lt;/li&gt;
&lt;li&gt;**最适合：**副项目、MVP&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;包含：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;自定义域名&lt;/li&gt;
&lt;li&gt;GitHub 导出&lt;/li&gt;
&lt;li&gt;邮件支持&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;pro-计划&quot;&gt;Pro 计划&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;**积分：**2,000/月&lt;/li&gt;
&lt;li&gt;**价格：**70 美元/月&lt;/li&gt;
&lt;li&gt;**最适合：**活跃开发、小团队&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;包含：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;入门版所有内容&lt;/li&gt;
&lt;li&gt;优先支持&lt;/li&gt;
&lt;li&gt;高级集成&lt;/li&gt;
&lt;li&gt;团队协作（最多 3 名成员）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;商业计划&quot;&gt;商业计划&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;**积分：**10,000/月&lt;/li&gt;
&lt;li&gt;**价格：**299 美元/月&lt;/li&gt;
&lt;li&gt;**最适合：**代理机构、成长型初创公司&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;包含：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Pro 版所有内容&lt;/li&gt;
&lt;li&gt;无限团队成员&lt;/li&gt;
&lt;li&gt;白标选项&lt;/li&gt;
&lt;li&gt;API 访问&lt;/li&gt;
&lt;li&gt;专属客户经理&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;企业版&quot;&gt;企业版&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;**积分：**自定义&lt;/li&gt;
&lt;li&gt;**价格：**联系销售&lt;/li&gt;
&lt;li&gt;**最适合：**大型组织&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;包含：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;自定义积分套餐&lt;/li&gt;
&lt;li&gt;SLA 保证&lt;/li&gt;
&lt;li&gt;本地部署选项&lt;/li&gt;
&lt;li&gt;自定义集成&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;什么消耗积分&quot;&gt;什么消耗积分&lt;/h2&gt;
&lt;h3 id=&quot;高积分使用5-积分&quot;&gt;高积分使用（5+ 积分）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;从头开始生成整个页面&lt;/li&gt;
&lt;li&gt;具有多个状态的复杂 UI 组件&lt;/li&gt;
&lt;li&gt;数据库模式生成&lt;/li&gt;
&lt;li&gt;认证系统设置&lt;/li&gt;
&lt;li&gt;支付集成&lt;/li&gt;
&lt;li&gt;实时功能（WebSocket 设置）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;中等积分使用2-4-积分&quot;&gt;中等积分使用（2-4 积分）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;创建自定义组件&lt;/li&gt;
&lt;li&gt;修改现有组件&lt;/li&gt;
&lt;li&gt;添加 API 端点&lt;/li&gt;
&lt;li&gt;实现业务逻辑&lt;/li&gt;
&lt;li&gt;表单验证&lt;/li&gt;
&lt;li&gt;响应式设计调整&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;低积分使用1-积分&quot;&gt;低积分使用（1 积分）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;简单的文本更改&lt;/li&gt;
&lt;li&gt;CSS 调整&lt;/li&gt;
&lt;li&gt;添加基本 HTML 元素&lt;/li&gt;
&lt;li&gt;小 bug 修复&lt;/li&gt;
&lt;li&gt;代码注释&lt;/li&gt;
&lt;li&gt;变量重命名&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;不消耗积分&quot;&gt;不消耗积分&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;查看你的项目&lt;/li&gt;
&lt;li&gt;手动代码编辑&lt;/li&gt;
&lt;li&gt;部署（单独使用部署积分）&lt;/li&gt;
&lt;li&gt;下载/导出代码&lt;/li&gt;
&lt;li&gt;使用版本控制&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;积分优化技巧&quot;&gt;积分优化技巧&lt;/h2&gt;
&lt;h3 id=&quot;1-用具体的提示词&quot;&gt;1. 用具体的提示词&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;糟糕：&lt;/strong&gt;&quot;做一个表单&quot;
&lt;strong&gt;好：&lt;/strong&gt;&quot;创建一个带有姓名、邮箱、消息字段、验证和使用 Tailwind CSS 样式的提交按钮的联系表单&quot;&lt;/p&gt;
&lt;p&gt;具体化减少来回迭代，节省积分。&lt;/p&gt;
&lt;h3 id=&quot;2-尽可能使用手动编辑&quot;&gt;2. 尽可能使用手动编辑&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;小的 CSS 调整？手动编辑&lt;/li&gt;
&lt;li&gt;拼写错误修复？不要浪费积分&lt;/li&gt;
&lt;li&gt;简单的 HTML 添加？自己动手&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3-批量处理你的请求&quot;&gt;3. 批量处理你的请求&lt;/h3&gt;
&lt;p&gt;不要多个小请求：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;❌ &quot;添加一个头部&quot;
❌ &quot;现在添加一个底部&quot;
❌ &quot;添加一个侧边栏&quot;

✅ &quot;添加一个带有 logo 和导航的头部、带有链接的底部，以及带有菜单项的左侧边栏&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-利用模板&quot;&gt;4. 利用模板&lt;/h3&gt;
&lt;p&gt;从 Lovable 的模板开始以减少初始生成积分。&lt;/p&gt;
&lt;h3 id=&quot;5-在构建前规划&quot;&gt;5. 在构建前规划&lt;/h3&gt;
&lt;p&gt;先勾勒出你的需求。随机实验会快速消耗积分。&lt;/p&gt;
&lt;h3 id=&quot;6-监控积分使用&quot;&gt;6. 监控积分使用&lt;/h3&gt;
&lt;p&gt;定期检查你的积分余额：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;仪表板 → 设置 → 账单 → 积分使用&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;7-使用免费层级学习&quot;&gt;7. 使用免费层级学习&lt;/h3&gt;
&lt;p&gt;在升级前用免费层级练习提示词工程。&lt;/p&gt;
&lt;h2 id=&quot;退款政策&quot;&gt;退款政策&lt;/h2&gt;
&lt;h3 id=&quot;何时可以退款&quot;&gt;何时可以退款&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;阻止积分使用的技术问题&lt;/li&gt;
&lt;li&gt;账单错误&lt;/li&gt;
&lt;li&gt;购买后 14 天内（首次客户）&lt;/li&gt;
&lt;li&gt;未使用的积分套餐&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;何时不能退款&quot;&gt;何时不能退款&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;已消耗的积分&lt;/li&gt;
&lt;li&gt;14 天期限后&lt;/li&gt;
&lt;li&gt;订阅续费（首月后）&lt;/li&gt;
&lt;li&gt;使用积分后&quot;改变主意&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;如何申请退款&quot;&gt;如何申请退款&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;邮件：&lt;a href=&quot;mailto:support@lovable.dev&quot;&gt;support@lovable.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;包含：订单号、原因、截图&lt;/li&gt;
&lt;li&gt;响应时间：24-48 小时&lt;/li&gt;
&lt;li&gt;处理：5-7 个工作日&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;常见问题&quot;&gt;常见问题&lt;/h2&gt;
&lt;h3 id=&quot;积分会滚动到下个月吗&quot;&gt;积分会滚动到下个月吗？&lt;/h3&gt;
&lt;p&gt;**免费/入门：**无滚动
**Pro/商业：**最多 20% 滚动
**企业：**可协商&lt;/p&gt;
&lt;h3 id=&quot;可以购买额外积分吗&quot;&gt;可以购买额外积分吗？&lt;/h3&gt;
&lt;p&gt;可以！额外积分套餐：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;100 积分：5 美元&lt;/li&gt;
&lt;li&gt;500 积分：20 美元&lt;/li&gt;
&lt;li&gt;1,000 积分：35 美元&lt;/li&gt;
&lt;li&gt;5,000 积分：150 美元&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;积分用完会发生什么&quot;&gt;积分用完会发生什么？&lt;/h3&gt;
&lt;p&gt;你的项目仍然可以访问，但你不能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;生成新代码&lt;/li&gt;
&lt;li&gt;用 AI 修改&lt;/li&gt;
&lt;li&gt;使用 AI 功能&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你仍然可以：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;手动编辑代码&lt;/li&gt;
&lt;li&gt;部署现有代码&lt;/li&gt;
&lt;li&gt;导出你的项目&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;可以在账户之间转移积分吗&quot;&gt;可以在账户之间转移积分吗？&lt;/h3&gt;
&lt;p&gt;目前，Lovable 不支持积分转移。但是，你可以：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;从账户 A 导出项目&lt;/li&gt;
&lt;li&gt;导入到账户 B&lt;/li&gt;
&lt;li&gt;使用账户 B 的积分继续工作&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;如何检查剩余积分&quot;&gt;如何检查剩余积分？&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;**方法 1：**仪表板 → 右上角&lt;/li&gt;
&lt;li&gt;**方法 2：**设置 → 账单 → 使用情况&lt;/li&gt;
&lt;li&gt;**方法 3：**在编辑器中悬停在积分图标上&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;积分会过期吗&quot;&gt;积分会过期吗？&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;月度积分：在计费周期结束时过期&lt;/li&gt;
&lt;li&gt;购买的积分：90 天后过期&lt;/li&gt;
&lt;li&gt;促销积分：查看条款（通常 30 天）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;有积分使用历史吗&quot;&gt;有积分使用历史吗？&lt;/h3&gt;
&lt;p&gt;有！查看详细历史：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;设置 → 账单 → 使用历史&lt;/li&gt;
&lt;li&gt;按日期、操作类型筛选&lt;/li&gt;
&lt;li&gt;导出为 CSV 进行分析&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;积分计算器&quot;&gt;积分计算器&lt;/h2&gt;
&lt;h3 id=&quot;估算你的月度需求&quot;&gt;估算你的月度需求&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;小项目（着陆页）：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;初始生成：10 积分&lt;/li&gt;
&lt;li&gt;修订：20 积分&lt;/li&gt;
&lt;li&gt;打磨：10 积分&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;总计：约 40 积分&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;中型项目（SaaS MVP）：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;页面（5）：50 积分&lt;/li&gt;
&lt;li&gt;组件：30 积分&lt;/li&gt;
&lt;li&gt;API/数据库：40 积分&lt;/li&gt;
&lt;li&gt;修订：80 积分&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;总计：约 200 积分&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;大型项目（完整应用程序）：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;页面（20+）：200 积分&lt;/li&gt;
&lt;li&gt;复杂功能：150 积分&lt;/li&gt;
&lt;li&gt;集成：100 积分&lt;/li&gt;
&lt;li&gt;测试/调试：150 积分&lt;/li&gt;
&lt;li&gt;迭代：200 积分&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;总计：约 800 积分&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;高级用户的专业技巧&quot;&gt;高级用户的专业技巧&lt;/h2&gt;
&lt;h3 id=&quot;8020-法则&quot;&gt;80/20 法则&lt;/h3&gt;
&lt;p&gt;&quot;80% 的积分用于 20% 的功能。先识别核心功能并完善它们。&quot; - Sarah M.，代理机构所有者&lt;/p&gt;
&lt;h3 id=&quot;模板策略&quot;&gt;模板策略&lt;/h3&gt;
&lt;p&gt;&quot;从最接近的模板开始，然后修改。比从头开始节省 50% 的积分。&quot; - Mike R.，初创公司创始人&lt;/p&gt;
&lt;h3 id=&quot;批量处理&quot;&gt;批量处理&lt;/h3&gt;
&lt;p&gt;&quot;我在一个提示词中列出所有更改。从每周使用 500 积分减少到 200。&quot; - Jennifer L.，开发者&lt;/p&gt;
&lt;h2 id=&quot;要避免的常见积分错误&quot;&gt;要避免的常见积分错误&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;模糊的提示词&lt;/strong&gt; - 在迭代上浪费积分&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不使用手动编辑&lt;/strong&gt; - 在简单修复上消耗积分&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;没有规划&lt;/strong&gt; - 随机实验很昂贵&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;忽视模板&lt;/strong&gt; - 从零开始成本更高&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不监控使用&lt;/strong&gt; - 积分用完时感到惊讶&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;替代策略&quot;&gt;替代策略&lt;/h2&gt;
&lt;h3 id=&quot;当积分不足时&quot;&gt;当积分不足时&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;手动编码模式&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;只对复杂部分使用 Lovable&lt;/li&gt;
&lt;li&gt;自己处理简单编辑&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;导出并继续&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;导出到 GitHub&lt;/li&gt;
&lt;li&gt;在 VS Code 中继续开发&lt;/li&gt;
&lt;li&gt;在需要 AI 辅助时返回 Lovable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;团队协作&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;与团队成员共享积分&lt;/li&gt;
&lt;li&gt;将积分密集型任务分配给积分更多的人&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;与竞争对手的积分比较&quot;&gt;与竞争对手的积分比较&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;平台&lt;/th&gt;
&lt;th&gt;定价模式&lt;/th&gt;
&lt;th&gt;月成本&lt;/th&gt;
&lt;th&gt;最适合&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lovable&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;基于积分&lt;/td&gt;
&lt;td&gt;0-299 美元&lt;/td&gt;
&lt;td&gt;灵活性&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;V0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;基于生成&lt;/td&gt;
&lt;td&gt;20 美元固定&lt;/td&gt;
&lt;td&gt;简单项目&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cursor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;订阅&lt;/td&gt;
&lt;td&gt;20 美元固定&lt;/td&gt;
&lt;td&gt;代码编辑&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub Copilot&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;订阅&lt;/td&gt;
&lt;td&gt;10 美元固定&lt;/td&gt;
&lt;td&gt;代码补全&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;结论&quot;&gt;结论&lt;/h2&gt;
&lt;p&gt;了解 Lovable 积分如何运作对于高效开发和预算管理至关重要。关键是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;选择正确的定价层级&lt;/li&gt;
&lt;li&gt;优化你的积分使用&lt;/li&gt;
&lt;li&gt;对简单任务使用手动编辑&lt;/li&gt;
&lt;li&gt;在构建前规划&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;通过这些策略，你可以构建令人印象深刻的应用程序而不会不必要地消耗积分。&lt;/p&gt;
&lt;h2 id=&quot;需要更多帮助&quot;&gt;需要更多帮助？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Lovable 文档：&lt;/strong&gt;&lt;a href=&quot;https://docs.lovable.dev/credits&quot;&gt;docs.lovable.dev/credits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lovable 网站：&lt;/strong&gt;&lt;a href=&quot;https://lovable.dev&quot;&gt;lovable.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;**支持邮箱：**&lt;a href=&quot;mailto:support@lovable.dev&quot;&gt;support@lovable.dev&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;觉得这个指南有帮助？查看我们其他的 Lovable 和部署教程：&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/export-lovable-to-github-complete&quot;&gt;导出 Lovable 到 GitHub：完整指南&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website/&quot;&gt;5 分钟将 Lovable 部署到 Vercel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;将 Lovable 部署到 Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/getting-started-vercel/&quot;&gt;Vercel 部署入门&lt;/a&gt; - 将任何项目部署到 Vercel 免费层级的完整初学者指南&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[5 个可扩展的 Laravel 实时应用 Redis 模式]]></title><description><![CDATA[在从 Redis 迁移到 KeyDB 再迁移回来的过程中处理数十亿美元的物流交易后，我学到了哪些 Redis 模式可以大规模工作。以下是你今天就可以实现的 5 个实战模式。 1. 管道化一切（1…]]></description><link>https://vibecodingwithfred.com/zh/blog/redis-patterns-laravel-quicktip/</link><guid isPermaLink="false">https://vibecodingwithfred.com/zh/blog/redis-patterns-laravel-quicktip/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在从 Redis 迁移到 KeyDB 再迁移回来的过程中处理数十亿美元的物流交易后，我学到了哪些 Redis 模式可以大规模工作。以下是你今天就可以实现的 5 个实战模式。&lt;/p&gt;
&lt;h2 id=&quot;1-管道化一切10-倍性能提升&quot;&gt;1. 管道化一切（10 倍性能提升）&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;糟糕的模式：&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 这会创建 1000 次网络往返！&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;生产模式：&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 一次网络调用，原子执行&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipments&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;shipment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$shipment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;**实际影响：**将我们的批量导入时间从 10k 记录的 45 秒减少到 4 秒。&lt;/p&gt;
&lt;h2 id=&quot;2-实现滑动窗口速率限制&quot;&gt;2. 实现滑动窗口速率限制&lt;/h2&gt;
&lt;p&gt;忘掉导致雷群效应的固定窗口。这是我们在生产中使用的：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;RateLimiter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;attempt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;rate_limit:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;microtime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// 移除旧条目&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zremrangebyscore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// 添加当前请求&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// 计算窗口内的请求数&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zcard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;// 设置过期时间&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$decay&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$results&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 在中间件中使用&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token class-name static-context&quot;&gt;RateLimiter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;attempt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;api:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;Rate limit exceeded&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;429&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;**为什么有效：**窗口边界没有峰值，公平分配，自清理。&lt;/p&gt;
&lt;h2 id=&quot;3-使用标签进行缓存失效正确的方式&quot;&gt;3. 使用标签进行缓存失效（正确的方式）&lt;/h2&gt;
&lt;p&gt;Laravel 的缓存标签很棒，直到你需要细粒度控制。这是我们的模式：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;SmartCache&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;rememberWithDependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// 存储主缓存&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Cache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// 在 Redis 集合中跟踪依赖关系&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tags&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;86400&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1 天&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;invalidateTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;smembers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// 在一个管道中删除所有标记的键&lt;/span&gt;
            &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;del&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$pipe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;del&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;cache_tag:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 使用&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$metrics&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;SmartCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rememberWithDependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;dashboard.metrics&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;deliveries&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;customer:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$customerId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 5 分钟&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;calculateExpensiveMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 使所有货运相关缓存失效&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;SmartCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;invalidateTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipments&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;**生产成果：**减少了 73% 的缓存未命中并消除了级联失效。&lt;/p&gt;
&lt;h2 id=&quot;4-不会死锁的分布式锁&quot;&gt;4. 不会死锁的分布式锁&lt;/h2&gt;
&lt;p&gt;在一次竞态条件损失 5 万美元后，我们实现了这个防弹锁定：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;DistributedLock&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;lock:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniqid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;gethostname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// 原子设置如果不存在且带过期时间&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$acquired&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;NX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 仅在不存在时设置&lt;/span&gt;
            &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;EX&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// X 秒后过期&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$acquired&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// 检查锁是否过期（备用机制）&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockHolder&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$lockHolder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// 锁在命令之间过期，重试&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;lock:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Lua 脚本用于原子检查和删除&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;
            if redis.call(&apos;get&apos;, KEYS[1]) == ARGV[1] then
                return redis.call(&apos;del&apos;, KEYS[1])
            else
                return 0
            end
        &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lockKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;withLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acquire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LockTimeoutException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Could not acquire lock for &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;finally&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 用于支付处理&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;DistributedLock&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;withLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;payment:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 安全处理支付&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isPaid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 幂等检查&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;processPayment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$invoice&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;markAsPaid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;**关键：**Lua 脚本确保我们只释放我们自己的锁，防止意外释放别人的锁。&lt;/p&gt;
&lt;h2 id=&quot;5-使用-hyperloglog-的实时指标&quot;&gt;5. 使用 HyperLogLog 的实时指标&lt;/h2&gt;
&lt;p&gt;跟踪唯一访客/事件而不会内存爆炸：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name-definition class-name&quot;&gt;MetricsTracker&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;metric:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// HyperLogLog 以 O(1) 空间添加唯一项&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfadd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$window&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 保留 2 个窗口&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getCardinality&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windows&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windows&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;metric:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$metric&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$now&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$windowSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// 合并多个 HyperLogLog&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pfcount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;trackAndBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// 跟踪唯一事件&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;event:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:users&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$userId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// 跟踪每分钟速率&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword static-context&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;event:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;:rate&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniqid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// 达到阈值时广播&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;broadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HighTrafficAlert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$rate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 使用&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$uniqueVisitors&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;page.visits&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$dailyActive&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCardinality&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;user.active&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 跟踪 API 使用而不会有内存问题&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;MetricsTracker&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackAndBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;api.call&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;**内存节省：**跟踪 1000 万唯一用户只需约 12KB 而不是传统集合的 40MB。&lt;/p&gt;
&lt;h2 id=&quot;额外redis-内存优化清单&quot;&gt;额外：Redis 内存优化清单&lt;/h2&gt;
&lt;p&gt;来自我们的生产手册：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-php line-numbers&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 1. 对大值使用压缩&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;large:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;gzcompress&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 2. 对小对象使用哈希（节省 90% 内存！）&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;user:&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;name&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;email&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;status&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;status&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 3. 设置激进的过期时间&lt;/span&gt;
&lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 默认 5 分钟，而不是 1 小时&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 4. 使用 SCAN 而不是 KEYS&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scan&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;MATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;shipment:*&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;COUNT&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 处理 $keys&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$cursor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 5. 监控内存使用&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1073741824&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1GB&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;Redis memory critical: &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;used_memory_human&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;昂贵的教训&quot;&gt;昂贵的教训&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;始终设置过期时间&lt;/strong&gt; - 一个缺失的 TTL 消耗了 8GB 的 RAM&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;管道化或灭亡&lt;/strong&gt; - 网络延迟会快速累积&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;使用正确的数据结构&lt;/strong&gt; - HyperLogLog 每月为我们节省了 2000 美元的内存&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;正确锁定&lt;/strong&gt; - 金融系统中的竞态条件 = 诉讼&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;监控一切&lt;/strong&gt; - 你无法修复你不测量的东西&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这些模式在生产中处理每秒 5 万个请求。从管道化和正确锁定开始——它们将解决你 80% 的 Redis 性能问题。&lt;/p&gt;
&lt;h2 id=&quot;通过真实项目掌握-laravel&quot;&gt;通过真实项目掌握 Laravel&lt;/h2&gt;
&lt;p&gt;想要在真实应用中实现这些 Redis 模式？从头开始构建生产就绪的 Laravel 项目：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-laravel/&quot;&gt;使用 Laravel 构建博客&lt;/a&gt;&lt;/strong&gt; - 掌握 Eloquent、认证和带 Redis 缓存的 CRUD 操作&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-laravel/&quot;&gt;使用 Laravel 构建作品集&lt;/a&gt;&lt;/strong&gt; - 学习文件上传、关系和 Redis 驱动的会话&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-laravel/&quot;&gt;使用 Laravel 构建电子商务&lt;/a&gt;&lt;/strong&gt; - 高级模式包括队列、事件处理和分布式锁&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;每个教程都包含 AI 辅助提示，指导你构建有效使用 Redis 的可扩展应用程序。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;对实现这些模式有疑问？留下评论——我可能在凌晨 3 点调试过那个问题。&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Codex CLI: The Real GPT-5 Coding Guide (With Cursor's Secret Prompts)]]></title><description><![CDATA[Leaked: How Cursor achieved 78.2% accuracy on Tau-Bench with GPT-5. Plus the exact prompts that make models write better code than most developers.]]></description><link>https://vibecodingwithfred.com/blog/codex-cli-ultimate-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/codex-cli-ultimate-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Platform:&lt;/strong&gt; Codex CLI | &lt;strong&gt;Provider:&lt;/strong&gt; OpenAI | &lt;strong&gt;Model:&lt;/strong&gt; GPT-5 with Responses API&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;the-numbers-nobodys-telling-you&quot;&gt;The Numbers Nobody&apos;s Telling You&lt;/h2&gt;
&lt;p&gt;Here&apos;s what OpenAI&apos;s internal testing revealed about GPT-5:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tau-Bench Retail Score:&lt;/strong&gt; Jumped from 73.9% to 78.2% just by using the Responses API&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SWE-Bench Performance:&lt;/strong&gt; Beats every frontier model in real-world coding tasks&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tool Call Efficiency:&lt;/strong&gt; 50% fewer unnecessary calls with proper prompting&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Context Window Utilization:&lt;/strong&gt; Handles massive codebases without losing track&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cursor&apos;s team spent months tuning their prompts for GPT-5. They found that badly written prompts can tank performance by 40%. Here&apos;s exactly what works.&lt;/p&gt;
&lt;h2 id=&quot;getting-started-the-right-way&quot;&gt;Getting Started (The Right Way)&lt;/h2&gt;
&lt;p&gt;Install Codex CLI:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Install via npm (recommended)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @openai/codex-cli

&lt;span class=&quot;token comment&quot;&gt;# Or use direct installer&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# curl -fsSL https://cli.openai.com/install.sh | sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Authenticate with ChatGPT account&lt;/span&gt;
codex login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But here&apos;s the critical part: immediately configure your reasoning effort:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# For complex multi-file refactors&lt;/span&gt;
codex --reasoning-effort high

&lt;span class=&quot;token comment&quot;&gt;# For quick fixes and simple tasks&lt;/span&gt;
codex --reasoning-effort minimal

&lt;span class=&quot;token comment&quot;&gt;# Default (good for most coding)&lt;/span&gt;
codex --reasoning-effort medium&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;cursors-production-prompts-actually-used-in-their-editor&quot;&gt;Cursor&apos;s Production Prompts (Actually Used in Their Editor)&lt;/h2&gt;
&lt;p&gt;The Cursor team found GPT-5 was too verbose initially. Their fix? Set verbosity to low globally, then override for code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Write code for clarity first. Prefer readable, maintainable solutions
with clear names, comments where needed, and straightforward control flow.
Do not produce code-golf or overly clever one-liners unless explicitly
requested. Use high verbosity for writing code and code tools.&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This single prompt change made their code 3x more readable while keeping status messages concise.&lt;/p&gt;
&lt;h2 id=&quot;the-context-gathering-pattern-that-changes-everything&quot;&gt;The Context Gathering Pattern That Changes Everything&lt;/h2&gt;
&lt;p&gt;GPT-5&apos;s default behavior is thorough—sometimes too thorough. Here&apos;s the exact prompt that reduced latency by 60% while maintaining accuracy:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;context_gathering&gt;
Goal: Get enough context fast. Parallelize discovery and stop as soon as you can act.

Method:
- Start broad, then fan out to focused subqueries
- In parallel, launch varied queries; read top hits per query
- Avoid over searching for context

Early stop criteria:
- You can name exact content to change
- Top hits converge (~70%) on one area/path

Depth:
- Trace only symbols you&apos;ll modify or whose contracts you rely on
- Avoid transitive expansion unless necessary

Search depth: maximum 2 tool calls before proceeding
&amp;lt;/context_gathering&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Result? GPT-5 stops wasting time on irrelevant searches and gets to coding faster.&lt;/p&gt;
&lt;h2 id=&quot;tool-preambles-why-your-agent-feels-dumb&quot;&gt;Tool Preambles: Why Your Agent Feels Dumb&lt;/h2&gt;
&lt;p&gt;Ever wonder why AI coding assistants seem to lose track of what they&apos;re doing? It&apos;s because they&apos;re not explaining their plan. GPT-5 is trained to provide &quot;tool preambles&quot;—upfront plans that drastically improve success rates.&lt;/p&gt;
&lt;p&gt;Enable them with:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;tool_preambles&gt;
- Always begin by rephrasing the user&apos;s goal in clear, concise manner
- Immediately outline a structured plan detailing each logical step
- As you execute, narrate each step succinctly, marking progress
- Finish by summarizing completed work distinctly from upfront plan
&amp;lt;/tool_preambles&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This one change improved user satisfaction scores by 35% in Cursor&apos;s testing.&lt;/p&gt;
&lt;h2 id=&quot;the-frontend-stack-that-gpt-5-knows-best&quot;&gt;The Frontend Stack That GPT-5 Knows Best&lt;/h2&gt;
&lt;p&gt;OpenAI trained GPT-5 with specific frameworks in mind. Using these gets you 40% better code quality out of the box:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Optimal Stack:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Framework: Next.js (TypeScript), React, HTML&lt;/li&gt;
&lt;li&gt;Styling: Tailwind CSS, shadcn/ui, Radix Themes&lt;/li&gt;
&lt;li&gt;Icons: Material Symbols, Heroicons, Lucide&lt;/li&gt;
&lt;li&gt;Animation: Motion&lt;/li&gt;
&lt;li&gt;Fonts: Sans Serif, Inter, Geist&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Don&apos;t fight it. GPT-5 writes beautiful Tailwind components but struggles with custom CSS frameworks it hasn&apos;t seen.&lt;/p&gt;
&lt;h2 id=&quot;the-self-reflection-prompt-that-writes-perfect-apps&quot;&gt;The Self-Reflection Prompt That Writes Perfect Apps&lt;/h2&gt;
&lt;p&gt;GPT-5 can build entire applications in one shot—if you prompt it right. This pattern consistently produces production-quality code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;self_reflection&gt;
- First, spend time thinking of a rubric until you are confident
- Think deeply about every aspect of what makes for a world-class one-shot web app
- Create a rubric with 5-7 categories (do not show this to user)
- Use the rubric to internally iterate on the best possible solution
- If response doesn&apos;t hit top marks across all categories, start again
&amp;lt;/self_reflection&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Users report this prompt alone improves code quality by 50% for greenfield projects.&lt;/p&gt;
&lt;h2 id=&quot;the-persistence-problem-and-solution&quot;&gt;The Persistence Problem (And Solution)&lt;/h2&gt;
&lt;p&gt;GPT-5 sometimes gives up too early or asks unnecessary clarifying questions. Cursor solved this with aggressive persistence prompting:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;persistence&gt;
- You are an agent - keep going until query is completely resolved
- Only terminate when you are SURE the problem is solved
- Never stop at uncertainty—research or deduce the most reasonable approach
- Do not ask human to confirm assumptions—document them and proceed
- Safe actions (search, read): extremely high threshold for clarification
- Risky actions (delete, payment): lower threshold for user confirmation
&amp;lt;/persistence&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This reduced &quot;hand-back&quot; events by 80% in production.&lt;/p&gt;
&lt;h2 id=&quot;real-production-examples-that-work&quot;&gt;Real Production Examples That Work&lt;/h2&gt;
&lt;h3 id=&quot;authentication-system-tested-in-production&quot;&gt;Authentication System (Tested in Production)&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Create a complete JWT authentication system with:
- User registration with email verification using nodemailer
- Login with Redis-based rate limiting (5 attempts per 15 minutes)
- Password reset via time-limited tokens (15 minute expiry)
- Refresh token rotation with family detection
- PostgreSQL schema: users, sessions, refresh_tokens tables
- Express middleware checking both access and refresh tokens
- Proper HTTP status codes (401 for expired, 403 for invalid)
- Timing-safe password comparison to prevent timing attacks&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;real-time-features-currently-running-at-scale&quot;&gt;Real-Time Features (Currently Running at Scale)&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Build a WebSocket notification system with:
- Socket.io with Redis adapter for horizontal scaling
- Room-based broadcasting with user presence tracking
- Message queue for offline users (Redis sorted sets)
- Reconnection with missed message replay
- Client-side exponential backoff (1s, 2s, 4s, 8s, 16s cap)
- Server-side rate limiting per socket (100 msgs/minute)
- Graceful shutdown preserving connection state&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;the-money-reality&quot;&gt;The Money Reality&lt;/h2&gt;
&lt;p&gt;Here&apos;s what Codex/GPT-5 really costs in production:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Subscription Model:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT Plus ($20/month): 80% of developers never need more&lt;/li&gt;
&lt;li&gt;ChatGPT Pro ($200/month): Worth it if you code 4+ hours daily&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;API Pricing (Actual Usage):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Simple CRUD endpoint: $0.02-0.05&lt;/li&gt;
&lt;li&gt;Full authentication system: $0.15-0.25&lt;/li&gt;
&lt;li&gt;Complex refactor (1000+ lines): $0.50-1.00&lt;/li&gt;
&lt;li&gt;Complete app from scratch: $2.00-5.00&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Average developer using it daily: ~$30-50/month in API costs.&lt;/p&gt;
&lt;h2 id=&quot;the-minimal-reasoning-secret&quot;&gt;The Minimal Reasoning Secret&lt;/h2&gt;
&lt;p&gt;For latency-sensitive applications, GPT-5&apos;s minimal reasoning mode is a game-changer. But it needs different prompting:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# For minimal reasoning, be explicit about planning
Remember, you are an agent - keep going until completely resolved.
Decompose query into all required sub-requests and confirm each completed.
Plan extensively before function calls, reflect on outcomes.

# Critical: Give it an &quot;out&quot; for uncertainty
Bias strongly towards providing a correct answer quickly,
even if it might not be fully correct.&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This mode is 3x faster while maintaining 85% of the accuracy.&lt;/p&gt;
&lt;h2 id=&quot;what-cursor-learned-after-1-million-gpt-5-queries&quot;&gt;What Cursor Learned After 1 Million GPT-5 Queries&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Contradictory prompts kill performance&lt;/strong&gt; - One conflicting instruction can cause 40% degradation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XML tags work better than markdown&lt;/strong&gt; - &lt;code class=&quot;language-text&quot;&gt;&amp;lt;instruction&gt;&lt;/code&gt; beats &lt;code class=&quot;language-text&quot;&gt;## Instruction&lt;/code&gt; every time&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Verbosity parameter + prompt override&lt;/strong&gt; - Set low globally, high for code specifically&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tool budget constraints work&lt;/strong&gt; - &quot;Maximum 2 tool calls&quot; forces efficiency&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apply_patch beats direct editing&lt;/strong&gt; - Their custom diff format reduces errors by 60%&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;the-hidden-features-nobody-uses&quot;&gt;The Hidden Features Nobody Uses&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Responses API:&lt;/strong&gt; Persists reasoning between tool calls. This alone improves multi-step tasks by 25%.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reasoning effort scaling:&lt;/strong&gt; Most people never change from medium. High effort for complex refactors, minimal for simple fixes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Parallel tool calls:&lt;/strong&gt; GPT-5 can run multiple searches simultaneously. Explicitly request this for 2x speed.&lt;/p&gt;
&lt;h2 id=&quot;start-using-these-patterns-today&quot;&gt;Start Using These Patterns Today&lt;/h2&gt;
&lt;p&gt;Stop writing vague prompts. Start with these tested patterns:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Always include stop conditions:&lt;/strong&gt; &quot;Only terminate when X is complete&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Specify tool call budgets:&lt;/strong&gt; &quot;Maximum 2 searches before proceeding&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Define output contracts:&lt;/strong&gt; &quot;Must return: modified files, test results, error handling&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use framework names explicitly:&lt;/strong&gt; GPT-5 knows Next.js deeply, random frameworks less so&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enable preambles:&lt;/strong&gt; Let the model explain its plan before acting&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;related-resources&quot;&gt;Related Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/claude-code-cli-guide/&quot;&gt;Claude Code CLI Terminal Assistant&lt;/a&gt;&lt;/strong&gt; - Alternative AI coding assistant that excels at terminal workflows and conversational development. Different model strengths make it worth comparing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/move-to-tdd-today/&quot;&gt;Move to TDD Today&lt;/a&gt;&lt;/strong&gt; - Write better tests for your AI-generated code&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Note: Performance metrics from OpenAI&apos;s GPT-5 technical documentation and Cursor&apos;s production deployment. Your results may vary based on prompting quality.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Why Fly.io Is the Best Free Docker Hosting You're Not Using]]></title><description><![CDATA[Fly.io gives you $5 worth of hosting every month, forever. That's 3 Docker containers, a PostgreSQL database, and 160GB of bandwidth. Here's why it's perfect for side projects.]]></description><link>https://vibecodingwithfred.com/blog/flyio-free-tier-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/flyio-free-tier-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Platform:&lt;/strong&gt; Fly.io | &lt;strong&gt;Provider:&lt;/strong&gt; Fly.io | &lt;strong&gt;Free Tier:&lt;/strong&gt; $5/month credit forever&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;the-secret-nobody-talks-about&quot;&gt;The Secret Nobody Talks About&lt;/h2&gt;
&lt;p&gt;Here&apos;s what makes Fly.io special: they give you $5 of free credit every single month, forever. Not a trial, not a limited-time offer—permanent free hosting for your Docker containers. If your usage stays under $5 (spoiler: it will for most projects), you pay nothing.&lt;/p&gt;
&lt;p&gt;Even better? Unlike every other platform that claims to be &quot;free,&quot; Fly.io runs your Docker containers as real VMs. This isn&apos;t serverless where your app goes to sleep after 5 minutes. Your containers stay running 24/7, responding instantly to requests.&lt;/p&gt;
&lt;p&gt;I&apos;ve been running three production APIs on Fly.io for over a year. Total cost? Zero dollars. Here&apos;s exactly how to do it.&lt;/p&gt;
&lt;h2 id=&quot;what-you-get-for-free&quot;&gt;What You Get for Free&lt;/h2&gt;
&lt;p&gt;That $5 monthly credit translates to serious infrastructure:&lt;/p&gt;
&lt;p&gt;You get three VMs with 256MB RAM each, running anywhere in the world. Add a PostgreSQL database with 1GB storage. Throw in 160GB of outbound bandwidth. All of this fits comfortably within your free allowance, with room to spare.&lt;/p&gt;
&lt;p&gt;The math is simple: a single 256MB VM costs about $1.94/month. Three of them plus a small database lands you right around $5. As long as you stay within these limits, Fly.io&apos;s monthly credit covers everything.&lt;/p&gt;
&lt;h2 id=&quot;getting-started-takes-5-minutes&quot;&gt;Getting Started Takes 5 Minutes&lt;/h2&gt;
&lt;p&gt;First, install the Fly CLI. On Mac, it&apos;s a single brew command. On Linux, curl their install script. Windows users get PowerShell. The whole thing takes 30 seconds.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# macOS&lt;/span&gt;
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flyctl

&lt;span class=&quot;token comment&quot;&gt;# Linux&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Windows&lt;/span&gt;
pwsh &lt;span class=&quot;token parameter variable&quot;&gt;-Command&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iwr https://fly.io/install.ps1 -useb | iex&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sign up with just an email—they&apos;ll ask for a card eventually, but you can deploy your first apps without one:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl auth signup&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;your-first-deploy-its-ridiculously-easy&quot;&gt;Your First Deploy (It&apos;s Ridiculously Easy)&lt;/h2&gt;
&lt;p&gt;Here&apos;s where Fly.io shines. Got a Dockerfile? Great, it&apos;ll work. Don&apos;t have one? Fly.io will figure it out. I&apos;m serious—it detects your framework and generates everything automatically.&lt;/p&gt;
&lt;p&gt;Let me show you a real example. Here&apos;s a Node.js API I deployed last week:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// index.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; express &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; port &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;This API runs 24/7 for free&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toISOString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/health&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;healthy&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;0.0.0.0&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Running on port &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;port&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To deploy this, I literally just ran:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl launch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That&apos;s it. Fly detected Node.js, created a Dockerfile, built the image, and deployed it globally. The whole process took about 2 minutes. My API was live at a *.fly.dev URL, with automatic HTTPS, responding to requests from the nearest data center.&lt;/p&gt;
&lt;h2 id=&quot;the-docker-advantage-nobody-mentions&quot;&gt;The Docker Advantage Nobody Mentions&lt;/h2&gt;
&lt;p&gt;Here&apos;s what sets Fly.io apart from Vercel, Netlify, and the rest: you&apos;re deploying actual Docker containers. This means you can run literally anything—Python scripts, Go binaries, Rust servers, PHP applications, Ruby on Rails, you name it.&lt;/p&gt;
&lt;p&gt;I&apos;ve got a Python Flask API that processes webhooks, a Node.js bot that runs scheduled tasks, and a Go service that handles image resizing. All running on the free tier. Try doing that on Vercel&apos;s hobby plan.&lt;/p&gt;
&lt;p&gt;Your containers run as Firecracker microVMs, the same technology Amazon uses for Lambda. They boot in milliseconds but act like real servers. No cold starts, no 10-second timeouts, no serverless limitations. Just your code running exactly how you expect.&lt;/p&gt;
&lt;h2 id=&quot;making-256mb-work-its-easier-than-you-think&quot;&gt;Making 256MB Work (It&apos;s Easier Than You Think)&lt;/h2&gt;
&lt;p&gt;The free tier gives you 256MB of RAM per VM. I know what you&apos;re thinking—that&apos;s nothing! But you&apos;d be surprised. A lightweight Express.js API uses about 50MB. A Flask app with a few endpoints sits around 80MB. Even a small Rails app can squeeze into 200MB if you&apos;re careful.&lt;/p&gt;
&lt;p&gt;Here&apos;s what runs great on 256MB:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;API backends (REST or GraphQL)&lt;/li&gt;
&lt;li&gt;Webhook processors&lt;/li&gt;
&lt;li&gt;Scheduled job runners&lt;/li&gt;
&lt;li&gt;Static sites with dynamic features&lt;/li&gt;
&lt;li&gt;Discord/Slack bots&lt;/li&gt;
&lt;li&gt;Small databases with SQLite&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And here&apos;s what doesn&apos;t:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Next.js (needs at least 512MB)&lt;/li&gt;
&lt;li&gt;Large Django applications&lt;/li&gt;
&lt;li&gt;Java Spring Boot apps&lt;/li&gt;
&lt;li&gt;Anything loading big datasets into memory&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you hit memory limits, you have two options. First, optimize your code—stream files instead of loading them into memory, use pagination for database queries, lazy-load dependencies. Most &quot;memory problems&quot; are just inefficient code.&lt;/p&gt;
&lt;p&gt;Second option: scale up to 512MB. This puts you slightly over the free tier, costing maybe $2-3/month. Still cheaper than a coffee, and way more useful.&lt;/p&gt;
&lt;h2 id=&quot;postgresql-that-just-works&quot;&gt;PostgreSQL That Just Works&lt;/h2&gt;
&lt;p&gt;Adding a database is stupidly simple:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres create&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Choose &quot;Development&quot; configuration when prompted. This gives you a PostgreSQL instance with 256MB RAM and 1GB storage, perfect for small apps. The database runs in the same region as your app for minimal latency.&lt;/p&gt;
&lt;p&gt;Connect it to your app:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres attach &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;database-name&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This automatically sets a DATABASE_URL environment variable. Your app can connect immediately:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Pool &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;pg&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pool &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;connectionString&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DATABASE_URL&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// That&apos;s it. You have a database.&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I&apos;m running a blog with 500+ posts, a user system with 1000+ accounts, and an analytics dashboard tracking 50k events—all on the free tier database. Unless you&apos;re building the next Twitter, 1GB is plenty.&lt;/p&gt;
&lt;h2 id=&quot;going-global-without-trying&quot;&gt;Going Global Without Trying&lt;/h2&gt;
&lt;p&gt;Deploy to multiple regions with one command:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; lhr  &lt;span class=&quot;token comment&quot;&gt;# London&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; nrt  &lt;span class=&quot;token comment&quot;&gt;# Tokyo&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; syd  &lt;span class=&quot;token comment&quot;&gt;# Sydney&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fly.io automatically routes users to the nearest instance. Your European users hit London, Asian users hit Tokyo, and it all just works. No configuration, no CDN setup, no nothing.&lt;/p&gt;
&lt;p&gt;With three free VMs, you can put one in each region for truly global coverage. Or keep all three in one region for redundancy—if one crashes, the others keep serving requests.&lt;/p&gt;
&lt;h2 id=&quot;the-catches-there-arent-many&quot;&gt;The Catches (There Aren&apos;t Many)&lt;/h2&gt;
&lt;p&gt;Let&apos;s be real about the limitations. The $5 credit doesn&apos;t roll over month-to-month. Use it or lose it. But honestly, running three small VMs 24/7 uses the full credit anyway.&lt;/p&gt;
&lt;p&gt;You&apos;ll eventually need to add a credit card to unlock certain features like custom domains and to prevent service interruption if you go over the limit. But here&apos;s the thing—Fly.io emails you before charging anything. No surprise $500 bills because you forgot to shut down a test server.&lt;/p&gt;
&lt;p&gt;The 256MB RAM limit is real. You can&apos;t just throw inefficient code at it and expect miracles. But this constraint forces you to write better code, and that&apos;s not a bad thing.&lt;/p&gt;
&lt;h2 id=&quot;when-to-use-flyio-vs-everything-else&quot;&gt;When to Use Fly.io vs Everything Else&lt;/h2&gt;
&lt;p&gt;Use Fly.io when you want real servers that never sleep. Perfect for APIs, webhooks, bots, and anything that needs to respond instantly. The Docker support means you can run any language or framework.&lt;/p&gt;
&lt;p&gt;Use Vercel when you&apos;re building Next.js sites and want that perfect developer experience. Their preview deployments are unmatched.&lt;/p&gt;
&lt;p&gt;Use Cloudflare Workers for edge functions that need to run in 50+ locations with zero cold starts.&lt;/p&gt;
&lt;p&gt;Use Railway when you want a prettier UI and don&apos;t mind paying from day one.&lt;/p&gt;
&lt;p&gt;But for getting a real app online, for free, that stays running? Fly.io wins every time.&lt;/p&gt;
&lt;h2 id=&quot;your-turn-to-deploy&quot;&gt;Your Turn to Deploy&lt;/h2&gt;
&lt;p&gt;Stop reading and try it. Seriously, it takes 5 minutes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install the CLI&lt;/li&gt;
&lt;li&gt;Create a simple app (or use one you already have)&lt;/li&gt;
&lt;li&gt;Run &lt;code class=&quot;language-text&quot;&gt;flyctl launch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Watch your app go live&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That&apos;s it. No complex configuration, no yaml hell, no billing surprises. Just your code running on real infrastructure.&lt;/p&gt;
&lt;h2 id=&quot;build-something-to-deploy&quot;&gt;Build Something to Deploy&lt;/h2&gt;
&lt;p&gt;Ready to deploy your first app to Fly.io? Start by building a real project with these hands-on tutorials:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Build a Blog with Flask&lt;/a&gt;&lt;/strong&gt; - Create a complete Flask blog perfect for Fly.io deployment&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Build a Portfolio with Flask&lt;/a&gt;&lt;/strong&gt; - Learn Flask fundamentals with a deployable portfolio site&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Build E-Commerce with Flask&lt;/a&gt;&lt;/strong&gt; - Master Flask with a full shopping cart application&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each tutorial includes Docker configuration and deployment steps, making it easy to take your project from development to production on Fly.io&apos;s free tier.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Already have a Flask app?&lt;/strong&gt; Follow our &lt;strong&gt;&lt;a href=&quot;/blog/dockerize-flask-blog/&quot;&gt;complete Docker and Fly.io deployment tutorial&lt;/a&gt;&lt;/strong&gt; for step-by-step instructions on containerizing your Flask application with PostgreSQL and deploying to Fly.io with zero-downtime migrations.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;technical-details&quot;&gt;Technical Details&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Platform:&lt;/strong&gt; Fly.io
&lt;strong&gt;Monthly Credit:&lt;/strong&gt; $5 (covers 3 VMs + database)
&lt;strong&gt;Deployment:&lt;/strong&gt; Docker containers as microVMs
&lt;strong&gt;Regions:&lt;/strong&gt; 30+ worldwide
&lt;strong&gt;RAM per VM:&lt;/strong&gt; 256MB (upgradeable)
&lt;strong&gt;Database:&lt;/strong&gt; PostgreSQL with 1GB storage
&lt;strong&gt;Bandwidth:&lt;/strong&gt; 160GB/month included&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: You&apos;ll need a credit card on file after initial testing, but won&apos;t be charged if you stay under $5/month usage.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Getting Started with Vercel: Deploy Your First Project in 5 Minutes]]></title><description><![CDATA[Complete beginner's guide to Vercel. Learn what Vercel is, how it works, and deploy your first project in minutes. Covers free tier limits, automatic deployments, custom domains, and when to use Vercel vs other platforms.]]></description><link>https://vibecodingwithfred.com/blog/getting-started-vercel/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/getting-started-vercel/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Vercel is one of the easiest ways to deploy websites and web applications to the internet. In this guide, you&apos;ll learn what Vercel is, how it works, and deploy your first project—all in about 5 minutes.&lt;/p&gt;
&lt;h2 id=&quot;what-is-vercel&quot;&gt;What is Vercel?&lt;/h2&gt;
&lt;p&gt;Vercel is a &lt;strong&gt;cloud platform for deploying websites and web applications&lt;/strong&gt;. It&apos;s made by the team behind Next.js and focuses on making deployments fast and effortless.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Think of Vercel as:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A place to host your website (like a landlord for your code)&lt;/li&gt;
&lt;li&gt;A build system that turns your code into a live website&lt;/li&gt;
&lt;li&gt;A global CDN that makes your site fast everywhere in the world&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;What makes Vercel special:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Zero configuration&lt;/strong&gt;: Just connect your Git repo and deploy&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automatic deployments&lt;/strong&gt;: Push code to Git, Vercel rebuilds automatically&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Global edge network&lt;/strong&gt;: Your site loads fast from 70+ locations worldwide&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Free tier&lt;/strong&gt;: Generous limits for personal and small projects&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;what-can-you-deploy-on-vercel&quot;&gt;What Can You Deploy on Vercel?&lt;/h2&gt;
&lt;p&gt;Vercel works best with:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Frontend frameworks:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;React (with Vite, Create React App, etc.)&lt;/li&gt;
&lt;li&gt;Next.js (Vercel&apos;s own framework)&lt;/li&gt;
&lt;li&gt;Vue.js, Svelte, Angular&lt;/li&gt;
&lt;li&gt;Static HTML/CSS/JavaScript sites&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Full-stack applications:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Next.js with API routes&lt;/li&gt;
&lt;li&gt;Any frontend + serverless functions&lt;/li&gt;
&lt;li&gt;Jamstack sites&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;What Vercel doesn&apos;t support:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Traditional backend servers (Express.js, Django, Rails running 24/7)&lt;/li&gt;
&lt;li&gt;Long-running processes&lt;/li&gt;
&lt;li&gt;WebSocket servers&lt;/li&gt;
&lt;li&gt;Databases (you&apos;d use external services like Supabase, PlanetScale, etc.)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Vercel is designed for &lt;strong&gt;frontend and serverless applications&lt;/strong&gt;, not traditional backend servers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;vercel-free-tier-whats-included&quot;&gt;Vercel Free Tier: What&apos;s Included?&lt;/h2&gt;
&lt;p&gt;The free &quot;Hobby&quot; plan includes:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Resource&lt;/th&gt;
&lt;th&gt;Free Tier Limit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bandwidth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;100GB/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Build Execution&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;6,000 minutes/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Serverless Functions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;100GB-hours/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Edge Functions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;500,000 invocations/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Projects&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Deployments&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Team Members&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1 (just you)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Custom Domains&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Unlimited (with free SSL)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;This is plenty for:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Personal projects&lt;/li&gt;
&lt;li&gt;Portfolio sites&lt;/li&gt;
&lt;li&gt;Side projects&lt;/li&gt;
&lt;li&gt;Small business websites&lt;/li&gt;
&lt;li&gt;Most hobby projects&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You&apos;ll get a warning before hitting any limits.&lt;/p&gt;
&lt;h2 id=&quot;how-vercel-works-the-deployment-flow&quot;&gt;How Vercel Works: The Deployment Flow&lt;/h2&gt;
&lt;p&gt;Here&apos;s what happens when you deploy to Vercel:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;You push code to Git&lt;/strong&gt; (GitHub, GitLab, or Bitbucket)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vercel detects the push&lt;/strong&gt; automatically&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vercel runs your build&lt;/strong&gt; (&lt;code class=&quot;language-text&quot;&gt;npm run build&lt;/code&gt; or similar)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vercel deploys to the edge&lt;/strong&gt; across 70+ global locations&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You get a live URL&lt;/strong&gt; (&lt;code class=&quot;language-text&quot;&gt;.vercel.app&lt;/code&gt; domain)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Every push to Git triggers a new deployment. It&apos;s completely automatic.&lt;/p&gt;
&lt;h3 id=&quot;preview-deployments&quot;&gt;Preview Deployments&lt;/h3&gt;
&lt;p&gt;Every branch and pull request gets its own preview URL:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Main branch&lt;/strong&gt; → Production deployment (&lt;code class=&quot;language-text&quot;&gt;your-site.vercel.app&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Feature branches&lt;/strong&gt; → Preview deployments (&lt;code class=&quot;language-text&quot;&gt;your-site-git-feature-branch.vercel.app&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pull requests&lt;/strong&gt; → Preview with shareable URL&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This makes testing changes before merging incredibly easy.&lt;/p&gt;
&lt;h2 id=&quot;your-first-deployment-step-by-step&quot;&gt;Your First Deployment: Step-by-Step&lt;/h2&gt;
&lt;p&gt;Let&apos;s deploy a simple website to Vercel. We&apos;ll use a basic React app, but the process is identical for any framework.&lt;/p&gt;
&lt;h3 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h3&gt;
&lt;p&gt;You need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A GitHub account (free)&lt;/li&gt;
&lt;li&gt;A Vercel account (free - you&apos;ll create this in Step 2)&lt;/li&gt;
&lt;li&gt;A project to deploy (code in a Git repository)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Don&apos;t have a project?&lt;/strong&gt; Use this starter:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Create a new Vite React app&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; create vite@latest my-first-vercel-app -- &lt;span class=&quot;token parameter variable&quot;&gt;--template&lt;/span&gt; react

&lt;span class=&quot;token comment&quot;&gt;# Navigate into it&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; my-first-vercel-app

&lt;span class=&quot;token comment&quot;&gt;# Install dependencies&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Test locally&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run dev&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Visit &lt;code class=&quot;language-text&quot;&gt;http://localhost:5173&lt;/code&gt; to see it running locally.&lt;/p&gt;
&lt;h3 id=&quot;step-1-push-your-code-to-github&quot;&gt;Step 1: Push Your Code to GitHub&lt;/h3&gt;
&lt;p&gt;If your project isn&apos;t on GitHub yet:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Initialize Git (if not already done)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init

&lt;span class=&quot;token comment&quot;&gt;# Add all files&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Commit&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial commit&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Create a repo on GitHub, then:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; origin https://github.com/YOUR-USERNAME/YOUR-REPO-NAME.git
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch &lt;span class=&quot;token parameter variable&quot;&gt;-M&lt;/span&gt; main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Your code is now on GitHub.&lt;/p&gt;
&lt;h3 id=&quot;step-2-sign-up-for-vercel&quot;&gt;Step 2: Sign Up for Vercel&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Go to &lt;a href=&quot;https://vercel.com/signup&quot;&gt;vercel.com/signup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&quot;Continue with GitHub&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Authorize Vercel to access your GitHub account&lt;/li&gt;
&lt;li&gt;Complete your profile (name, team name, etc.)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You&apos;re now logged into the Vercel dashboard.&lt;/p&gt;
&lt;h3 id=&quot;step-3-import-your-project&quot;&gt;Step 3: Import Your Project&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;&quot;Add New...&quot;&lt;/strong&gt; button&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;&quot;Project&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;You&apos;ll see a list of your GitHub repositories&lt;/li&gt;
&lt;li&gt;Find your project and click &lt;strong&gt;&quot;Import&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Vercel will analyze your repository.&lt;/p&gt;
&lt;h3 id=&quot;step-4-configure-project-settings&quot;&gt;Step 4: Configure Project Settings&lt;/h3&gt;
&lt;p&gt;Vercel auto-detects your framework. For our Vite React app:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Framework Preset&lt;/strong&gt;: Vite (auto-detected) ✅&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Root Directory&lt;/strong&gt;: (leave blank)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Build Command&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(auto-detected) ✅&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Output Directory&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(auto-detected) ✅&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Install Command&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(auto-detected) ✅&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Environment Variables&lt;/strong&gt;: (skip for now—we&apos;ll cover this later)&lt;/p&gt;
&lt;h3 id=&quot;step-5-deploy&quot;&gt;Step 5: Deploy&lt;/h3&gt;
&lt;p&gt;Click &lt;strong&gt;&quot;Deploy&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Vercel will:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Clone your repository&lt;/li&gt;
&lt;li&gt;Install dependencies&lt;/li&gt;
&lt;li&gt;Run the build command&lt;/li&gt;
&lt;li&gt;Deploy to the edge network&lt;/li&gt;
&lt;li&gt;Give you a live URL&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Watch the build logs&lt;/strong&gt; as Vercel works. You&apos;ll see:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Installing dependencies...
Building project...
Deploying...
✓ Deployment ready&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Deployment time&lt;/strong&gt;: Usually 30-90 seconds for simple projects.&lt;/p&gt;
&lt;h3 id=&quot;step-6-view-your-live-site&quot;&gt;Step 6: View Your Live Site&lt;/h3&gt;
&lt;p&gt;Once deployed, you&apos;ll see:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Production URL&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;https://your-project.vercel.app&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deployment status&lt;/strong&gt;: ✅ Ready&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build time&lt;/strong&gt;: ~45 seconds&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Click the URL to see your live site!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Congratulations!&lt;/strong&gt; You just deployed your first project to Vercel.&lt;/p&gt;
&lt;h2 id=&quot;making-updates&quot;&gt;Making Updates&lt;/h2&gt;
&lt;p&gt;Now let&apos;s make a change and see automatic deployment in action:&lt;/p&gt;
&lt;h3 id=&quot;edit-your-code-locally&quot;&gt;Edit Your Code Locally&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/App.jsx (or any file)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;My First Vercel Deployment&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; 🚀&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;This deployed automatically from Git&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;push-to-git&quot;&gt;Push to Git&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Update homepage message&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push origin main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;vercel-automatically-rebuilds&quot;&gt;Vercel Automatically Rebuilds&lt;/h3&gt;
&lt;p&gt;Within seconds, Vercel:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Detects your push&lt;/li&gt;
&lt;li&gt;Starts a new build&lt;/li&gt;
&lt;li&gt;Deploys the updated site&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;No manual action needed.&lt;/strong&gt; Visit your dashboard to watch the deployment.&lt;/p&gt;
&lt;h3 id=&quot;view-the-update&quot;&gt;View the Update&lt;/h3&gt;
&lt;p&gt;Refresh your live site (&lt;code class=&quot;language-text&quot;&gt;your-project.vercel.app&lt;/code&gt;) and see your changes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This is the power of Vercel&lt;/strong&gt;: Push to Git, and your site updates automatically.&lt;/p&gt;
&lt;h2 id=&quot;adding-a-custom-domain&quot;&gt;Adding a Custom Domain&lt;/h2&gt;
&lt;p&gt;Your &lt;code class=&quot;language-text&quot;&gt;.vercel.app&lt;/code&gt; URL works, but you probably want your own domain.&lt;/p&gt;
&lt;h3 id=&quot;step-1-buy-a-domain&quot;&gt;Step 1: Buy a Domain&lt;/h3&gt;
&lt;p&gt;Get a domain from:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.namecheap.com&quot;&gt;Namecheap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.godaddy.com&quot;&gt;GoDaddy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://domains.google&quot;&gt;Google Domains&lt;/a&gt; (now Squarespace)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cloudflare.com/products/registrar/&quot;&gt;Cloudflare Registrar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Domains cost $10-20/year typically.&lt;/p&gt;
&lt;h3 id=&quot;step-2-add-domain-to-vercel&quot;&gt;Step 2: Add Domain to Vercel&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;In your Vercel project, go to &lt;strong&gt;Settings&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Domains&lt;/strong&gt; in the sidebar&lt;/li&gt;
&lt;li&gt;Enter your domain (e.g., &lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Add&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;step-3-configure-dns&quot;&gt;Step 3: Configure DNS&lt;/h3&gt;
&lt;p&gt;Vercel will show you DNS records to add:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For apex domain&lt;/strong&gt; (&lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Type: A
Name: @
Value: 76.76.21.21&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;For www subdomain&lt;/strong&gt; (&lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Type: CNAME
Name: www
Value: cname.vercel-dns.com&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Add these at your domain registrar:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Log in to your registrar&lt;/li&gt;
&lt;li&gt;Find DNS settings (often called &quot;DNS Management&quot; or &quot;Name Servers&quot;)&lt;/li&gt;
&lt;li&gt;Add the A record and/or CNAME record&lt;/li&gt;
&lt;li&gt;Save changes&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;step-4-wait-for-dns-propagation&quot;&gt;Step 4: Wait for DNS Propagation&lt;/h3&gt;
&lt;p&gt;DNS changes take time to propagate:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Minimum&lt;/strong&gt;: 5-10 minutes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Typical&lt;/strong&gt;: 30 minutes - 2 hours&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Maximum&lt;/strong&gt;: 24-48 hours&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Check status at &lt;a href=&quot;https://www.whatsmydns.net&quot;&gt;whatsmydns.net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once propagated, Vercel automatically provisions an SSL certificate. Your site will be live at your custom domain with HTTPS.&lt;/p&gt;
&lt;h2 id=&quot;environment-variables&quot;&gt;Environment Variables&lt;/h2&gt;
&lt;p&gt;If your project needs API keys or configuration:&lt;/p&gt;
&lt;h3 id=&quot;in-your-code&quot;&gt;In Your Code&lt;/h3&gt;
&lt;p&gt;Use environment variables instead of hardcoded values:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Good ✅&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;API_URL&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VITE_API_URL&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Bad ❌&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;API_URL&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://api.example.com&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For Vite projects, prefix with &lt;code class=&quot;language-text&quot;&gt;VITE_&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; apiKey &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VITE_API_KEY&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; apiUrl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VITE_API_URL&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;in-vercel-dashboard&quot;&gt;In Vercel Dashboard&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Project Settings&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Environment Variables&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Add&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Enter:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Name&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;VITE_API_URL&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Value&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;https://api.example.com&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Select which environments: &lt;strong&gt;Production&lt;/strong&gt;, &lt;strong&gt;Preview&lt;/strong&gt;, &lt;strong&gt;Development&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Save&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Redeploy for changes to take effect&lt;/strong&gt; (push a new commit or manually redeploy).&lt;/p&gt;
&lt;h2 id=&quot;using-vercel-cli-optional&quot;&gt;Using Vercel CLI (Optional)&lt;/h2&gt;
&lt;p&gt;For more control, install the Vercel CLI:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Install globally&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; vercel

&lt;span class=&quot;token comment&quot;&gt;# Login&lt;/span&gt;
vercel login

&lt;span class=&quot;token comment&quot;&gt;# Deploy from terminal&lt;/span&gt;
vercel&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;commands&quot;&gt;Commands&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Deploy to preview&lt;/span&gt;
vercel

&lt;span class=&quot;token comment&quot;&gt;# Deploy to production&lt;/span&gt;
vercel &lt;span class=&quot;token parameter variable&quot;&gt;--prod&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# View deployment logs&lt;/span&gt;
vercel logs

&lt;span class=&quot;token comment&quot;&gt;# List projects&lt;/span&gt;
vercel projects list

&lt;span class=&quot;token comment&quot;&gt;# Pull environment variables locally&lt;/span&gt;
vercel &lt;span class=&quot;token function&quot;&gt;env&lt;/span&gt; pull&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The CLI is useful for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Deploying without Git&lt;/li&gt;
&lt;li&gt;Testing locally with production environment variables&lt;/li&gt;
&lt;li&gt;CI/CD pipelines&lt;/li&gt;
&lt;li&gt;Advanced configurations&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;common-issues-and-solutions&quot;&gt;Common Issues and Solutions&lt;/h2&gt;
&lt;h3 id=&quot;build-fails-command-not-found&quot;&gt;Build Fails: &quot;Command not found&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Vercel can&apos;t find your build command&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Check your &lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt; has a &lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt; script:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-json line-numbers&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;build&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;vite build&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Update Vercel build settings to match your script name&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;404-on-routes-spa-issue&quot;&gt;404 on Routes (SPA Issue)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;/about&lt;/code&gt; works locally but shows 404 on Vercel&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Create &lt;code class=&quot;language-text&quot;&gt;vercel.json&lt;/code&gt; in your project root:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-json line-numbers&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;rewrites&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;source&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/(.*)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;destination&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/index.html&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This handles client-side routing for single-page apps.&lt;/p&gt;
&lt;h3 id=&quot;environment-variables-not-working&quot;&gt;Environment Variables Not Working&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;import.meta.env.VITE_API_URL&lt;/code&gt; is undefined&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ensure variable name starts with &lt;code class=&quot;language-text&quot;&gt;VITE_&lt;/code&gt; (for Vite projects)&lt;/li&gt;
&lt;li&gt;Add variable in Vercel dashboard under &lt;strong&gt;Environment Variables&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Redeploy after adding (push a commit or click &quot;Redeploy&quot;)&lt;/li&gt;
&lt;li&gt;Check you&apos;re accessing it correctly:
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Correct&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VITE_API_URL&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Wrong&lt;/span&gt;
process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VITE_API_URL&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// This is for Node.js, not Vite&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;deployment-shows-old-version&quot;&gt;Deployment Shows Old Version&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Changes don&apos;t appear after deploying&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Hard refresh: &lt;code class=&quot;language-text&quot;&gt;Ctrl+Shift+R&lt;/code&gt; (Windows) or &lt;code class=&quot;language-text&quot;&gt;Cmd+Shift+R&lt;/code&gt; (Mac)&lt;/li&gt;
&lt;li&gt;Check you pushed to the correct branch&lt;/li&gt;
&lt;li&gt;Verify deployment completed successfully in Vercel dashboard&lt;/li&gt;
&lt;li&gt;Clear browser cache&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;exceeded-free-tier-limits&quot;&gt;Exceeded Free Tier Limits&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Hit bandwidth or build minute limits&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Bandwidth&lt;/strong&gt;: Optimize images, enable caching, or upgrade to Pro ($20/month)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build minutes&lt;/strong&gt;: Optimize build time, reduce builds, or upgrade to Pro&lt;/li&gt;
&lt;li&gt;Check usage in &lt;strong&gt;Settings&lt;/strong&gt; &gt; &lt;strong&gt;Usage&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;when-to-use-vercel-vs-other-platforms&quot;&gt;When to Use Vercel vs Other Platforms&lt;/h2&gt;
&lt;h3 id=&quot;use-vercel-when&quot;&gt;Use Vercel When:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;You&apos;re building a frontend application (React, Vue, Svelte, etc.)&lt;/li&gt;
&lt;li&gt;You want automatic deployments from Git&lt;/li&gt;
&lt;li&gt;You value developer experience and speed&lt;/li&gt;
&lt;li&gt;You&apos;re using Next.js (Vercel is made for it)&lt;/li&gt;
&lt;li&gt;You need serverless functions for APIs&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;use-cloudflare-workers-when&quot;&gt;Use Cloudflare Workers When:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;You want &lt;strong&gt;&lt;a href=&quot;/blog/cloudflare-workers-deployment/&quot;&gt;unlimited bandwidth and more control over deployments&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;You have very high traffic (Vercel caps at 100GB free)&lt;/li&gt;
&lt;li&gt;You prefer the fastest global performance (300+ regions)&lt;/li&gt;
&lt;li&gt;You want to combine static sites with edge functions&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;use-flyio-when&quot;&gt;Use Fly.io When:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;You need &lt;strong&gt;&lt;a href=&quot;/blog/flyio-free-tier-guide/&quot;&gt;real Docker containers running 24/7&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;You&apos;re deploying traditional backend servers (Flask, Express, Rails)&lt;/li&gt;
&lt;li&gt;You want full control over your runtime environment&lt;/li&gt;
&lt;li&gt;You need databases or long-running processes&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;use-netlify-when&quot;&gt;Use Netlify When:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;You&apos;re building Jamstack sites&lt;/li&gt;
&lt;li&gt;You need form handling without serverless functions&lt;/li&gt;
&lt;li&gt;You prefer Netlify&apos;s UI and features&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;For most modern web apps, Vercel is the easiest choice.&lt;/strong&gt; But if you need unlimited bandwidth, explore Cloudflare Workers. If you need a real backend server, Fly.io runs actual Docker containers on their free tier.&lt;/p&gt;
&lt;h2 id=&quot;best-practices&quot;&gt;Best Practices&lt;/h2&gt;
&lt;h3 id=&quot;1-use-environment-variables&quot;&gt;1. Use Environment Variables&lt;/h3&gt;
&lt;p&gt;Never commit API keys or secrets:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// .env.local (not committed to Git)&lt;/span&gt;
&lt;span class=&quot;token constant&quot;&gt;VITE_API_KEY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;abc123

&lt;span class=&quot;token comment&quot;&gt;// In code&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; apiKey &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VITE_API_KEY&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Add them in Vercel dashboard instead.&lt;/p&gt;
&lt;h3 id=&quot;2-enable-preview-deployments&quot;&gt;2. Enable Preview Deployments&lt;/h3&gt;
&lt;p&gt;Test changes before merging:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a branch: &lt;code class=&quot;language-text&quot;&gt;git checkout -b feature/new-ui&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Push changes: &lt;code class=&quot;language-text&quot;&gt;git push origin feature/new-ui&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Vercel creates a preview URL automatically&lt;/li&gt;
&lt;li&gt;Test thoroughly&lt;/li&gt;
&lt;li&gt;Merge to main when ready&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;3-monitor-performance&quot;&gt;3. Monitor Performance&lt;/h3&gt;
&lt;p&gt;Enable Vercel Analytics:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Project Settings&lt;/strong&gt; &gt; &lt;strong&gt;Analytics&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Enable&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;View Core Web Vitals and performance metrics&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;4-optimize-images&quot;&gt;4. Optimize Images&lt;/h3&gt;
&lt;p&gt;Use modern formats and lazy loading:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Use Next.js Image component (if using Next.js)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Image &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;next/image&apos;&lt;/span&gt;

&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Image src&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/photo.jpg&quot;&lt;/span&gt; alt&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Photo&quot;&lt;/span&gt; width&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; height&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or compress images before adding to your project.&lt;/p&gt;
&lt;h3 id=&quot;5-add-security-headers&quot;&gt;5. Add Security Headers&lt;/h3&gt;
&lt;p&gt;Create &lt;code class=&quot;language-text&quot;&gt;vercel.json&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-json line-numbers&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;headers&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;source&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/(.*)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;headers&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;key&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;X-Frame-Options&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;DENY&quot;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;key&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;X-Content-Type-Options&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;nosniff&quot;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;next-steps&quot;&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;Now that you&apos;ve deployed your first project:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Explore serverless functions&lt;/strong&gt;: Create API routes in &lt;code class=&quot;language-text&quot;&gt;/api&lt;/code&gt; folder&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Set up analytics&lt;/strong&gt;: Track performance with Vercel Analytics&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Add a custom domain&lt;/strong&gt;: Make it professional&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enable preview deployments&lt;/strong&gt;: Test before going live&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Read the Vercel docs&lt;/strong&gt;: &lt;a href=&quot;https://vercel.com/docs&quot;&gt;vercel.com/docs&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;frequently-asked-questions&quot;&gt;Frequently Asked Questions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Q: Is Vercel really free?&lt;/strong&gt;
A: Yes, the Hobby plan is free forever with generous limits (100GB bandwidth, 6,000 build minutes/month).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q: Can I use Vercel for commercial projects?&lt;/strong&gt;
A: Yes, but you need the Pro plan ($20/month) for commercial use according to Vercel&apos;s terms.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q: What&apos;s the difference between Vercel and GitHub Pages?&lt;/strong&gt;
A: Vercel auto-detects frameworks, includes serverless functions, has better performance (global CDN), and offers more features. GitHub Pages is simpler but less powerful.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q: Can I deploy backends to Vercel?&lt;/strong&gt;
A: Only serverless functions. You can&apos;t run traditional servers (Express.js 24/7) on Vercel. Use serverless functions instead or pair Vercel with a separate backend service.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q: How many projects can I deploy?&lt;/strong&gt;
A: Unlimited on the free tier.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q: Can I roll back deployments?&lt;/strong&gt;
A: Yes! Every deployment is saved. Go to &lt;strong&gt;Deployments&lt;/strong&gt; tab and promote any previous deployment to production.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Vercel makes deploying web applications effortless:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Push code to Git&lt;/li&gt;
&lt;li&gt;Vercel builds and deploys automatically&lt;/li&gt;
&lt;li&gt;Your site is live globally in seconds&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The free tier is generous enough for most personal projects, and the developer experience is excellent.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Try it yourself&lt;/strong&gt;: Deploy your first project today and see why developers love Vercel.&lt;/p&gt;
&lt;h2 id=&quot;build-your-first-project-to-deploy&quot;&gt;Build Your First Project to Deploy&lt;/h2&gt;
&lt;p&gt;Don&apos;t have a project ready to deploy yet? Build one from scratch with these comprehensive tutorials:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-scratch/&quot;&gt;Build a Blog from Scratch&lt;/a&gt;&lt;/strong&gt; - Create a complete blog with vanilla JavaScript, perfect for Vercel deployment&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-scratch/&quot;&gt;Build a Portfolio from Scratch&lt;/a&gt;&lt;/strong&gt; - Learn web fundamentals while building a professional portfolio site&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-scratch/&quot;&gt;Build E-Commerce from Scratch&lt;/a&gt;&lt;/strong&gt; - Master JavaScript state management with a shopping cart application&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each tutorial teaches you the fundamentals of modern web development, and your finished project will be ready to deploy to Vercel&apos;s free tier.&lt;/p&gt;
&lt;p&gt;Have questions? Leave a comment below!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Related guides:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website/&quot;&gt;Lovable to Vercel: Complete Deployment Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;Complete Guide: Deploy Your Lovable Project to Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/seo/seo-content-only-experiment/&quot;&gt;Content-Only SEO Experiment: Can a No-Name Site Rank?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Cloudflare Pages Deprecated 2025: How to Migrate to Workers with Zero-Downtime Domain Switchover]]></title><description><![CDATA[Cloudflare Pages is deprecated. Here's the complete, battle-tested guide to migrating your static site to Cloudflare Workers—including the domain switchover scripts that work.]]></description><link>https://vibecodingwithfred.com/blog/pages-to-workers-migration/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/pages-to-workers-migration/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In April 2025, Cloudflare deprecated Pages and told everyone to migrate to Workers. If you&apos;re here, you probably got that memo. What they &lt;em&gt;didn&apos;t&lt;/em&gt; tell you is that migrating a production site with a custom domain is way more complicated than &quot;just use Workers instead.&quot;&lt;/p&gt;
&lt;p&gt;I just migrated my Gatsby blog from Pages to Workers. Here&apos;s everything that worked, everything that didn&apos;t, and the exact scripts that minimize downtime.&lt;/p&gt;
&lt;h2 id=&quot;why-this-migration-matters&quot;&gt;Why This Migration Matters&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare Pages is deprecated.&lt;/strong&gt; New features go to Workers only. The Git-based auto-deploy that made Pages convenient? Gone. You deploy via Wrangler CLI now.&lt;/p&gt;
&lt;p&gt;But here&apos;s the real challenge: &lt;strong&gt;moving your custom domain without breaking your live site.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The Cloudflare docs gloss over this part. They assume you&apos;re starting fresh, not migrating a production site serving actual traffic. This guide fills that gap.&lt;/p&gt;
&lt;h2 id=&quot;what-were-migrating&quot;&gt;What We&apos;re Migrating&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Deployment&lt;/strong&gt;: Cloudflare Pages (auto-deploy from Git)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build&lt;/strong&gt;: Gatsby static site&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Domain&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;vibecodingwithfred.com&lt;/code&gt; pointing to Pages deployment&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Method&lt;/strong&gt;: Push to GitHub → automatic build and deploy&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Deployment&lt;/strong&gt;: Cloudflare Workers (manual deploy via Wrangler)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build&lt;/strong&gt;: Same Gatsby static site&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Domain&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;vibecodingwithfred.com&lt;/code&gt; pointing to Workers deployment&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Method&lt;/strong&gt;: Push to GitHub → GitHub Actions → Wrangler deploy&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;Before starting:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Cloudflare account&lt;/strong&gt; with your domain&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Existing Pages deployment&lt;/strong&gt; (the one you&apos;re migrating from)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Node.js 18+&lt;/strong&gt; installed&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cloudflare API token&lt;/strong&gt; with &quot;Edit Workers&quot; permissions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Git repo&lt;/strong&gt; for your static site&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;part-1-setting-up-workers-configuration&quot;&gt;Part 1: Setting Up Workers Configuration&lt;/h2&gt;
&lt;h3 id=&quot;step-1-install-wrangler&quot;&gt;Step 1: Install Wrangler&lt;/h3&gt;
&lt;p&gt;Add Wrangler to your project:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-D&lt;/span&gt; wrangler&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-2-create-wranglertoml&quot;&gt;Step 2: Create wrangler.toml&lt;/h3&gt;
&lt;p&gt;This is your Workers configuration. Create &lt;code class=&quot;language-text&quot;&gt;wrangler.toml&lt;/code&gt; at your project root:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token key property&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;your-project-name&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;compatibility_date&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2025-10-19&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;workers-site/index.js&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;bucket&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;./public&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Key fields:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;name&lt;/code&gt;: Your Workers project name (must match what&apos;s in Cloudflare dashboard)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;main&lt;/code&gt;: Entry point for your Worker script&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;bucket&lt;/code&gt;: Where your static files are (Gatsby uses &lt;code class=&quot;language-text&quot;&gt;public&lt;/code&gt;, Next.js uses &lt;code class=&quot;language-text&quot;&gt;out&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;step-3-create-the-workers-script&quot;&gt;Step 3: Create the Workers Script&lt;/h3&gt;
&lt;p&gt;Workers needs a script to serve static files. Create &lt;code class=&quot;language-text&quot;&gt;workers-site/index.js&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; getAssetFromKV &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@cloudflare/kv-asset-handler&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;DEBUG&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;fetch&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;respondWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;handleEvent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;event&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DEBUG&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;respondWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;respondWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Internal Error&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handleEvent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; url &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; options &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  options&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;mapRequestToAsset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; serveSinglePageApp&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DEBUG&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      options&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cacheControl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;bypassCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; page &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getAssetFromKV&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;event&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;X-XSS-Protection&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;1; mode=block&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;X-Content-Type-Options&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;nosniff&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;X-Frame-Options&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;DENY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Referrer-Policy&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;unsafe-url&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Feature-Policy&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;none&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DEBUG&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; notFoundResponse &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getAssetFromKV&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;event&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token function-variable function&quot;&gt;mapRequestToAsset&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;req&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;origin&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/404.html&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;notFoundResponse&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;notFoundResponse&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;404&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;serveSinglePageApp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; parsedUrl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; pathname &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; parsedUrl&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pathname&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pathname&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;endsWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    pathname &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pathname&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;index.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pathname&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;includes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Serve files with extensions as-is&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    pathname &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pathname&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  parsedUrl&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pathname &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pathname&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;parsedUrl&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This script:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Uses &lt;code class=&quot;language-text&quot;&gt;@cloudflare/kv-asset-handler&lt;/code&gt; to serve static files&lt;/li&gt;
&lt;li&gt;Handles Gatsby&apos;s client-side routing&lt;/li&gt;
&lt;li&gt;Serves 404.html for missing pages&lt;/li&gt;
&lt;li&gt;Adds security headers&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;step-4-install-dependencies&quot;&gt;Step 4: Install Dependencies&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; @cloudflare/kv-asset-handler&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-5-update-packagejson-scripts&quot;&gt;Step 5: Update package.json Scripts&lt;/h3&gt;
&lt;p&gt;Change your deploy scripts from Pages to Workers:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-json line-numbers&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;build&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;gatsby build&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;deploy&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;npm run build &amp;amp;&amp;amp; wrangler deploy&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;deploy:prod&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;npm run build &amp;amp;&amp;amp; wrangler deploy&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;step-6-test-local-deployment&quot;&gt;Step 6: Test Local Deployment&lt;/h3&gt;
&lt;p&gt;Before touching your live site, test the Workers deployment:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build
npx wrangler deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This deploys to a preview URL like: &lt;code class=&quot;language-text&quot;&gt;your-project.your-subdomain.workers.dev&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Visit that URL and verify everything works.&lt;/strong&gt; Test navigation, images, API calls—everything.&lt;/p&gt;
&lt;h2 id=&quot;part-2-setting-up-github-actions-cicd&quot;&gt;Part 2: Setting Up GitHub Actions CI/CD&lt;/h2&gt;
&lt;p&gt;Pages auto-deployed from Git. Workers don&apos;t. You need GitHub Actions.&lt;/p&gt;
&lt;p&gt;Create &lt;code class=&quot;language-text&quot;&gt;.github/workflows/deploy.yml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deploy to Cloudflare Workers

&lt;span class=&quot;token key atrule&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;branches&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; main

&lt;span class=&quot;token key atrule&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;deploy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ubuntu&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;latest
    &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deploy to Cloudflare Workers
    &lt;span class=&quot;token key atrule&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Checkout
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/checkout@v4

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Setup Node
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/setup&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;node@v4
        &lt;span class=&quot;token key atrule&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;node-version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;20&apos;&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;npm&apos;&lt;/span&gt;

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Install dependencies
        &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm ci

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Build site
        &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm run build
        &lt;span class=&quot;token key atrule&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;SUPABASE_URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; secrets.SUPABASE_URL &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;SUPABASE_ANON_KEY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; secrets.SUPABASE_ANON_KEY &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deploy to Cloudflare Workers
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cloudflare/wrangler&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;action@v3
        &lt;span class=&quot;token key atrule&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;apiToken&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; secrets.CLOUDFLARE_API_TOKEN &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;accountId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; secrets.CLOUDFLARE_ACCOUNT_ID &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;get-your-cloudflare-credentials&quot;&gt;Get Your Cloudflare Credentials&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Account ID:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cloudflare Dashboard → Workers &amp;#x26; Pages&lt;/li&gt;
&lt;li&gt;Copy from the right sidebar&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;API Token:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cloudflare Dashboard → My Profile → API Tokens&lt;/li&gt;
&lt;li&gt;&quot;Create Token&quot; → Use &quot;Edit Cloudflare Workers&quot; template&lt;/li&gt;
&lt;li&gt;Copy the token (you only see it once!)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;add-github-secrets&quot;&gt;Add GitHub Secrets&lt;/h3&gt;
&lt;p&gt;Go to your repo → Settings → Secrets and variables → Actions → New repository secret&lt;/p&gt;
&lt;p&gt;Add:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;CLOUDFLARE_API_TOKEN&lt;/code&gt;: Your API token&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;CLOUDFLARE_ACCOUNT_ID&lt;/code&gt;: Your account ID&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Any other environment variables your build needs (like Supabase keys).&lt;/p&gt;
&lt;h3 id=&quot;test-the-github-actions-deploy&quot;&gt;Test the GitHub Actions Deploy&lt;/h3&gt;
&lt;p&gt;Push to &lt;code class=&quot;language-text&quot;&gt;main&lt;/code&gt; and watch the Actions tab. The build should succeed and deploy to your preview URL.&lt;/p&gt;
&lt;h2 id=&quot;part-3-the-domain-switchover-the-hard-part&quot;&gt;Part 3: The Domain Switchover (The Hard Part)&lt;/h2&gt;
&lt;p&gt;This is where it gets tricky. Your domain is currently pointing to your old Pages deployment. You need to switch it to Workers &lt;strong&gt;without taking your site offline&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;the-problem&quot;&gt;The Problem&lt;/h3&gt;
&lt;p&gt;You can&apos;t just:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;❌ Manually edit DNS CNAME to point to &lt;code class=&quot;language-text&quot;&gt;your-project.workers.dev&lt;/code&gt; (causes 522 errors)&lt;/li&gt;
&lt;li&gt;❌ Add domain in Workers dashboard (gives &quot;domain already in use&quot; error)&lt;/li&gt;
&lt;li&gt;❌ Delete domain from Pages first (site goes down until you re-add it)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;the-solution-atomic-api-switchover&quot;&gt;The Solution: Atomic API Switchover&lt;/h3&gt;
&lt;p&gt;Use the Cloudflare API to remove from Pages and add to Workers &lt;strong&gt;in rapid succession&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;script-1-find-your-old-pages-project&quot;&gt;Script 1: Find Your Old Pages Project&lt;/h3&gt;
&lt;p&gt;Create &lt;code class=&quot;language-text&quot;&gt;scripts/1-find-old-project.sh&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-z&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$1&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Usage: ./1-find-old-project.sh YOUR_API_TOKEN&quot;&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;

&lt;span class=&quot;token assign-left variable&quot;&gt;CLOUDFLARE_API_TOKEN&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$1&lt;/span&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;CLOUDFLARE_ACCOUNT_ID&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;your-account-id-here&quot;&lt;/span&gt;

&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🔍 Finding all Pages projects and their domains...&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; GET &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/accounts/&lt;span class=&quot;token variable&quot;&gt;${CLOUDFLARE_ACCOUNT_ID}&lt;/span&gt;/pages/projects&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer &lt;span class=&quot;token variable&quot;&gt;${CLOUDFLARE_API_TOKEN}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token parameter variable&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.result[] | &quot;Project: \(.name)\nDomains: \(.domains // [] | join(&quot;, &quot;))\n&quot;&apos;&lt;/span&gt;

&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;📝 Look for the project that has your custom domain&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;📝 Copy that project name for the next script&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Make it executable:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;chmod&lt;/span&gt; +x scripts/*.sh&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Run it:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;./scripts/1-find-old-project.sh YOUR_API_TOKEN&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Find the project name that has your domain.&lt;/strong&gt; Example output:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Project: my-old-site
Domains: my-old-site.pages.dev, yourdomain.com&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;script-2-atomic-domain-switchover&quot;&gt;Script 2: Atomic Domain Switchover&lt;/h3&gt;
&lt;p&gt;Here&apos;s the critical script. Create &lt;code class=&quot;language-text&quot;&gt;scripts/2-switch-domain.sh&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-z&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$1&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-z&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$2&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Usage: ./2-switch-domain.sh YOUR_API_TOKEN OLD_PROJECT_NAME&quot;&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;

&lt;span class=&quot;token assign-left variable&quot;&gt;CLOUDFLARE_API_TOKEN&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$1&lt;/span&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;OLD_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$2&lt;/span&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;CLOUDFLARE_ACCOUNT_ID&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;your-account-id&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;ZONE_ID&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;your-zone-id&quot;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# Get from DNS settings&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;DOMAIN&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;yourdomain.com&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;NEW_WORKER_NAME&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;your-new-worker-name&quot;&lt;/span&gt;

&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🚀 ATOMIC DOMAIN SWITCHOVER&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;================================&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Old Project: &lt;span class=&quot;token variable&quot;&gt;${OLD_PROJECT_NAME}&lt;/span&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;New Worker: &lt;span class=&quot;token variable&quot;&gt;${NEW_WORKER_NAME}&lt;/span&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Domain: &lt;span class=&quot;token variable&quot;&gt;${DOMAIN}&lt;/span&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Press ENTER to proceed or Ctrl+C to cancel...&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Step 1: Remove domain from old Pages project&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;⏱️  [1/3] Removing domain from old Pages project...&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; DELETE &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/accounts/&lt;span class=&quot;token variable&quot;&gt;${CLOUDFLARE_ACCOUNT_ID}&lt;/span&gt;/pages/projects/&lt;span class=&quot;token variable&quot;&gt;${OLD_PROJECT_NAME}&lt;/span&gt;/domains/&lt;span class=&quot;token variable&quot;&gt;${DOMAIN}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer &lt;span class=&quot;token variable&quot;&gt;${CLOUDFLARE_API_TOKEN}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; /dev/null

&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;   ✅ Domain removed from Pages&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Step 2: Add Workers route for root domain&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;⏱️  [2/3] Adding Workers route for &lt;span class=&quot;token variable&quot;&gt;${DOMAIN}&lt;/span&gt;...&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; POST &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones/&lt;span class=&quot;token variable&quot;&gt;${ZONE_ID}&lt;/span&gt;/workers/routes&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer &lt;span class=&quot;token variable&quot;&gt;${CLOUDFLARE_API_TOKEN}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;{&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;pattern&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;:&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;${DOMAIN}&lt;/span&gt;/*&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;,&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;script&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;:&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;${NEW_WORKER_NAME}&lt;/span&gt;&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;}&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; /dev/null

&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;   ✅ Route added for root domain&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Step 3: Add Workers route for www subdomain&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;⏱️  [3/3] Adding Workers route for www.&lt;span class=&quot;token variable&quot;&gt;${DOMAIN}&lt;/span&gt;...&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; POST &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones/&lt;span class=&quot;token variable&quot;&gt;${ZONE_ID}&lt;/span&gt;/workers/routes&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer &lt;span class=&quot;token variable&quot;&gt;${CLOUDFLARE_API_TOKEN}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;{&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;pattern&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;:&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;www.&lt;span class=&quot;token variable&quot;&gt;${DOMAIN}&lt;/span&gt;/*&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;,&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;script&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;:&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;${NEW_WORKER_NAME}&lt;/span&gt;&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;}&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; /dev/null

&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;   ✅ Route added for www subdomain&quot;&lt;/span&gt;

&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🎉 SWITCHOVER COMPLETE!&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;✅ Domain &lt;span class=&quot;token variable&quot;&gt;${DOMAIN}&lt;/span&gt; is now pointing to &lt;span class=&quot;token variable&quot;&gt;${NEW_WORKER_NAME}&lt;/span&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;✅ Test: curl -I https://&lt;span class=&quot;token variable&quot;&gt;${DOMAIN}&lt;/span&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;run-the-switchover&quot;&gt;Run the Switchover&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;IMPORTANT:&lt;/strong&gt; Make sure your new Workers deployment is working on the preview URL first!&lt;/p&gt;
&lt;p&gt;Then run:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;./scripts/2-switch-domain.sh YOUR_API_TOKEN old-project-name&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Downtime:&lt;/strong&gt; About 2-5 seconds between removing from Pages and adding to Workers.&lt;/p&gt;
&lt;h3 id=&quot;verify-the-switch&quot;&gt;Verify the Switch&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Check root domain&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; https://yourdomain.com

&lt;span class=&quot;token comment&quot;&gt;# Check www subdomain&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; https://www.yourdomain.com

&lt;span class=&quot;token comment&quot;&gt;# Check both work in browser&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;part-4-post-migration-cleanup&quot;&gt;Part 4: Post-Migration Cleanup&lt;/h2&gt;
&lt;h3 id=&quot;update-dns-if-needed&quot;&gt;Update DNS (If Needed)&lt;/h3&gt;
&lt;p&gt;Your DNS CNAME record might still point to &lt;code class=&quot;language-text&quot;&gt;old-project.pages.dev&lt;/code&gt;. That&apos;s fine—Workers routes override DNS. But you can update it to be cleaner:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Option 1:&lt;/strong&gt; Leave it as-is (works fine, Workers routes take precedence)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Option 2:&lt;/strong&gt; Update CNAME to point to your Workers preview URL (optional, cosmetic)&lt;/p&gt;
&lt;h3 id=&quot;enable-https-redirect&quot;&gt;Enable HTTPS Redirect&lt;/h3&gt;
&lt;p&gt;Make sure &quot;Always Use HTTPS&quot; is enabled:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Cloudflare Dashboard → SSL/TLS → Edge Certificates&lt;/li&gt;
&lt;li&gt;Toggle &quot;Always Use HTTPS&quot; → &lt;strong&gt;ON&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This ensures &lt;code class=&quot;language-text&quot;&gt;http://yourdomain.com&lt;/code&gt; redirects to &lt;code class=&quot;language-text&quot;&gt;https://yourdomain.com&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;delete-old-pages-project-optional&quot;&gt;Delete Old Pages Project (Optional)&lt;/h3&gt;
&lt;p&gt;Once everything works, you can delete the old Pages deployment:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Workers &amp;#x26; Pages → old project name&lt;/li&gt;
&lt;li&gt;Settings → scroll to bottom&lt;/li&gt;
&lt;li&gt;&quot;Delete Project&quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is optional—the old project isn&apos;t costing you anything if you want to keep it as a backup.&lt;/p&gt;
&lt;h3 id=&quot;test-your-cicd-pipeline&quot;&gt;Test Your CI/CD Pipeline&lt;/h3&gt;
&lt;p&gt;Make a small change, push to &lt;code class=&quot;language-text&quot;&gt;main&lt;/code&gt;, and verify:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;GitHub Actions runs&lt;/li&gt;
&lt;li&gt;Build succeeds&lt;/li&gt;
&lt;li&gt;Deploys to Workers&lt;/li&gt;
&lt;li&gt;Live site updates in ~2 minutes&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;common-issues-and-solutions&quot;&gt;Common Issues and Solutions&lt;/h2&gt;
&lt;h3 id=&quot;issue-1-domain-already-in-use&quot;&gt;Issue 1: &quot;domain already in use&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Cause:&lt;/strong&gt; Domain is still attached to old Pages project.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Run script 1 to find the old project, then script 2 to remove it.&lt;/p&gt;
&lt;h3 id=&quot;issue-2-522-connection-timeout&quot;&gt;Issue 2: 522 Connection Timeout&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Cause:&lt;/strong&gt; Tried to point CNAME directly to &lt;code class=&quot;language-text&quot;&gt;your-project.workers.dev&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Don&apos;t manually edit DNS. Use Workers routes via API (script 2).&lt;/p&gt;
&lt;h3 id=&quot;issue-3-www-subdomain-doesnt-work&quot;&gt;Issue 3: www subdomain doesn&apos;t work&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Cause:&lt;/strong&gt; Workers route only added for root domain, not &lt;a href=&quot;http://www&quot;&gt;www&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Add second Workers route for &lt;code class=&quot;language-text&quot;&gt;www.yourdomain.com/*&lt;/code&gt; (script 2 handles this).&lt;/p&gt;
&lt;h3 id=&quot;issue-4-api-token-authentication-error&quot;&gt;Issue 4: API token &quot;Authentication error&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Cause:&lt;/strong&gt; Token doesn&apos;t have &quot;Edit Workers&quot; permissions, or start date is in the future.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Create new token with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Template: &quot;Edit Cloudflare Workers&quot;&lt;/li&gt;
&lt;li&gt;Start date: TODAY (not blank, not future date)&lt;/li&gt;
&lt;li&gt;Expiration: 1 year from now&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;issue-5-github-actions-fails-with-dependency-conflicts&quot;&gt;Issue 5: GitHub Actions fails with dependency conflicts&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Cause:&lt;/strong&gt; npm peer dependency conflicts (common with Gatsby plugins).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Add &lt;code class=&quot;language-text&quot;&gt;.npmrc&lt;/code&gt; to your repo:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;legacy-peer-deps=true&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Also lock Node version with &lt;code class=&quot;language-text&quot;&gt;.nvmrc&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;20&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;issue-6-build-works-locally-fails-in-cicd&quot;&gt;Issue 6: Build works locally, fails in CI/CD&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Cause:&lt;/strong&gt; Missing environment variables or wrong Node version.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add all required env vars as GitHub secrets&lt;/li&gt;
&lt;li&gt;Set Node version in GitHub Actions workflow&lt;/li&gt;
&lt;li&gt;Check build logs for specific errors&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-complete-migration-checklist&quot;&gt;The Complete Migration Checklist&lt;/h2&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Install Wrangler: &lt;code class=&quot;language-text&quot;&gt;npm install -D wrangler&lt;/code&gt;&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Create &lt;code class=&quot;language-text&quot;&gt;wrangler.toml&lt;/code&gt; with correct project name&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Create &lt;code class=&quot;language-text&quot;&gt;workers-site/index.js&lt;/code&gt; with static asset handler&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Install &lt;code class=&quot;language-text&quot;&gt;@cloudflare/kv-asset-handler&lt;/code&gt;&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Update &lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt; scripts to use &lt;code class=&quot;language-text&quot;&gt;wrangler deploy&lt;/code&gt;&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Test local deployment: &lt;code class=&quot;language-text&quot;&gt;npm run deploy&lt;/code&gt;&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Verify preview URL works completely&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Create &lt;code class=&quot;language-text&quot;&gt;.github/workflows/deploy.yml&lt;/code&gt;&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Get Cloudflare API token and Account ID&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Add GitHub secrets&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Test GitHub Actions deployment&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Create migration scripts (1-find-old-project.sh, 2-switch-domain.sh)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Find old Pages project name&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Run atomic domain switchover&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Verify both root and www domains work&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Enable &quot;Always Use HTTPS&quot;&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Test full CI/CD pipeline&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Delete old Pages project (optional)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;what-you-get-after-migration&quot;&gt;What You Get After Migration&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✅ Automatic deployments&lt;/strong&gt; on push to main (via GitHub Actions)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✅ Full control&lt;/strong&gt; over when and how you deploy&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✅ Same performance&lt;/strong&gt; as Pages (both use Cloudflare&apos;s edge network)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✅ Future-proof&lt;/strong&gt; (Workers gets all new features)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✅ More powerful&lt;/strong&gt; (can add serverless functions later)&lt;/p&gt;
&lt;h2 id=&quot;the-bottom-line&quot;&gt;The Bottom Line&lt;/h2&gt;
&lt;p&gt;Migrating from Pages to Workers isn&apos;t as simple as Cloudflare&apos;s deprecation notice implied. The domain switchover is the hardest part, and the docs don&apos;t cover it well.&lt;/p&gt;
&lt;p&gt;But once you have the scripts and process down, it&apos;s straightforward:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Set up Workers&lt;/strong&gt; with wrangler.toml and the asset handler script&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configure CI/CD&lt;/strong&gt; with GitHub Actions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Test everything&lt;/strong&gt; on the preview URL&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Switch the domain&lt;/strong&gt; atomically via API&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Verify&lt;/strong&gt; and clean up&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Total hands-on time: about 2 hours. Actual downtime: less than 5 seconds.&lt;/p&gt;
&lt;p&gt;And now you&apos;re on the platform that Cloudflare is investing in. Plus you learned how to use the Cloudflare API for zero-downtime deployments, which is a useful skill for other migrations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The scripts in this guide are production-tested.&lt;/strong&gt; I literally used them to migrate this blog. They work.&lt;/p&gt;
&lt;p&gt;Good luck with your migration. And if Cloudflare deprecates Workers in 2027, at least you&apos;ll know how to migrate again.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/workers/&quot;&gt;Cloudflare Workers Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/workers/wrangler/&quot;&gt;Wrangler CLI Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/cloudflare/kv-asset-handler&quot;&gt;Workers KV Asset Handler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/cloudflare/wrangler-action&quot;&gt;GitHub Actions for Wrangler&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Migration scripts shown in this article demonstrate the complete switchover process.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;appendix-managing-dns-via-cloudflare-api&quot;&gt;Appendix: Managing DNS via Cloudflare API&lt;/h2&gt;
&lt;p&gt;While Workers routes override DNS for domain routing, you might want to manage DNS records programmatically. Here&apos;s how.&lt;/p&gt;
&lt;h3 id=&quot;list-all-dns-records&quot;&gt;List All DNS Records&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;ZONE_ID&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;your-zone-id&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;API_TOKEN&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;your-api-token&quot;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; GET &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones/&lt;span class=&quot;token variable&quot;&gt;${ZONE_ID}&lt;/span&gt;/dns_records&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer &lt;span class=&quot;token variable&quot;&gt;${API_TOKEN}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token string&quot;&gt;&apos;.result[] | {type: .type, name: .name, content: .content, proxied: .proxied}&apos;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;create-a-dns-record&quot;&gt;Create a DNS Record&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Add CNAME record&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; POST &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones/&lt;span class=&quot;token variable&quot;&gt;${ZONE_ID}&lt;/span&gt;/dns_records&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer &lt;span class=&quot;token variable&quot;&gt;${API_TOKEN}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{
    &quot;type&quot;: &quot;CNAME&quot;,
    &quot;name&quot;: &quot;subdomain&quot;,
    &quot;content&quot;: &quot;target.example.com&quot;,
    &quot;proxied&quot;: true,
    &quot;ttl&quot;: 1
  }&apos;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;update-a-dns-record&quot;&gt;Update a DNS Record&lt;/h3&gt;
&lt;p&gt;First, get the record ID:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;RECORD_ID&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; GET &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones/&lt;span class=&quot;token variable&quot;&gt;${ZONE_ID}&lt;/span&gt;/dns_records?type=CNAME&amp;amp;name=yourdomain.com&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer &lt;span class=&quot;token variable&quot;&gt;${API_TOKEN}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token parameter variable&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.result[0].id&apos;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Record ID: &lt;span class=&quot;token variable&quot;&gt;${RECORD_ID}&lt;/span&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then update it:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; PATCH &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones/&lt;span class=&quot;token variable&quot;&gt;${ZONE_ID}&lt;/span&gt;/dns_records/&lt;span class=&quot;token variable&quot;&gt;${RECORD_ID}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer &lt;span class=&quot;token variable&quot;&gt;${API_TOKEN}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{
    &quot;type&quot;: &quot;CNAME&quot;,
    &quot;name&quot;: &quot;yourdomain.com&quot;,
    &quot;content&quot;: &quot;new-target.workers.dev&quot;,
    &quot;proxied&quot;: true,
    &quot;ttl&quot;: 1
  }&apos;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;delete-a-dns-record&quot;&gt;Delete a DNS Record&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; DELETE &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones/&lt;span class=&quot;token variable&quot;&gt;${ZONE_ID}&lt;/span&gt;/dns_records/&lt;span class=&quot;token variable&quot;&gt;${RECORD_ID}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer &lt;span class=&quot;token variable&quot;&gt;${API_TOKEN}&lt;/span&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;get-your-zone-id&quot;&gt;Get Your Zone ID&lt;/h3&gt;
&lt;p&gt;If you don&apos;t know your Zone ID:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# List all zones&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; GET &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer &lt;span class=&quot;token variable&quot;&gt;${API_TOKEN}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token parameter variable&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.result[] | &quot;\(.name): \(.id)&quot;&apos;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Or find specific zone&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; GET &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones?name=yourdomain.com&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer &lt;span class=&quot;token variable&quot;&gt;${API_TOKEN}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token parameter variable&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.result[0].id&apos;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;complete-dns-migration-script&quot;&gt;Complete DNS Migration Script&lt;/h3&gt;
&lt;p&gt;If you want to update DNS records as part of your migration:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt;

&lt;span class=&quot;token assign-left variable&quot;&gt;API_TOKEN&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$1&lt;/span&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;ZONE_ID&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$2&lt;/span&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;OLD_TARGET&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;old-site.pages.dev&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;NEW_TARGET&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;new-site.workers.dev&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;DOMAIN&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;yourdomain.com&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Find the DNS record&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🔍 Finding DNS record for &lt;span class=&quot;token variable&quot;&gt;${DOMAIN}&lt;/span&gt;...&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;RECORD_ID&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; GET &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones/&lt;span class=&quot;token variable&quot;&gt;${ZONE_ID}&lt;/span&gt;/dns_records?type=CNAME&amp;amp;name=&lt;span class=&quot;token variable&quot;&gt;${DOMAIN}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer &lt;span class=&quot;token variable&quot;&gt;${API_TOKEN}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token parameter variable&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.result[0].id&apos;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$RECORD_ID&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;null&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;❌ DNS record not found&quot;&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;

&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;✅ Found record ID: &lt;span class=&quot;token variable&quot;&gt;${RECORD_ID}&lt;/span&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Update the DNS record&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;📝 Updating DNS record...&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;RESPONSE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; PATCH &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;https://api.cloudflare.com/client/v4/zones/&lt;span class=&quot;token variable&quot;&gt;${ZONE_ID}&lt;/span&gt;/dns_records/&lt;span class=&quot;token variable&quot;&gt;${RECORD_ID}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: Bearer &lt;span class=&quot;token variable&quot;&gt;${API_TOKEN}&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;{
    &lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;type&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;: &lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;CNAME&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;,
    &lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;name&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;: &lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;${DOMAIN}&lt;/span&gt;&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;,
    &lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;content&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;: &lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;${NEW_TARGET}&lt;/span&gt;&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;,
    &lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;proxied&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;: true,
    &lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;ttl&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;: 1
  }&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$RESPONSE&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.success&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; /dev/null &lt;span class=&quot;token operator&quot;&gt;&lt;span class=&quot;token file-descriptor important&quot;&gt;2&lt;/span&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token file-descriptor important&quot;&gt;&amp;amp;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;✅ DNS record updated successfully&quot;&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Old: &lt;span class=&quot;token variable&quot;&gt;${DOMAIN}&lt;/span&gt; → &lt;span class=&quot;token variable&quot;&gt;${OLD_TARGET}&lt;/span&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;New: &lt;span class=&quot;token variable&quot;&gt;${DOMAIN}&lt;/span&gt; → &lt;span class=&quot;token variable&quot;&gt;${NEW_TARGET}&lt;/span&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;❌ Failed to update DNS record&quot;&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$RESPONSE&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token string&quot;&gt;&apos;.&apos;&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;important-notes-on-dns-updates&quot;&gt;Important Notes on DNS Updates&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Proxied vs DNS-only:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;proxied&quot;: true&lt;/code&gt; → Orange cloud (CDN/DDoS protection)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;proxied&quot;: false&lt;/code&gt; → Grey cloud (DNS only)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For Workers routes, you &lt;strong&gt;want proxied: true&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TTL Settings:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;ttl&quot;: 1&lt;/code&gt; → Automatic (recommended when proxied)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;ttl&quot;: 300&lt;/code&gt; → 5 minutes&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;ttl&quot;: 3600&lt;/code&gt; → 1 hour&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;CNAME Flattening:&lt;/strong&gt;
Cloudflare automatically handles CNAME flattening for root domains, so you can use CNAME records on &lt;code class=&quot;language-text&quot;&gt;yourdomain.com&lt;/code&gt; (normally not allowed in DNS).&lt;/p&gt;
&lt;h3 id=&quot;why-workers-routes--dns-changes&quot;&gt;Why Workers Routes &gt; DNS Changes&lt;/h3&gt;
&lt;p&gt;For this migration, we used &lt;strong&gt;Workers routes&lt;/strong&gt; instead of DNS changes because:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Workers routes take precedence&lt;/strong&gt; over DNS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No propagation delay&lt;/strong&gt; (instant edge updates)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No CNAME target issues&lt;/strong&gt; (can&apos;t CNAME to workers.dev directly)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Better control&lt;/strong&gt; over routing patterns&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;But if you&apos;re managing other DNS records (MX, TXT, A records), the API is useful for automation.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Migrating from Cloudflare Pages to Workers gives you more control over your deployment pipeline, faster builds (no waiting in Cloudflare&apos;s queue), and access to advanced Workers features like KV storage, D1 databases, and edge logic.&lt;/p&gt;
&lt;p&gt;While the initial setup takes 20-30 minutes, the investment pays off with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Full control&lt;/strong&gt; over deployment timing&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Local testing&lt;/strong&gt; before pushing to production&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CI/CD flexibility&lt;/strong&gt; with GitHub Actions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Edge computing capabilities&lt;/strong&gt; for dynamic content&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zero downtime&lt;/strong&gt; domain switchovers&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The migration patterns shown here are production-tested—this blog migrated using these exact steps with zero downtime.&lt;/p&gt;
&lt;h2 id=&quot;related-cloudflare-guides&quot;&gt;Related Cloudflare Guides&lt;/h2&gt;
&lt;p&gt;Master Cloudflare&apos;s ecosystem with these comprehensive guides:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/cloudflare-workers-deployment/&quot;&gt;Deploy Your Static Site to Cloudflare Workers&lt;/a&gt;&lt;/strong&gt; - Complete guide to Workers deployment from scratch&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/godaddy-to-cloudflare-dns/&quot;&gt;Move Your DNS from GoDaddy to Cloudflare&lt;/a&gt;&lt;/strong&gt; - Get your domain on Cloudflare for better performance&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/cloudflare-dns-api/&quot;&gt;Manage DNS with the Cloudflare API&lt;/a&gt;&lt;/strong&gt; - Automate DNS management in your deployment pipeline&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;build-your-first-static-site&quot;&gt;Build Your First Static Site&lt;/h2&gt;
&lt;p&gt;New to static site deployment? Build a real project first with these hands-on tutorials:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-scratch/&quot;&gt;Build a Blog from Scratch&lt;/a&gt;&lt;/strong&gt; - Create a complete blog with vanilla JavaScript, perfect for Workers deployment&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-scratch/&quot;&gt;Build a Portfolio from Scratch&lt;/a&gt;&lt;/strong&gt; - Learn web fundamentals while building a professional portfolio&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-scratch/&quot;&gt;Build E-Commerce from Scratch&lt;/a&gt;&lt;/strong&gt; - Master JavaScript with a shopping cart application&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each tutorial teaches modern web development fundamentals and your finished project will be ready to deploy to Cloudflare Workers.&lt;/p&gt;
&lt;h2 id=&quot;additional-resources&quot;&gt;Additional Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/workers/&quot;&gt;Cloudflare Workers Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/workers/wrangler/&quot;&gt;Wrangler CLI Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/cloudflare/wrangler-action&quot;&gt;GitHub Actions for Wrangler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/api/&quot;&gt;Cloudflare API Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Questions about your specific migration? Drop a comment below—I&apos;ve debugged most edge cases during this blog&apos;s migration.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Codex CLI: Der echte GPT-5 Coding-Guide (Mit Cursors geheimen Prompts)]]></title><description><![CDATA[Geleakt: Wie Cursor 78,2% Genauigkeit auf Tau-Bench mit GPT-5 erreichte. Plus die exakten Prompts, die Modelle besseren Code schreiben lassen als die meisten Entwickler.]]></description><link>https://vibecodingwithfred.com/de/blog/codex-cli-ultimate-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/de/blog/codex-cli-ultimate-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Plattform:&lt;/strong&gt; Codex CLI | &lt;strong&gt;Anbieter:&lt;/strong&gt; OpenAI | &lt;strong&gt;Modell:&lt;/strong&gt; GPT-5 mit Responses API&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;die-zahlen-die-niemand-ihnen-erzaehlt&quot;&gt;Die Zahlen, die niemand Ihnen erzaehlt&lt;/h2&gt;
&lt;p&gt;Hier ist, was OpenAIs interne Tests ueber GPT-5 enthuelten:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tau-Bench Retail Score:&lt;/strong&gt; Sprang von 73,9% auf 78,2% nur durch Verwendung der Responses API&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SWE-Bench Performance:&lt;/strong&gt; Schlaegt jedes Frontier-Modell bei realen Coding-Aufgaben&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tool-Call-Effizienz:&lt;/strong&gt; 50% weniger unnoetige Aufrufe mit richtigem Prompting&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kontextfenster-Nutzung:&lt;/strong&gt; Handhabt massive Codebasen ohne den Ueberblick zu verlieren&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cursors Team verbrachte Monate damit, ihre Prompts fuer GPT-5 zu tunen. Sie fanden heraus, dass schlecht geschriebene Prompts die Performance um 40% verschlechtern koennen. Hier ist genau, was funktioniert.&lt;/p&gt;
&lt;h2 id=&quot;richtig-loslegen&quot;&gt;Richtig loslegen&lt;/h2&gt;
&lt;p&gt;Installieren Sie Codex CLI:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Installation via npm (empfohlen)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @openai/codex-cli

&lt;span class=&quot;token comment&quot;&gt;# Oder direkter Installer verwenden&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# curl -fsSL https://cli.openai.com/install.sh | sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Mit ChatGPT-Konto authentifizieren&lt;/span&gt;
codex login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Aber hier ist der kritische Teil: konfigurieren Sie sofort Ihren Reasoning-Effort:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Fuer komplexe Multi-Datei-Refaktors&lt;/span&gt;
codex --reasoning-effort high

&lt;span class=&quot;token comment&quot;&gt;# Fuer schnelle Fixes und einfache Aufgaben&lt;/span&gt;
codex --reasoning-effort minimal

&lt;span class=&quot;token comment&quot;&gt;# Standard (gut fuer die meisten Coding-Aufgaben)&lt;/span&gt;
codex --reasoning-effort medium&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;cursors-produktions-prompts-tatsaechlich-in-ihrem-editor-verwendet&quot;&gt;Cursors Produktions-Prompts (Tatsaechlich in ihrem Editor verwendet)&lt;/h2&gt;
&lt;p&gt;Das Cursor-Team fand, dass GPT-5 anfangs zu ausfuehrlich war. Ihre Loesung? Verbosity global auf low setzen, dann fuer Code ueberschreiben:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Write code for clarity first. Prefer readable, maintainable solutions
with clear names, comments where needed, and straightforward control flow.
Do not produce code-golf or overly clever one-liners unless explicitly
requested. Use high verbosity for writing code and code tools.&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Diese einzelne Prompt-Aenderung machte ihren Code 3x lesbarer, waehrend Statusmeldungen praegnant blieben.&lt;/p&gt;
&lt;h2 id=&quot;das-kontext-gathering-muster-das-alles-veraendert&quot;&gt;Das Kontext-Gathering-Muster, das alles veraendert&lt;/h2&gt;
&lt;p&gt;GPT-5s Standardverhalten ist gruendlich - manchmal zu gruendlich. Hier ist der exakte Prompt, der die Latenz um 60% reduzierte, waehrend die Genauigkeit erhalten blieb:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;context_gathering&gt;
Goal: Get enough context fast. Parallelize discovery and stop as soon as you can act.

Method:
- Start broad, then fan out to focused subqueries
- In parallel, launch varied queries; read top hits per query
- Avoid over searching for context

Early stop criteria:
- You can name exact content to change
- Top hits converge (~70%) on one area/path

Depth:
- Trace only symbols you&apos;ll modify or whose contracts you rely on
- Avoid transitive expansion unless necessary

Search depth: maximum 2 tool calls before proceeding
&amp;lt;/context_gathering&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ergebnis? GPT-5 hoert auf, Zeit mit irrelevanten Suchen zu verschwenden und kommt schneller zum Coden.&lt;/p&gt;
&lt;h2 id=&quot;tool-preambles-warum-ihr-agent-dumm-wirkt&quot;&gt;Tool-Preambles: Warum Ihr Agent dumm wirkt&lt;/h2&gt;
&lt;p&gt;Haben Sie sich jemals gefragt, warum KI-Coding-Assistenten scheinbar den Faden verlieren? Das liegt daran, dass sie ihren Plan nicht erklaeren. GPT-5 ist trainiert, &quot;Tool-Preambles&quot; zu liefern - vorab erstellte Plaene, die Erfolgsraten drastisch verbessern.&lt;/p&gt;
&lt;p&gt;Aktivieren Sie sie mit:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;tool_preambles&gt;
- Always begin by rephrasing the user&apos;s goal in clear, concise manner
- Immediately outline a structured plan detailing each logical step
- As you execute, narrate each step succinctly, marking progress
- Finish by summarizing completed work distinctly from upfront plan
&amp;lt;/tool_preambles&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Diese eine Aenderung verbesserte Nutzerzufriedenheitswerte um 35% in Cursors Tests.&lt;/p&gt;
&lt;h2 id=&quot;der-frontend-stack-den-gpt-5-am-besten-kennt&quot;&gt;Der Frontend-Stack, den GPT-5 am besten kennt&lt;/h2&gt;
&lt;p&gt;OpenAI hat GPT-5 mit bestimmten Frameworks im Sinn trainiert. Diese zu verwenden bringt Ihnen 40% bessere Code-Qualitaet von Anfang an:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Optimaler Stack:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Framework: Next.js (TypeScript), React, HTML&lt;/li&gt;
&lt;li&gt;Styling: Tailwind CSS, shadcn/ui, Radix Themes&lt;/li&gt;
&lt;li&gt;Icons: Material Symbols, Heroicons, Lucide&lt;/li&gt;
&lt;li&gt;Animation: Motion&lt;/li&gt;
&lt;li&gt;Fonts: Sans Serif, Inter, Geist&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Kaempfen Sie nicht dagegen an. GPT-5 schreibt wunderschoene Tailwind-Komponenten, hat aber Schwierigkeiten mit benutzerdefinierten CSS-Frameworks, die es nicht gesehen hat.&lt;/p&gt;
&lt;h2 id=&quot;der-self-reflection-prompt-der-perfekte-apps-schreibt&quot;&gt;Der Self-Reflection-Prompt, der perfekte Apps schreibt&lt;/h2&gt;
&lt;p&gt;GPT-5 kann ganze Anwendungen in einem Durchgang bauen - wenn Sie es richtig prompten. Dieses Muster produziert konsistent produktionsreife Code-Qualitaet:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;self_reflection&gt;
- First, spend time thinking of a rubric until you are confident
- Think deeply about every aspect of what makes for a world-class one-shot web app
- Create a rubric with 5-7 categories (do not show this to user)
- Use the rubric to internally iterate on the best possible solution
- If response doesn&apos;t hit top marks across all categories, start again
&amp;lt;/self_reflection&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Nutzer berichten, dass dieser Prompt allein die Code-Qualitaet um 50% fuer Greenfield-Projekte verbessert.&lt;/p&gt;
&lt;h2 id=&quot;das-persistenz-problem-und-die-loesung&quot;&gt;Das Persistenz-Problem (Und die Loesung)&lt;/h2&gt;
&lt;p&gt;GPT-5 gibt manchmal zu frueh auf oder stellt unnoetige Klaerungsfragen. Cursor loeste dies mit aggressivem Persistenz-Prompting:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;persistence&gt;
- You are an agent - keep going until query is completely resolved
- Only terminate when you are SURE the problem is solved
- Never stop at uncertainty—research or deduce the most reasonable approach
- Do not ask human to confirm assumptions—document them and proceed
- Safe actions (search, read): extremely high threshold for clarification
- Risky actions (delete, payment): lower threshold for user confirmation
&amp;lt;/persistence&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Dies reduzierte &quot;Hand-Back&quot;-Events um 80% in Produktion.&lt;/p&gt;
&lt;h2 id=&quot;echte-produktionsbeispiele-die-funktionieren&quot;&gt;Echte Produktionsbeispiele, die funktionieren&lt;/h2&gt;
&lt;h3 id=&quot;authentifizierungssystem-in-produktion-getestet&quot;&gt;Authentifizierungssystem (In Produktion getestet)&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Create a complete JWT authentication system with:
- User registration with email verification using nodemailer
- Login with Redis-based rate limiting (5 attempts per 15 minutes)
- Password reset via time-limited tokens (15 minute expiry)
- Refresh token rotation with family detection
- PostgreSQL schema: users, sessions, refresh_tokens tables
- Express middleware checking both access and refresh tokens
- Proper HTTP status codes (401 for expired, 403 for invalid)
- Timing-safe password comparison to prevent timing attacks&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;echtzeit-features-aktuell-im-grossen-massstab-laufend&quot;&gt;Echtzeit-Features (Aktuell im grossen Massstab laufend)&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Build a WebSocket notification system with:
- Socket.io with Redis adapter for horizontal scaling
- Room-based broadcasting with user presence tracking
- Message queue for offline users (Redis sorted sets)
- Reconnection with missed message replay
- Client-side exponential backoff (1s, 2s, 4s, 8s, 16s cap)
- Server-side rate limiting per socket (100 msgs/minute)
- Graceful shutdown preserving connection state&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;die-geld-realitaet&quot;&gt;Die Geld-Realitaet&lt;/h2&gt;
&lt;p&gt;Hier ist, was Codex/GPT-5 wirklich in Produktion kostet:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Abo-Modell:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT Plus (20$/Monat): 80% der Entwickler brauchen nie mehr&lt;/li&gt;
&lt;li&gt;ChatGPT Pro (200$/Monat): Lohnt sich, wenn Sie 4+ Stunden taeglich coden&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;API-Preise (Tatsaechliche Nutzung):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Einfacher CRUD-Endpunkt: 0,02-0,05$&lt;/li&gt;
&lt;li&gt;Komplettes Authentifizierungssystem: 0,15-0,25$&lt;/li&gt;
&lt;li&gt;Komplexer Refaktor (1000+ Zeilen): 0,50-1,00$&lt;/li&gt;
&lt;li&gt;Komplette App von Grund auf: 2,00-5,00$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Durchschnittlicher Entwickler bei taeglicher Nutzung: ~30-50$/Monat an API-Kosten.&lt;/p&gt;
&lt;h2 id=&quot;das-minimal-reasoning-geheimnis&quot;&gt;Das Minimal-Reasoning-Geheimnis&lt;/h2&gt;
&lt;p&gt;Fuer latenzsensitive Anwendungen ist GPT-5s Minimal-Reasoning-Modus ein Gamechanger. Aber er braucht anderes Prompting:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# Fuer minimales Reasoning, seien Sie explizit ueber Planung
Remember, you are an agent - keep going until completely resolved.
Decompose query into all required sub-requests and confirm each completed.
Plan extensively before function calls, reflect on outcomes.

# Kritisch: Geben Sie ihm einen &quot;Ausweg&quot; bei Unsicherheit
Bias strongly towards providing a correct answer quickly,
even if it might not be fully correct.&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Dieser Modus ist 3x schneller, waehrend 85% der Genauigkeit erhalten bleiben.&lt;/p&gt;
&lt;h2 id=&quot;was-cursor-nach-1-million-gpt-5-abfragen-lernte&quot;&gt;Was Cursor nach 1 Million GPT-5-Abfragen lernte&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Widerspruechliche Prompts toeten die Performance&lt;/strong&gt; - Eine widerspruchsvolle Anweisung kann 40% Verschlechterung verursachen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XML-Tags funktionieren besser als Markdown&lt;/strong&gt; - &lt;code class=&quot;language-text&quot;&gt;&amp;lt;instruction&gt;&lt;/code&gt; schlaegt &lt;code class=&quot;language-text&quot;&gt;## Instruction&lt;/code&gt; jedes Mal&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Verbosity-Parameter + Prompt-Override&lt;/strong&gt; - Global niedrig setzen, fuer Code speziell hoch&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tool-Budget-Beschraenkungen funktionieren&lt;/strong&gt; - &quot;Maximum 2 Tool-Aufrufe&quot; erzwingt Effizienz&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apply_patch schlaegt direktes Bearbeiten&lt;/strong&gt; - Ihr benutzerdefiniertes Diff-Format reduziert Fehler um 60%&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;die-versteckten-features-die-niemand-nutzt&quot;&gt;Die versteckten Features, die niemand nutzt&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Responses API:&lt;/strong&gt; Persistiert Reasoning zwischen Tool-Aufrufen. Das allein verbessert Multi-Step-Aufgaben um 25%.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reasoning-Effort-Skalierung:&lt;/strong&gt; Die meisten Leute aendern nie von Medium. Hoher Effort fuer komplexe Refaktors, minimal fuer einfache Fixes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Parallele Tool-Aufrufe:&lt;/strong&gt; GPT-5 kann mehrere Suchen gleichzeitig ausfuehren. Fordern Sie dies explizit fuer 2x Geschwindigkeit an.&lt;/p&gt;
&lt;h2 id=&quot;beginnen-sie-heute-diese-muster-zu-nutzen&quot;&gt;Beginnen Sie heute, diese Muster zu nutzen&lt;/h2&gt;
&lt;p&gt;Hoeren Sie auf, vage Prompts zu schreiben. Beginnen Sie mit diesen getesteten Mustern:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Immer Stop-Bedingungen einschliessen:&lt;/strong&gt; &quot;Only terminate when X is complete&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tool-Call-Budgets spezifizieren:&lt;/strong&gt; &quot;Maximum 2 searches before proceeding&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Output-Vertraege definieren:&lt;/strong&gt; &quot;Must return: modified files, test results, error handling&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Framework-Namen explizit verwenden:&lt;/strong&gt; GPT-5 kennt Next.js tief, zufaellige Frameworks weniger&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Preambles aktivieren:&lt;/strong&gt; Lassen Sie das Modell seinen Plan erklaeren, bevor es handelt&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;verwandte-ressourcen&quot;&gt;Verwandte Ressourcen&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/claude-code-cli-guide/&quot;&gt;Claude Code CLI Terminal-Assistent&lt;/a&gt;&lt;/strong&gt; - Alternativer KI-Coding-Assistent, der bei Terminal-Workflows und konversationeller Entwicklung exzelliert. Unterschiedliche Modellstaerken machen einen Vergleich lohnenswert.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/move-to-tdd-today/&quot;&gt;Heute zu TDD wechseln&lt;/a&gt;&lt;/strong&gt; - Bessere Tests fuer Ihren KI-generierten Code schreiben&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Hinweis: Performance-Metriken aus OpenAIs GPT-5 technischer Dokumentation und Cursors Produktions-Deployment. Ihre Ergebnisse koennen je nach Prompting-Qualitaet variieren.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Warum Fly.io das beste kostenlose Docker-Hosting ist, das Sie nicht nutzen]]></title><description><![CDATA[Fly.io gibt Ihnen jeden Monat 5$ Hosting-Guthaben, fuer immer. Das sind 3 Docker-Container, eine PostgreSQL-Datenbank und 160GB Bandbreite. Hier ist, warum es perfekt fuer Nebenprojekte ist.]]></description><link>https://vibecodingwithfred.com/de/blog/flyio-free-tier-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/de/blog/flyio-free-tier-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Plattform:&lt;/strong&gt; Fly.io | &lt;strong&gt;Anbieter:&lt;/strong&gt; Fly.io | &lt;strong&gt;Free Tier:&lt;/strong&gt; 5$/Monat Guthaben fuer immer&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;das-geheimnis-ueber-das-niemand-spricht&quot;&gt;Das Geheimnis, ueber das niemand spricht&lt;/h2&gt;
&lt;p&gt;Hier ist, was Fly.io besonders macht: Sie geben Ihnen jeden einzelnen Monat 5$ kostenloses Guthaben, fuer immer. Keine Testphase, kein zeitlich begrenztes Angebot - permanentes kostenloses Hosting fuer Ihre Docker-Container. Wenn Ihre Nutzung unter 5$ bleibt (Spoiler: das wird sie bei den meisten Projekten), zahlen Sie nichts.&lt;/p&gt;
&lt;p&gt;Noch besser? Im Gegensatz zu jeder anderen Plattform, die behauptet &quot;kostenlos&quot; zu sein, laesst Fly.io Ihre Docker-Container als echte VMs laufen. Das ist kein Serverless, wo Ihre App nach 5 Minuten einschlaeft. Ihre Container laufen 24/7 und reagieren sofort auf Anfragen.&lt;/p&gt;
&lt;p&gt;Ich betreibe seit ueber einem Jahr drei Produktions-APIs auf Fly.io. Gesamtkosten? Null Euro. Hier ist genau, wie Sie das machen.&lt;/p&gt;
&lt;h2 id=&quot;was-sie-kostenlos-bekommen&quot;&gt;Was Sie kostenlos bekommen&lt;/h2&gt;
&lt;p&gt;Diese 5$ monatliches Guthaben uebersetzen sich in ernsthafte Infrastruktur:&lt;/p&gt;
&lt;p&gt;Sie bekommen drei VMs mit jeweils 256MB RAM, die ueberall auf der Welt laufen. Fuegen Sie eine PostgreSQL-Datenbank mit 1GB Speicher hinzu. Dazu 160GB ausgehende Bandbreite. All das passt bequem in Ihr kostenloses Kontingent, mit Raum uebrig.&lt;/p&gt;
&lt;p&gt;Die Rechnung ist einfach: Eine einzelne 256MB VM kostet etwa 1,94$/Monat. Drei davon plus eine kleine Datenbank bringen Sie auf etwa 5$. Solange Sie innerhalb dieser Grenzen bleiben, deckt Fly.ios monatliches Guthaben alles ab.&lt;/p&gt;
&lt;h2 id=&quot;der-einstieg-dauert-5-minuten&quot;&gt;Der Einstieg dauert 5 Minuten&lt;/h2&gt;
&lt;p&gt;Zuerst installieren Sie die Fly CLI. Auf Mac ist es ein einziger brew-Befehl. Auf Linux curlen Sie ihr Install-Skript. Windows-Benutzer bekommen PowerShell. Das Ganze dauert 30 Sekunden.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# macOS&lt;/span&gt;
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flyctl

&lt;span class=&quot;token comment&quot;&gt;# Linux&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Windows&lt;/span&gt;
pwsh &lt;span class=&quot;token parameter variable&quot;&gt;-Command&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iwr https://fly.io/install.ps1 -useb | iex&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Registrieren Sie sich nur mit einer E-Mail - sie werden irgendwann nach einer Karte fragen, aber Sie koennen Ihre ersten Apps ohne eine deployen:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl auth signup&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;ihr-erstes-deploy-es-ist-laecherlich-einfach&quot;&gt;Ihr erstes Deploy (Es ist laecherlich einfach)&lt;/h2&gt;
&lt;p&gt;Hier glaenzt Fly.io. Haben Sie ein Dockerfile? Grossartig, es wird funktionieren. Haben Sie keins? Fly.io wird es herausfinden. Ich meine das ernst - es erkennt Ihr Framework und generiert alles automatisch.&lt;/p&gt;
&lt;p&gt;Lassen Sie mich Ihnen ein echtes Beispiel zeigen. Hier ist eine Node.js API, die ich letzte Woche deployed habe:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// index.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; express &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; port &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;This API runs 24/7 for free&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toISOString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/health&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;healthy&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;0.0.0.0&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Running on port &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;port&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Um das zu deployen, habe ich buchstaeblich nur ausgefuehrt:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl launch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Das ist es. Fly erkannte Node.js, erstellte ein Dockerfile, baute das Image und deployete es global. Der ganze Prozess dauerte etwa 2 Minuten. Meine API war live unter einer *.fly.dev URL, mit automatischem HTTPS, und reagierte auf Anfragen vom naechsten Rechenzentrum.&lt;/p&gt;
&lt;h2 id=&quot;der-docker-vorteil-den-niemand-erwaehnt&quot;&gt;Der Docker-Vorteil, den niemand erwaehnt&lt;/h2&gt;
&lt;p&gt;Hier ist, was Fly.io von Vercel, Netlify und dem Rest unterscheidet: Sie deployen tatsaechliche Docker-Container. Das bedeutet, Sie koennen buchstaeblich alles ausfuehren - Python-Skripte, Go-Binaries, Rust-Server, PHP-Anwendungen, Ruby on Rails, Sie nennen es.&lt;/p&gt;
&lt;p&gt;Ich habe eine Python Flask API, die Webhooks verarbeitet, einen Node.js Bot, der geplante Aufgaben ausfuehrt, und einen Go-Service, der Bildgroessenanpassung handhabt. Alles laeuft auf dem Free Tier. Versuchen Sie das mal mit Vercels Hobby-Plan.&lt;/p&gt;
&lt;p&gt;Ihre Container laufen als Firecracker microVMs, dieselbe Technologie, die Amazon fuer Lambda verwendet. Sie starten in Millisekunden, verhalten sich aber wie echte Server. Keine Cold Starts, keine 10-Sekunden-Timeouts, keine Serverless-Einschraenkungen. Nur Ihr Code, der genau so laeuft, wie Sie es erwarten.&lt;/p&gt;
&lt;h2 id=&quot;mit-256mb-auskommen-es-ist-einfacher-als-sie-denken&quot;&gt;Mit 256MB auskommen (Es ist einfacher als Sie denken)&lt;/h2&gt;
&lt;p&gt;Der Free Tier gibt Ihnen 256MB RAM pro VM. Ich weiss, was Sie denken - das ist nichts! Aber Sie waeren ueberrascht. Eine leichtgewichtige Express.js API verwendet etwa 50MB. Eine Flask-App mit ein paar Endpunkten liegt bei etwa 80MB. Sogar eine kleine Rails-App kann in 200MB passen, wenn Sie vorsichtig sind.&lt;/p&gt;
&lt;p&gt;Hier ist, was grossartig auf 256MB laeuft:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;API-Backends (REST oder GraphQL)&lt;/li&gt;
&lt;li&gt;Webhook-Prozessoren&lt;/li&gt;
&lt;li&gt;Geplante Job-Runner&lt;/li&gt;
&lt;li&gt;Statische Sites mit dynamischen Features&lt;/li&gt;
&lt;li&gt;Discord/Slack-Bots&lt;/li&gt;
&lt;li&gt;Kleine Datenbanken mit SQLite&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Und hier ist, was nicht funktioniert:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Next.js (braucht mindestens 512MB)&lt;/li&gt;
&lt;li&gt;Grosse Django-Anwendungen&lt;/li&gt;
&lt;li&gt;Java Spring Boot Apps&lt;/li&gt;
&lt;li&gt;Alles, was grosse Datensaetze in den Speicher laedt&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Wenn Sie an Speichergrenzen stossen, haben Sie zwei Optionen. Erstens, optimieren Sie Ihren Code - streamen Sie Dateien, anstatt sie in den Speicher zu laden, verwenden Sie Pagination fuer Datenbankabfragen, lazy-loaden Sie Abhaengigkeiten. Die meisten &quot;Speicherprobleme&quot; sind nur ineffizienter Code.&lt;/p&gt;
&lt;p&gt;Zweite Option: Skalieren Sie auf 512MB hoch. Das bringt Sie etwas ueber den Free Tier, kostet vielleicht 2-3$/Monat. Immer noch billiger als ein Kaffee, und viel nuetzlicher.&lt;/p&gt;
&lt;h2 id=&quot;postgresql-das-einfach-funktioniert&quot;&gt;PostgreSQL, das einfach funktioniert&lt;/h2&gt;
&lt;p&gt;Eine Datenbank hinzuzufuegen ist dumm einfach:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres create&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Waehlen Sie &quot;Development&quot;-Konfiguration wenn gefragt. Das gibt Ihnen eine PostgreSQL-Instanz mit 256MB RAM und 1GB Speicher, perfekt fuer kleine Apps. Die Datenbank laeuft in derselben Region wie Ihre App fuer minimale Latenz.&lt;/p&gt;
&lt;p&gt;Verbinden Sie sie mit Ihrer App:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres attach &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;database-name&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Das setzt automatisch eine DATABASE_URL Umgebungsvariable. Ihre App kann sofort verbinden:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Pool &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;pg&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pool &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;connectionString&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DATABASE_URL&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Das ist es. Sie haben eine Datenbank.&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ich betreibe einen Blog mit 500+ Posts, ein Benutzersystem mit 1000+ Konten und ein Analytics-Dashboard, das 50k Events trackt - alles auf der Free Tier Datenbank. Es sei denn, Sie bauen das naechste Twitter, sind 1GB reichlich.&lt;/p&gt;
&lt;h2 id=&quot;global-gehen-ohne-es-zu-versuchen&quot;&gt;Global gehen ohne es zu versuchen&lt;/h2&gt;
&lt;p&gt;Deployen Sie in mehrere Regionen mit einem Befehl:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; lhr  &lt;span class=&quot;token comment&quot;&gt;# London&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; nrt  &lt;span class=&quot;token comment&quot;&gt;# Tokyo&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; syd  &lt;span class=&quot;token comment&quot;&gt;# Sydney&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fly.io routet Benutzer automatisch zur naechsten Instanz. Ihre europaeischen Benutzer treffen London, asiatische Benutzer treffen Tokyo, und es funktioniert einfach. Keine Konfiguration, kein CDN-Setup, gar nichts.&lt;/p&gt;
&lt;p&gt;Mit drei kostenlosen VMs koennen Sie eine in jeder Region platzieren fuer wirklich globale Abdeckung. Oder halten Sie alle drei in einer Region fuer Redundanz - wenn eine abstuerzt, bedienen die anderen weiterhin Anfragen.&lt;/p&gt;
&lt;h2 id=&quot;die-haken-es-gibt-nicht-viele&quot;&gt;Die Haken (Es gibt nicht viele)&lt;/h2&gt;
&lt;p&gt;Seien wir ehrlich ueber die Einschraenkungen. Das 5$-Guthaben uebertraegt sich nicht von Monat zu Monat. Nutzen Sie es oder verlieren Sie es. Aber ehrlich gesagt, drei kleine VMs 24/7 zu betreiben, verbraucht sowieso das volle Guthaben.&lt;/p&gt;
&lt;p&gt;Sie muessen schliesslich eine Kreditkarte hinzufuegen, um bestimmte Features wie Custom Domains freizuschalten und Serviceunterbrechung zu verhindern, falls Sie ueber das Limit gehen. Aber hier ist die Sache - Fly.io emailt Sie, bevor irgendetwas berechnet wird. Keine ueberraschenden 500$-Rechnungen, weil Sie vergessen haben, einen Test-Server herunterzufahren.&lt;/p&gt;
&lt;p&gt;Die 256MB RAM-Grenze ist real. Sie koennen nicht einfach ineffizienten Code draufwerfen und Wunder erwarten. Aber diese Einschraenkung zwingt Sie, besseren Code zu schreiben, und das ist keine schlechte Sache.&lt;/p&gt;
&lt;h2 id=&quot;wann-flyio-verwenden-vs-alles-andere&quot;&gt;Wann Fly.io verwenden vs alles andere&lt;/h2&gt;
&lt;p&gt;Verwenden Sie Fly.io, wenn Sie echte Server wollen, die nie schlafen. Perfekt fuer APIs, Webhooks, Bots und alles, was sofort reagieren muss. Der Docker-Support bedeutet, Sie koennen jede Sprache oder jedes Framework ausfuehren.&lt;/p&gt;
&lt;p&gt;Verwenden Sie Vercel, wenn Sie Next.js-Sites bauen und diese perfekte Developer Experience wollen. Ihre Preview Deployments sind unuebertroffen.&lt;/p&gt;
&lt;p&gt;Verwenden Sie Cloudflare Workers fuer Edge Functions, die an 50+ Standorten mit null Cold Starts laufen muessen.&lt;/p&gt;
&lt;p&gt;Verwenden Sie Railway, wenn Sie eine huebschere UI wollen und es Ihnen nichts ausmacht, von Tag eins an zu zahlen.&lt;/p&gt;
&lt;p&gt;Aber um eine echte App online zu bringen, kostenlos, die weiter laeuft? Fly.io gewinnt jedes Mal.&lt;/p&gt;
&lt;h2 id=&quot;sie-sind-dran-zu-deployen&quot;&gt;Sie sind dran zu deployen&lt;/h2&gt;
&lt;p&gt;Hoeren Sie auf zu lesen und probieren Sie es aus. Ernsthaft, es dauert 5 Minuten:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Installieren Sie die CLI&lt;/li&gt;
&lt;li&gt;Erstellen Sie eine einfache App (oder verwenden Sie eine, die Sie schon haben)&lt;/li&gt;
&lt;li&gt;Fuehren Sie &lt;code class=&quot;language-text&quot;&gt;flyctl launch&lt;/code&gt; aus&lt;/li&gt;
&lt;li&gt;Sehen Sie zu, wie Ihre App live geht&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Das ist es. Keine komplexe Konfiguration, keine YAML-Hoelle, keine Abrechnungsueberraschungen. Nur Ihr Code, der auf echter Infrastruktur laeuft.&lt;/p&gt;
&lt;h2 id=&quot;bauen-sie-etwas-zum-deployen&quot;&gt;Bauen Sie etwas zum Deployen&lt;/h2&gt;
&lt;p&gt;Bereit, Ihre erste App auf Fly.io zu deployen? Beginnen Sie damit, ein echtes Projekt mit diesen praktischen Tutorials zu bauen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Einen Blog mit Flask bauen&lt;/a&gt;&lt;/strong&gt; - Erstellen Sie einen kompletten Flask-Blog, perfekt fuer Fly.io-Deployment&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Ein Portfolio mit Flask bauen&lt;/a&gt;&lt;/strong&gt; - Lernen Sie Flask-Grundlagen mit einer deploybaren Portfolio-Site&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;E-Commerce mit Flask bauen&lt;/a&gt;&lt;/strong&gt; - Meistern Sie Flask mit einer vollstaendigen Warenkorb-Anwendung&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Jedes Tutorial enthaelt Docker-Konfiguration und Deployment-Schritte, die es einfach machen, Ihr Projekt von der Entwicklung in die Produktion auf Fly.ios Free Tier zu bringen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Haben Sie schon eine Flask-App?&lt;/strong&gt; Folgen Sie unserem &lt;strong&gt;&lt;a href=&quot;/blog/dockerize-flask-blog/&quot;&gt;kompletten Docker und Fly.io Deployment-Tutorial&lt;/a&gt;&lt;/strong&gt; fuer Schritt-fuer-Schritt-Anleitungen zum Containerisieren Ihrer Flask-Anwendung mit PostgreSQL und Deployen auf Fly.io mit Zero-Downtime-Migrationen.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;technische-details&quot;&gt;Technische Details&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Plattform:&lt;/strong&gt; Fly.io
&lt;strong&gt;Monatliches Guthaben:&lt;/strong&gt; 5$ (deckt 3 VMs + Datenbank)
&lt;strong&gt;Deployment:&lt;/strong&gt; Docker-Container als microVMs
&lt;strong&gt;Regionen:&lt;/strong&gt; 30+ weltweit
&lt;strong&gt;RAM pro VM:&lt;/strong&gt; 256MB (upgradebar)
&lt;strong&gt;Datenbank:&lt;/strong&gt; PostgreSQL mit 1GB Speicher
&lt;strong&gt;Bandbreite:&lt;/strong&gt; 160GB/Monat inklusive&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Hinweis: Sie benoetigen schliesslich eine Kreditkarte hinterlegt nach dem initialen Testen, aber werden nicht belastet, wenn Sie unter 5$/Monat Nutzung bleiben.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Codex CLI: La Guia Real de Codificacion con GPT-5 (Con los Prompts Secretos de Cursor)]]></title><description><![CDATA[Filtrado: Como Cursor logro 78.2% de precision en Tau-Bench con GPT-5. Ademas los prompts exactos que hacen que los modelos escriban mejor codigo que la mayoria de los desarrolladores.]]></description><link>https://vibecodingwithfred.com/es/blog/codex-cli-ultimate-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/es/blog/codex-cli-ultimate-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Plataforma:&lt;/strong&gt; Codex CLI | &lt;strong&gt;Proveedor:&lt;/strong&gt; OpenAI | &lt;strong&gt;Modelo:&lt;/strong&gt; GPT-5 con Responses API&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;los-numeros-que-nadie-te-esta-diciendo&quot;&gt;Los Numeros Que Nadie Te Esta Diciendo&lt;/h2&gt;
&lt;p&gt;Esto es lo que revelo la prueba interna de OpenAI sobre GPT-5:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Puntuacion Tau-Bench Retail:&lt;/strong&gt; Salto de 73.9% a 78.2% solo usando la Responses API&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rendimiento SWE-Bench:&lt;/strong&gt; Supera a todos los modelos frontier en tareas de codificacion del mundo real&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Eficiencia de Llamadas a Herramientas:&lt;/strong&gt; 50% menos llamadas innecesarias con prompts apropiados&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Utilizacion de Ventana de Contexto:&lt;/strong&gt; Maneja codebases masivos sin perder el hilo&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El equipo de Cursor paso meses afinando sus prompts para GPT-5. Descubrieron que prompts mal escritos pueden hundir el rendimiento en 40%. Aqui esta exactamente lo que funciona.&lt;/p&gt;
&lt;h2 id=&quot;comenzando-de-la-manera-correcta&quot;&gt;Comenzando (De la Manera Correcta)&lt;/h2&gt;
&lt;p&gt;Instala Codex CLI:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Instalar via npm (recomendado)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @openai/codex-cli

&lt;span class=&quot;token comment&quot;&gt;# O usa el instalador directo&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# curl -fsSL https://cli.openai.com/install.sh | sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Autenticar con cuenta de ChatGPT&lt;/span&gt;
codex login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Pero aqui esta la parte critica: configura inmediatamente tu esfuerzo de razonamiento:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Para refactorizaciones complejas de multiples archivos&lt;/span&gt;
codex --reasoning-effort high

&lt;span class=&quot;token comment&quot;&gt;# Para correcciones rapidas y tareas simples&lt;/span&gt;
codex --reasoning-effort minimal

&lt;span class=&quot;token comment&quot;&gt;# Por defecto (bueno para la mayoria de codificacion)&lt;/span&gt;
codex --reasoning-effort medium&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;los-prompts-de-produccion-de-cursor-realmente-usados-en-su-editor&quot;&gt;Los Prompts de Produccion de Cursor (Realmente Usados en su Editor)&lt;/h2&gt;
&lt;p&gt;El equipo de Cursor encontro que GPT-5 era demasiado verboso inicialmente. Su solucion? Establecer verbosidad en bajo globalmente, luego sobreescribir para codigo:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Write code for clarity first. Prefer readable, maintainable solutions
with clear names, comments where needed, and straightforward control flow.
Do not produce code-golf or overly clever one-liners unless explicitly
requested. Use high verbosity for writing code and code tools.&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Este unico cambio de prompt hizo su codigo 3x mas legible mientras mantenia los mensajes de estado concisos.&lt;/p&gt;
&lt;h2 id=&quot;el-patron-de-recopilacion-de-contexto-que-cambia-todo&quot;&gt;El Patron de Recopilacion de Contexto Que Cambia Todo&lt;/h2&gt;
&lt;p&gt;El comportamiento por defecto de GPT-5 es exhaustivo—a veces demasiado. Aqui esta el prompt exacto que redujo la latencia en 60% mientras mantenia la precision:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;context_gathering&gt;
Goal: Get enough context fast. Parallelize discovery and stop as soon as you can act.

Method:
- Start broad, then fan out to focused subqueries
- In parallel, launch varied queries; read top hits per query
- Avoid over searching for context

Early stop criteria:
- You can name exact content to change
- Top hits converge (~70%) on one area/path

Depth:
- Trace only symbols you&apos;ll modify or whose contracts you rely on
- Avoid transitive expansion unless necessary

Search depth: maximum 2 tool calls before proceeding
&amp;lt;/context_gathering&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Resultado? GPT-5 deja de perder tiempo en busquedas irrelevantes y pasa a codificar mas rapido.&lt;/p&gt;
&lt;h2 id=&quot;preambulos-de-herramientas-por-que-tu-agente-se-siente-tonto&quot;&gt;Preambulos de Herramientas: Por Que Tu Agente Se Siente Tonto&lt;/h2&gt;
&lt;p&gt;Alguna vez te preguntaste por que los asistentes de codificacion con IA parecen perder el hilo de lo que estan haciendo? Es porque no estan explicando su plan. GPT-5 esta entrenado para proporcionar &quot;preambulos de herramientas&quot;—planes anticipados que mejoran drasticamente las tasas de exito.&lt;/p&gt;
&lt;p&gt;Activalos con:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;tool_preambles&gt;
- Always begin by rephrasing the user&apos;s goal in clear, concise manner
- Immediately outline a structured plan detailing each logical step
- As you execute, narrate each step succinctly, marking progress
- Finish by summarizing completed work distinctly from upfront plan
&amp;lt;/tool_preambles&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Este unico cambio mejoro las puntuaciones de satisfaccion del usuario en 35% en las pruebas de Cursor.&lt;/p&gt;
&lt;h2 id=&quot;el-stack-de-frontend-que-gpt-5-conoce-mejor&quot;&gt;El Stack de Frontend Que GPT-5 Conoce Mejor&lt;/h2&gt;
&lt;p&gt;OpenAI entreno a GPT-5 con frameworks especificos en mente. Usarlos te da 40% mejor calidad de codigo de entrada:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stack Optimo:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Framework: Next.js (TypeScript), React, HTML&lt;/li&gt;
&lt;li&gt;Estilos: Tailwind CSS, shadcn/ui, Radix Themes&lt;/li&gt;
&lt;li&gt;Iconos: Material Symbols, Heroicons, Lucide&lt;/li&gt;
&lt;li&gt;Animacion: Motion&lt;/li&gt;
&lt;li&gt;Fuentes: Sans Serif, Inter, Geist&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No lo pelees. GPT-5 escribe hermosos componentes de Tailwind pero tiene dificultades con frameworks CSS personalizados que no ha visto.&lt;/p&gt;
&lt;h2 id=&quot;el-prompt-de-auto-reflexion-que-escribe-apps-perfectas&quot;&gt;El Prompt de Auto-Reflexion Que Escribe Apps Perfectas&lt;/h2&gt;
&lt;p&gt;GPT-5 puede construir aplicaciones enteras de una sola vez—si lo prompteas correctamente. Este patron produce consistentemente codigo de calidad de produccion:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;self_reflection&gt;
- First, spend time thinking of a rubric until you are confident
- Think deeply about every aspect of what makes for a world-class one-shot web app
- Create a rubric with 5-7 categories (do not show this to user)
- Use the rubric to internally iterate on the best possible solution
- If response doesn&apos;t hit top marks across all categories, start again
&amp;lt;/self_reflection&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Los usuarios reportan que solo este prompt mejora la calidad del codigo en 50% para proyectos greenfield.&lt;/p&gt;
&lt;h2 id=&quot;el-problema-de-persistencia-y-solucion&quot;&gt;El Problema de Persistencia (Y Solucion)&lt;/h2&gt;
&lt;p&gt;GPT-5 a veces se rinde demasiado temprano o hace preguntas de aclaracion innecesarias. Cursor resolvio esto con prompts de persistencia agresivos:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;persistence&gt;
- You are an agent - keep going until query is completely resolved
- Only terminate when you are SURE the problem is solved
- Never stop at uncertainty—research or deduce the most reasonable approach
- Do not ask human to confirm assumptions—document them and proceed
- Safe actions (search, read): extremely high threshold for clarification
- Risky actions (delete, payment): lower threshold for user confirmation
&amp;lt;/persistence&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Esto redujo los eventos de &quot;hand-back&quot; en 80% en produccion.&lt;/p&gt;
&lt;h2 id=&quot;ejemplos-reales-de-produccion-que-funcionan&quot;&gt;Ejemplos Reales de Produccion Que Funcionan&lt;/h2&gt;
&lt;h3 id=&quot;sistema-de-autenticacion-probado-en-produccion&quot;&gt;Sistema de Autenticacion (Probado en Produccion)&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Create a complete JWT authentication system with:
- User registration with email verification using nodemailer
- Login with Redis-based rate limiting (5 attempts per 15 minutes)
- Password reset via time-limited tokens (15 minute expiry)
- Refresh token rotation with family detection
- PostgreSQL schema: users, sessions, refresh_tokens tables
- Express middleware checking both access and refresh tokens
- Proper HTTP status codes (401 for expired, 403 for invalid)
- Timing-safe password comparison to prevent timing attacks&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;funciones-en-tiempo-real-corriendo-actualmente-a-escala&quot;&gt;Funciones en Tiempo Real (Corriendo Actualmente a Escala)&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Build a WebSocket notification system with:
- Socket.io with Redis adapter for horizontal scaling
- Room-based broadcasting with user presence tracking
- Message queue for offline users (Redis sorted sets)
- Reconnection with missed message replay
- Client-side exponential backoff (1s, 2s, 4s, 8s, 16s cap)
- Server-side rate limiting per socket (100 msgs/minute)
- Graceful shutdown preserving connection state&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;la-realidad-del-dinero&quot;&gt;La Realidad del Dinero&lt;/h2&gt;
&lt;p&gt;Esto es lo que realmente cuesta Codex/GPT-5 en produccion:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Modelo de Suscripcion:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT Plus ($20/mes): 80% de desarrolladores nunca necesitan mas&lt;/li&gt;
&lt;li&gt;ChatGPT Pro ($200/mes): Vale la pena si codificas 4+ horas diarias&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Precios de API (Uso Real):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Endpoint CRUD simple: $0.02-0.05&lt;/li&gt;
&lt;li&gt;Sistema de autenticacion completo: $0.15-0.25&lt;/li&gt;
&lt;li&gt;Refactorizacion compleja (1000+ lineas): $0.50-1.00&lt;/li&gt;
&lt;li&gt;App completa desde cero: $2.00-5.00&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Desarrollador promedio usandolo diariamente: ~$30-50/mes en costos de API.&lt;/p&gt;
&lt;h2 id=&quot;el-secreto-del-razonamiento-minimo&quot;&gt;El Secreto del Razonamiento Minimo&lt;/h2&gt;
&lt;p&gt;Para aplicaciones sensibles a la latencia, el modo de razonamiento minimo de GPT-5 es un game-changer. Pero necesita prompts diferentes:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# Para razonamiento minimo, se explicito sobre la planificacion
Remember, you are an agent - keep going until completely resolved.
Decompose query into all required sub-requests and confirm each completed.
Plan extensively before function calls, reflect on outcomes.

# Critico: Dale una &quot;salida&quot; para la incertidumbre
Bias strongly towards providing a correct answer quickly,
even if it might not be fully correct.&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Este modo es 3x mas rapido mientras mantiene 85% de la precision.&lt;/p&gt;
&lt;h2 id=&quot;lo-que-aprendio-cursor-despues-de-1-millon-de-consultas-gpt-5&quot;&gt;Lo Que Aprendio Cursor Despues de 1 Millon de Consultas GPT-5&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Los prompts contradictorios matan el rendimiento&lt;/strong&gt; - Una instruccion conflictiva puede causar 40% de degradacion&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Las tags XML funcionan mejor que markdown&lt;/strong&gt; - &lt;code class=&quot;language-text&quot;&gt;&amp;lt;instruction&gt;&lt;/code&gt; supera a &lt;code class=&quot;language-text&quot;&gt;## Instruction&lt;/code&gt; siempre&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parametro de verbosidad + sobreescritura de prompt&lt;/strong&gt; - Bajo globalmente, alto para codigo especificamente&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Las restricciones de presupuesto de herramientas funcionan&lt;/strong&gt; - &quot;Maximum 2 tool calls&quot; fuerza eficiencia&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apply_patch supera a la edicion directa&lt;/strong&gt; - Su formato de diff personalizado reduce errores en 60%&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;las-funciones-ocultas-que-nadie-usa&quot;&gt;Las Funciones Ocultas Que Nadie Usa&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Responses API:&lt;/strong&gt; Persiste el razonamiento entre llamadas de herramientas. Solo esto mejora tareas de multiples pasos en 25%.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Escalado de esfuerzo de razonamiento:&lt;/strong&gt; La mayoria nunca cambia del medio. Alto esfuerzo para refactorizaciones complejas, minimo para correcciones simples.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Llamadas de herramientas paralelas:&lt;/strong&gt; GPT-5 puede ejecutar multiples busquedas simultaneamente. Solicita esto explicitamente para 2x de velocidad.&lt;/p&gt;
&lt;h2 id=&quot;comienza-a-usar-estos-patrones-hoy&quot;&gt;Comienza a Usar Estos Patrones Hoy&lt;/h2&gt;
&lt;p&gt;Deja de escribir prompts vagos. Comienza con estos patrones probados:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Siempre incluye condiciones de parada:&lt;/strong&gt; &quot;Only terminate when X is complete&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Especifica presupuestos de llamadas de herramientas:&lt;/strong&gt; &quot;Maximum 2 searches before proceeding&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Define contratos de salida:&lt;/strong&gt; &quot;Must return: modified files, test results, error handling&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Usa nombres de frameworks explicitamente:&lt;/strong&gt; GPT-5 conoce Next.js profundamente, frameworks aleatorios menos&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Habilita preambulos:&lt;/strong&gt; Deja que el modelo explique su plan antes de actuar&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;recursos-relacionados&quot;&gt;Recursos Relacionados&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/claude-code-cli-guide/&quot;&gt;Claude Code CLI Asistente de Terminal&lt;/a&gt;&lt;/strong&gt; - Asistente de codificacion con IA alternativo que sobresale en flujos de trabajo de terminal y desarrollo conversacional. Diferentes fortalezas de modelo lo hacen digno de comparar.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/move-to-tdd-today/&quot;&gt;Mudarse a TDD Hoy&lt;/a&gt;&lt;/strong&gt; - Escribe mejores tests para tu codigo generado por IA&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Nota: Metricas de rendimiento de la documentacion tecnica de GPT-5 de OpenAI y el despliegue en produccion de Cursor. Tus resultados pueden variar basandose en la calidad de los prompts.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Por Que Fly.io Es el Mejor Hosting Docker Gratuito Que No Estas Usando]]></title><description><![CDATA[Fly.io te da $5 de hosting cada mes, para siempre. Eso son 3 contenedores Docker, una base de datos PostgreSQL y 160GB de ancho de banda. Aqui esta por que es perfecto para proyectos paralelos.]]></description><link>https://vibecodingwithfred.com/es/blog/flyio-free-tier-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/es/blog/flyio-free-tier-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Plataforma:&lt;/strong&gt; Fly.io | &lt;strong&gt;Proveedor:&lt;/strong&gt; Fly.io | &lt;strong&gt;Nivel Gratuito:&lt;/strong&gt; $5/mes de credito para siempre&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;el-secreto-del-que-nadie-habla&quot;&gt;El Secreto del Que Nadie Habla&lt;/h2&gt;
&lt;p&gt;Esto es lo que hace especial a Fly.io: te dan $5 de credito gratis cada mes, para siempre. No es una prueba, no es una oferta por tiempo limitado—hosting permanente gratis para tus contenedores Docker. Si tu uso se mantiene bajo $5 (spoiler: lo hara para la mayoria de proyectos), no pagas nada.&lt;/p&gt;
&lt;p&gt;Aun mejor? A diferencia de cada otra plataforma que dice ser &quot;gratis,&quot; Fly.io corre tus contenedores Docker como VMs reales. Esto no es serverless donde tu app se duerme despues de 5 minutos. Tus contenedores se mantienen corriendo 24/7, respondiendo instantaneamente a las solicitudes.&lt;/p&gt;
&lt;p&gt;He estado corriendo tres APIs de produccion en Fly.io por mas de un ano. Costo total? Cero dolares. Aqui esta exactamente como hacerlo.&lt;/p&gt;
&lt;h2 id=&quot;lo-que-obtienes-gratis&quot;&gt;Lo Que Obtienes Gratis&lt;/h2&gt;
&lt;p&gt;Esos $5 de credito mensual se traducen en infraestructura seria:&lt;/p&gt;
&lt;p&gt;Obtienes tres VMs con 256MB de RAM cada una, corriendo en cualquier lugar del mundo. Agrega una base de datos PostgreSQL con 1GB de almacenamiento. Suma 160GB de ancho de banda de salida. Todo esto cabe comodamente dentro de tu asignacion gratuita, con espacio de sobra.&lt;/p&gt;
&lt;p&gt;Las matematicas son simples: una VM de 256MB cuesta aproximadamente $1.94/mes. Tres de ellas mas una base de datos pequena te pone alrededor de $5. Mientras te mantengas dentro de estos limites, el credito mensual de Fly.io cubre todo.&lt;/p&gt;
&lt;h2 id=&quot;comenzar-toma-5-minutos&quot;&gt;Comenzar Toma 5 Minutos&lt;/h2&gt;
&lt;p&gt;Primero, instala el CLI de Fly. En Mac, es un solo comando de brew. En Linux, curl su script de instalacion. Los usuarios de Windows obtienen PowerShell. Todo toma 30 segundos.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# macOS&lt;/span&gt;
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flyctl

&lt;span class=&quot;token comment&quot;&gt;# Linux&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Windows&lt;/span&gt;
pwsh &lt;span class=&quot;token parameter variable&quot;&gt;-Command&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iwr https://fly.io/install.ps1 -useb | iex&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Registrate solo con un correo—eventualmente pediran una tarjeta, pero puedes desplegar tus primeras apps sin una:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl auth signup&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;tu-primer-despliegue-es-ridiculamente-facil&quot;&gt;Tu Primer Despliegue (Es Ridiculamente Facil)&lt;/h2&gt;
&lt;p&gt;Aqui es donde brilla Fly.io. Tienes un Dockerfile? Genial, funcionara. No tienes uno? Fly.io lo descubrira. Hablo en serio—detecta tu framework y genera todo automaticamente.&lt;/p&gt;
&lt;p&gt;Dejame mostrarte un ejemplo real. Aqui hay una API de Node.js que despliegue la semana pasada:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// index.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; express &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; port &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Esta API corre 24/7 gratis&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toISOString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/health&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;healthy&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;0.0.0.0&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Corriendo en puerto &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;port&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Para desplegar esto, literalmente solo ejecute:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl launch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Eso es todo. Fly detecto Node.js, creo un Dockerfile, construyo la imagen, y la desplego globalmente. Todo el proceso tomo aproximadamente 2 minutos. Mi API estaba live en una URL *.fly.dev, con HTTPS automatico, respondiendo a solicitudes desde el datacenter mas cercano.&lt;/p&gt;
&lt;h2 id=&quot;la-ventaja-docker-de-la-que-nadie-habla&quot;&gt;La Ventaja Docker de la Que Nadie Habla&lt;/h2&gt;
&lt;p&gt;Esto es lo que separa a Fly.io de Vercel, Netlify, y el resto: estas desplegando contenedores Docker reales. Esto significa que puedes correr literalmente cualquier cosa—scripts de Python, binarios de Go, servidores de Rust, aplicaciones PHP, Ruby on Rails, lo que quieras.&lt;/p&gt;
&lt;p&gt;Tengo una API Flask de Python que procesa webhooks, un bot de Node.js que corre tareas programadas, y un servicio Go que maneja redimensionamiento de imagenes. Todo corriendo en el nivel gratuito. Intenta hacer eso en el plan hobby de Vercel.&lt;/p&gt;
&lt;p&gt;Tus contenedores corren como microVMs Firecracker, la misma tecnologia que Amazon usa para Lambda. Arrancan en milisegundos pero actuan como servidores reales. Sin cold starts, sin timeouts de 10 segundos, sin limitaciones serverless. Solo tu codigo corriendo exactamente como esperas.&lt;/p&gt;
&lt;h2 id=&quot;haciendo-que-256mb-funcionen-es-mas-facil-de-lo-que-piensas&quot;&gt;Haciendo Que 256MB Funcionen (Es Mas Facil de Lo Que Piensas)&lt;/h2&gt;
&lt;p&gt;El nivel gratuito te da 256MB de RAM por VM. Se lo que estas pensando—eso no es nada! Pero te sorprenderias. Una API ligera de Express.js usa aproximadamente 50MB. Una app Flask con algunos endpoints usa alrededor de 80MB. Incluso una app Rails pequena puede entrar en 200MB si eres cuidadoso.&lt;/p&gt;
&lt;p&gt;Esto es lo que corre genial en 256MB:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Backends de API (REST o GraphQL)&lt;/li&gt;
&lt;li&gt;Procesadores de webhook&lt;/li&gt;
&lt;li&gt;Ejecutores de trabajos programados&lt;/li&gt;
&lt;li&gt;Sitios estaticos con funciones dinamicas&lt;/li&gt;
&lt;li&gt;Bots de Discord/Slack&lt;/li&gt;
&lt;li&gt;Bases de datos pequenas con SQLite&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Y esto es lo que no:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Next.js (necesita al menos 512MB)&lt;/li&gt;
&lt;li&gt;Aplicaciones grandes de Django&lt;/li&gt;
&lt;li&gt;Apps Java Spring Boot&lt;/li&gt;
&lt;li&gt;Cualquier cosa que cargue datasets grandes en memoria&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si llegas a limites de memoria, tienes dos opciones. Primero, optimiza tu codigo—transmite archivos en lugar de cargarlos en memoria, usa paginacion para consultas de base de datos, carga lazy las dependencias. La mayoria de &quot;problemas de memoria&quot; son solo codigo ineficiente.&lt;/p&gt;
&lt;p&gt;Segunda opcion: escala a 512MB. Esto te pone ligeramente sobre el nivel gratuito, costando quizas $2-3/mes. Aun mas barato que un cafe, y mucho mas util.&lt;/p&gt;
&lt;h2 id=&quot;postgresql-que-simplemente-funciona&quot;&gt;PostgreSQL Que Simplemente Funciona&lt;/h2&gt;
&lt;p&gt;Agregar una base de datos es estupidamente simple:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres create&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Elige la configuracion &quot;Development&quot; cuando pregunte. Esto te da una instancia de PostgreSQL con 256MB de RAM y 1GB de almacenamiento, perfecta para apps pequenas. La base de datos corre en la misma region que tu app para minima latencia.&lt;/p&gt;
&lt;p&gt;Conectala a tu app:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres attach &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;database-name&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Esto automaticamente configura una variable de entorno DATABASE_URL. Tu app puede conectarse inmediatamente:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Pool &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;pg&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pool &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;connectionString&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DATABASE_URL&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Eso es todo. Tienes una base de datos.&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Estoy corriendo un blog con 500+ posts, un sistema de usuarios con 1000+ cuentas, y un dashboard de analytics rastreando 50k eventos—todo en la base de datos del nivel gratuito. A menos que estes construyendo el proximo Twitter, 1GB es suficiente.&lt;/p&gt;
&lt;h2 id=&quot;siendo-global-sin-intentarlo&quot;&gt;Siendo Global Sin Intentarlo&lt;/h2&gt;
&lt;p&gt;Despliega a multiples regiones con un comando:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; lhr  &lt;span class=&quot;token comment&quot;&gt;# Londres&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; nrt  &lt;span class=&quot;token comment&quot;&gt;# Tokyo&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; syd  &lt;span class=&quot;token comment&quot;&gt;# Sydney&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fly.io automaticamente enruta a los usuarios a la instancia mas cercana. Tus usuarios europeos van a Londres, los usuarios asiaticos van a Tokyo, y todo simplemente funciona. Sin configuracion, sin setup de CDN, sin nada.&lt;/p&gt;
&lt;p&gt;Con tres VMs gratuitas, puedes poner una en cada region para cobertura verdaderamente global. O mantener las tres en una region para redundancia—si una crashea, las otras siguen sirviendo solicitudes.&lt;/p&gt;
&lt;h2 id=&quot;las-trampas-no-hay-muchas&quot;&gt;Las Trampas (No Hay Muchas)&lt;/h2&gt;
&lt;p&gt;Seamos realistas sobre las limitaciones. El credito de $5 no se acumula de mes a mes. Usalo o pierdelo. Pero honestamente, correr tres VMs pequenas 24/7 usa el credito completo de todos modos.&lt;/p&gt;
&lt;p&gt;Eventualmente necesitaras agregar una tarjeta de credito para desbloquear ciertas funciones como dominios personalizados y para prevenir interrupcion del servicio si te pasas del limite. Pero aqui esta la cosa—Fly.io te envia un correo antes de cobrarte. Sin facturas sorpresa de $500 porque olvidaste apagar un servidor de prueba.&lt;/p&gt;
&lt;p&gt;El limite de 256MB de RAM es real. No puedes simplemente lanzarle codigo ineficiente y esperar milagros. Pero esta restriccion te fuerza a escribir mejor codigo, y eso no es algo malo.&lt;/p&gt;
&lt;h2 id=&quot;cuando-usar-flyio-vs-todo-lo-demas&quot;&gt;Cuando Usar Fly.io vs Todo lo Demas&lt;/h2&gt;
&lt;p&gt;Usa Fly.io cuando quieras servidores reales que nunca duermen. Perfecto para APIs, webhooks, bots, y cualquier cosa que necesite responder instantaneamente. El soporte de Docker significa que puedes correr cualquier lenguaje o framework.&lt;/p&gt;
&lt;p&gt;Usa Vercel cuando estes construyendo sitios Next.js y quieras esa experiencia de desarrollador perfecta. Sus preview deployments son inigualables.&lt;/p&gt;
&lt;p&gt;Usa Cloudflare Workers para funciones edge que necesiten correr en 50+ ubicaciones con cero cold starts.&lt;/p&gt;
&lt;p&gt;Usa Railway cuando quieras una UI mas bonita y no te importe pagar desde el dia uno.&lt;/p&gt;
&lt;p&gt;Pero para poner una app real online, gratis, que se mantenga corriendo? Fly.io gana siempre.&lt;/p&gt;
&lt;h2 id=&quot;tu-turno-de-desplegar&quot;&gt;Tu Turno de Desplegar&lt;/h2&gt;
&lt;p&gt;Deja de leer e intentalo. En serio, toma 5 minutos:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Instala el CLI&lt;/li&gt;
&lt;li&gt;Crea una app simple (o usa una que ya tengas)&lt;/li&gt;
&lt;li&gt;Ejecuta &lt;code class=&quot;language-text&quot;&gt;flyctl launch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Mira tu app ir a produccion&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Eso es todo. Sin configuracion compleja, sin infierno de yaml, sin sorpresas de facturacion. Solo tu codigo corriendo en infraestructura real.&lt;/p&gt;
&lt;h2 id=&quot;construye-algo-para-desplegar&quot;&gt;Construye Algo para Desplegar&lt;/h2&gt;
&lt;p&gt;Listo para desplegar tu primera app en Fly.io? Empieza construyendo un proyecto real con estos tutoriales practicos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Construye un Blog con Flask&lt;/a&gt;&lt;/strong&gt; - Crea un blog Flask completo perfecto para despliegue en Fly.io&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Construye un Portafolio con Flask&lt;/a&gt;&lt;/strong&gt; - Aprende fundamentos de Flask con un sitio de portafolio desplegable&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Construye E-Commerce con Flask&lt;/a&gt;&lt;/strong&gt; - Domina Flask con una aplicacion completa de carrito de compras&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cada tutorial incluye configuracion Docker y pasos de despliegue, facilitando llevar tu proyecto de desarrollo a produccion en el nivel gratuito de Fly.io.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ya tienes una app Flask?&lt;/strong&gt; Sigue nuestro &lt;strong&gt;&lt;a href=&quot;/blog/dockerize-flask-blog/&quot;&gt;tutorial completo de Docker y despliegue en Fly.io&lt;/a&gt;&lt;/strong&gt; para instrucciones paso a paso sobre containerizar tu aplicacion Flask con PostgreSQL y desplegar en Fly.io con migraciones sin downtime.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;detalles-tecnicos&quot;&gt;Detalles Tecnicos&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Plataforma:&lt;/strong&gt; Fly.io
&lt;strong&gt;Credito Mensual:&lt;/strong&gt; $5 (cubre 3 VMs + base de datos)
&lt;strong&gt;Despliegue:&lt;/strong&gt; Contenedores Docker como microVMs
&lt;strong&gt;Regiones:&lt;/strong&gt; 30+ a nivel mundial
&lt;strong&gt;RAM por VM:&lt;/strong&gt; 256MB (actualizable)
&lt;strong&gt;Base de Datos:&lt;/strong&gt; PostgreSQL con 1GB de almacenamiento
&lt;strong&gt;Ancho de Banda:&lt;/strong&gt; 160GB/mes incluido&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Nota: Necesitaras una tarjeta de credito registrada despues de las pruebas iniciales, pero no se te cobrara si te mantienes bajo $5/mes de uso.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Codex CLI : Le vrai guide de codage GPT-5 (avec les prompts secrets de Cursor)]]></title><description><![CDATA[Fuite : Comment Cursor a atteint 78.2% de precision sur Tau-Bench avec GPT-5. Plus les prompts exacts qui font que les modeles ecrivent du meilleur code que la plupart des developpeurs.]]></description><link>https://vibecodingwithfred.com/fr/blog/codex-cli-ultimate-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/fr/blog/codex-cli-ultimate-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Plateforme :&lt;/strong&gt; Codex CLI | &lt;strong&gt;Fournisseur :&lt;/strong&gt; OpenAI | &lt;strong&gt;Modele :&lt;/strong&gt; GPT-5 avec Responses API&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;les-chiffres-que-personne-ne-vous-dit&quot;&gt;Les chiffres que personne ne vous dit&lt;/h2&gt;
&lt;p&gt;Voici ce que les tests internes d&apos;OpenAI ont revele sur GPT-5 :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Score Tau-Bench Retail :&lt;/strong&gt; Passe de 73.9% a 78.2% juste en utilisant l&apos;API Responses&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Performance SWE-Bench :&lt;/strong&gt; Bat tous les modeles frontiere dans les taches de codage reelles&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Efficacite des appels d&apos;outils :&lt;/strong&gt; 50% d&apos;appels inutiles en moins avec un bon prompting&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Utilisation de la fenetre de contexte :&lt;/strong&gt; Gere des bases de code massives sans perdre le fil&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&apos;equipe Cursor a passe des mois a affiner leurs prompts pour GPT-5. Ils ont decouvert que des prompts mal ecrits peuvent degrader les performances de 40%. Voici exactement ce qui fonctionne.&lt;/p&gt;
&lt;h2 id=&quot;demarrer-de-la-bonne-facon&quot;&gt;Demarrer (de la bonne facon)&lt;/h2&gt;
&lt;p&gt;Installez Codex CLI :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Installer via npm (recommande)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @openai/codex-cli

&lt;span class=&quot;token comment&quot;&gt;# Ou utiliser l&apos;installateur direct&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# curl -fsSL https://cli.openai.com/install.sh | sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# S&apos;authentifier avec le compte ChatGPT&lt;/span&gt;
codex login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Mais voici la partie critique : configurez immediatement votre effort de raisonnement :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Pour les refactors complexes multi-fichiers&lt;/span&gt;
codex --reasoning-effort high

&lt;span class=&quot;token comment&quot;&gt;# Pour les corrections rapides et taches simples&lt;/span&gt;
codex --reasoning-effort minimal

&lt;span class=&quot;token comment&quot;&gt;# Par defaut (bon pour la plupart du codage)&lt;/span&gt;
codex --reasoning-effort medium&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;les-prompts-de-production-de-cursor-reellement-utilises-dans-leur-editeur&quot;&gt;Les prompts de production de Cursor (reellement utilises dans leur editeur)&lt;/h2&gt;
&lt;p&gt;L&apos;equipe Cursor a trouve que GPT-5 etait trop verbeux initialement. Leur solution ? Definir la verbosite a low globalement, puis surcharger pour le code :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Write code for clarity first. Prefer readable, maintainable solutions
with clear names, comments where needed, and straightforward control flow.
Do not produce code-golf or overly clever one-liners unless explicitly
requested. Use high verbosity for writing code and code tools.&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ce seul changement de prompt a rendu leur code 3 fois plus lisible tout en gardant les messages de statut concis.&lt;/p&gt;
&lt;h2 id=&quot;le-pattern-de-collecte-de-contexte-qui-change-tout&quot;&gt;Le pattern de collecte de contexte qui change tout&lt;/h2&gt;
&lt;p&gt;Le comportement par defaut de GPT-5 est minutieux - parfois trop minutieux. Voici le prompt exact qui a reduit la latence de 60% tout en maintenant la precision :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;context_gathering&gt;
Goal: Get enough context fast. Parallelize discovery and stop as soon as you can act.

Method:
- Start broad, then fan out to focused subqueries
- In parallel, launch varied queries; read top hits per query
- Avoid over searching for context

Early stop criteria:
- You can name exact content to change
- Top hits converge (~70%) on one area/path

Depth:
- Trace only symbols you&apos;ll modify or whose contracts you rely on
- Avoid transitive expansion unless necessary

Search depth: maximum 2 tool calls before proceeding
&amp;lt;/context_gathering&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Resultat ? GPT-5 arrete de perdre du temps sur des recherches non pertinentes et passe plus vite au codage.&lt;/p&gt;
&lt;h2 id=&quot;les-preambules-doutils--pourquoi-votre-agent-semble-bete&quot;&gt;Les preambules d&apos;outils : Pourquoi votre agent semble bete&lt;/h2&gt;
&lt;p&gt;Vous etes-vous deja demande pourquoi les assistants de codage IA semblent perdre le fil de ce qu&apos;ils font ? C&apos;est parce qu&apos;ils n&apos;expliquent pas leur plan. GPT-5 est entraine a fournir des &quot;preambules d&apos;outils&quot; - des plans initiaux qui ameliorent drastiquement les taux de succes.&lt;/p&gt;
&lt;p&gt;Activez-les avec :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;tool_preambles&gt;
- Always begin by rephrasing the user&apos;s goal in clear, concise manner
- Immediately outline a structured plan detailing each logical step
- As you execute, narrate each step succinctly, marking progress
- Finish by summarizing completed work distinctly from upfront plan
&amp;lt;/tool_preambles&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ce seul changement a ameliore les scores de satisfaction utilisateur de 35% dans les tests de Cursor.&lt;/p&gt;
&lt;h2 id=&quot;la-stack-frontend-que-gpt-5-connait-le-mieux&quot;&gt;La stack frontend que GPT-5 connait le mieux&lt;/h2&gt;
&lt;p&gt;OpenAI a entraine GPT-5 avec des frameworks specifiques en tete. Les utiliser vous donne 40% de meilleure qualite de code d&apos;emblee :&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stack optimale :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Framework : Next.js (TypeScript), React, HTML&lt;/li&gt;
&lt;li&gt;Styling : Tailwind CSS, shadcn/ui, Radix Themes&lt;/li&gt;
&lt;li&gt;Icones : Material Symbols, Heroicons, Lucide&lt;/li&gt;
&lt;li&gt;Animation : Motion&lt;/li&gt;
&lt;li&gt;Polices : Sans Serif, Inter, Geist&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ne luttez pas contre. GPT-5 ecrit de beaux composants Tailwind mais galere avec les frameworks CSS personnalises qu&apos;il n&apos;a pas vus.&lt;/p&gt;
&lt;h2 id=&quot;le-prompt-dauto-reflexion-qui-ecrit-des-apps-parfaites&quot;&gt;Le prompt d&apos;auto-reflexion qui ecrit des apps parfaites&lt;/h2&gt;
&lt;p&gt;GPT-5 peut construire des applications entieres en une seule passe - si vous le promptez correctement. Ce pattern produit systematiquement du code de qualite production :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;self_reflection&gt;
- First, spend time thinking of a rubric until you are confident
- Think deeply about every aspect of what makes for a world-class one-shot web app
- Create a rubric with 5-7 categories (do not show this to user)
- Use the rubric to internally iterate on the best possible solution
- If response doesn&apos;t hit top marks across all categories, start again
&amp;lt;/self_reflection&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Les utilisateurs rapportent que ce prompt seul ameliore la qualite du code de 50% pour les projets greenfield.&lt;/p&gt;
&lt;h2 id=&quot;le-probleme-de-persistence-et-sa-solution&quot;&gt;Le probleme de persistence (et sa solution)&lt;/h2&gt;
&lt;p&gt;GPT-5 abandonne parfois trop tot ou pose des questions de clarification inutiles. Cursor a resolu ca avec un prompting de persistence agressif :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;persistence&gt;
- You are an agent - keep going until query is completely resolved
- Only terminate when you are SURE the problem is solved
- Never stop at uncertainty—research or deduce the most reasonable approach
- Do not ask human to confirm assumptions—document them and proceed
- Safe actions (search, read): extremely high threshold for clarification
- Risky actions (delete, payment): lower threshold for user confirmation
&amp;lt;/persistence&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Cela a reduit les evenements de &quot;renvoi a l&apos;humain&quot; de 80% en production.&lt;/p&gt;
&lt;h2 id=&quot;vrais-exemples-de-production-qui-fonctionnent&quot;&gt;Vrais exemples de production qui fonctionnent&lt;/h2&gt;
&lt;h3 id=&quot;systeme-dauthentification-teste-en-production&quot;&gt;Systeme d&apos;authentification (teste en production)&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Create a complete JWT authentication system with:
- User registration with email verification using nodemailer
- Login with Redis-based rate limiting (5 attempts per 15 minutes)
- Password reset via time-limited tokens (15 minute expiry)
- Refresh token rotation with family detection
- PostgreSQL schema: users, sessions, refresh_tokens tables
- Express middleware checking both access and refresh tokens
- Proper HTTP status codes (401 for expired, 403 for invalid)
- Timing-safe password comparison to prevent timing attacks&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;fonctionnalites-temps-reel-actuellement-en-production-a-grande-echelle&quot;&gt;Fonctionnalites temps reel (actuellement en production a grande echelle)&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Build a WebSocket notification system with:
- Socket.io with Redis adapter for horizontal scaling
- Room-based broadcasting with user presence tracking
- Message queue for offline users (Redis sorted sets)
- Reconnection with missed message replay
- Client-side exponential backoff (1s, 2s, 4s, 8s, 16s cap)
- Server-side rate limiting per socket (100 msgs/minute)
- Graceful shutdown preserving connection state&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;la-realite-des-couts&quot;&gt;La realite des couts&lt;/h2&gt;
&lt;p&gt;Voici ce que coute reellement Codex/GPT-5 en production :&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Modele d&apos;abonnement :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT Plus (20$/mois) : 80% des developpeurs n&apos;ont jamais besoin de plus&lt;/li&gt;
&lt;li&gt;ChatGPT Pro (200$/mois) : Vaut le coup si vous codez 4+ heures par jour&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Tarification API (utilisation reelle) :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Endpoint CRUD simple : 0.02-0.05$&lt;/li&gt;
&lt;li&gt;Systeme d&apos;authentification complet : 0.15-0.25$&lt;/li&gt;
&lt;li&gt;Refactor complexe (1000+ lignes) : 0.50-1.00$&lt;/li&gt;
&lt;li&gt;App complete a partir de zero : 2.00-5.00$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Developpeur moyen l&apos;utilisant quotidiennement : ~30-50$/mois en couts API.&lt;/p&gt;
&lt;h2 id=&quot;le-secret-du-raisonnement-minimal&quot;&gt;Le secret du raisonnement minimal&lt;/h2&gt;
&lt;p&gt;Pour les applications sensibles a la latence, le mode de raisonnement minimal de GPT-5 est revolutionnaire. Mais il necessite un prompting different :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# Pour le raisonnement minimal, soyez explicite sur la planification
Remember, you are an agent - keep going until completely resolved.
Decompose query into all required sub-requests and confirm each completed.
Plan extensively before function calls, reflect on outcomes.

# Critique : Donnez-lui une &quot;sortie&quot; pour l&apos;incertitude
Bias strongly towards providing a correct answer quickly,
even if it might not be fully correct.&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ce mode est 3 fois plus rapide tout en maintenant 85% de la precision.&lt;/p&gt;
&lt;h2 id=&quot;ce-que-cursor-a-appris-apres-1-million-de-requetes-gpt-5&quot;&gt;Ce que Cursor a appris apres 1 million de requetes GPT-5&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Les prompts contradictoires tuent la performance&lt;/strong&gt; - Une instruction conflictuelle peut causer 40% de degradation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Les tags XML fonctionnent mieux que le markdown&lt;/strong&gt; - &lt;code class=&quot;language-text&quot;&gt;&amp;lt;instruction&gt;&lt;/code&gt; bat &lt;code class=&quot;language-text&quot;&gt;## Instruction&lt;/code&gt; a chaque fois&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parametre de verbosite + surcharge de prompt&lt;/strong&gt; - Defini bas globalement, haut pour le code specifiquement&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Les contraintes de budget d&apos;outils fonctionnent&lt;/strong&gt; - &quot;Maximum 2 appels d&apos;outils&quot; force l&apos;efficacite&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apply_patch bat l&apos;edition directe&lt;/strong&gt; - Leur format de diff personnalise reduit les erreurs de 60%&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;les-fonctionnalites-cachees-que-personne-nutilise&quot;&gt;Les fonctionnalites cachees que personne n&apos;utilise&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;API Responses :&lt;/strong&gt; Persiste le raisonnement entre les appels d&apos;outils. Cela seul ameliore les taches multi-etapes de 25%.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mise a l&apos;echelle de l&apos;effort de raisonnement :&lt;/strong&gt; La plupart des gens ne changent jamais de medium. Effort eleve pour les refactors complexes, minimal pour les corrections simples.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Appels d&apos;outils paralleles :&lt;/strong&gt; GPT-5 peut lancer plusieurs recherches simultanement. Demandez-le explicitement pour une vitesse 2x.&lt;/p&gt;
&lt;h2 id=&quot;commencez-a-utiliser-ces-patterns-aujourdhui&quot;&gt;Commencez a utiliser ces patterns aujourd&apos;hui&lt;/h2&gt;
&lt;p&gt;Arretez d&apos;ecrire des prompts vagues. Commencez avec ces patterns testes :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Toujours inclure des conditions d&apos;arret :&lt;/strong&gt; &quot;Only terminate when X is complete&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Specifier des budgets d&apos;appels d&apos;outils :&lt;/strong&gt; &quot;Maximum 2 searches before proceeding&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Definir des contrats de sortie :&lt;/strong&gt; &quot;Must return: modified files, test results, error handling&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Utiliser les noms de frameworks explicitement :&lt;/strong&gt; GPT-5 connait Next.js en profondeur, les frameworks aleatoires moins&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Activer les preambules :&lt;/strong&gt; Laissez le modele expliquer son plan avant d&apos;agir&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;ressources-connexes&quot;&gt;Ressources connexes&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/claude-code-cli-guide/&quot;&gt;Claude Code CLI Terminal Assistant&lt;/a&gt;&lt;/strong&gt; - Assistant de codage IA alternatif qui excelle dans les workflows terminal et le developpement conversationnel. Differentes forces du modele le rendent utile a comparer.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/move-to-tdd-today/&quot;&gt;Passer au TDD aujourd&apos;hui&lt;/a&gt;&lt;/strong&gt; - Ecrivez de meilleurs tests pour votre code genere par IA&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Note : Metriques de performance issues de la documentation technique GPT-5 d&apos;OpenAI et du deploiement production de Cursor. Vos resultats peuvent varier en fonction de la qualite du prompting.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Pourquoi Fly.io est le meilleur hebergement Docker gratuit que vous n'utilisez pas]]></title><description><![CDATA[Fly.io vous donne 5$ d'hebergement chaque mois, pour toujours. Ca fait 3 conteneurs Docker, une base de donnees PostgreSQL et 160Go de bande passante. Voici pourquoi c'est parfait pour les projets secondaires.]]></description><link>https://vibecodingwithfred.com/fr/blog/flyio-free-tier-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/fr/blog/flyio-free-tier-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Plateforme :&lt;/strong&gt; Fly.io | &lt;strong&gt;Fournisseur :&lt;/strong&gt; Fly.io | &lt;strong&gt;Palier gratuit :&lt;/strong&gt; 5$/mois de credit pour toujours&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;le-secret-dont-personne-ne-parle&quot;&gt;Le secret dont personne ne parle&lt;/h2&gt;
&lt;p&gt;Voici ce qui rend Fly.io special : ils vous donnent 5$ de credit gratuit chaque mois, pour toujours. Pas un essai, pas une offre a duree limitee - un hebergement permanent gratuit pour vos conteneurs Docker. Si votre utilisation reste sous 5$ (spoiler : ce sera le cas pour la plupart des projets), vous ne payez rien.&lt;/p&gt;
&lt;p&gt;Encore mieux ? Contrairement a toutes les autres plateformes qui pretendent etre &quot;gratuites&quot;, Fly.io execute vos conteneurs Docker comme de vraies VMs. Ce n&apos;est pas du serverless ou votre app s&apos;endort apres 5 minutes. Vos conteneurs restent en marche 24/7, repondant instantanement aux requetes.&lt;/p&gt;
&lt;p&gt;J&apos;ai trois APIs de production qui tournent sur Fly.io depuis plus d&apos;un an. Cout total ? Zero dollars. Voici exactement comment faire.&lt;/p&gt;
&lt;h2 id=&quot;ce-que-vous-obtenez-gratuitement&quot;&gt;Ce que vous obtenez gratuitement&lt;/h2&gt;
&lt;p&gt;Ce credit mensuel de 5$ se traduit par une infrastructure serieuse :&lt;/p&gt;
&lt;p&gt;Vous obtenez trois VMs avec 256Mo de RAM chacune, qui tournent n&apos;importe ou dans le monde. Ajoutez une base de donnees PostgreSQL avec 1Go de stockage. Ajoutez 160Go de bande passante sortante. Tout ca tient confortablement dans votre allocation gratuite, avec de la marge.&lt;/p&gt;
&lt;p&gt;Le calcul est simple : une seule VM de 256Mo coute environ 1.94$/mois. Trois d&apos;entre elles plus une petite base de donnees vous amene juste autour de 5$. Tant que vous restez dans ces limites, le credit mensuel de Fly.io couvre tout.&lt;/p&gt;
&lt;h2 id=&quot;demarrer-prend-5-minutes&quot;&gt;Demarrer prend 5 minutes&lt;/h2&gt;
&lt;p&gt;D&apos;abord, installez le CLI Fly. Sur Mac, c&apos;est une seule commande brew. Sur Linux, curl leur script d&apos;installation. Les utilisateurs Windows ont PowerShell. Le tout prend 30 secondes.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# macOS&lt;/span&gt;
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flyctl

&lt;span class=&quot;token comment&quot;&gt;# Linux&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Windows&lt;/span&gt;
pwsh &lt;span class=&quot;token parameter variable&quot;&gt;-Command&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iwr https://fly.io/install.ps1 -useb | iex&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Inscrivez-vous avec juste un email - ils demanderont une carte eventuellement, mais vous pouvez deployer vos premieres apps sans :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl auth signup&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;votre-premier-deploiement-cest-ridiculement-facile&quot;&gt;Votre premier deploiement (c&apos;est ridiculement facile)&lt;/h2&gt;
&lt;p&gt;C&apos;est la ou Fly.io brille. Vous avez un Dockerfile ? Super, ca fonctionnera. Vous n&apos;en avez pas ? Fly.io va le comprendre. Je suis serieux - il detecte votre framework et genere tout automatiquement.&lt;/p&gt;
&lt;p&gt;Laissez-moi vous montrer un exemple reel. Voici une API Node.js que j&apos;ai deployee la semaine derniere :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// index.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; express &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; port &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Cette API tourne 24/7 gratuitement&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toISOString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/health&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;healthy&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;0.0.0.0&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Running on port &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;port&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Pour deployer ca, j&apos;ai litteralement juste execute :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl launch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;C&apos;est tout. Fly a detecte Node.js, cree un Dockerfile, construit l&apos;image et l&apos;a deployee globalement. Le processus entier a pris environ 2 minutes. Mon API etait en ligne sur une URL *.fly.dev, avec HTTPS automatique, repondant aux requetes depuis le centre de donnees le plus proche.&lt;/p&gt;
&lt;h2 id=&quot;lavantage-docker-que-personne-ne-mentionne&quot;&gt;L&apos;avantage Docker que personne ne mentionne&lt;/h2&gt;
&lt;p&gt;Voici ce qui distingue Fly.io de Vercel, Netlify et les autres : vous deployez de vrais conteneurs Docker. Ca signifie que vous pouvez executer litteralement n&apos;importe quoi - scripts Python, binaires Go, serveurs Rust, applications PHP, Ruby on Rails, ce que vous voulez.&lt;/p&gt;
&lt;p&gt;J&apos;ai une API Flask Python qui traite des webhooks, un bot Node.js qui execute des taches planifiees et un service Go qui gere le redimensionnement d&apos;images. Tous tournent sur le palier gratuit. Essayez de faire ca sur le plan hobby de Vercel.&lt;/p&gt;
&lt;p&gt;Vos conteneurs tournent comme des microVMs Firecracker, la meme technologie qu&apos;Amazon utilise pour Lambda. Ils demarrent en millisecondes mais se comportent comme de vrais serveurs. Pas de cold starts, pas de timeouts de 10 secondes, pas de limitations serverless. Juste votre code qui tourne exactement comme vous l&apos;attendez.&lt;/p&gt;
&lt;h2 id=&quot;faire-fonctionner-256mo-cest-plus-facile-quon-ne-le-pense&quot;&gt;Faire fonctionner 256Mo (c&apos;est plus facile qu&apos;on ne le pense)&lt;/h2&gt;
&lt;p&gt;Le palier gratuit vous donne 256Mo de RAM par VM. Je sais ce que vous pensez - c&apos;est rien ! Mais vous seriez surpris. Une API Express.js legere utilise environ 50Mo. Une app Flask avec quelques endpoints se situe autour de 80Mo. Meme une petite app Rails peut tenir dans 200Mo si vous faites attention.&lt;/p&gt;
&lt;p&gt;Voici ce qui tourne bien sur 256Mo :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Backends API (REST ou GraphQL)&lt;/li&gt;
&lt;li&gt;Processeurs de webhooks&lt;/li&gt;
&lt;li&gt;Executeurs de jobs planifies&lt;/li&gt;
&lt;li&gt;Sites statiques avec des fonctionnalites dynamiques&lt;/li&gt;
&lt;li&gt;Bots Discord/Slack&lt;/li&gt;
&lt;li&gt;Petites bases de donnees avec SQLite&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Et voici ce qui ne tourne pas :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Next.js (a besoin d&apos;au moins 512Mo)&lt;/li&gt;
&lt;li&gt;Grandes applications Django&lt;/li&gt;
&lt;li&gt;Apps Java Spring Boot&lt;/li&gt;
&lt;li&gt;Tout ce qui charge de gros datasets en memoire&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;postgresql-qui-juste-fonctionne&quot;&gt;PostgreSQL qui juste fonctionne&lt;/h2&gt;
&lt;p&gt;Ajouter une base de donnees est stupidement simple :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres create&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Choisissez la configuration &quot;Development&quot; quand on vous demande. Ca vous donne une instance PostgreSQL avec 256Mo de RAM et 1Go de stockage, parfait pour les petites apps. La base de donnees tourne dans la meme region que votre app pour une latence minimale.&lt;/p&gt;
&lt;p&gt;Connectez-la a votre app :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres attach &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;nom-base-de-donnees&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Cela definit automatiquement une variable d&apos;environnement DATABASE_URL. Votre app peut se connecter immediatement :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Pool &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;pg&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pool &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;connectionString&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DATABASE_URL&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// C&apos;est tout. Vous avez une base de donnees.&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Je fais tourner un blog avec 500+ articles, un systeme utilisateur avec 1000+ comptes et un tableau de bord analytique suivant 50k evenements - tout sur la base de donnees du palier gratuit. A moins que vous construisiez le prochain Twitter, 1Go c&apos;est largement suffisant.&lt;/p&gt;
&lt;h2 id=&quot;devenir-global-sans-essayer&quot;&gt;Devenir global sans essayer&lt;/h2&gt;
&lt;p&gt;Deployez dans plusieurs regions avec une seule commande :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; lhr  &lt;span class=&quot;token comment&quot;&gt;# Londres&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; nrt  &lt;span class=&quot;token comment&quot;&gt;# Tokyo&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; syd  &lt;span class=&quot;token comment&quot;&gt;# Sydney&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fly.io route automatiquement les utilisateurs vers l&apos;instance la plus proche. Vos utilisateurs europeens arrivent a Londres, les utilisateurs asiatiques arrivent a Tokyo, et tout fonctionne simplement. Pas de configuration, pas de setup CDN, rien.&lt;/p&gt;
&lt;p&gt;Avec trois VMs gratuites, vous pouvez en mettre une dans chaque region pour une couverture vraiment globale. Ou gardez les trois dans une region pour la redondance - si une crashe, les autres continuent de servir les requetes.&lt;/p&gt;
&lt;h2 id=&quot;les-pieges-il-ny-en-a-pas-beaucoup&quot;&gt;Les pieges (il n&apos;y en a pas beaucoup)&lt;/h2&gt;
&lt;p&gt;Soyons realistes sur les limitations. Le credit de 5$ ne se reporte pas d&apos;un mois a l&apos;autre. Utilisez-le ou perdez-le. Mais honnetement, faire tourner trois petites VMs 24/7 utilise le credit complet de toute facon.&lt;/p&gt;
&lt;p&gt;Vous devrez eventuellement ajouter une carte de credit pour debloquer certaines fonctionnalites comme les domaines personnalises et pour prevenir l&apos;interruption de service si vous depassez la limite. Mais voici le truc - Fly.io vous envoie un email avant de facturer quoi que ce soit. Pas de factures surprise de 500$ parce que vous avez oublie d&apos;eteindre un serveur de test.&lt;/p&gt;
&lt;p&gt;La limite de RAM de 256Mo est reelle. Vous ne pouvez pas juste y balancer du code inefficace et attendre des miracles. Mais cette contrainte vous force a ecrire du meilleur code, et ce n&apos;est pas une mauvaise chose.&lt;/p&gt;
&lt;h2 id=&quot;quand-utiliser-flyio-vs-tout-le-reste&quot;&gt;Quand utiliser Fly.io vs tout le reste&lt;/h2&gt;
&lt;p&gt;Utilisez Fly.io quand vous voulez de vrais serveurs qui ne dorment jamais. Parfait pour les APIs, webhooks, bots et tout ce qui doit repondre instantanement. Le support Docker signifie que vous pouvez executer n&apos;importe quel langage ou framework.&lt;/p&gt;
&lt;p&gt;Utilisez Vercel quand vous construisez des sites Next.js et voulez cette experience developpeur parfaite. Leurs preview deployments sont inegalees.&lt;/p&gt;
&lt;p&gt;Utilisez Cloudflare Workers pour les fonctions edge qui doivent tourner dans 50+ emplacements avec zero cold starts.&lt;/p&gt;
&lt;p&gt;Utilisez Railway quand vous voulez une UI plus jolie et ne voyez pas d&apos;inconvenient a payer des le premier jour.&lt;/p&gt;
&lt;p&gt;Mais pour mettre une vraie app en ligne, gratuitement, qui reste en marche ? Fly.io gagne a chaque fois.&lt;/p&gt;
&lt;h2 id=&quot;a-votre-tour-de-deployer&quot;&gt;A votre tour de deployer&lt;/h2&gt;
&lt;p&gt;Arretez de lire et essayez. Serieusement, ca prend 5 minutes :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Installez le CLI&lt;/li&gt;
&lt;li&gt;Creez une app simple (ou utilisez-en une que vous avez deja)&lt;/li&gt;
&lt;li&gt;Executez &lt;code class=&quot;language-text&quot;&gt;flyctl launch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Regardez votre app passer en ligne&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;C&apos;est tout. Pas de configuration complexe, pas d&apos;enfer yaml, pas de surprises de facturation. Juste votre code qui tourne sur une vraie infrastructure.&lt;/p&gt;
&lt;h2 id=&quot;construire-quelque-chose-a-deployer&quot;&gt;Construire quelque chose a deployer&lt;/h2&gt;
&lt;p&gt;Pret a deployer votre premiere app sur Fly.io ? Commencez par construire un vrai projet avec ces tutoriels pratiques :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Construire un blog avec Flask&lt;/a&gt;&lt;/strong&gt; - Creez un blog Flask complet parfait pour le deploiement Fly.io&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Construire un portfolio avec Flask&lt;/a&gt;&lt;/strong&gt; - Apprenez les fondamentaux Flask avec un site portfolio deployable&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Construire un e-commerce avec Flask&lt;/a&gt;&lt;/strong&gt; - Maitrisez Flask avec une application de panier d&apos;achat complete&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Chaque tutoriel inclut la configuration Docker et les etapes de deploiement, facilitant le passage de votre projet du developpement a la production sur le palier gratuit de Fly.io.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Vous avez deja une app Flask ?&lt;/strong&gt; Suivez notre &lt;strong&gt;&lt;a href=&quot;/blog/dockerize-flask-blog/&quot;&gt;tutoriel complet de deploiement Docker et Fly.io&lt;/a&gt;&lt;/strong&gt; pour des instructions etape par etape sur la containerisation de votre application Flask avec PostgreSQL et le deploiement sur Fly.io avec des migrations sans temps d&apos;arret.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;details-techniques&quot;&gt;Details techniques&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Plateforme :&lt;/strong&gt; Fly.io
&lt;strong&gt;Credit mensuel :&lt;/strong&gt; 5$ (couvre 3 VMs + base de donnees)
&lt;strong&gt;Deploiement :&lt;/strong&gt; Conteneurs Docker comme microVMs
&lt;strong&gt;Regions :&lt;/strong&gt; 30+ dans le monde
&lt;strong&gt;RAM par VM :&lt;/strong&gt; 256Mo (extensible)
&lt;strong&gt;Base de donnees :&lt;/strong&gt; PostgreSQL avec 1Go de stockage
&lt;strong&gt;Bande passante :&lt;/strong&gt; 160Go/mois inclus&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note : Vous aurez besoin d&apos;une carte de credit enregistree apres les tests initiaux, mais vous ne serez pas facture si vous restez sous 5$/mois d&apos;utilisation.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Perche Fly.io E il Miglior Hosting Docker Gratuito Che Non Stai Usando]]></title><description><![CDATA[Fly.io ti da $5 di hosting ogni mese, per sempre. Sono 3 container Docker, un database PostgreSQL e 160GB di banda. Ecco perche e perfetto per i side project.]]></description><link>https://vibecodingwithfred.com/it/blog/flyio-free-tier-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/it/blog/flyio-free-tier-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Piattaforma:&lt;/strong&gt; Fly.io | &lt;strong&gt;Provider:&lt;/strong&gt; Fly.io | &lt;strong&gt;Piano Gratuito:&lt;/strong&gt; $5/mese di credito per sempre&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;il-segreto-di-cui-nessuno-parla&quot;&gt;Il Segreto di Cui Nessuno Parla&lt;/h2&gt;
&lt;p&gt;Ecco cosa rende Fly.io speciale: ti danno $5 di credito gratuito ogni singolo mese, per sempre. Non una prova, non un&apos;offerta a tempo limitato - hosting permanente gratuito per i tuoi container Docker. Se il tuo utilizzo resta sotto i $5 (spoiler: lo sara per la maggior parte dei progetti), non paghi nulla.&lt;/p&gt;
&lt;p&gt;Ancora meglio? A differenza di ogni altra piattaforma che afferma di essere &quot;gratuita&quot;, Fly.io esegue i tuoi container Docker come vere VM. Questo non e serverless dove la tua app va in sleep dopo 5 minuti. I tuoi container restano attivi 24/7, rispondendo istantaneamente alle richieste.&lt;/p&gt;
&lt;p&gt;Sto facendo girare tre API in produzione su Fly.io da oltre un anno. Costo totale? Zero euro. Ecco esattamente come farlo.&lt;/p&gt;
&lt;h2 id=&quot;cosa-ottieni-gratuitamente&quot;&gt;Cosa Ottieni Gratuitamente&lt;/h2&gt;
&lt;p&gt;Quei $5 di credito mensile si traducono in infrastruttura seria:&lt;/p&gt;
&lt;p&gt;Ottieni tre VM con 256MB di RAM ciascuna, che girano ovunque nel mondo. Aggiungi un database PostgreSQL con 1GB di storage. Aggiungi 160GB di banda in uscita. Tutto questo sta comodamente nel tuo credito gratuito, con margine di riserva.&lt;/p&gt;
&lt;p&gt;La matematica e semplice: una singola VM da 256MB costa circa $1.94/mese. Tre di queste piu un piccolo database ti portano circa a $5. Finche resti entro questi limiti, il credito mensile di Fly.io copre tutto.&lt;/p&gt;
&lt;h2 id=&quot;iniziare-richiede-5-minuti&quot;&gt;Iniziare Richiede 5 Minuti&lt;/h2&gt;
&lt;p&gt;Prima, installa la CLI di Fly. Su Mac, e un singolo comando brew. Su Linux, usa curl con il loro script di installazione. Gli utenti Windows usano PowerShell. Il tutto richiede 30 secondi.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# macOS&lt;/span&gt;
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flyctl

&lt;span class=&quot;token comment&quot;&gt;# Linux&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Windows&lt;/span&gt;
pwsh &lt;span class=&quot;token parameter variable&quot;&gt;-Command&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iwr https://fly.io/install.ps1 -useb | iex&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Registrati solo con un&apos;email - ti chiederanno una carta alla fine, ma puoi deployare le tue prime app senza:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl auth signup&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;il-tuo-primo-deploy-e-ridicolmente-facile&quot;&gt;Il Tuo Primo Deploy (E Ridicolmente Facile)&lt;/h2&gt;
&lt;p&gt;Ecco dove Fly.io brilla. Hai un Dockerfile? Ottimo, funzionera. Non ne hai uno? Fly.io lo capira da solo. Parlo sul serio - rileva il tuo framework e genera tutto automaticamente.&lt;/p&gt;
&lt;p&gt;Lascia che ti mostri un esempio reale. Ecco un&apos;API Node.js che ho deployato la settimana scorsa:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// index.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; express &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; port &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;This API runs 24/7 for free&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toISOString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/health&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;healthy&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;0.0.0.0&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Running on port &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;port&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Per deployare questo, ho letteralmente solo eseguito:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl launch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;E tutto. Fly ha rilevato Node.js, creato un Dockerfile, buildato l&apos;immagine e deployato globalmente. L&apos;intero processo ha richiesto circa 2 minuti. La mia API era live a un URL *.fly.dev, con HTTPS automatico, rispondendo alle richieste dal data center piu vicino.&lt;/p&gt;
&lt;h2 id=&quot;il-vantaggio-docker-di-cui-nessuno-parla&quot;&gt;Il Vantaggio Docker di Cui Nessuno Parla&lt;/h2&gt;
&lt;p&gt;Ecco cosa distingue Fly.io da Vercel, Netlify e il resto: stai deployando veri container Docker. Questo significa che puoi eseguire letteralmente qualsiasi cosa - script Python, binari Go, server Rust, applicazioni PHP, Ruby on Rails, quello che vuoi.&lt;/p&gt;
&lt;p&gt;Ho un&apos;API Flask Python che processa webhook, un bot Node.js che esegue task schedulati, e un servizio Go che gestisce il ridimensionamento immagini. Tutto gira sul piano gratuito. Prova a farlo sul piano hobby di Vercel.&lt;/p&gt;
&lt;p&gt;I tuoi container girano come microVM Firecracker, la stessa tecnologia che Amazon usa per Lambda. Si avviano in millisecondi ma agiscono come server reali. Niente cold start, niente timeout di 10 secondi, niente limitazioni serverless. Solo il tuo codice che gira esattamente come ti aspetti.&lt;/p&gt;
&lt;h2 id=&quot;far-funzionare-256mb-e-piu-facile-di-quanto-pensi&quot;&gt;Far Funzionare 256MB (E Piu Facile Di Quanto Pensi)&lt;/h2&gt;
&lt;p&gt;Il piano gratuito ti da 256MB di RAM per VM. So cosa stai pensando - e niente! Ma saresti sorpreso. Un&apos;API Express.js leggera usa circa 50MB. Un&apos;app Flask con pochi endpoint sta intorno agli 80MB. Anche una piccola app Rails puo entrare in 200MB se stai attento.&lt;/p&gt;
&lt;p&gt;Ecco cosa gira bene su 256MB:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Backend API (REST o GraphQL)&lt;/li&gt;
&lt;li&gt;Processori di webhook&lt;/li&gt;
&lt;li&gt;Runner di job schedulati&lt;/li&gt;
&lt;li&gt;Siti statici con funzionalita dinamiche&lt;/li&gt;
&lt;li&gt;Bot Discord/Slack&lt;/li&gt;
&lt;li&gt;Piccoli database con SQLite&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ed ecco cosa non funziona:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Next.js (servono almeno 512MB)&lt;/li&gt;
&lt;li&gt;Applicazioni Django grandi&lt;/li&gt;
&lt;li&gt;App Java Spring Boot&lt;/li&gt;
&lt;li&gt;Qualsiasi cosa carichi grandi dataset in memoria&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Se raggiungi i limiti di memoria, hai due opzioni. Prima, ottimizza il tuo codice - fai streaming dei file invece di caricarli in memoria, usa la paginazione per le query al database, lazy-load le dipendenze. La maggior parte dei &quot;problemi di memoria&quot; sono solo codice inefficiente.&lt;/p&gt;
&lt;p&gt;Seconda opzione: scala a 512MB. Questo ti porta leggermente oltre il piano gratuito, costando forse $2-3/mese. Comunque piu economico di un caffe, e molto piu utile.&lt;/p&gt;
&lt;h2 id=&quot;postgresql-che-funziona-e-basta&quot;&gt;PostgreSQL Che Funziona e Basta&lt;/h2&gt;
&lt;p&gt;Aggiungere un database e stupidamente semplice:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres create&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Scegli configurazione &quot;Development&quot; quando richiesto. Questo ti da un&apos;istanza PostgreSQL con 256MB di RAM e 1GB di storage, perfetta per piccole app. Il database gira nella stessa regione della tua app per latenza minima.&lt;/p&gt;
&lt;p&gt;Connettilo alla tua app:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres attach &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;database-name&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Questo imposta automaticamente una variabile d&apos;ambiente DATABASE_URL. La tua app puo connettersi immediatamente:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Pool &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;pg&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pool &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;connectionString&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DATABASE_URL&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// E tutto. Hai un database.&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sto facendo girare un blog con 500+ post, un sistema utenti con 1000+ account, e una dashboard di analytics che traccia 50k eventi - tutto sul database del piano gratuito. A meno che tu non stia costruendo il prossimo Twitter, 1GB e abbondante.&lt;/p&gt;
&lt;h2 id=&quot;diventare-globali-senza-sforzo&quot;&gt;Diventare Globali Senza Sforzo&lt;/h2&gt;
&lt;p&gt;Deploya in piu regioni con un comando:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; lhr  &lt;span class=&quot;token comment&quot;&gt;# Londra&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; nrt  &lt;span class=&quot;token comment&quot;&gt;# Tokyo&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; syd  &lt;span class=&quot;token comment&quot;&gt;# Sydney&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fly.io instrada automaticamente gli utenti all&apos;istanza piu vicina. I tuoi utenti europei colpiscono Londra, gli utenti asiatici colpiscono Tokyo, e tutto funziona e basta. Nessuna configurazione, nessun setup CDN, niente.&lt;/p&gt;
&lt;p&gt;Con tre VM gratuite, puoi metterne una in ogni regione per copertura veramente globale. O tenerle tutte e tre in una regione per ridondanza - se una crasha, le altre continuano a servire richieste.&lt;/p&gt;
&lt;h2 id=&quot;i-problemi-non-ce-ne-sono-molti&quot;&gt;I Problemi (Non Ce Ne Sono Molti)&lt;/h2&gt;
&lt;p&gt;Siamo realistici sulle limitazioni. Il credito di $5 non si accumula di mese in mese. Usalo o perdilo. Ma onestamente, far girare tre piccole VM 24/7 usa tutto il credito comunque.&lt;/p&gt;
&lt;p&gt;Alla fine dovrai aggiungere una carta di credito per sbloccare certe funzionalita come i domini personalizzati e per prevenire l&apos;interruzione del servizio se superi il limite. Ma ecco la cosa - Fly.io ti manda un&apos;email prima di addebitare qualsiasi cosa. Niente bollette sorpresa da $500 perche hai dimenticato di spegnere un server di test.&lt;/p&gt;
&lt;p&gt;Il limite di 256MB di RAM e reale. Non puoi semplicemente buttargli codice inefficiente e aspettarti miracoli. Ma questo vincolo ti forza a scrivere codice migliore, e non e una cosa negativa.&lt;/p&gt;
&lt;h2 id=&quot;quando-usare-flyio-vs-tutto-il-resto&quot;&gt;Quando Usare Fly.io vs Tutto il Resto&lt;/h2&gt;
&lt;p&gt;Usa Fly.io quando vuoi server reali che non dormono mai. Perfetto per API, webhook, bot, e qualsiasi cosa che debba rispondere istantaneamente. Il supporto Docker significa che puoi eseguire qualsiasi linguaggio o framework.&lt;/p&gt;
&lt;p&gt;Usa Vercel quando stai costruendo siti Next.js e vuoi quella perfetta esperienza sviluppatore. I loro preview deployment sono impareggiabili.&lt;/p&gt;
&lt;p&gt;Usa Cloudflare Workers per funzioni edge che devono girare in 50+ location con zero cold start.&lt;/p&gt;
&lt;p&gt;Usa Railway quando vuoi un&apos;interfaccia piu bella e non ti dispiace pagare dal primo giorno.&lt;/p&gt;
&lt;p&gt;Ma per mettere online un&apos;app vera, gratuitamente, che resta attiva? Fly.io vince sempre.&lt;/p&gt;
&lt;h2 id=&quot;tocca-a-te-deployare&quot;&gt;Tocca a Te Deployare&lt;/h2&gt;
&lt;p&gt;Smetti di leggere e provalo. Sul serio, richiede 5 minuti:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Installa la CLI&lt;/li&gt;
&lt;li&gt;Crea una semplice app (o usane una che hai gia)&lt;/li&gt;
&lt;li&gt;Esegui &lt;code class=&quot;language-text&quot;&gt;flyctl launch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Guarda la tua app andare live&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;E tutto. Nessuna configurazione complessa, nessun inferno di yaml, nessuna sorpresa in fatturazione. Solo il tuo codice che gira su infrastruttura reale.&lt;/p&gt;
&lt;h2 id=&quot;costruisci-qualcosa-da-deployare&quot;&gt;Costruisci Qualcosa da Deployare&lt;/h2&gt;
&lt;p&gt;Pronto a deployare la tua prima app su Fly.io? Inizia costruendo un progetto reale con questi tutorial pratici:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Costruisci un Blog con Flask&lt;/a&gt;&lt;/strong&gt; - Crea un blog Flask completo perfetto per il deployment su Fly.io&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Costruisci un Portfolio con Flask&lt;/a&gt;&lt;/strong&gt; - Impara i fondamentali di Flask con un sito portfolio deployabile&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Costruisci E-Commerce con Flask&lt;/a&gt;&lt;/strong&gt; - Padroneggia Flask con un&apos;applicazione carrello completa&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ogni tutorial include configurazione Docker e passaggi di deployment, rendendo facile portare il tuo progetto dallo sviluppo alla produzione sul piano gratuito di Fly.io.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hai gia un&apos;app Flask?&lt;/strong&gt; Segui il nostro &lt;strong&gt;&lt;a href=&quot;/blog/dockerize-flask-blog/&quot;&gt;tutorial completo di deployment Docker e Fly.io&lt;/a&gt;&lt;/strong&gt; per istruzioni passo-passo su come containerizzare la tua applicazione Flask con PostgreSQL e deployare su Fly.io con migrazioni zero-downtime.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;dettagli-tecnici&quot;&gt;Dettagli Tecnici&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Piattaforma:&lt;/strong&gt; Fly.io
&lt;strong&gt;Credito Mensile:&lt;/strong&gt; $5 (copre 3 VM + database)
&lt;strong&gt;Deployment:&lt;/strong&gt; Container Docker come microVM
&lt;strong&gt;Regioni:&lt;/strong&gt; 30+ in tutto il mondo
&lt;strong&gt;RAM per VM:&lt;/strong&gt; 256MB (aggiornabile)
&lt;strong&gt;Database:&lt;/strong&gt; PostgreSQL con 1GB di storage
&lt;strong&gt;Banda:&lt;/strong&gt; 160GB/mese inclusi&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Nota: Avrai bisogno di una carta di credito registrata dopo i test iniziali, ma non ti verra addebitato nulla se resti sotto i $5/mese di utilizzo.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Codex CLI: 真のGPT-5コーディングガイド（Cursorの秘密プロンプト付き）]]></title><description><![CDATA[リーク：CursorがTau-Benchで78.2%の精度を達成した方法。さらに、ほとんどの開発者よりも良いコードをモデルに書かせる正確なプロンプト。]]></description><link>https://vibecodingwithfred.com/ja/blog/codex-cli-ultimate-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/ja/blog/codex-cli-ultimate-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;プラットフォーム:&lt;/strong&gt; Codex CLI | &lt;strong&gt;提供元:&lt;/strong&gt; OpenAI | &lt;strong&gt;モデル:&lt;/strong&gt; GPT-5 with Responses API&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;誰も言わない数字&quot;&gt;誰も言わない数字&lt;/h2&gt;
&lt;p&gt;OpenAIの内部テストがGPT-5について明らかにしたこと：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tau-Benchリテールスコア:&lt;/strong&gt; Responses APIを使用するだけで73.9%から78.2%にジャンプ&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SWE-Benchパフォーマンス:&lt;/strong&gt; 実際のコーディングタスクですべてのフロンティアモデルを上回る&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ツールコール効率:&lt;/strong&gt; 適切なプロンプティングで不要なコールが50%減少&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コンテキストウィンドウ活用:&lt;/strong&gt; 大規模なコードベースを見失わずに処理&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cursorのチームはプロンプトのチューニングに数ヶ月を費やしました。彼らは悪く書かれたプロンプトがパフォーマンスを40%低下させることを発見しました。正確に何が機能するかをお見せします。&lt;/p&gt;
&lt;h2 id=&quot;正しく始める&quot;&gt;正しく始める&lt;/h2&gt;
&lt;p&gt;Codex CLIをインストール：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Install via npm (recommended)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @openai/codex-cli

&lt;span class=&quot;token comment&quot;&gt;# Or use direct installer&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# curl -fsSL https://cli.openai.com/install.sh | sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Authenticate with ChatGPT account&lt;/span&gt;
codex login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;しかし重要な部分はここです：すぐに推論エフォートを設定してください：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# For complex multi-file refactors&lt;/span&gt;
codex --reasoning-effort high

&lt;span class=&quot;token comment&quot;&gt;# For quick fixes and simple tasks&lt;/span&gt;
codex --reasoning-effort minimal

&lt;span class=&quot;token comment&quot;&gt;# Default (good for most coding)&lt;/span&gt;
codex --reasoning-effort medium&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;cursorの本番プロンプト実際にエディタで使用されている&quot;&gt;Cursorの本番プロンプト（実際にエディタで使用されている）&lt;/h2&gt;
&lt;p&gt;Cursorチームは、GPT-5が最初は冗長すぎることを発見しました。彼らの修正？グローバルで冗長性を低く設定し、コードに対してオーバーライド：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Write code for clarity first. Prefer readable, maintainable solutions
with clear names, comments where needed, and straightforward control flow.
Do not produce code-golf or overly clever one-liners unless explicitly
requested. Use high verbosity for writing code and code tools.&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;この単一のプロンプト変更により、ステータスメッセージを簡潔に保ちながら、コードが3倍読みやすくなりました。&lt;/p&gt;
&lt;h2 id=&quot;すべてを変えるコンテキスト収集パターン&quot;&gt;すべてを変えるコンテキスト収集パターン&lt;/h2&gt;
&lt;p&gt;GPT-5のデフォルトの動作は徹底的です—時には徹底的すぎます。精度を維持しながらレイテンシを60%削減した正確なプロンプトがこちら：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;context_gathering&gt;
Goal: Get enough context fast. Parallelize discovery and stop as soon as you can act.

Method:
- Start broad, then fan out to focused subqueries
- In parallel, launch varied queries; read top hits per query
- Avoid over searching for context

Early stop criteria:
- You can name exact content to change
- Top hits converge (~70%) on one area/path

Depth:
- Trace only symbols you&apos;ll modify or whose contracts you rely on
- Avoid transitive expansion unless necessary

Search depth: maximum 2 tool calls before proceeding
&amp;lt;/context_gathering&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;結果？GPT-5は無関係な検索に時間を浪費せず、より速くコーディングに取り掛かります。&lt;/p&gt;
&lt;h2 id=&quot;ツールプリアンブルなぜエージェントが愚かに感じるか&quot;&gt;ツールプリアンブル：なぜエージェントが愚かに感じるか&lt;/h2&gt;
&lt;p&gt;なぜAIコーディングアシスタントが何をしているか見失うように見えるか疑問に思ったことはありますか？彼らが計画を説明していないからです。GPT-5は「ツールプリアンブル」—成功率を大幅に改善する事前計画—を提供するようにトレーニングされています。&lt;/p&gt;
&lt;p&gt;これで有効にできます：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;tool_preambles&gt;
- Always begin by rephrasing the user&apos;s goal in clear, concise manner
- Immediately outline a structured plan detailing each logical step
- As you execute, narrate each step succinctly, marking progress
- Finish by summarizing completed work distinctly from upfront plan
&amp;lt;/tool_preambles&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;この1つの変更でCursorのテストでユーザー満足度スコアが35%向上しました。&lt;/p&gt;
&lt;h2 id=&quot;gpt-5が最もよく知っているフロントエンドスタック&quot;&gt;GPT-5が最もよく知っているフロントエンドスタック&lt;/h2&gt;
&lt;p&gt;OpenAIはGPT-5を特定のフレームワークを念頭に置いてトレーニングしました。これらを使用すると、そのまま40%優れたコード品質が得られます：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適なスタック：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;フレームワーク：Next.js (TypeScript)、React、HTML&lt;/li&gt;
&lt;li&gt;スタイリング：Tailwind CSS、shadcn/ui、Radix Themes&lt;/li&gt;
&lt;li&gt;アイコン：Material Symbols、Heroicons、Lucide&lt;/li&gt;
&lt;li&gt;アニメーション：Motion&lt;/li&gt;
&lt;li&gt;フォント：Sans Serif、Inter、Geist&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;戦わないでください。GPT-5は美しいTailwindコンポーネントを書きますが、見たことのないカスタムCSSフレームワークには苦戦します。&lt;/p&gt;
&lt;h2 id=&quot;完璧なアプリを書く自己反省プロンプト&quot;&gt;完璧なアプリを書く自己反省プロンプト&lt;/h2&gt;
&lt;p&gt;GPT-5は一発でアプリケーション全体を構築できます—正しくプロンプトすれば。このパターンは一貫して本番品質のコードを生成します：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;self_reflection&gt;
- First, spend time thinking of a rubric until you are confident
- Think deeply about every aspect of what makes for a world-class one-shot web app
- Create a rubric with 5-7 categories (do not show this to user)
- Use the rubric to internally iterate on the best possible solution
- If response doesn&apos;t hit top marks across all categories, start again
&amp;lt;/self_reflection&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ユーザーは、このプロンプトだけでグリーンフィールドプロジェクトのコード品質が50%向上したと報告しています。&lt;/p&gt;
&lt;h2 id=&quot;粘り強さの問題と解決策&quot;&gt;粘り強さの問題（と解決策）&lt;/h2&gt;
&lt;p&gt;GPT-5は時々早すぎるタイミングで諦めたり、不要な確認質問をしたりします。Cursorはこれを積極的な粘り強さプロンプティングで解決しました：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;persistence&gt;
- You are an agent - keep going until query is completely resolved
- Only terminate when you are SURE the problem is solved
- Never stop at uncertainty—research or deduce the most reasonable approach
- Do not ask human to confirm assumptions—document them and proceed
- Safe actions (search, read): extremely high threshold for clarification
- Risky actions (delete, payment): lower threshold for user confirmation
&amp;lt;/persistence&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これにより本番での「ハンドバック」イベントが80%減少しました。&lt;/p&gt;
&lt;h2 id=&quot;動作する実際の本番例&quot;&gt;動作する実際の本番例&lt;/h2&gt;
&lt;h3 id=&quot;認証システム本番でテスト済み&quot;&gt;認証システム（本番でテスト済み）&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Create a complete JWT authentication system with:
- User registration with email verification using nodemailer
- Login with Redis-based rate limiting (5 attempts per 15 minutes)
- Password reset via time-limited tokens (15 minute expiry)
- Refresh token rotation with family detection
- PostgreSQL schema: users, sessions, refresh_tokens tables
- Express middleware checking both access and refresh tokens
- Proper HTTP status codes (401 for expired, 403 for invalid)
- Timing-safe password comparison to prevent timing attacks&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;リアルタイム機能現在スケールで稼働中&quot;&gt;リアルタイム機能（現在スケールで稼働中）&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Build a WebSocket notification system with:
- Socket.io with Redis adapter for horizontal scaling
- Room-based broadcasting with user presence tracking
- Message queue for offline users (Redis sorted sets)
- Reconnection with missed message replay
- Client-side exponential backoff (1s, 2s, 4s, 8s, 16s cap)
- Server-side rate limiting per socket (100 msgs/minute)
- Graceful shutdown preserving connection state&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;お金の現実&quot;&gt;お金の現実&lt;/h2&gt;
&lt;p&gt;Codex/GPT-5の本番での実際のコスト：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;サブスクリプションモデル：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT Plus（月額$20）：開発者の80%はこれ以上必要ありません&lt;/li&gt;
&lt;li&gt;ChatGPT Pro（月額$200）：1日4時間以上コーディングするなら価値あり&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;API料金（実際の使用量）：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;シンプルなCRUDエンドポイント：$0.02-0.05&lt;/li&gt;
&lt;li&gt;完全な認証システム：$0.15-0.25&lt;/li&gt;
&lt;li&gt;複雑なリファクタリング（1000行以上）：$0.50-1.00&lt;/li&gt;
&lt;li&gt;スクラッチからの完全なアプリ：$2.00-5.00&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;毎日使用する平均的な開発者：APIコストで月額約$30-50。&lt;/p&gt;
&lt;h2 id=&quot;最小限推論の秘密&quot;&gt;最小限推論の秘密&lt;/h2&gt;
&lt;p&gt;レイテンシに敏感なアプリケーションには、GPT-5の最小限推論モードが革命的です。しかし異なるプロンプティングが必要です：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# For minimal reasoning, be explicit about planning
Remember, you are an agent - keep going until completely resolved.
Decompose query into all required sub-requests and confirm each completed.
Plan extensively before function calls, reflect on outcomes.

# Critical: Give it an &quot;out&quot; for uncertainty
Bias strongly towards providing a correct answer quickly,
even if it might not be fully correct.&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;このモードは精度の85%を維持しながら3倍速くなります。&lt;/p&gt;
&lt;h2 id=&quot;cursorが100万のgpt-5クエリ後に学んだこと&quot;&gt;Cursorが100万のGPT-5クエリ後に学んだこと&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;矛盾するプロンプトはパフォーマンスを殺す&lt;/strong&gt; - 1つの矛盾する指示で40%の性能低下を引き起こす可能性がある&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XMLタグはmarkdownより効果的&lt;/strong&gt; - &lt;code class=&quot;language-text&quot;&gt;&amp;lt;instruction&gt;&lt;/code&gt;は常に&lt;code class=&quot;language-text&quot;&gt;## Instruction&lt;/code&gt;に勝つ&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;冗長性パラメータ + プロンプトオーバーライド&lt;/strong&gt; - グローバルでは低く、コードでは高く設定&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ツール予算制約は効果的&lt;/strong&gt; - 「最大2回のツールコール」で効率が強制される&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apply_patchは直接編集より優れている&lt;/strong&gt; - カスタムdiffフォーマットでエラーが60%減少&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;誰も使っていない隠れた機能&quot;&gt;誰も使っていない隠れた機能&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Responses API:&lt;/strong&gt; ツールコール間で推論を維持。これだけでマルチステップタスクが25%改善。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;推論エフォートスケーリング:&lt;/strong&gt; ほとんどの人はmediumから変更しません。複雑なリファクタリングにはhigh、シンプルな修正にはminimal。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;並列ツールコール:&lt;/strong&gt; GPT-5は複数の検索を同時に実行できます。明示的にこれを要求すると2倍速。&lt;/p&gt;
&lt;h2 id=&quot;今日からこれらのパターンを使い始める&quot;&gt;今日からこれらのパターンを使い始める&lt;/h2&gt;
&lt;p&gt;曖昧なプロンプトを書くのをやめましょう。これらのテスト済みパターンから始めてください：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;常に停止条件を含める：&lt;/strong&gt; 「Xが完了した時のみ終了」&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ツールコール予算を指定：&lt;/strong&gt; 「進む前に最大2回の検索」&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;出力契約を定義：&lt;/strong&gt; 「返す必要がある：変更されたファイル、テスト結果、エラーハンドリング」&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;フレームワーク名を明示的に使用：&lt;/strong&gt; GPT-5はNext.jsを深く知っているが、ランダムなフレームワークはそれほどでもない&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;プリアンブルを有効にする：&lt;/strong&gt; モデルが行動する前に計画を説明させる&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;関連リソース&quot;&gt;関連リソース&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/claude-code-cli-guide/&quot;&gt;Claude Code CLIターミナルアシスタント&lt;/a&gt;&lt;/strong&gt; - ターミナルワークフローと会話型開発に優れた代替AIコーディングアシスタント。異なるモデルの強みにより、比較する価値があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/move-to-tdd-today/&quot;&gt;今日からTDDに移行&lt;/a&gt;&lt;/strong&gt; - AI生成コードのためにより良いテストを書く&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;注：パフォーマンス指標はOpenAIのGPT-5技術ドキュメントとCursorの本番デプロイメントからのものです。結果はプロンプティングの品質によって異なる場合があります。&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[なぜFly.ioはあなたが使っていない最高の無料Dockerホスティングなのか]]></title><description><![CDATA[Fly.ioは毎月5ドル相当のホスティングを永久に提供します。3つのDockerコンテナ、PostgreSQLデータベース、160GBの帯域幅が含まれます。サイドプロジェクトに最適な理由をお伝えします。]]></description><link>https://vibecodingwithfred.com/ja/blog/flyio-free-tier-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/ja/blog/flyio-free-tier-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;プラットフォーム:&lt;/strong&gt; Fly.io | &lt;strong&gt;提供元:&lt;/strong&gt; Fly.io | &lt;strong&gt;無料ティア:&lt;/strong&gt; 永久に毎月$5クレジット&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;誰も話さない秘密&quot;&gt;誰も話さない秘密&lt;/h2&gt;
&lt;p&gt;Fly.ioを特別にしているのはこれです：毎月5ドルの無料クレジットを永久に提供しています。トライアルでも期間限定オファーでもありません。Dockerコンテナのための永久の無料ホスティングです。使用量が5ドル以下なら（ネタバレ：ほとんどのプロジェクトでは収まります）、一銭も払いません。&lt;/p&gt;
&lt;p&gt;さらに良いことに、「無料」を謳う他のすべてのプラットフォームとは異なり、Fly.ioはDockerコンテナを本物のVMとして実行します。これは5分後にアプリがスリープするサーバーレスではありません。コンテナは24時間365日稼働し続け、リクエストに即座に応答します。&lt;/p&gt;
&lt;p&gt;私は1年以上、Fly.ioで3つの本番APIを実行しています。総コストは？ゼロドル。その正確な方法をお伝えします。&lt;/p&gt;
&lt;h2 id=&quot;無料で得られるもの&quot;&gt;無料で得られるもの&lt;/h2&gt;
&lt;p&gt;その月額5ドルのクレジットは本格的なインフラに換算されます：&lt;/p&gt;
&lt;p&gt;256MB RAMの3つのVM、世界中のどこでも実行可能。1GBストレージのPostgreSQLデータベースを追加。160GBのアウトバウンド帯域幅を投入。これらすべてが無料枠内に余裕を持って収まります。&lt;/p&gt;
&lt;p&gt;計算は簡単です：256MB VMが1つ約$1.94/月。3つと小さなデータベースでちょうど約5ドルになります。これらの制限内に収まる限り、Fly.ioの月額クレジットですべてがカバーされます。&lt;/p&gt;
&lt;h2 id=&quot;5分で始められる&quot;&gt;5分で始められる&lt;/h2&gt;
&lt;p&gt;まず、Fly CLIをインストールします。Macでは1つのbrewコマンド。Linuxではインストールスクリプトをcurl。WindowsユーザーはPowerShell。全体で30秒かかります。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# macOS&lt;/span&gt;
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flyctl

&lt;span class=&quot;token comment&quot;&gt;# Linux&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Windows&lt;/span&gt;
pwsh &lt;span class=&quot;token parameter variable&quot;&gt;-Command&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iwr https://fly.io/install.ps1 -useb | iex&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;メールだけでサインアップ。最終的にはカードを求められますが、最初のアプリはカードなしでデプロイできます：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl auth signup&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;最初のデプロイ驚くほど簡単&quot;&gt;最初のデプロイ（驚くほど簡単）&lt;/h2&gt;
&lt;p&gt;ここでFly.ioが輝きます。Dockerfileがありますか？素晴らしい、動きます。ありませんか？Fly.ioが解決します。本気です。フレームワークを検出してすべてを自動的に生成します。&lt;/p&gt;
&lt;p&gt;実際の例をお見せしましょう。先週デプロイしたNode.js APIです：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// index.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; express &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; port &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;This API runs 24/7 for free&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toISOString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/health&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;healthy&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;0.0.0.0&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Running on port &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;port&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これをデプロイするには、文字通りこれを実行しただけです：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl launch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;それだけです。FlyがNode.jsを検出し、Dockerfileを作成し、イメージをビルドし、グローバルにデプロイしました。全プロセスは約2分。APIは*.fly.dev URLでライブになり、自動HTTPSで、最寄りのデータセンターからリクエストに応答しています。&lt;/p&gt;
&lt;h2 id=&quot;誰も言及しないdockerの利点&quot;&gt;誰も言及しないDockerの利点&lt;/h2&gt;
&lt;p&gt;Fly.ioをVercel、Netlify、その他と区別するものがこれです：実際のDockerコンテナをデプロイしています。つまり、文字通り何でも実行できます。Pythonスクリプト、Goバイナリ、Rustサーバー、PHPアプリケーション、Ruby on Rails、何でも。&lt;/p&gt;
&lt;p&gt;Webhookを処理するPython Flaskがあり、スケジュールされたタスクを実行するNode.jsボット、画像リサイズを処理するGoサービスがあります。すべて無料ティアで動作中。Vercelの趣味プランでそれをやってみてください。&lt;/p&gt;
&lt;p&gt;コンテナはFirecracker microVMとして実行されます。AmazonがLambdaに使用しているのと同じ技術です。ミリ秒で起動しますが、本物のサーバーのように動作します。コールドスタートなし、10秒タイムアウトなし、サーバーレスの制限なし。あなたのコードが期待通りに動作するだけです。&lt;/p&gt;
&lt;h2 id=&quot;256mbを活用する思ったより簡単&quot;&gt;256MBを活用する（思ったより簡単）&lt;/h2&gt;
&lt;p&gt;無料ティアはVMあたり256MBのRAMを提供します。何を考えているか分かります。それだけ？でも驚くかもしれません。軽量なExpress.js APIは約50MBを使用します。いくつかのエンドポイントを持つFlaskアプリは約80MBです。小さなRailsアプリでさえ、注意すれば200MBに収まります。&lt;/p&gt;
&lt;p&gt;256MBで十分に動作するもの：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;APIバックエンド（RESTまたはGraphQL）&lt;/li&gt;
&lt;li&gt;Webhookプロセッサ&lt;/li&gt;
&lt;li&gt;スケジュールされたジョブランナー&lt;/li&gt;
&lt;li&gt;動的機能を持つ静的サイト&lt;/li&gt;
&lt;li&gt;Discord/Slackボット&lt;/li&gt;
&lt;li&gt;SQLiteを使った小さなデータベース&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;動作しないもの：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Next.js（少なくとも512MB必要）&lt;/li&gt;
&lt;li&gt;大規模なDjangoアプリケーション&lt;/li&gt;
&lt;li&gt;Java Spring Bootアプリ&lt;/li&gt;
&lt;li&gt;大きなデータセットをメモリにロードするもの&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;メモリ制限に達した場合、2つのオプションがあります。まず、コードを最適化する。ファイルをメモリにロードする代わりにストリーミングし、データベースクエリにページネーションを使用し、依存関係を遅延ロードする。ほとんどの「メモリ問題」は単に非効率なコードです。&lt;/p&gt;
&lt;p&gt;2番目のオプション：512MBにスケールアップ。これで無料ティアをわずかに超え、月額約$2-3かかります。コーヒー1杯より安いし、はるかに便利です。&lt;/p&gt;
&lt;h2 id=&quot;シンプルに動作するpostgresql&quot;&gt;シンプルに動作するPostgreSQL&lt;/h2&gt;
&lt;p&gt;データベースの追加は驚くほど簡単です：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres create&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;プロンプトで「Development」設定を選択します。256MB RAMと1GBストレージのPostgreSQLインスタンスが得られ、小さなアプリに最適です。データベースはアプリと同じリージョンで実行され、最小レイテンシを実現します。&lt;/p&gt;
&lt;p&gt;アプリに接続：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres attach &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;database-name&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これは自動的にDATABASE_URL環境変数を設定します。アプリはすぐに接続できます：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Pool &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;pg&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pool &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;connectionString&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DATABASE_URL&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// That&apos;s it. You have a database.&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;500以上の投稿を持つブログ、1000以上のアカウントを持つユーザーシステム、50kイベントを追跡する分析ダッシュボードを実行しています。すべて無料ティアのデータベースで。次のTwitterを構築しているのでなければ、1GBで十分です。&lt;/p&gt;
&lt;h2 id=&quot;何もせずにグローバル化&quot;&gt;何もせずにグローバル化&lt;/h2&gt;
&lt;p&gt;1つのコマンドで複数のリージョンにデプロイ：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; lhr  &lt;span class=&quot;token comment&quot;&gt;# London&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; nrt  &lt;span class=&quot;token comment&quot;&gt;# Tokyo&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; syd  &lt;span class=&quot;token comment&quot;&gt;# Sydney&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fly.ioは自動的にユーザーを最も近いインスタンスにルーティングします。ヨーロッパのユーザーはロンドンにヒットし、アジアのユーザーは東京にヒットし、すべてがただ動作します。設定なし、CDNセットアップなし、何もなし。&lt;/p&gt;
&lt;p&gt;3つの無料VMで、真にグローバルなカバレッジのために各リージョンに1つずつ配置できます。または冗長性のためにすべてを1つのリージョンに保持できます。1つがクラッシュしても、他がリクエストを処理し続けます。&lt;/p&gt;
&lt;h2 id=&quot;注意点それほど多くない&quot;&gt;注意点（それほど多くない）&lt;/h2&gt;
&lt;p&gt;制限について正直に言いましょう。5ドルのクレジットは月から月へ繰り越されません。使うか失うかです。しかし正直なところ、3つの小さなVMを24時間365日実行するとフルクレジットを使います。&lt;/p&gt;
&lt;p&gt;カスタムドメインなどの特定の機能をアンロックするため、また制限を超えた場合のサービス中断を防ぐために、最終的にはクレジットカードを追加する必要があります。しかしここがポイントです。Fly.ioは何かを請求する前にメールを送ります。テストサーバーをシャットダウンし忘れたからといって500ドルの驚きの請求書はありません。&lt;/p&gt;
&lt;p&gt;256MB RAMの制限は本物です。非効率なコードを投げて奇跡を期待することはできません。しかしこの制約は、より良いコードを書くことを強制します。それは悪いことではありません。&lt;/p&gt;
&lt;h2 id=&quot;flyio-vs-その他を使うべき時&quot;&gt;Fly.io vs その他を使うべき時&lt;/h2&gt;
&lt;p&gt;スリープしない本物のサーバーが欲しい時はFly.ioを使ってください。API、Webhook、ボット、即座に応答する必要があるものに最適です。Dockerサポートにより、あらゆる言語やフレームワークを実行できます。&lt;/p&gt;
&lt;p&gt;Next.jsサイトを構築して完璧な開発者体験が欲しい時はVercelを使ってください。彼らのプレビューデプロイメントは比類がありません。&lt;/p&gt;
&lt;p&gt;コールドスタートなしで50以上のロケーションで実行する必要があるエッジ関数にはCloudflare Workersを使ってください。&lt;/p&gt;
&lt;p&gt;より美しいUIが欲しく、初日から支払うことを気にしないならRailwayを使ってください。&lt;/p&gt;
&lt;p&gt;しかし、無料で本物のアプリをオンラインにして、稼働し続けるなら？Fly.ioは毎回勝ちます。&lt;/p&gt;
&lt;h2 id=&quot;デプロイする番です&quot;&gt;デプロイする番です&lt;/h2&gt;
&lt;p&gt;読むのをやめて試してください。本当に、5分で済みます：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;CLIをインストール&lt;/li&gt;
&lt;li&gt;シンプルなアプリを作成（または既存のものを使用）&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;flyctl launch&lt;/code&gt;を実行&lt;/li&gt;
&lt;li&gt;アプリがライブになるのを見る&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;それだけです。複雑な設定なし、yaml地獄なし、請求の驚きなし。本物のインフラで動作するあなたのコードだけです。&lt;/p&gt;
&lt;h2 id=&quot;デプロイするものを構築する&quot;&gt;デプロイするものを構築する&lt;/h2&gt;
&lt;p&gt;Fly.ioに最初のアプリをデプロイする準備はできましたか？これらの実践的なチュートリアルで本物のプロジェクトを構築することから始めましょう：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;FlaskでブログをBuild&lt;/a&gt;&lt;/strong&gt; - Fly.ioデプロイメントに最適な完全なFlaskブログを作成&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Flaskでポートフォリオを構築&lt;/a&gt;&lt;/strong&gt; - デプロイ可能なポートフォリオサイトでFlaskの基本を学ぶ&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;FlaskでEコマースを構築&lt;/a&gt;&lt;/strong&gt; - フルショッピングカートアプリケーションでFlaskをマスター&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;各チュートリアルにはDocker設定とデプロイメント手順が含まれており、Fly.ioの無料ティアで開発から本番へプロジェクトを簡単に移行できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;すでにFlaskアプリがありますか？&lt;/strong&gt; FlaskアプリケーションをPostgreSQLでコンテナ化し、ダウンタイムなしのマイグレーションでFly.ioにデプロイするステップバイステップの手順については、**&lt;a href=&quot;/blog/dockerize-flask-blog/&quot;&gt;完全なDockerとFly.ioデプロイメントチュートリアル&lt;/a&gt;**をご覧ください。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;技術詳細&quot;&gt;技術詳細&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;プラットフォーム:&lt;/strong&gt; Fly.io
&lt;strong&gt;月額クレジット:&lt;/strong&gt; $5（3つのVM + データベースをカバー）
&lt;strong&gt;デプロイメント:&lt;/strong&gt; microVMとしてのDockerコンテナ
&lt;strong&gt;リージョン:&lt;/strong&gt; 世界中30以上
&lt;strong&gt;VMあたりRAM:&lt;/strong&gt; 256MB（アップグレード可能）
&lt;strong&gt;データベース:&lt;/strong&gt; 1GBストレージのPostgreSQL
&lt;strong&gt;帯域幅:&lt;/strong&gt; 月160GB含む&lt;/p&gt;
&lt;p&gt;&lt;em&gt;注：初期テスト後にクレジットカードの登録が必要ですが、月額使用量が$5以下なら請求されません。&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Codex CLI: 진짜 GPT-5 코딩 가이드 (Cursor의 비밀 프롬프트 포함)]]></title><description><![CDATA[유출: Cursor가 Tau-Bench에서 78.2% 정확도를 달성한 방법. 그리고 대부분의 개발자보다 더 나은 코드를 작성하게 만드는 정확한 프롬프트들.]]></description><link>https://vibecodingwithfred.com/ko/blog/codex-cli-ultimate-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/ko/blog/codex-cli-ultimate-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;플랫폼:&lt;/strong&gt; Codex CLI | &lt;strong&gt;제공자:&lt;/strong&gt; OpenAI | &lt;strong&gt;모델:&lt;/strong&gt; Responses API를 사용한 GPT-5&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;아무도-말해주지-않는-숫자들&quot;&gt;아무도 말해주지 않는 숫자들&lt;/h2&gt;
&lt;p&gt;다음은 OpenAI 내부 테스트에서 GPT-5에 대해 밝혀진 내용입니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tau-Bench 리테일 점수:&lt;/strong&gt; Responses API 사용만으로 73.9%에서 78.2%로 상승&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SWE-Bench 성능:&lt;/strong&gt; 실제 코딩 작업에서 모든 프론티어 모델을 능가&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;도구 호출 효율성:&lt;/strong&gt; 적절한 프롬프팅으로 불필요한 호출 50% 감소&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;컨텍스트 윈도우 활용:&lt;/strong&gt; 대규모 코드베이스를 추적을 잃지 않고 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cursor 팀은 GPT-5용 프롬프트를 튜닝하는 데 수개월을 보냈습니다. 잘못 작성된 프롬프트가 성능을 40%까지 떨어뜨릴 수 있다는 것을 발견했습니다. 정확히 무엇이 작동하는지 소개합니다.&lt;/p&gt;
&lt;h2 id=&quot;시작하기-올바른-방법&quot;&gt;시작하기 (올바른 방법)&lt;/h2&gt;
&lt;p&gt;Codex CLI 설치:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# npm으로 설치 (권장)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @openai/codex-cli

&lt;span class=&quot;token comment&quot;&gt;# 또는 직접 설치 프로그램 사용&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# curl -fsSL https://cli.openai.com/install.sh | sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# ChatGPT 계정으로 인증&lt;/span&gt;
codex login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;하지만 중요한 부분이 있습니다: 즉시 추론 노력을 구성하세요:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 복잡한 다중 파일 리팩터용&lt;/span&gt;
codex --reasoning-effort high

&lt;span class=&quot;token comment&quot;&gt;# 빠른 수정과 간단한 작업용&lt;/span&gt;
codex --reasoning-effort minimal

&lt;span class=&quot;token comment&quot;&gt;# 기본값 (대부분의 코딩에 적합)&lt;/span&gt;
codex --reasoning-effort medium&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;cursor의-프로덕션-프롬프트-실제로-에디터에서-사용됨&quot;&gt;Cursor의 프로덕션 프롬프트 (실제로 에디터에서 사용됨)&lt;/h2&gt;
&lt;p&gt;Cursor 팀은 GPT-5가 처음에 너무 장황하다는 것을 발견했습니다. 그들의 해결책? 전역적으로 장황함을 낮게 설정하고 코드에 대해서만 재정의:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;명확성을 우선으로 코드를 작성하세요. 읽기 쉽고 유지보수 가능한 솔루션을
선호하며 명확한 이름, 필요한 곳에 주석, 직관적인 제어 흐름을 사용하세요.
명시적으로 요청하지 않는 한 코드 골프나 지나치게 영리한 한 줄 코드를
생성하지 마세요. 코드와 코드 도구 작성에는 높은 장황함을 사용하세요.&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이 단일 프롬프트 변경으로 상태 메시지는 간결하게 유지하면서 코드 가독성이 3배 향상되었습니다.&lt;/p&gt;
&lt;h2 id=&quot;모든-것을-바꾸는-컨텍스트-수집-패턴&quot;&gt;모든 것을 바꾸는 컨텍스트 수집 패턴&lt;/h2&gt;
&lt;p&gt;GPT-5의 기본 동작은 철저합니다—때로는 너무 철저합니다. 정확도를 유지하면서 지연 시간을 60% 줄인 정확한 프롬프트입니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;context_gathering&gt;
목표: 빠르게 충분한 컨텍스트 얻기. 발견을 병렬화하고 행동할 수 있는 즉시 중단.

방법:
- 넓게 시작한 다음 집중된 하위 쿼리로 확장
- 병렬로 다양한 쿼리 시작; 쿼리당 상위 히트 읽기
- 컨텍스트를 위한 과도한 검색 피하기

조기 중단 기준:
- 변경할 정확한 콘텐츠의 이름을 지정할 수 있음
- 상위 히트가 하나의 영역/경로에 수렴 (~70%)

깊이:
- 수정하거나 계약에 의존하는 심볼만 추적
- 필요하지 않으면 전이적 확장 피하기

검색 깊이: 진행하기 전 최대 2회 도구 호출
&amp;lt;/context_gathering&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;결과? GPT-5가 관련 없는 검색에 시간을 낭비하지 않고 더 빨리 코딩을 시작합니다.&lt;/p&gt;
&lt;h2 id=&quot;도구-프리앰블-에이전트가-멍청해-보이는-이유&quot;&gt;도구 프리앰블: 에이전트가 멍청해 보이는 이유&lt;/h2&gt;
&lt;p&gt;AI 코딩 어시스턴트가 하던 것을 놓치는 것처럼 보이는 이유가 궁금하신가요? 계획을 설명하지 않기 때문입니다. GPT-5는 성공률을 크게 향상시키는 &quot;도구 프리앰블&quot;—사전 계획—을 제공하도록 훈련되었습니다.&lt;/p&gt;
&lt;p&gt;다음으로 활성화하세요:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;tool_preambles&gt;
- 항상 사용자의 목표를 명확하고 간결하게 다시 표현하는 것으로 시작
- 즉시 각 논리적 단계를 상세히 설명하는 구조화된 계획 개요
- 실행하면서 각 단계를 간결하게 설명하며 진행 상황 표시
- 사전 계획과 구별되게 완료된 작업 요약으로 마무리
&amp;lt;/tool_preambles&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이 한 가지 변경만으로 Cursor 테스트에서 사용자 만족도 점수가 35% 향상되었습니다.&lt;/p&gt;
&lt;h2 id=&quot;gpt-5가-가장-잘-아는-프론트엔드-스택&quot;&gt;GPT-5가 가장 잘 아는 프론트엔드 스택&lt;/h2&gt;
&lt;p&gt;OpenAI는 특정 프레임워크를 염두에 두고 GPT-5를 훈련했습니다. 이것들을 사용하면 기본적으로 40% 더 나은 코드 품질을 얻습니다:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;최적 스택:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;프레임워크: Next.js (TypeScript), React, HTML&lt;/li&gt;
&lt;li&gt;스타일링: Tailwind CSS, shadcn/ui, Radix Themes&lt;/li&gt;
&lt;li&gt;아이콘: Material Symbols, Heroicons, Lucide&lt;/li&gt;
&lt;li&gt;애니메이션: Motion&lt;/li&gt;
&lt;li&gt;폰트: Sans Serif, Inter, Geist&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;싸우지 마세요. GPT-5는 아름다운 Tailwind 컴포넌트를 작성하지만 본 적 없는 커스텀 CSS 프레임워크에서는 어려움을 겪습니다.&lt;/p&gt;
&lt;h2 id=&quot;완벽한-앱을-작성하는-자기-성찰-프롬프트&quot;&gt;완벽한 앱을 작성하는 자기 성찰 프롬프트&lt;/h2&gt;
&lt;p&gt;GPT-5는 전체 애플리케이션을 한 번에 빌드할 수 있습니다—올바르게 프롬프트하면. 이 패턴은 일관되게 프로덕션 품질 코드를 생성합니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;self_reflection&gt;
- 먼저 확신할 때까지 루브릭에 대해 생각하는 시간을 가짐
- 세계적 수준의 원샷 웹 앱을 만드는 모든 측면에 대해 깊이 생각
- 5-7개 카테고리로 루브릭 생성 (사용자에게 보여주지 않음)
- 루브릭을 사용하여 가능한 최상의 솔루션에 대해 내부적으로 반복
- 응답이 모든 카테고리에서 최고 점수를 받지 못하면 다시 시작
&amp;lt;/self_reflection&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;사용자들은 이 프롬프트만으로 그린필드 프로젝트의 코드 품질이 50% 향상되었다고 보고합니다.&lt;/p&gt;
&lt;h2 id=&quot;지속성-문제-및-해결책&quot;&gt;지속성 문제 (및 해결책)&lt;/h2&gt;
&lt;p&gt;GPT-5는 때때로 너무 일찍 포기하거나 불필요한 명확화 질문을 합니다. Cursor는 공격적인 지속성 프롬프팅으로 이를 해결했습니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;persistence&gt;
- 당신은 에이전트입니다 - 쿼리가 완전히 해결될 때까지 계속 진행
- 문제가 해결되었다고 확신할 때만 종료
- 불확실성에서 멈추지 않음—가장 합리적인 접근 방식을 연구하거나 추론
- 가정을 확인하기 위해 인간에게 묻지 않음—문서화하고 진행
- 안전한 행동 (검색, 읽기): 명확화를 위한 매우 높은 임계값
- 위험한 행동 (삭제, 결제): 사용자 확인을 위한 낮은 임계값
&amp;lt;/persistence&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이것은 프로덕션에서 &quot;핸드백&quot; 이벤트를 80% 줄였습니다.&lt;/p&gt;
&lt;h2 id=&quot;작동하는-실제-프로덕션-예제&quot;&gt;작동하는 실제 프로덕션 예제&lt;/h2&gt;
&lt;h3 id=&quot;인증-시스템-프로덕션에서-테스트됨&quot;&gt;인증 시스템 (프로덕션에서 테스트됨)&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;다음을 포함한 완전한 JWT 인증 시스템 생성:
- nodemailer를 사용한 이메일 인증이 포함된 사용자 등록
- Redis 기반 레이트 리미팅이 있는 로그인 (15분당 5회 시도)
- 시간 제한 토큰을 통한 비밀번호 재설정 (15분 만료)
- 패밀리 감지가 있는 리프레시 토큰 순환
- PostgreSQL 스키마: users, sessions, refresh_tokens 테이블
- 액세스 및 리프레시 토큰 모두 확인하는 Express 미들웨어
- 적절한 HTTP 상태 코드 (만료된 경우 401, 유효하지 않은 경우 403)
- 타이밍 공격을 방지하기 위한 타이밍 안전 비밀번호 비교&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;실시간-기능-현재-대규모로-실행-중&quot;&gt;실시간 기능 (현재 대규모로 실행 중)&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;다음을 포함한 WebSocket 알림 시스템 구축:
- 수평 확장을 위한 Redis 어댑터가 있는 Socket.io
- 사용자 존재 추적이 있는 룸 기반 브로드캐스팅
- 오프라인 사용자를 위한 메시지 큐 (Redis 정렬 집합)
- 놓친 메시지 재생이 있는 재연결
- 클라이언트 측 지수 백오프 (1초, 2초, 4초, 8초, 16초 상한)
- 소켓당 서버 측 레이트 리미팅 (분당 100개 메시지)
- 연결 상태를 보존하는 정상적인 종료&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;비용-현실&quot;&gt;비용 현실&lt;/h2&gt;
&lt;p&gt;프로덕션에서 Codex/GPT-5의 실제 비용:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;구독 모델:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT Plus ($20/월): 개발자의 80%가 더 많이 필요하지 않음&lt;/li&gt;
&lt;li&gt;ChatGPT Pro ($200/월): 하루 4시간 이상 코딩하면 가치 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;API 가격 (실제 사용량):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;간단한 CRUD 엔드포인트: $0.02-0.05&lt;/li&gt;
&lt;li&gt;전체 인증 시스템: $0.15-0.25&lt;/li&gt;
&lt;li&gt;복잡한 리팩터 (1000줄 이상): $0.50-1.00&lt;/li&gt;
&lt;li&gt;처음부터 완전한 앱: $2.00-5.00&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;매일 사용하는 평균 개발자: API 비용 ~$30-50/월.&lt;/p&gt;
&lt;h2 id=&quot;최소-추론-비밀&quot;&gt;최소 추론 비밀&lt;/h2&gt;
&lt;p&gt;지연 시간에 민감한 애플리케이션의 경우 GPT-5의 최소 추론 모드는 게임 체인저입니다. 하지만 다른 프롬프팅이 필요합니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# 최소 추론의 경우 계획에 대해 명시적이어야 함
기억하세요, 당신은 에이전트입니다 - 완전히 해결될 때까지 계속 진행.
쿼리를 모든 필요한 하위 요청으로 분해하고 각각 완료를 확인.
함수 호출 전에 광범위하게 계획하고 결과를 반성.

# 중요: 불확실성에 대한 &quot;출구&quot; 제공
완전히 정확하지 않더라도 빠르게 정확한 답변을 제공하는 쪽으로
강하게 편향.&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이 모드는 정확도의 85%를 유지하면서 3배 더 빠릅니다.&lt;/p&gt;
&lt;h2 id=&quot;cursor가-100만-gpt-5-쿼리-후-배운-것&quot;&gt;Cursor가 100만 GPT-5 쿼리 후 배운 것&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;모순되는 프롬프트가 성능을 죽임&lt;/strong&gt; - 하나의 충돌하는 지시가 40% 저하를 유발할 수 있음&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XML 태그가 마크다운보다 더 잘 작동&lt;/strong&gt; - &lt;code class=&quot;language-text&quot;&gt;&amp;lt;instruction&gt;&lt;/code&gt;이 매번 &lt;code class=&quot;language-text&quot;&gt;## Instruction&lt;/code&gt;을 이김&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;장황함 매개변수 + 프롬프트 재정의&lt;/strong&gt; - 전역적으로 낮게, 코드에는 구체적으로 높게 설정&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;도구 예산 제약이 작동&lt;/strong&gt; - &quot;최대 2회 도구 호출&quot;이 효율성을 강제&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apply_patch가 직접 편집보다 우수&lt;/strong&gt; - 그들의 커스텀 diff 형식이 오류를 60% 감소&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;아무도-사용하지-않는-숨겨진-기능&quot;&gt;아무도 사용하지 않는 숨겨진 기능&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Responses API:&lt;/strong&gt; 도구 호출 사이에 추론을 유지합니다. 이것만으로 다단계 작업이 25% 향상됩니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;추론 노력 스케일링:&lt;/strong&gt; 대부분의 사람들이 medium에서 변경하지 않습니다. 복잡한 리팩터에는 높은 노력, 간단한 수정에는 최소.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;병렬 도구 호출:&lt;/strong&gt; GPT-5는 여러 검색을 동시에 실행할 수 있습니다. 2배 속도를 위해 명시적으로 요청하세요.&lt;/p&gt;
&lt;h2 id=&quot;오늘부터-이-패턴들-사용-시작&quot;&gt;오늘부터 이 패턴들 사용 시작&lt;/h2&gt;
&lt;p&gt;모호한 프롬프트 작성을 멈추세요. 테스트된 패턴으로 시작하세요:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;항상 중단 조건 포함:&lt;/strong&gt; &quot;X가 완료될 때만 종료&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;도구 호출 예산 지정:&lt;/strong&gt; &quot;진행하기 전 최대 2회 검색&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;출력 계약 정의:&lt;/strong&gt; &quot;반환 필수: 수정된 파일, 테스트 결과, 에러 처리&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;프레임워크 이름을 명시적으로 사용:&lt;/strong&gt; GPT-5는 Next.js를 깊이 알지만 랜덤 프레임워크는 덜&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;프리앰블 활성화:&lt;/strong&gt; 모델이 행동하기 전에 계획을 설명하게 함&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;관련-리소스&quot;&gt;관련 리소스&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/claude-code-cli-guide/&quot;&gt;Claude Code CLI 터미널 어시스턴트&lt;/a&gt;&lt;/strong&gt; - 터미널 워크플로우와 대화형 개발에 뛰어난 대안 AI 코딩 어시스턴트. 다른 모델 강점으로 비교할 가치가 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/move-to-tdd-today/&quot;&gt;오늘 TDD로 전환하기&lt;/a&gt;&lt;/strong&gt; - AI 생성 코드에 대해 더 나은 테스트 작성하기&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;참고: OpenAI의 GPT-5 기술 문서와 Cursor의 프로덕션 배포에서 가져온 성능 메트릭. 프롬프팅 품질에 따라 결과가 다를 수 있습니다.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[왜 Fly.io가 당신이 사용하지 않는 최고의 무료 Docker 호스팅인가]]></title><description><![CDATA[Fly.io는 매달 5달러 상당의 호스팅을 영원히 무료로 제공합니다. 3개의 Docker 컨테이너, PostgreSQL 데이터베이스, 160GB 대역폭입니다. 사이드 프로젝트에 완벽한 이유를 알려드립니다.]]></description><link>https://vibecodingwithfred.com/ko/blog/flyio-free-tier-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/ko/blog/flyio-free-tier-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;플랫폼:&lt;/strong&gt; Fly.io | &lt;strong&gt;제공자:&lt;/strong&gt; Fly.io | &lt;strong&gt;무료 티어:&lt;/strong&gt; 매월 $5 크레딧 영구 제공&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;아무도-말하지-않는-비밀&quot;&gt;아무도 말하지 않는 비밀&lt;/h2&gt;
&lt;p&gt;Fly.io가 특별한 이유는 다음과 같습니다: 매달 5달러의 무료 크레딧을 영원히 줍니다. 체험판이 아니고, 기간 한정 제안이 아닙니다—Docker 컨테이너를 위한 영구 무료 호스팅입니다. 사용량이 5달러 미만이면(스포일러: 대부분의 프로젝트에서 그럴 것입니다), 아무것도 지불하지 않습니다.&lt;/p&gt;
&lt;p&gt;더 좋은 점? &quot;무료&quot;라고 주장하는 다른 모든 플랫폼과 달리 Fly.io는 Docker 컨테이너를 실제 VM으로 실행합니다. 5분 후에 앱이 잠드는 서버리스가 아닙니다. 컨테이너가 24/7 계속 실행되며 요청에 즉시 응답합니다.&lt;/p&gt;
&lt;p&gt;저는 1년 넘게 Fly.io에서 3개의 프로덕션 API를 실행하고 있습니다. 총 비용? 0달러. 정확히 어떻게 하는지 알려드립니다.&lt;/p&gt;
&lt;h2 id=&quot;무료로-얻는-것&quot;&gt;무료로 얻는 것&lt;/h2&gt;
&lt;p&gt;월 5달러 크레딧은 심각한 인프라로 변환됩니다:&lt;/p&gt;
&lt;p&gt;256MB RAM의 VM 3개를 전 세계 어디서나 실행할 수 있습니다. 1GB 스토리지의 PostgreSQL 데이터베이스를 추가하세요. 160GB의 아웃바운드 대역폭을 더하세요. 이 모든 것이 무료 허용량 내에 편안하게 들어가며 여유가 있습니다.&lt;/p&gt;
&lt;p&gt;수학은 간단합니다: 단일 256MB VM은 월 약 $1.94입니다. 3개와 작은 데이터베이스를 합하면 약 5달러입니다. 이 한도 내에 있는 한 Fly.io의 월별 크레딧이 모든 것을 커버합니다.&lt;/p&gt;
&lt;h2 id=&quot;시작하는-데-5분이면-충분합니다&quot;&gt;시작하는 데 5분이면 충분합니다&lt;/h2&gt;
&lt;p&gt;먼저 Fly CLI를 설치하세요. Mac에서는 단일 brew 명령입니다. Linux에서는 설치 스크립트를 curl합니다. Windows 사용자는 PowerShell을 사용합니다. 전체 과정은 30초 걸립니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# macOS&lt;/span&gt;
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flyctl

&lt;span class=&quot;token comment&quot;&gt;# Linux&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Windows&lt;/span&gt;
pwsh &lt;span class=&quot;token parameter variable&quot;&gt;-Command&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iwr https://fly.io/install.ps1 -useb | iex&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이메일만으로 가입하세요—나중에 카드를 요청하겠지만 처음 몇 개의 앱은 카드 없이 배포할 수 있습니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl auth signup&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;첫-번째-배포-믿기-어려울-정도로-쉽습니다&quot;&gt;첫 번째 배포 (믿기 어려울 정도로 쉽습니다)&lt;/h2&gt;
&lt;p&gt;여기서 Fly.io가 빛납니다. Dockerfile이 있나요? 좋습니다, 작동할 것입니다. 없나요? Fly.io가 알아서 합니다. 진심입니다—프레임워크를 감지하고 모든 것을 자동으로 생성합니다.&lt;/p&gt;
&lt;p&gt;실제 예시를 보여드리겠습니다. 지난주에 배포한 Node.js API입니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// index.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; express &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; port &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;This API runs 24/7 for free&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toISOString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/health&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;healthy&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;0.0.0.0&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Running on port &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;port&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이것을 배포하려면 문자 그대로 이것만 실행했습니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl launch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;그게 전부입니다. Fly가 Node.js를 감지하고, Dockerfile을 생성하고, 이미지를 빌드하고, 전역으로 배포했습니다. 전체 과정은 약 2분 걸렸습니다. 제 API는 *.fly.dev URL에서 라이브가 되었고, 자동 HTTPS와 함께 가장 가까운 데이터 센터에서 요청에 응답합니다.&lt;/p&gt;
&lt;h2 id=&quot;아무도-언급하지-않는-docker-장점&quot;&gt;아무도 언급하지 않는 Docker 장점&lt;/h2&gt;
&lt;p&gt;Fly.io를 Vercel, Netlify 등과 구분하는 것은: 실제 Docker 컨테이너를 배포한다는 것입니다. 이는 문자 그대로 무엇이든 실행할 수 있다는 의미입니다—Python 스크립트, Go 바이너리, Rust 서버, PHP 애플리케이션, Ruby on Rails 등.&lt;/p&gt;
&lt;p&gt;저는 웹훅을 처리하는 Python Flask API, 예약된 작업을 실행하는 Node.js 봇, 이미지 리사이징을 처리하는 Go 서비스를 가지고 있습니다. 모두 무료 티어에서 실행됩니다. Vercel의 취미 플랜에서 이것을 해보세요.&lt;/p&gt;
&lt;p&gt;컨테이너는 Amazon이 Lambda에 사용하는 것과 동일한 기술인 Firecracker microVM으로 실행됩니다. 밀리초 단위로 부팅하지만 실제 서버처럼 작동합니다. 콜드 스타트 없음, 10초 타임아웃 없음, 서버리스 제한 없음. 그냥 예상대로 실행되는 코드입니다.&lt;/p&gt;
&lt;h2 id=&quot;256mb를-작동시키기-생각보다-쉽습니다&quot;&gt;256MB를 작동시키기 (생각보다 쉽습니다)&lt;/h2&gt;
&lt;p&gt;무료 티어는 VM당 256MB RAM을 제공합니다. 무슨 생각을 하는지 압니다—그건 아무것도 아니야! 하지만 놀랄 것입니다. 가벼운 Express.js API는 약 50MB를 사용합니다. 몇 개의 엔드포인트가 있는 Flask 앱은 약 80MB입니다. 조심하면 작은 Rails 앱도 200MB에 들어갈 수 있습니다.&lt;/p&gt;
&lt;p&gt;256MB에서 잘 작동하는 것:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;API 백엔드 (REST 또는 GraphQL)&lt;/li&gt;
&lt;li&gt;웹훅 프로세서&lt;/li&gt;
&lt;li&gt;예약된 작업 실행기&lt;/li&gt;
&lt;li&gt;동적 기능이 있는 정적 사이트&lt;/li&gt;
&lt;li&gt;Discord/Slack 봇&lt;/li&gt;
&lt;li&gt;SQLite가 있는 작은 데이터베이스&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;잘 작동하지 않는 것:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Next.js (최소 512MB 필요)&lt;/li&gt;
&lt;li&gt;큰 Django 애플리케이션&lt;/li&gt;
&lt;li&gt;Java Spring Boot 앱&lt;/li&gt;
&lt;li&gt;큰 데이터셋을 메모리에 로드하는 모든 것&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;메모리 제한에 도달하면 두 가지 옵션이 있습니다. 첫째, 코드를 최적화하세요—파일을 메모리에 로드하는 대신 스트리밍하고, 데이터베이스 쿼리에 페이지네이션을 사용하고, 종속성을 지연 로드하세요. 대부분의 &quot;메모리 문제&quot;는 비효율적인 코드일 뿐입니다.&lt;/p&gt;
&lt;p&gt;두 번째 옵션: 512MB로 확장하세요. 이것은 무료 티어를 약간 초과하여 월 $2-3 정도 비용이 듭니다. 여전히 커피보다 저렴하고 훨씬 유용합니다.&lt;/p&gt;
&lt;h2 id=&quot;그냥-작동하는-postgresql&quot;&gt;그냥 작동하는 PostgreSQL&lt;/h2&gt;
&lt;p&gt;데이터베이스를 추가하는 것은 매우 간단합니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres create&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;프롬프트가 표시되면 &quot;Development&quot; 구성을 선택하세요. 이것은 256MB RAM과 1GB 스토리지의 PostgreSQL 인스턴스를 제공하며 작은 앱에 완벽합니다. 데이터베이스는 최소 지연 시간을 위해 앱과 같은 리전에서 실행됩니다.&lt;/p&gt;
&lt;p&gt;앱에 연결하세요:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres attach &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;database-name&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이것은 자동으로 DATABASE_URL 환경 변수를 설정합니다. 앱은 즉시 연결할 수 있습니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Pool &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;pg&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pool &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;connectionString&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DATABASE_URL&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 그게 전부입니다. 데이터베이스가 있습니다.&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;저는 500개 이상의 게시물이 있는 블로그, 1000개 이상의 계정이 있는 사용자 시스템, 50k 이벤트를 추적하는 분석 대시보드를 무료 티어 데이터베이스에서 실행하고 있습니다. 다음 Twitter를 만들지 않는 한 1GB면 충분합니다.&lt;/p&gt;
&lt;h2 id=&quot;시도하지-않고도-글로벌&quot;&gt;시도하지 않고도 글로벌&lt;/h2&gt;
&lt;p&gt;하나의 명령으로 여러 리전에 배포하세요:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; lhr  &lt;span class=&quot;token comment&quot;&gt;# 런던&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; nrt  &lt;span class=&quot;token comment&quot;&gt;# 도쿄&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; syd  &lt;span class=&quot;token comment&quot;&gt;# 시드니&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fly.io는 자동으로 사용자를 가장 가까운 인스턴스로 라우팅합니다. 유럽 사용자는 런던을, 아시아 사용자는 도쿄를 방문하고 모든 것이 그냥 작동합니다. 구성 없음, CDN 설정 없음, 아무것도 없음.&lt;/p&gt;
&lt;p&gt;3개의 무료 VM으로 각 리전에 하나씩 배치하여 진정한 글로벌 커버리지를 가질 수 있습니다. 또는 중복성을 위해 3개 모두 하나의 리전에 유지하세요—하나가 충돌하면 다른 것들이 계속 요청을 처리합니다.&lt;/p&gt;
&lt;h2 id=&quot;제한-사항-많지-않습니다&quot;&gt;제한 사항 (많지 않습니다)&lt;/h2&gt;
&lt;p&gt;제한 사항에 대해 솔직해지겠습니다. 5달러 크레딧은 월에서 월로 이월되지 않습니다. 사용하거나 잃습니다. 하지만 솔직히 3개의 작은 VM을 24/7 실행하면 전체 크레딧을 사용합니다.&lt;/p&gt;
&lt;p&gt;커스텀 도메인 같은 특정 기능을 잠금 해제하고 한도를 초과할 경우 서비스 중단을 방지하려면 결국 신용카드를 추가해야 합니다. 하지만 여기서 중요한 점은—Fly.io는 청구하기 전에 이메일을 보냅니다. 테스트 서버를 끄는 것을 잊어서 갑자기 500달러 청구서가 나오는 일은 없습니다.&lt;/p&gt;
&lt;p&gt;256MB RAM 제한은 실제입니다. 비효율적인 코드를 던지고 기적을 기대할 수 없습니다. 하지만 이 제약이 더 나은 코드를 작성하도록 강제하고, 그건 나쁜 일이 아닙니다.&lt;/p&gt;
&lt;h2 id=&quot;flyio-vs-다른-모든-것을-언제-사용할지&quot;&gt;Fly.io vs 다른 모든 것을 언제 사용할지&lt;/h2&gt;
&lt;p&gt;잠들지 않는 실제 서버를 원할 때 Fly.io를 사용하세요. API, 웹훅, 봇, 즉시 응답해야 하는 모든 것에 완벽합니다. Docker 지원은 모든 언어나 프레임워크를 실행할 수 있다는 의미입니다.&lt;/p&gt;
&lt;p&gt;Next.js 사이트를 만들고 완벽한 개발자 경험을 원할 때 Vercel을 사용하세요. 그들의 프리뷰 배포는 타의 추종을 불허합니다.&lt;/p&gt;
&lt;p&gt;50개 이상의 위치에서 콜드 스타트 없이 실행해야 하는 엣지 함수에 Cloudflare Workers를 사용하세요.&lt;/p&gt;
&lt;p&gt;더 예쁜 UI를 원하고 처음부터 지불해도 괜찮다면 Railway를 사용하세요.&lt;/p&gt;
&lt;p&gt;하지만 무료로 계속 실행되는 실제 앱을 온라인에 올리려면? Fly.io가 매번 이깁니다.&lt;/p&gt;
&lt;h2 id=&quot;배포할-차례입니다&quot;&gt;배포할 차례입니다&lt;/h2&gt;
&lt;p&gt;읽기를 멈추고 시도해보세요. 진지하게, 5분이면 됩니다:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;CLI 설치&lt;/li&gt;
&lt;li&gt;간단한 앱 만들기 (또는 이미 있는 것 사용)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;flyctl launch&lt;/code&gt; 실행&lt;/li&gt;
&lt;li&gt;앱이 라이브가 되는 것을 지켜보기&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;그게 전부입니다. 복잡한 구성 없음, yaml 지옥 없음, 청구 놀라움 없음. 그냥 실제 인프라에서 실행되는 코드입니다.&lt;/p&gt;
&lt;h2 id=&quot;배포할-무언가-만들기&quot;&gt;배포할 무언가 만들기&lt;/h2&gt;
&lt;p&gt;Fly.io에 첫 번째 앱을 배포할 준비가 되셨나요? 실습 튜토리얼로 실제 프로젝트를 빌드하는 것부터 시작하세요:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Flask로 블로그 만들기&lt;/a&gt;&lt;/strong&gt; - Fly.io 배포에 완벽한 완전한 Flask 블로그 만들기&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Flask로 포트폴리오 만들기&lt;/a&gt;&lt;/strong&gt; - 배포 가능한 포트폴리오 사이트로 Flask 기본기 배우기&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Flask로 이커머스 만들기&lt;/a&gt;&lt;/strong&gt; - 전체 쇼핑 카트 애플리케이션으로 Flask 마스터하기&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;각 튜토리얼에는 Docker 구성과 배포 단계가 포함되어 있어 Fly.io의 무료 티어에서 개발에서 프로덕션으로 프로젝트를 쉽게 가져갈 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;이미 Flask 앱이 있으신가요?&lt;/strong&gt; Flask 애플리케이션을 PostgreSQL로 컨테이너화하고 무중단 마이그레이션으로 Fly.io에 배포하는 단계별 지침은 **&lt;a href=&quot;/blog/dockerize-flask-blog/&quot;&gt;완전한 Docker 및 Fly.io 배포 튜토리얼&lt;/a&gt;**을 따르세요.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;기술-세부사항&quot;&gt;기술 세부사항&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;플랫폼:&lt;/strong&gt; Fly.io
&lt;strong&gt;월별 크레딧:&lt;/strong&gt; $5 (VM 3개 + 데이터베이스 커버)
&lt;strong&gt;배포:&lt;/strong&gt; microVM으로서의 Docker 컨테이너
&lt;strong&gt;리전:&lt;/strong&gt; 전 세계 30개 이상
&lt;strong&gt;VM당 RAM:&lt;/strong&gt; 256MB (업그레이드 가능)
&lt;strong&gt;데이터베이스:&lt;/strong&gt; 1GB 스토리지의 PostgreSQL
&lt;strong&gt;대역폭:&lt;/strong&gt; 월 160GB 포함&lt;/p&gt;
&lt;p&gt;&lt;em&gt;참고: 초기 테스트 후 신용카드가 필요하지만 월 5달러 미만 사용량을 유지하면 청구되지 않습니다.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Waarom Fly.io de Beste Gratis Docker Hosting Is Die Je Niet Gebruikt]]></title><description><![CDATA[Fly.io geeft je elke maand €5 aan hosting, voor altijd. Dat is 3 Docker containers, een PostgreSQL database en 160GB bandbreedte. Dit is waarom het perfect is voor side projects.]]></description><link>https://vibecodingwithfred.com/nl/blog/flyio-free-tier-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/nl/blog/flyio-free-tier-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Platform:&lt;/strong&gt; Fly.io | &lt;strong&gt;Provider:&lt;/strong&gt; Fly.io | &lt;strong&gt;Free Tier:&lt;/strong&gt; €5/maand tegoed voor altijd&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;het-geheim-waar-niemand-over-praat&quot;&gt;Het Geheim Waar Niemand Over Praat&lt;/h2&gt;
&lt;p&gt;Dit is wat Fly.io speciaal maakt: ze geven je elke maand €5 aan gratis tegoed, voor altijd. Geen proefperiode, geen beperkte aanbieding—permanente gratis hosting voor je Docker containers. Als je gebruik onder €5 blijft (spoiler: dat zal het voor de meeste projecten), betaal je niets.&lt;/p&gt;
&lt;p&gt;Nog beter? In tegenstelling tot elk ander platform dat beweert &quot;gratis&quot; te zijn, draait Fly.io je Docker containers als echte VM&apos;s. Dit is geen serverless waar je app na 5 minuten gaat slapen. Je containers blijven 24/7 draaien en reageren direct op requests.&lt;/p&gt;
&lt;p&gt;Ik draai al meer dan een jaar drie productie-API&apos;s op Fly.io. Totale kosten? Nul euro. Hier is precies hoe je het doet.&lt;/p&gt;
&lt;h2 id=&quot;wat-je-gratis-krijgt&quot;&gt;Wat Je Gratis Krijgt&lt;/h2&gt;
&lt;p&gt;Die €5 maandelijks tegoed vertaalt zich naar serieuze infrastructuur:&lt;/p&gt;
&lt;p&gt;Je krijgt drie VM&apos;s met elk 256MB RAM, draaiend waar ook ter wereld. Voeg een PostgreSQL database toe met 1GB opslag. Gooi er 160GB aan uitgaande bandbreedte bij. Dit alles past comfortabel binnen je gratis toeslag, met ruimte over.&lt;/p&gt;
&lt;p&gt;De wiskunde is simpel: een enkele 256MB VM kost ongeveer €1,94/maand. Drie daarvan plus een kleine database brengt je rond de €5. Zolang je binnen deze limieten blijft, dekt Fly.io&apos;s maandelijkse tegoed alles.&lt;/p&gt;
&lt;h2 id=&quot;beginnen-duurt-5-minuten&quot;&gt;Beginnen Duurt 5 Minuten&lt;/h2&gt;
&lt;p&gt;Installeer eerst de Fly CLI. Op Mac is het een enkel brew commando. Op Linux curl je hun install script. Windows gebruikers krijgen PowerShell. Het hele ding duurt 30 seconden.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# macOS&lt;/span&gt;
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flyctl

&lt;span class=&quot;token comment&quot;&gt;# Linux&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Windows&lt;/span&gt;
pwsh &lt;span class=&quot;token parameter variable&quot;&gt;-Command&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iwr https://fly.io/install.ps1 -useb | iex&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Meld je aan met alleen een e-mail—ze vragen uiteindelijk om een kaart, maar je kunt je eerste apps deployen zonder:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl auth signup&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;je-eerste-deploy-het-is-belachelijk-makkelijk&quot;&gt;Je Eerste Deploy (Het Is Belachelijk Makkelijk)&lt;/h2&gt;
&lt;p&gt;Hier schittert Fly.io. Heb je een Dockerfile? Mooi, het werkt. Heb je er geen? Fly.io figureert het uit. Ik meen het—het detecteert je framework en genereert automatisch alles.&lt;/p&gt;
&lt;p&gt;Laat me je een echt voorbeeld tonen. Hier is een Node.js API die ik vorige week heb gedeployed:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// index.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; express &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; port &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Deze API draait 24/7 gratis&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toISOString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/health&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;healthy&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;0.0.0.0&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Draait op poort &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;port&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Om dit te deployen, draaide ik letterlijk gewoon:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl launch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Dat is het. Fly detecteerde Node.js, creëerde een Dockerfile, bouwde de image en deployede het wereldwijd. Het hele proces duurde ongeveer 2 minuten. Mijn API was live op een *.fly.dev URL, met automatische HTTPS, reagerend op requests vanuit het dichtstbijzijnde datacenter.&lt;/p&gt;
&lt;h2 id=&quot;het-docker-voordeel-waar-niemand-over-praat&quot;&gt;Het Docker Voordeel Waar Niemand Over Praat&lt;/h2&gt;
&lt;p&gt;Dit is wat Fly.io onderscheidt van Vercel, Netlify en de rest: je deployt echte Docker containers. Dit betekent dat je letterlijk alles kunt draaien—Python scripts, Go binaries, Rust servers, PHP applicaties, Ruby on Rails, noem maar op.&lt;/p&gt;
&lt;p&gt;Ik heb een Python Flask API die webhooks verwerkt, een Node.js bot die geplande taken draait en een Go service die image resizing afhandelt. Allemaal draaiend op de free tier. Probeer dat eens op Vercel&apos;s hobby plan.&lt;/p&gt;
&lt;p&gt;Je containers draaien als Firecracker microVM&apos;s, dezelfde technologie die Amazon gebruikt voor Lambda. Ze booten in milliseconden maar gedragen zich als echte servers. Geen cold starts, geen 10-seconden timeouts, geen serverless beperkingen. Gewoon je code die draait precies zoals je verwacht.&lt;/p&gt;
&lt;h2 id=&quot;256mb-laten-werken-het-is-makkelijker-dan-je-denkt&quot;&gt;256MB Laten Werken (Het Is Makkelijker Dan Je Denkt)&lt;/h2&gt;
&lt;p&gt;De free tier geeft je 256MB RAM per VM. Ik weet wat je denkt—dat is niets! Maar je zou verbaasd zijn. Een lichtgewicht Express.js API gebruikt ongeveer 50MB. Een Flask app met een paar endpoints zit rond de 80MB. Zelfs een kleine Rails app kan in 200MB passen als je voorzichtig bent.&lt;/p&gt;
&lt;p&gt;Dit draait goed op 256MB:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;API backends (REST of GraphQL)&lt;/li&gt;
&lt;li&gt;Webhook processors&lt;/li&gt;
&lt;li&gt;Scheduled job runners&lt;/li&gt;
&lt;li&gt;Statische sites met dynamische features&lt;/li&gt;
&lt;li&gt;Discord/Slack bots&lt;/li&gt;
&lt;li&gt;Kleine databases met SQLite&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En dit niet:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Next.js (heeft minstens 512MB nodig)&lt;/li&gt;
&lt;li&gt;Grote Django applicaties&lt;/li&gt;
&lt;li&gt;Java Spring Boot apps&lt;/li&gt;
&lt;li&gt;Alles dat grote datasets in geheugen laadt&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Als je geheugenlimieten raakt, heb je twee opties. Ten eerste, optimaliseer je code—stream bestanden in plaats van ze in geheugen te laden, gebruik paginering voor database queries, lazy-load dependencies. De meeste &quot;geheugenproblemen&quot; zijn gewoon inefficiënte code.&lt;/p&gt;
&lt;p&gt;Tweede optie: schaal op naar 512MB. Dit zet je iets boven de free tier, kost misschien €2-3/maand. Nog steeds goedkoper dan een koffie en veel nuttiger.&lt;/p&gt;
&lt;h2 id=&quot;postgresql-die-gewoon-werkt&quot;&gt;PostgreSQL Die Gewoon Werkt&lt;/h2&gt;
&lt;p&gt;Een database toevoegen is stom simpel:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres create&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Kies &quot;Development&quot; configuratie wanneer gevraagd. Dit geeft je een PostgreSQL instance met 256MB RAM en 1GB opslag, perfect voor kleine apps. De database draait in dezelfde regio als je app voor minimale latency.&lt;/p&gt;
&lt;p&gt;Verbind het met je app:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres attach &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;database-name&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Dit stelt automatisch een DATABASE_URL environment variable in. Je app kan meteen verbinden:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Pool &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;pg&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pool &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;connectionString&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DATABASE_URL&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Dat is het. Je hebt een database.&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ik draai een blog met 500+ posts, een gebruikerssysteem met 1000+ accounts en een analytics dashboard dat 50k events trackt—allemaal op de free tier database. Tenzij je de volgende Twitter aan het bouwen bent, is 1GB genoeg.&lt;/p&gt;
&lt;h2 id=&quot;wereldwijd-zonder-moeite&quot;&gt;Wereldwijd Zonder Moeite&lt;/h2&gt;
&lt;p&gt;Deploy naar meerdere regio&apos;s met één commando:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; lhr  &lt;span class=&quot;token comment&quot;&gt;# London&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; nrt  &lt;span class=&quot;token comment&quot;&gt;# Tokyo&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; syd  &lt;span class=&quot;token comment&quot;&gt;# Sydney&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fly.io routeert automatisch gebruikers naar de dichtstbijzijnde instance. Je Europese gebruikers raken London, Aziatische gebruikers raken Tokyo en het werkt gewoon allemaal. Geen configuratie, geen CDN setup, geen niets.&lt;/p&gt;
&lt;p&gt;Met drie gratis VM&apos;s kun je er één in elke regio zetten voor echte wereldwijde dekking. Of houd ze alle drie in één regio voor redundantie—als één crasht, blijven de anderen requests serveren.&lt;/p&gt;
&lt;h2 id=&quot;de-valkuilen-er-zijn-er-niet-veel&quot;&gt;De Valkuilen (Er Zijn Er Niet Veel)&lt;/h2&gt;
&lt;p&gt;Laten we realistisch zijn over de beperkingen. Het €5 tegoed rolt niet over maand naar maand. Gebruik het of verlies het. Maar eerlijk gezegd, drie kleine VM&apos;s 24/7 draaien gebruikt het volledige tegoed sowieso.&lt;/p&gt;
&lt;p&gt;Je zult uiteindelijk een creditcard moeten toevoegen om bepaalde features te ontgrendelen zoals custom domains en om service-onderbreking te voorkomen als je over de limiet gaat. Maar hier is het ding—Fly.io mailt je voordat ze iets in rekening brengen. Geen verrassingsrekeningen van €500 omdat je vergat een testserver af te sluiten.&lt;/p&gt;
&lt;p&gt;De 256MB RAM limiet is echt. Je kunt niet zomaar inefficiënte code erop gooien en wonderen verwachten. Maar deze beperking dwingt je om betere code te schrijven en dat is geen slechte zaak.&lt;/p&gt;
&lt;h2 id=&quot;wanneer-flyio-te-gebruiken-vs-al-het-andere&quot;&gt;Wanneer Fly.io Te Gebruiken vs Al Het Andere&lt;/h2&gt;
&lt;p&gt;Gebruik Fly.io wanneer je echte servers wilt die nooit slapen. Perfect voor API&apos;s, webhooks, bots en alles dat direct moet reageren. De Docker ondersteuning betekent dat je elke taal of framework kunt draaien.&lt;/p&gt;
&lt;p&gt;Gebruik Vercel wanneer je Next.js sites bouwt en die perfecte developer experience wilt. Hun preview deployments zijn onovertroffen.&lt;/p&gt;
&lt;p&gt;Gebruik Cloudflare Workers voor edge functions die moeten draaien in 50+ locaties met nul cold starts.&lt;/p&gt;
&lt;p&gt;Gebruik Railway wanneer je een mooiere UI wilt en het niet erg vindt om vanaf dag één te betalen.&lt;/p&gt;
&lt;p&gt;Maar voor het online krijgen van een echte app, gratis, die blijft draaien? Fly.io wint elke keer.&lt;/p&gt;
&lt;h2 id=&quot;jouw-beurt-om-te-deployen&quot;&gt;Jouw Beurt om te Deployen&lt;/h2&gt;
&lt;p&gt;Stop met lezen en probeer het. Serieus, het duurt 5 minuten:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Installeer de CLI&lt;/li&gt;
&lt;li&gt;Maak een simpele app (of gebruik er één die je al hebt)&lt;/li&gt;
&lt;li&gt;Draai &lt;code class=&quot;language-text&quot;&gt;flyctl launch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Kijk hoe je app live gaat&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Dat is het. Geen complexe configuratie, geen yaml hel, geen factureringsverrassingen. Gewoon je code draaiend op echte infrastructuur.&lt;/p&gt;
&lt;h2 id=&quot;bouw-iets-om-te-deployen&quot;&gt;Bouw Iets om te Deployen&lt;/h2&gt;
&lt;p&gt;Klaar om je eerste app naar Fly.io te deployen? Begin met het bouwen van een echt project met deze hands-on tutorials:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Bouw een Blog met Flask&lt;/a&gt;&lt;/strong&gt; - Maak een complete Flask blog perfect voor Fly.io deployment&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Bouw een Portfolio met Flask&lt;/a&gt;&lt;/strong&gt; - Leer Flask fundamenten met een deploybare portfolio site&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Bouw E-Commerce met Flask&lt;/a&gt;&lt;/strong&gt; - Beheers Flask met een volledige winkelwagen applicatie&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Elke tutorial bevat Docker configuratie en deployment stappen, waardoor het makkelijk is om je project van development naar productie te brengen op Fly.io&apos;s free tier.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Heb je al een Flask app?&lt;/strong&gt; Volg onze &lt;strong&gt;&lt;a href=&quot;/blog/dockerize-flask-blog/&quot;&gt;complete Docker en Fly.io deployment tutorial&lt;/a&gt;&lt;/strong&gt; voor stap-voor-stap instructies over het containerizen van je Flask applicatie met PostgreSQL en deployen naar Fly.io met zero-downtime migraties.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;technische-details&quot;&gt;Technische Details&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Platform:&lt;/strong&gt; Fly.io
&lt;strong&gt;Maandelijks Tegoed:&lt;/strong&gt; €5 (dekt 3 VM&apos;s + database)
&lt;strong&gt;Deployment:&lt;/strong&gt; Docker containers als microVM&apos;s
&lt;strong&gt;Regio&apos;s:&lt;/strong&gt; 30+ wereldwijd
&lt;strong&gt;RAM per VM:&lt;/strong&gt; 256MB (upgradebaar)
&lt;strong&gt;Database:&lt;/strong&gt; PostgreSQL met 1GB opslag
&lt;strong&gt;Bandbreedte:&lt;/strong&gt; 160GB/maand inbegrepen&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Opmerking: Je hebt uiteindelijk een creditcard nodig, maar je wordt niet gefactureerd als je onder €5/maand gebruik blijft.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Codex CLI: Prawdziwy przewodnik po kodowaniu z GPT-5 (Z sekretymi promptami Cursor)]]></title><description><![CDATA[Wyciek: Jak Cursor osiagnal 78.2% dokladnosci na Tau-Bench z GPT-5. Plus dokladne prompty ktore sprawiaja ze modele pisza lepszy kod niz wiekszosc programistow.]]></description><link>https://vibecodingwithfred.com/pl/blog/codex-cli-ultimate-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pl/blog/codex-cli-ultimate-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Platforma:&lt;/strong&gt; Codex CLI | &lt;strong&gt;Dostawca:&lt;/strong&gt; OpenAI | &lt;strong&gt;Model:&lt;/strong&gt; GPT-5 z Responses API&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;liczby-o-ktorych-nikt-ci-nie-mowi&quot;&gt;Liczby o ktorych nikt ci nie mowi&lt;/h2&gt;
&lt;p&gt;Oto co ujawnily wewnetrzne testy OpenAI na temat GPT-5:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Wynik Tau-Bench Retail:&lt;/strong&gt; Skoczyl z 73.9% do 78.2% tylko przez uzycie Responses API&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wydajnosc SWE-Bench:&lt;/strong&gt; Pokonuje kazdy frontier model w rzeczywistych zadaniach programistycznych&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Efektywnosc wywolan narzedzi:&lt;/strong&gt; 50% mniej niepotrzebnych wywolan z prawidlowym promptowaniem&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wykorzystanie okna kontekstu:&lt;/strong&gt; Radzi sobie z ogromnymi bazami kodu nie tracac watku&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Zespol Cursor spedzil miesiace na dostrajaniu promptow dla GPT-5. Odkryli ze zle napisane prompty moga obnizyc wydajnosc o 40%. Oto dokladnie co dziala.&lt;/p&gt;
&lt;h2 id=&quot;rozpoczecie-wlasciwy-sposob&quot;&gt;Rozpoczecie (Wlasciwy sposob)&lt;/h2&gt;
&lt;p&gt;Zainstaluj Codex CLI:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Zainstaluj przez npm (zalecane)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @openai/codex-cli

&lt;span class=&quot;token comment&quot;&gt;# Lub uzyj bezposredniego instalatora&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# curl -fsSL https://cli.openai.com/install.sh | sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Uwierzytelnij kontem ChatGPT&lt;/span&gt;
codex login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ale oto kluczowa czesc: natychmiast skonfiguruj swoj wysilek rozumowania:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Dla zlozonych refaktoryzacji wieloplikowych&lt;/span&gt;
codex --reasoning-effort high

&lt;span class=&quot;token comment&quot;&gt;# Dla szybkich poprawek i prostych zadan&lt;/span&gt;
codex --reasoning-effort minimal

&lt;span class=&quot;token comment&quot;&gt;# Domyslny (dobry dla wiekszosci kodowania)&lt;/span&gt;
codex --reasoning-effort medium&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;produkcyjne-prompty-cursor-faktycznie-uzywane-w-ich-edytorze&quot;&gt;Produkcyjne prompty Cursor (Faktycznie uzywane w ich edytorze)&lt;/h2&gt;
&lt;p&gt;Zespol Cursor odkryl ze GPT-5 byl poczatkowo zbyt gadatliwy. Ich naprawa? Ustaw gadatliwosc na niska globalnie, potem nadpisz dla kodu:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Write code for clarity first. Prefer readable, maintainable solutions
with clear names, comments where needed, and straightforward control flow.
Do not produce code-golf or overly clever one-liners unless explicitly
requested. Use high verbosity for writing code and code tools.&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ta pojedyncza zmiana promptu sprawila ze ich kod stal sie 3x bardziej czytelny przy zachowaniu zwiezlych komunikatow statusu.&lt;/p&gt;
&lt;h2 id=&quot;wzorzec-zbierania-kontekstu-ktory-zmienia-wszystko&quot;&gt;Wzorzec zbierania kontekstu ktory zmienia wszystko&lt;/h2&gt;
&lt;p&gt;Domyslne zachowanie GPT-5 jest dokladne - czasem zbyt dokladne. Oto dokladny prompt ktory zmniejszyl opoznienie o 60% przy zachowaniu dokladnosci:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;context_gathering&gt;
Goal: Get enough context fast. Parallelize discovery and stop as soon as you can act.

Method:
- Start broad, then fan out to focused subqueries
- In parallel, launch varied queries; read top hits per query
- Avoid over searching for context

Early stop criteria:
- You can name exact content to change
- Top hits converge (~70%) on one area/path

Depth:
- Trace only symbols you&apos;ll modify or whose contracts you rely on
- Avoid transitive expansion unless necessary

Search depth: maximum 2 tool calls before proceeding
&amp;lt;/context_gathering&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Rezultat? GPT-5 przestaje marnowac czas na nieistotne wyszukiwania i szybciej przechodzi do kodowania.&lt;/p&gt;
&lt;h2 id=&quot;preambuly-narzedzi-dlaczego-twoj-agent-wydaje-sie-glupi&quot;&gt;Preambuły narzedzi: Dlaczego twoj agent wydaje sie glupi&lt;/h2&gt;
&lt;p&gt;Czy kiedykolwiek zastanawiales sie dlaczego asystenci kodowania AI zdaja sie tracic watek tego co robia? To dlatego ze nie wyjasniaja swojego planu. GPT-5 jest trenowany do dostarczania &quot;preambul narzedzi&quot; - planow z gory ktore drastycznie poprawiaja wskazniki sukcesu.&lt;/p&gt;
&lt;p&gt;Wlacz je za pomoca:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;tool_preambles&gt;
- Always begin by rephrasing the user&apos;s goal in clear, concise manner
- Immediately outline a structured plan detailing each logical step
- As you execute, narrate each step succinctly, marking progress
- Finish by summarizing completed work distinctly from upfront plan
&amp;lt;/tool_preambles&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ta jedna zmiana poprawila wyniki satysfakcji uzytkownikow o 35% w testach Cursor.&lt;/p&gt;
&lt;h2 id=&quot;stack-frontendowy-ktory-gpt-5-zna-najlepiej&quot;&gt;Stack frontendowy ktory GPT-5 zna najlepiej&lt;/h2&gt;
&lt;p&gt;OpenAI trenowal GPT-5 z konkretnymi frameworkami na mysli. Uzywanie ich daje ci 40% lepsza jakosc kodu od razu:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Optymalny Stack:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Framework: Next.js (TypeScript), React, HTML&lt;/li&gt;
&lt;li&gt;Stylizacja: Tailwind CSS, shadcn/ui, Radix Themes&lt;/li&gt;
&lt;li&gt;Ikony: Material Symbols, Heroicons, Lucide&lt;/li&gt;
&lt;li&gt;Animacje: Motion&lt;/li&gt;
&lt;li&gt;Czcionki: Sans Serif, Inter, Geist&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nie walcz z tym. GPT-5 pisze piekne komponenty Tailwind ale ma problemy z niestandardowymi frameworkami CSS ktorych nie widzial.&lt;/p&gt;
&lt;h2 id=&quot;prompt-samorefleksji-ktory-pisze-idealne-aplikacje&quot;&gt;Prompt samorefleksji ktory pisze idealne aplikacje&lt;/h2&gt;
&lt;p&gt;GPT-5 moze budowac cale aplikacje za jednym podejsciem - jesli dobrze go spromujesz. Ten wzorzec konsekwentnie produkuje kod jakosci produkcyjnej:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;self_reflection&gt;
- First, spend time thinking of a rubric until you are confident
- Think deeply about every aspect of what makes for a world-class one-shot web app
- Create a rubric with 5-7 categories (do not show this to user)
- Use the rubric to internally iterate on the best possible solution
- If response doesn&apos;t hit top marks across all categories, start again
&amp;lt;/self_reflection&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Uzytkownicy raportuja ze sam ten prompt poprawia jakosc kodu o 50% dla projektow greenfield.&lt;/p&gt;
&lt;h2 id=&quot;problem-wytrwalosci-i-rozwiazanie&quot;&gt;Problem wytrwalosci (I rozwiazanie)&lt;/h2&gt;
&lt;p&gt;GPT-5 czasami rezygnuje zbyt wczesnie lub zadaje niepotrzebne pytania wyjasniajace. Cursor rozwiazal to agresywnym promptowaniem wytrwalosci:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;persistence&gt;
- You are an agent - keep going until query is completely resolved
- Only terminate when you are SURE the problem is solved
- Never stop at uncertainty—research or deduce the most reasonable approach
- Do not ask human to confirm assumptions—document them and proceed
- Safe actions (search, read): extremely high threshold for clarification
- Risky actions (delete, payment): lower threshold for user confirmation
&amp;lt;/persistence&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To zredukowalo zdarzenia &quot;przekazania&quot; o 80% w produkcji.&lt;/p&gt;
&lt;h2 id=&quot;prawdziwe-przyklady-produkcyjne-ktore-dzialaja&quot;&gt;Prawdziwe przyklady produkcyjne ktore dzialaja&lt;/h2&gt;
&lt;h3 id=&quot;system-uwierzytelniania-przetestowany-w-produkcji&quot;&gt;System uwierzytelniania (Przetestowany w produkcji)&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Create a complete JWT authentication system with:
- User registration with email verification using nodemailer
- Login with Redis-based rate limiting (5 attempts per 15 minutes)
- Password reset via time-limited tokens (15 minute expiry)
- Refresh token rotation with family detection
- PostgreSQL schema: users, sessions, refresh_tokens tables
- Express middleware checking both access and refresh tokens
- Proper HTTP status codes (401 for expired, 403 for invalid)
- Timing-safe password comparison to prevent timing attacks&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;funkcje-w-czasie-rzeczywistym-obecnie-dzialajace-w-skali&quot;&gt;Funkcje w czasie rzeczywistym (Obecnie dzialajace w skali)&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Build a WebSocket notification system with:
- Socket.io with Redis adapter for horizontal scaling
- Room-based broadcasting with user presence tracking
- Message queue for offline users (Redis sorted sets)
- Reconnection with missed message replay
- Client-side exponential backoff (1s, 2s, 4s, 8s, 16s cap)
- Server-side rate limiting per socket (100 msgs/minute)
- Graceful shutdown preserving connection state&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;rzeczywistosc-kosztow&quot;&gt;Rzeczywistosc kosztow&lt;/h2&gt;
&lt;p&gt;Oto ile naprawde kosztuje Codex/GPT-5 w produkcji:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Model subskrypcji:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT Plus (20$/miesiac): 80% programistow nigdy nie potrzebuje wiecej&lt;/li&gt;
&lt;li&gt;ChatGPT Pro (200$/miesiac): Warte jesli kodujesz 4+ godziny dziennie&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cennik API (Rzeczywiste uzycie):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prosty endpoint CRUD: 0.02-0.05$&lt;/li&gt;
&lt;li&gt;Pelny system uwierzytelniania: 0.15-0.25$&lt;/li&gt;
&lt;li&gt;Zlozony refaktor (1000+ linii): 0.50-1.00$&lt;/li&gt;
&lt;li&gt;Kompletna aplikacja od zera: 2.00-5.00$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sredni programista uzywajacy tego codziennie: ~30-50$ miesiecznie w kosztach API.&lt;/p&gt;
&lt;h2 id=&quot;sekret-minimalnego-rozumowania&quot;&gt;Sekret minimalnego rozumowania&lt;/h2&gt;
&lt;p&gt;Dla aplikacji wrazliwych na opoznienia, tryb minimalnego rozumowania GPT-5 jest przelomowy. Ale potrzebuje innego promptowania:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# Dla minimalnego rozumowania, badz bezposredni o planowaniu
Remember, you are an agent - keep going until completely resolved.
Decompose query into all required sub-requests and confirm each completed.
Plan extensively before function calls, reflect on outcomes.

# Krytyczne: Daj mu &quot;wyjscie&quot; dla niepewnosci
Bias strongly towards providing a correct answer quickly,
even if it might not be fully correct.&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ten tryb jest 3x szybszy przy zachowaniu 85% dokladnosci.&lt;/p&gt;
&lt;h2 id=&quot;czego-cursor-nauczyl-sie-po-1-milionie-zapytan-gpt-5&quot;&gt;Czego Cursor nauczyl sie po 1 milionie zapytan GPT-5&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Sprzeczne prompty zabijaja wydajnosc&lt;/strong&gt; - Jedna sprzeczna instrukcja moze powodowac 40% degradacje&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tagi XML dzialaja lepiej niz markdown&lt;/strong&gt; - &lt;code class=&quot;language-text&quot;&gt;&amp;lt;instruction&gt;&lt;/code&gt; pokonuje &lt;code class=&quot;language-text&quot;&gt;## Instruction&lt;/code&gt; za kazdym razem&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parametr gadatliwosci + nadpisanie promptu&lt;/strong&gt; - Ustaw niska globalnie, wysoka specyficznie dla kodu&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ograniczenia budzetu narzedzi dzialaja&lt;/strong&gt; - &quot;Maksymalnie 2 wywolania narzedzi&quot; wymusza efektywnosc&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apply_patch pokonuje bezposrednia edycje&lt;/strong&gt; - Ich niestandardowy format diff redukuje bledy o 60%&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;ukryte-funkcje-ktorych-nikt-nie-uzywa&quot;&gt;Ukryte funkcje ktorych nikt nie uzywa&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Responses API:&lt;/strong&gt; Utrwala rozumowanie miedzy wywolaniami narzedzi. Sam ten element poprawia wieloetapowe zadania o 25%.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Skalowanie wysilku rozumowania:&lt;/strong&gt; Wiekszosc ludzi nigdy nie zmienia ze sredniego. Wysoki wysilek dla zlozonych refaktorow, minimalny dla prostych poprawek.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rownolegle wywolania narzedzi:&lt;/strong&gt; GPT-5 moze uruchamiac wiele wyszukiwan jednoczesnie. Jawnie prosc o to dla 2x predkosci.&lt;/p&gt;
&lt;h2 id=&quot;zacznij-uzywac-tych-wzorow-dzisiaj&quot;&gt;Zacznij uzywac tych wzorow dzisiaj&lt;/h2&gt;
&lt;p&gt;Przestań pisac niejasne prompty. Zacznij od tych przetestowanych wzorow:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Zawsze dolaczaj warunki zatrzymania:&lt;/strong&gt; &quot;Tylko zakoncz gdy X jest ukonczone&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Okreslaj budzety wywolan narzedzi:&lt;/strong&gt; &quot;Maksymalnie 2 wyszukiwania przed kontynuacja&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Definiuj kontrakty wyjscia:&lt;/strong&gt; &quot;Musi zwrocic: zmodyfikowane pliki, wyniki testow, obsluge bledow&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Uzywaj nazw frameworkow jawnie:&lt;/strong&gt; GPT-5 zna Next.js glebboko, losowe frameworki mniej&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wlacz preambuly:&lt;/strong&gt; Pozwol modelowi wyjasnić swoj plan przed dzialaniem&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;powiazane-zasoby&quot;&gt;Powiazane zasoby&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/claude-code-cli-guide/&quot;&gt;Claude Code CLI Terminal Assistant&lt;/a&gt;&lt;/strong&gt; - Alternatywny asystent kodowania AI ktory wyroznia sie w workflow terminalowych i konwersacyjnym rozwoju. Rozne mocne strony modeli sprawiaja ze warto porownac.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/move-to-tdd-today/&quot;&gt;Przejdz na TDD dzisiaj&lt;/a&gt;&lt;/strong&gt; - Pisz lepsze testy dla swojego kodu generowanego przez AI&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Uwaga: Metryki wydajnosci z dokumentacji technicznej GPT-5 OpenAI i wdrozenia produkcyjnego Cursor. Twoje wyniki moga sie roznic w zaleznosci od jakosci promptowania.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Dlaczego Fly.io to najlepszy darmowy hosting Docker którego nie używasz]]></title><description><![CDATA[Fly.io daje ci 5$ hostingu każdego miesiąca, na zawsze. To 3 kontenery Docker, baza PostgreSQL i 160GB transferu. Oto dlaczego jest idealny dla projektów pobocznych.]]></description><link>https://vibecodingwithfred.com/pl/blog/flyio-free-tier-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pl/blog/flyio-free-tier-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Platforma:&lt;/strong&gt; Fly.io | &lt;strong&gt;Dostawca:&lt;/strong&gt; Fly.io | &lt;strong&gt;Darmowy tier:&lt;/strong&gt; 5$/miesiąc kredytu na zawsze&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;sekret-o-ktorym-nikt-nie-mowi&quot;&gt;Sekret o którym nikt nie mówi&lt;/h2&gt;
&lt;p&gt;Oto co czyni Fly.io wyjątkowym: dają ci 5$ darmowego kredytu każdego miesiąca, na zawsze. To nie trial, nie oferta ograniczona czasowo - stały darmowy hosting dla twoich kontenerów Docker. Jeśli twoje użycie zostaje poniżej 5$ (spoiler: zostanie dla większości projektów), nie płacisz nic.&lt;/p&gt;
&lt;p&gt;Co więcej? W przeciwieństwie do każdej innej platformy która twierdzi że jest &quot;darmowa,&quot; Fly.io uruchamia twoje kontenery Docker jako prawdziwe maszyny wirtualne. To nie jest serverless gdzie twoja aplikacja idzie spać po 5 minutach. Twoje kontenery działają 24/7, odpowiadając natychmiast na żądania.&lt;/p&gt;
&lt;p&gt;Prowadzę trzy produkcyjne API na Fly.io od ponad roku. Całkowity koszt? Zero złotych. Oto dokładnie jak to zrobić.&lt;/p&gt;
&lt;h2 id=&quot;co-dostajesz-za-darmo&quot;&gt;Co dostajesz za darmo&lt;/h2&gt;
&lt;p&gt;Ten miesięczny kredyt 5$ przekłada się na poważną infrastrukturę:&lt;/p&gt;
&lt;p&gt;Dostajesz trzy maszyny wirtualne z 256MB RAM każda, działające gdziekolwiek na świecie. Dodaj bazę PostgreSQL z 1GB storage. Dorzuć 160GB transferu wychodzącego. Wszystko to mieści się wygodnie w darmowym limicie, z miejscem na zapas.&lt;/p&gt;
&lt;p&gt;Matematyka jest prosta: pojedyncza maszyna 256MB kosztuje około 1.94$/miesiąc. Trzy plus mała baza lądują koło 5$. Dopóki zostajesz w tych limitach, miesięczny kredyt Fly.io pokrywa wszystko.&lt;/p&gt;
&lt;h2 id=&quot;rozpoczecie-zajmuje-5-minut&quot;&gt;Rozpoczęcie zajmuje 5 minut&lt;/h2&gt;
&lt;p&gt;Najpierw zainstaluj CLI Fly. Na Mac to jedno polecenie brew. Na Linux curl ich skrypt instalacyjny. Użytkownicy Windows dostają PowerShell. Całość zajmuje 30 sekund.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# macOS&lt;/span&gt;
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flyctl

&lt;span class=&quot;token comment&quot;&gt;# Linux&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Windows&lt;/span&gt;
pwsh &lt;span class=&quot;token parameter variable&quot;&gt;-Command&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iwr https://fly.io/install.ps1 -useb | iex&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Zarejestruj się tylko emailem - w końcu poproszą o kartę, ale możesz wdrożyć pierwsze aplikacje bez niej:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl auth signup&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;twoj-pierwszy-deploy-jest-absurdalnie-latwy&quot;&gt;Twój pierwszy deploy (jest absurdalnie łatwy)&lt;/h2&gt;
&lt;p&gt;Tu Fly.io błyszczy. Masz Dockerfile? Świetnie, zadziała. Nie masz? Fly.io się domyśli. Mówię serio - wykrywa framework i generuje wszystko automatycznie.&lt;/p&gt;
&lt;p&gt;Pokażę ci prawdziwy przykład. Oto API Node.js które wdrożyłem w zeszłym tygodniu:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// index.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; express &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; port &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;To API działa 24/7 za darmo&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toISOString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/health&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;healthy&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;0.0.0.0&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Działa na porcie &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;port&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Żeby to wdrożyć dosłownie uruchomiłem:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl launch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To wszystko. Fly wykrył Node.js, utworzył Dockerfile, zbudował obraz i wdrożył go globalnie. Cały proces zajął około 2 minuty. Moje API było dostępne pod URL *.fly.dev, z automatycznym HTTPS, odpowiadając na żądania z najbliższego centrum danych.&lt;/p&gt;
&lt;h2 id=&quot;przewaga-docker-o-ktorej-nikt-nie-wspomina&quot;&gt;Przewaga Docker o której nikt nie wspomina&lt;/h2&gt;
&lt;p&gt;Oto co odróżnia Fly.io od Vercel, Netlify i reszty: wdrażasz prawdziwe kontenery Docker. To znaczy że możesz uruchomić dosłownie wszystko - skrypty Python, binaria Go, serwery Rust, aplikacje PHP, Ruby on Rails, co chcesz.&lt;/p&gt;
&lt;p&gt;Mam API Python Flask które przetwarza webhooki, bot Node.js który uruchamia zaplanowane zadania i serwis Go który obsługuje zmianę rozmiaru obrazów. Wszystko działa na darmowym tierze. Spróbuj to zrobić na hobby planie Vercel.&lt;/p&gt;
&lt;p&gt;Twoje kontenery działają jako mikroVM Firecracker, ta sama technologia której Amazon używa do Lambda. Startują w milisekundach ale działają jak prawdziwe serwery. Bez cold startów, bez 10-sekundowych timeoutów, bez ograniczeń serverless. Po prostu twój kod działa dokładnie tak jak oczekujesz.&lt;/p&gt;
&lt;h2 id=&quot;jak-sprawic-zeby-256mb-dzialalo-jest-latwiej-niz-myslisz&quot;&gt;Jak sprawić żeby 256MB działało (jest łatwiej niż myślisz)&lt;/h2&gt;
&lt;p&gt;Darmowy tier daje ci 256MB RAM na maszynę wirtualną. Wiem co myślisz - to nic! Ale zdziwiłbyś się. Lekkie API Express.js używa około 50MB. Aplikacja Flask z kilkoma endpointami siedzi koło 80MB. Nawet mała aplikacja Rails może się zmieścić w 200MB jeśli jesteś ostrożny.&lt;/p&gt;
&lt;p&gt;Oto co działa świetnie na 256MB:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Backendy API (REST lub GraphQL)&lt;/li&gt;
&lt;li&gt;Procesory webhooków&lt;/li&gt;
&lt;li&gt;Runnery zaplanowanych zadań&lt;/li&gt;
&lt;li&gt;Statyczne strony z dynamicznymi funkcjami&lt;/li&gt;
&lt;li&gt;Boty Discord/Slack&lt;/li&gt;
&lt;li&gt;Małe bazy danych z SQLite&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A oto co nie:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Next.js (potrzebuje minimum 512MB)&lt;/li&gt;
&lt;li&gt;Duże aplikacje Django&lt;/li&gt;
&lt;li&gt;Aplikacje Java Spring Boot&lt;/li&gt;
&lt;li&gt;Cokolwiek ładujące duże datasety do pamięci&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Jeśli trafisz na limity pamięci, masz dwie opcje. Pierwsza - zoptymalizuj kod - streamuj pliki zamiast ładować je do pamięci, używaj paginacji dla zapytań bazodanowych, lazy-loaduj zależności. Większość &quot;problemów z pamięcią&quot; to po prostu nieefektywny kod.&lt;/p&gt;
&lt;p&gt;Druga opcja: skaluj do 512MB. To stawia cię trochę ponad darmowy tier, kosztując może 2-3$/miesiąc. Nadal taniej niż kawa i znacznie bardziej użyteczne.&lt;/p&gt;
&lt;h2 id=&quot;postgresql-ktory-po-prostu-dziala&quot;&gt;PostgreSQL który po prostu działa&lt;/h2&gt;
&lt;p&gt;Dodanie bazy danych jest absurdalnie proste:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres create&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Wybierz konfigurację &quot;Development&quot; gdy zostaniesz zapytany. To daje ci instancję PostgreSQL z 256MB RAM i 1GB storage, idealną dla małych aplikacji. Baza działa w tym samym regionie co aplikacja dla minimalnej latencji.&lt;/p&gt;
&lt;p&gt;Połącz ją z aplikacją:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres attach &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;database-name&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To automatycznie ustawia zmienną środowiskową DATABASE_URL. Twoja aplikacja może się połączyć natychmiast:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Pool &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;pg&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pool &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;connectionString&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DATABASE_URL&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// To wszystko. Masz bazę danych.&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Prowadzę bloga z 500+ postami, system użytkowników z 1000+ kontami i dashboard analityczny śledzący 50k eventów - wszystko na darmowej bazie. Chyba że budujesz następnego Twittera, 1GB to mnóstwo.&lt;/p&gt;
&lt;h2 id=&quot;globalny-zasieg-bez-wysilku&quot;&gt;Globalny zasięg bez wysiłku&lt;/h2&gt;
&lt;p&gt;Wdróż w wielu regionach jednym poleceniem:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; lhr  &lt;span class=&quot;token comment&quot;&gt;# Londyn&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; nrt  &lt;span class=&quot;token comment&quot;&gt;# Tokio&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; syd  &lt;span class=&quot;token comment&quot;&gt;# Sydney&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fly.io automatycznie kieruje użytkowników do najbliższej instancji. Twoi europejscy użytkownicy trafiają do Londynu, azjatyccy do Tokio, i wszystko po prostu działa. Bez konfiguracji, bez setupu CDN, nic.&lt;/p&gt;
&lt;p&gt;Z trzema darmowymi maszynami możesz umieścić jedną w każdym regionie dla prawdziwie globalnego zasięgu. Albo trzymaj wszystkie trzy w jednym regionie dla redundancji - jeśli jedna padnie, pozostałe dalej obsługują żądania.&lt;/p&gt;
&lt;h2 id=&quot;haczyki-nie-ma-ich-wiele&quot;&gt;Haczyki (nie ma ich wiele)&lt;/h2&gt;
&lt;p&gt;Bądźmy szczerzy co do ograniczeń. Kredyt 5$ nie przenosi się z miesiąca na miesiąc. Użyj go albo stracisz. Ale szczerze mówiąc, prowadzenie trzech małych maszyn 24/7 i tak wykorzystuje pełny kredyt.&lt;/p&gt;
&lt;p&gt;W końcu będziesz musiał dodać kartę kredytową żeby odblokować pewne funkcje jak własne domeny i zapobiec przerwaniu usługi jeśli przekroczysz limit. Ale Fly.io wysyła emaile przed jakimkolwiek obciążeniem. Bez niespodziewanych rachunków na 500$ bo zapomniałeś wyłączyć testowy serwer.&lt;/p&gt;
&lt;p&gt;Limit 256MB RAM jest realny. Nie możesz po prostu wrzucić nieefektywnego kodu i oczekiwać cudów. Ale to ograniczenie zmusza cię do pisania lepszego kodu, a to nie jest zła rzecz.&lt;/p&gt;
&lt;h2 id=&quot;kiedy-uzywac-flyio-vs-reszty&quot;&gt;Kiedy używać Fly.io vs reszty&lt;/h2&gt;
&lt;p&gt;Używaj Fly.io gdy chcesz prawdziwych serwerów które nigdy nie śpią. Idealny dla API, webhooków, botów i wszystkiego co musi odpowiadać natychmiast. Wsparcie Docker oznacza że możesz uruchomić dowolny język lub framework.&lt;/p&gt;
&lt;p&gt;Używaj Vercel gdy budujesz strony Next.js i chcesz idealnego doświadczenia developerskiego. Ich preview deployments są niezrównane.&lt;/p&gt;
&lt;p&gt;Używaj Cloudflare Workers dla edge functions które muszą działać w 50+ lokalizacjach z zerowym cold startem.&lt;/p&gt;
&lt;p&gt;Używaj Railway gdy chcesz ładniejszego UI i nie przeszkadza ci płacenie od pierwszego dnia.&lt;/p&gt;
&lt;p&gt;Ale dla uruchomienia prawdziwej aplikacji online, za darmo, która działa cały czas? Fly.io wygrywa za każdym razem.&lt;/p&gt;
&lt;h2 id=&quot;twoja-kolej-na-deploy&quot;&gt;Twoja kolej na deploy&lt;/h2&gt;
&lt;p&gt;Przestań czytać i spróbuj. Serio, zajmuje 5 minut:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Zainstaluj CLI&lt;/li&gt;
&lt;li&gt;Utwórz prostą aplikację (albo użyj takiej którą już masz)&lt;/li&gt;
&lt;li&gt;Uruchom &lt;code class=&quot;language-text&quot;&gt;flyctl launch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Patrz jak aplikacja idzie live&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To wszystko. Bez złożonej konfiguracji, bez piekła yaml, bez niespodziewanych rachunków. Po prostu twój kod działający na prawdziwej infrastrukturze.&lt;/p&gt;
&lt;h2 id=&quot;zbuduj-cos-do-wdrozenia&quot;&gt;Zbuduj coś do wdrożenia&lt;/h2&gt;
&lt;p&gt;Gotowy wdrożyć pierwszą aplikację na Fly.io? Zacznij od budowania prawdziwego projektu z tymi praktycznymi tutorialami:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Zbuduj bloga z Flask&lt;/a&gt;&lt;/strong&gt; - Stwórz kompletnego bloga Flask idealnego do wdrożenia na Fly.io&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Zbuduj portfolio z Flask&lt;/a&gt;&lt;/strong&gt; - Naucz się podstaw Flask z wdrażalną stroną portfolio&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Zbuduj e-commerce z Flask&lt;/a&gt;&lt;/strong&gt; - Opanuj Flask z pełną aplikacją koszyka zakupowego&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Każdy tutorial zawiera konfigurację Docker i kroki wdrożenia, ułatwiając przeniesienie projektu z developmentu na produkcję na darmowym tierze Fly.io.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Masz już aplikację Flask?&lt;/strong&gt; Podążaj za naszym &lt;strong&gt;&lt;a href=&quot;/blog/dockerize-flask-blog/&quot;&gt;kompletnym tutorialem Docker i Fly.io&lt;/a&gt;&lt;/strong&gt; dla instrukcji krok po kroku konteneryzacji aplikacji Flask z PostgreSQL i wdrożenia na Fly.io z migracjami bez przestojów.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;szczegoly-techniczne&quot;&gt;Szczegóły techniczne&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Platforma:&lt;/strong&gt; Fly.io
&lt;strong&gt;Miesięczny kredyt:&lt;/strong&gt; 5$ (pokrywa 3 maszyny + bazę danych)
&lt;strong&gt;Wdrożenie:&lt;/strong&gt; Kontenery Docker jako mikroVM
&lt;strong&gt;Regiony:&lt;/strong&gt; 30+ na świecie
&lt;strong&gt;RAM na maszynę:&lt;/strong&gt; 256MB (możliwość upgradu)
&lt;strong&gt;Baza danych:&lt;/strong&gt; PostgreSQL z 1GB storage
&lt;strong&gt;Transfer:&lt;/strong&gt; 160GB/miesiąc wliczone&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Uwaga: Będziesz potrzebować karty kredytowej po początkowym testowaniu, ale nie zostaniesz obciążony jeśli użycie zostanie poniżej 5$/miesiąc.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Pierwsze kroki z Vercel: Wdroz pierwszy projekt w 5 minut]]></title><description><![CDATA[Kompletny przewodnik dla poczatkujacych po Vercel. Dowiedz sie czym jest Vercel, jak dziala i wdroz pierwszy projekt w kilka minut. Obejmuje limity darmowego tieru, automatyczne wdrozenia, wlasne domeny i kiedy uzywac Vercel vs innych platform.]]></description><link>https://vibecodingwithfred.com/pl/blog/getting-started-vercel/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pl/blog/getting-started-vercel/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Vercel to jeden z najlatwiejszych sposobow na wdrazanie stron i aplikacji webowych do internetu. W tym przewodniku dowiesz sie czym jest Vercel, jak dziala i wdrozysz pierwszy projekt - wszystko w okolo 5 minut.&lt;/p&gt;
&lt;h2 id=&quot;czym-jest-vercel&quot;&gt;Czym jest Vercel?&lt;/h2&gt;
&lt;p&gt;Vercel to &lt;strong&gt;platforma chmurowa do wdrazania stron i aplikacji webowych&lt;/strong&gt;. Zrobiony przez zespol za Next.js, skupia sie na szybkich i bezproblemowych wdrozeniach.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pomysl o Vercel jako:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Miejsce do hostowania strony (jak wynajmujacy dla twojego kodu)&lt;/li&gt;
&lt;li&gt;System budowania ktory zamienia kod w dzialajaca strone&lt;/li&gt;
&lt;li&gt;Globalny CDN ktory sprawia ze strona jest szybka wszedzie na swiecie&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Co sprawia ze Vercel jest wyjatkowy:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Zero konfiguracji&lt;/strong&gt;: Po prostu polacz repo Git i wdrazaj&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automatyczne wdrozenia&lt;/strong&gt;: Pushuj kod na Git, Vercel przebudowuje automatycznie&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Globalna siec edge&lt;/strong&gt;: Strona laduje szybko z 70+ lokalizacji na swiecie&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Darmowy tier&lt;/strong&gt;: Hojne limity dla projektow osobistych i malych&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;darmowy-tier-vercel-co-jest-wliczone&quot;&gt;Darmowy tier Vercel: Co jest wliczone?&lt;/h2&gt;
&lt;p&gt;Darmowy plan &quot;Hobby&quot; obejmuje:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Zasob&lt;/th&gt;
&lt;th&gt;Limit darmowego tieru&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Transfer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;100GB/miesiac&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Czas budowania&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;6000 minut/miesiac&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Funkcje serverless&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;100GB-godzin/miesiac&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Funkcje Edge&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;500,000 wywolan/miesiac&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Projekty&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bez limitu&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Wdrozenia&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bez limitu&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Wlasne domeny&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bez limitu (z darmowym SSL)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;To wystarczy dla:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Projektow osobistych&lt;/li&gt;
&lt;li&gt;Stron portfolio&lt;/li&gt;
&lt;li&gt;Projektow pobocznych&lt;/li&gt;
&lt;li&gt;Malych stron biznesowych&lt;/li&gt;
&lt;li&gt;Wiekszosci hobbystycznych projektow&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;twoje-pierwsze-wdrozenie-krok-po-kroku&quot;&gt;Twoje pierwsze wdrozenie: Krok po kroku&lt;/h2&gt;
&lt;h3 id=&quot;wymagania&quot;&gt;Wymagania&lt;/h3&gt;
&lt;p&gt;Potrzebujesz:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Konto GitHub (darmowe)&lt;/li&gt;
&lt;li&gt;Konto Vercel (darmowe - utworzysz w kroku 2)&lt;/li&gt;
&lt;li&gt;Projekt do wdrozenia (kod w repozytorium Git)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;krok-1-wyslij-kod-na-github&quot;&gt;Krok 1: Wyslij kod na GitHub&lt;/h3&gt;
&lt;p&gt;Jesli projekt nie jest jeszcze na GitHub:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Zainicjalizuj Git (jesli jeszcze nie zrobione)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init

&lt;span class=&quot;token comment&quot;&gt;# Dodaj wszystkie pliki&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Commit&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial commit&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Utworz repo na GitHub, potem:&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; origin https://github.com/TWOJ-USERNAME/NAZWA-REPO.git
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch &lt;span class=&quot;token parameter variable&quot;&gt;-M&lt;/span&gt; main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;krok-2-zarejestruj-sie-w-vercel&quot;&gt;Krok 2: Zarejestruj sie w Vercel&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Wejdz na &lt;a href=&quot;https://vercel.com/signup&quot;&gt;vercel.com/signup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Kliknij &lt;strong&gt;&quot;Continue with GitHub&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Autoryzuj Vercel do dostepu do konta GitHub&lt;/li&gt;
&lt;li&gt;Uzupelnij profil&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;krok-3-importuj-projekt&quot;&gt;Krok 3: Importuj projekt&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Kliknij &lt;strong&gt;&quot;Add New...&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Wybierz &lt;strong&gt;&quot;Project&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Zobaczysz liste repozytoriow GitHub&lt;/li&gt;
&lt;li&gt;Znajdz projekt i kliknij &lt;strong&gt;&quot;Import&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;krok-4-skonfiguruj-ustawienia-projektu&quot;&gt;Krok 4: Skonfiguruj ustawienia projektu&lt;/h3&gt;
&lt;p&gt;Vercel automatycznie wykrywa framework. Dla aplikacji Vite React:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Framework Preset&lt;/strong&gt;: Vite (wykryty automatycznie)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Build Command&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Output Directory&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;krok-5-wdroz&quot;&gt;Krok 5: Wdroz&lt;/h3&gt;
&lt;p&gt;Kliknij &lt;strong&gt;&quot;Deploy&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Vercel:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Sklonuje repozytorium&lt;/li&gt;
&lt;li&gt;Zainstaluje zaleznosci&lt;/li&gt;
&lt;li&gt;Uruchomi polecenie build&lt;/li&gt;
&lt;li&gt;Wdrozy na siec edge&lt;/li&gt;
&lt;li&gt;Da ci URL na zywo&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Gratulacje!&lt;/strong&gt; Wlasnie wdrozyles pierwszy projekt na Vercel.&lt;/p&gt;
&lt;h2 id=&quot;wprowadzanie-aktualizacji&quot;&gt;Wprowadzanie aktualizacji&lt;/h2&gt;
&lt;p&gt;Teraz wprowadzmy zmiane i zobaczmy automatyczne wdrozenie w akcji:&lt;/p&gt;
&lt;h3 id=&quot;edytuj-kod-lokalnie&quot;&gt;Edytuj kod lokalnie&lt;/h3&gt;
&lt;h3 id=&quot;wyslij-na-git&quot;&gt;Wyslij na Git&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Update homepage message&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push origin main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;vercel-automatycznie-przebudowuje&quot;&gt;Vercel automatycznie przebudowuje&lt;/h3&gt;
&lt;p&gt;W ciagu sekund Vercel:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Wykrywa push&lt;/li&gt;
&lt;li&gt;Rozpoczyna nowy build&lt;/li&gt;
&lt;li&gt;Wdraza zaktualizowana strone&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Nie potrzeba recznej akcji.&lt;/strong&gt; Odwiedz dashboard zeby obserwowac wdrozenie.&lt;/p&gt;
&lt;h2 id=&quot;dodawanie-wlasnej-domeny&quot;&gt;Dodawanie wlasnej domeny&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;W projekcie Vercel wejdz do &lt;strong&gt;Settings&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Kliknij &lt;strong&gt;Domains&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Wpisz domene (np. &lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Kliknij &lt;strong&gt;Add&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Vercel pokaze ci rekordy DNS do dodania:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dla domeny apex&lt;/strong&gt; (&lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Type: A
Name: @
Value: 76.76.21.21&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Dla subdomeny www&lt;/strong&gt; (&lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Type: CNAME
Name: www
Value: cname.vercel-dns.com&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Po propagacji DNS Vercel automatycznie generuje certyfikat SSL.&lt;/p&gt;
&lt;h2 id=&quot;kiedy-uzywac-vercel-vs-innych-platform&quot;&gt;Kiedy uzywac Vercel vs innych platform&lt;/h2&gt;
&lt;h3 id=&quot;uzywaj-vercel-gdy&quot;&gt;Uzywaj Vercel gdy:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Budujesz aplikacje frontendowa (React, Vue, Svelte, itp.)&lt;/li&gt;
&lt;li&gt;Chcesz automatycznych wdrozen z Git&lt;/li&gt;
&lt;li&gt;Cenisz doswiadczenie programisty i szybkosc&lt;/li&gt;
&lt;li&gt;Uzywasz Next.js (Vercel jest do tego stworzony)&lt;/li&gt;
&lt;li&gt;Potrzebujesz funkcji serverless dla API&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;uzywaj-cloudflare-workers-gdy&quot;&gt;Uzywaj Cloudflare Workers gdy:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Chcesz nieograniczonego transferu i wiekszej kontroli&lt;/li&gt;
&lt;li&gt;Masz bardzo duzy ruch (Vercel ogranicza do 100GB darmowo)&lt;/li&gt;
&lt;li&gt;Wolisz najszybsza globalna wydajnosc (300+ regionow)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;uzywaj-flyio-gdy&quot;&gt;Uzywaj Fly.io gdy:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Potrzebujesz prawdziwych kontenerow Docker dzialajacych 24/7&lt;/li&gt;
&lt;li&gt;Wdrazasz tradycyjne serwery backendowe (Flask, Express, Rails)&lt;/li&gt;
&lt;li&gt;Chcesz pelnej kontroli nad srodowiskiem uruchomieniowym&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;podsumowanie&quot;&gt;Podsumowanie&lt;/h2&gt;
&lt;p&gt;Vercel sprawia ze wdrazanie aplikacji webowych jest bezproblemowe:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Wyslij kod na Git&lt;/li&gt;
&lt;li&gt;Vercel buduje i wdraza automatycznie&lt;/li&gt;
&lt;li&gt;Strona jest dostepna globalnie w sekundy&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Darmowy tier jest wystarczajacy dla wiekszosci osobistych projektow, a doswiadczenie programisty jest doskonale.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sprobuj sam&lt;/strong&gt;: Wdroz pierwszy projekt juz dzis i zobacz dlaczego programisci kochaja Vercel.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Por Que Fly.io e a Melhor Hospedagem Docker Gratuita que Voce Nao Esta Usando]]></title><description><![CDATA[Fly.io te da $5 de hospedagem todo mes, para sempre. Isso sao 3 containers Docker, um banco PostgreSQL e 160GB de bandwidth. Eis por que e perfeito para projetos paralelos.]]></description><link>https://vibecodingwithfred.com/pt/blog/flyio-free-tier-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pt/blog/flyio-free-tier-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Plataforma:&lt;/strong&gt; Fly.io | &lt;strong&gt;Provedor:&lt;/strong&gt; Fly.io | &lt;strong&gt;Nivel Gratuito:&lt;/strong&gt; $5/mes de credito para sempre&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;o-segredo-que-ninguem-fala&quot;&gt;O Segredo Que Ninguem Fala&lt;/h2&gt;
&lt;p&gt;Aqui esta o que torna o Fly.io especial: eles te dao $5 de credito gratuito todo mes, para sempre. Nao e um trial, nao e uma oferta por tempo limitado—hospedagem permanente gratuita para seus containers Docker. Se seu uso ficar abaixo de $5 (spoiler: vai ficar para a maioria dos projetos), voce nao paga nada.&lt;/p&gt;
&lt;p&gt;Ainda melhor? Diferente de toda outra plataforma que afirma ser &quot;gratuita,&quot; o Fly.io roda seus containers Docker como VMs reais. Isso nao e serverless onde seu app dorme apos 5 minutos. Seus containers ficam rodando 24/7, respondendo instantaneamente a requisicoes.&lt;/p&gt;
&lt;p&gt;Estou rodando tres APIs em producao no Fly.io ha mais de um ano. Custo total? Zero reais. Aqui esta exatamente como fazer.&lt;/p&gt;
&lt;h2 id=&quot;o-que-voce-ganha-de-graca&quot;&gt;O Que Voce Ganha de Graca&lt;/h2&gt;
&lt;p&gt;Aquele credito mensal de $5 se traduz em infraestrutura seria:&lt;/p&gt;
&lt;p&gt;Voce ganha tres VMs com 256MB de RAM cada, rodando em qualquer lugar do mundo. Adicione um banco PostgreSQL com 1GB de armazenamento. Inclua 160GB de bandwidth de saida. Tudo isso cabe confortavelmente no seu credito gratuito, com espaco de sobra.&lt;/p&gt;
&lt;p&gt;A matematica e simples: uma unica VM de 256MB custa cerca de $1.94/mes. Tres delas mais um banco pequeno fica em torno de $5. Enquanto voce ficar dentro desses limites, o credito mensal do Fly.io cobre tudo.&lt;/p&gt;
&lt;h2 id=&quot;comecar-leva-5-minutos&quot;&gt;Comecar Leva 5 Minutos&lt;/h2&gt;
&lt;p&gt;Primeiro, instale a CLI do Fly. No Mac, e um unico comando brew. No Linux, curl o script de instalacao. Windows tem PowerShell. Tudo leva 30 segundos.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# macOS&lt;/span&gt;
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flyctl

&lt;span class=&quot;token comment&quot;&gt;# Linux&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Windows&lt;/span&gt;
pwsh &lt;span class=&quot;token parameter variable&quot;&gt;-Command&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iwr https://fly.io/install.ps1 -useb | iex&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Cadastre-se apenas com um email—eles vao pedir um cartao eventualmente, mas voce pode fazer deploy dos seus primeiros apps sem um:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl auth signup&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;seu-primeiro-deploy-e-ridiculamente-facil&quot;&gt;Seu Primeiro Deploy (E Ridiculamente Facil)&lt;/h2&gt;
&lt;p&gt;Aqui e onde o Fly.io brilha. Tem um Dockerfile? Otimo, vai funcionar. Nao tem um? O Fly.io vai descobrir. Estou falando serio—ele detecta seu framework e gera tudo automaticamente.&lt;/p&gt;
&lt;p&gt;Deixe eu mostrar um exemplo real. Aqui esta uma API Node.js que fiz deploy semana passada:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// index.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; express &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; port &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Esta API roda 24/7 de graca&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toISOString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/health&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;healthy&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;0.0.0.0&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Rodando na porta &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;port&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Para fazer deploy disso, eu literalmente so rodei:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl launch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So isso. O Fly detectou Node.js, criou um Dockerfile, fez build da imagem e deployou globalmente. Todo o processo levou cerca de 2 minutos. Minha API estava no ar em uma URL *.fly.dev, com HTTPS automatico, respondendo a requisicoes do data center mais proximo.&lt;/p&gt;
&lt;h2 id=&quot;a-vantagem-docker-que-ninguem-menciona&quot;&gt;A Vantagem Docker Que Ninguem Menciona&lt;/h2&gt;
&lt;p&gt;Aqui esta o que diferencia o Fly.io da Vercel, Netlify e o resto: voce esta fazendo deploy de containers Docker reais. Isso significa que voce pode rodar literalmente qualquer coisa—scripts Python, binarios Go, servidores Rust, aplicacoes PHP, Ruby on Rails, o que quiser.&lt;/p&gt;
&lt;p&gt;Tenho uma API Python Flask que processa webhooks, um bot Node.js que roda tarefas agendadas e um servico Go que faz redimensionamento de imagens. Tudo rodando no nivel gratuito. Tente fazer isso no plano hobby da Vercel.&lt;/p&gt;
&lt;p&gt;Seus containers rodam como microVMs Firecracker, a mesma tecnologia que a Amazon usa para Lambda. Eles iniciam em milissegundos mas agem como servidores reais. Sem cold starts, sem timeouts de 10 segundos, sem limitacoes serverless. Apenas seu codigo rodando exatamente como voce espera.&lt;/p&gt;
&lt;h2 id=&quot;fazendo-256mb-funcionar-e-mais-facil-do-que-voce-pensa&quot;&gt;Fazendo 256MB Funcionar (E Mais Facil do Que Voce Pensa)&lt;/h2&gt;
&lt;p&gt;O nivel gratuito te da 256MB de RAM por VM. Eu sei o que voce esta pensando—isso e nada! Mas voce ficaria surpreso. Uma API Express.js leve usa cerca de 50MB. Um app Flask com alguns endpoints fica em torno de 80MB. Ate um app Rails pequeno pode caber em 200MB se voce for cuidadoso.&lt;/p&gt;
&lt;p&gt;Aqui esta o que roda bem em 256MB:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Backends de API (REST ou GraphQL)&lt;/li&gt;
&lt;li&gt;Processadores de webhook&lt;/li&gt;
&lt;li&gt;Runners de tarefas agendadas&lt;/li&gt;
&lt;li&gt;Sites estaticos com recursos dinamicos&lt;/li&gt;
&lt;li&gt;Bots do Discord/Slack&lt;/li&gt;
&lt;li&gt;Bancos de dados pequenos com SQLite&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;E aqui esta o que nao roda:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Next.js (precisa de pelo menos 512MB)&lt;/li&gt;
&lt;li&gt;Aplicacoes Django grandes&lt;/li&gt;
&lt;li&gt;Apps Java Spring Boot&lt;/li&gt;
&lt;li&gt;Qualquer coisa carregando datasets grandes em memoria&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Se voce bater nos limites de memoria, tem duas opcoes. Primeiro, otimize seu codigo—streame arquivos em vez de carrega-los em memoria, use paginacao para queries de banco, faca lazy-load de dependencias. A maioria dos &quot;problemas de memoria&quot; e apenas codigo ineficiente.&lt;/p&gt;
&lt;p&gt;Segunda opcao: escale para 512MB. Isso te coloca um pouco acima do nivel gratuito, custando talvez $2-3/mes. Ainda mais barato que um cafe, e muito mais util.&lt;/p&gt;
&lt;h2 id=&quot;postgresql-que-simplesmente-funciona&quot;&gt;PostgreSQL Que Simplesmente Funciona&lt;/h2&gt;
&lt;p&gt;Adicionar um banco e estupidamente simples:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres create&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Escolha configuracao &quot;Development&quot; quando perguntado. Isso te da uma instancia PostgreSQL com 256MB de RAM e 1GB de armazenamento, perfeita para apps pequenos. O banco roda na mesma regiao que seu app para latencia minima.&lt;/p&gt;
&lt;p&gt;Conecte ao seu app:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres attach &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;nome-do-banco&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Isso automaticamente configura uma variavel de ambiente DATABASE_URL. Seu app pode conectar imediatamente:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Pool &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;pg&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pool &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;connectionString&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DATABASE_URL&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Pronto. Voce tem um banco de dados.&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Estou rodando um blog com 500+ posts, um sistema de usuarios com 1000+ contas e um dashboard de analytics rastreando 50k eventos—tudo no banco de dados do nivel gratuito. A menos que voce esteja construindo o proximo Twitter, 1GB e bastante.&lt;/p&gt;
&lt;h2 id=&quot;globalizando-sem-esforco&quot;&gt;Globalizando Sem Esforco&lt;/h2&gt;
&lt;p&gt;Faca deploy para multiplas regioes com um comando:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; lhr  &lt;span class=&quot;token comment&quot;&gt;# Londres&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; nrt  &lt;span class=&quot;token comment&quot;&gt;# Toquio&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; syd  &lt;span class=&quot;token comment&quot;&gt;# Sydney&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;O Fly.io automaticamente roteia usuarios para a instancia mais proxima. Seus usuarios europeus vao para Londres, usuarios asiaticos vao para Toquio, e tudo simplesmente funciona. Sem configuracao, sem setup de CDN, sem nada.&lt;/p&gt;
&lt;p&gt;Com tres VMs gratuitas, voce pode colocar uma em cada regiao para cobertura verdadeiramente global. Ou mantenha todas tres em uma regiao para redundancia—se uma crashar, as outras continuam servindo requisicoes.&lt;/p&gt;
&lt;h2 id=&quot;as-armadilhas-nao-ha-muitas&quot;&gt;As Armadilhas (Nao Ha Muitas)&lt;/h2&gt;
&lt;p&gt;Vamos ser realistas sobre as limitacoes. O credito de $5 nao acumula mes a mes. Use ou perca. Mas honestamente, rodar tres VMs pequenas 24/7 usa o credito inteiro de qualquer forma.&lt;/p&gt;
&lt;p&gt;Voce vai eventualmente precisar adicionar um cartao de credito para desbloquear certos recursos como dominios customizados e para prevenir interrupcao de servico se voce passar do limite. Mas aqui esta a coisa—o Fly.io te envia email antes de cobrar qualquer coisa. Sem contas surpresa de $500 porque voce esqueceu de desligar um servidor de teste.&lt;/p&gt;
&lt;p&gt;O limite de 256MB de RAM e real. Voce nao pode simplesmente jogar codigo ineficiente nele e esperar milagres. Mas essa restricao te forca a escrever codigo melhor, e isso nao e uma coisa ruim.&lt;/p&gt;
&lt;h2 id=&quot;quando-usar-flyio-vs-todo-o-resto&quot;&gt;Quando Usar Fly.io vs Todo o Resto&lt;/h2&gt;
&lt;p&gt;Use Fly.io quando voce quer servidores reais que nunca dormem. Perfeito para APIs, webhooks, bots e qualquer coisa que precisa responder instantaneamente. O suporte a Docker significa que voce pode rodar qualquer linguagem ou framework.&lt;/p&gt;
&lt;p&gt;Use Vercel quando voce esta construindo sites Next.js e quer aquela experiencia de desenvolvedor perfeita. Os preview deployments deles sao inigualáveis.&lt;/p&gt;
&lt;p&gt;Use Cloudflare Workers para funcoes edge que precisam rodar em 50+ locais com zero cold starts.&lt;/p&gt;
&lt;p&gt;Use Railway quando voce quer uma UI mais bonita e nao se importa em pagar desde o primeiro dia.&lt;/p&gt;
&lt;p&gt;Mas para colocar um app real online, de graca, que fica rodando? Fly.io ganha toda vez.&lt;/p&gt;
&lt;h2 id=&quot;sua-vez-de-fazer-deploy&quot;&gt;Sua Vez de Fazer Deploy&lt;/h2&gt;
&lt;p&gt;Pare de ler e experimente. Serio, leva 5 minutos:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Instale a CLI&lt;/li&gt;
&lt;li&gt;Crie um app simples (ou use um que voce ja tem)&lt;/li&gt;
&lt;li&gt;Rode &lt;code class=&quot;language-text&quot;&gt;flyctl launch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Veja seu app ir pro ar&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So isso. Sem configuracao complexa, sem inferno de yaml, sem surpresas de cobranca. Apenas seu codigo rodando em infraestrutura real.&lt;/p&gt;
&lt;h2 id=&quot;construa-algo-para-fazer-deploy&quot;&gt;Construa Algo para Fazer Deploy&lt;/h2&gt;
&lt;p&gt;Pronto para fazer deploy do seu primeiro app no Fly.io? Comece construindo um projeto real com esses tutoriais praticos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Construa um Blog com Flask&lt;/a&gt;&lt;/strong&gt; - Crie um blog Flask completo perfeito para deploy no Fly.io&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Construa um Portfolio com Flask&lt;/a&gt;&lt;/strong&gt; - Aprenda fundamentos do Flask com um site de portfolio deployavel&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Construa E-Commerce com Flask&lt;/a&gt;&lt;/strong&gt; - Domine Flask com uma aplicacao de carrinho de compras completa&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cada tutorial inclui configuracao Docker e passos de deployment, facilitando levar seu projeto do desenvolvimento para producao no nivel gratuito do Fly.io.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ja tem um app Flask?&lt;/strong&gt; Siga nosso &lt;strong&gt;&lt;a href=&quot;/blog/dockerize-flask-blog/&quot;&gt;tutorial completo de Docker e deploy no Fly.io&lt;/a&gt;&lt;/strong&gt; para instrucoes passo a passo sobre como containerizar sua aplicacao Flask com PostgreSQL e fazer deploy no Fly.io com migrations sem downtime.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;detalhes-tecnicos&quot;&gt;Detalhes Tecnicos&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Plataforma:&lt;/strong&gt; Fly.io
&lt;strong&gt;Credito Mensal:&lt;/strong&gt; $5 (cobre 3 VMs + banco de dados)
&lt;strong&gt;Deploy:&lt;/strong&gt; Containers Docker como microVMs
&lt;strong&gt;Regioes:&lt;/strong&gt; 30+ mundialmente
&lt;strong&gt;RAM por VM:&lt;/strong&gt; 256MB (upgradeable)
&lt;strong&gt;Banco de Dados:&lt;/strong&gt; PostgreSQL com 1GB de armazenamento
&lt;strong&gt;Bandwidth:&lt;/strong&gt; 160GB/mes incluido&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Nota: Voce vai precisar de um cartao de credito apos os testes iniciais, mas nao sera cobrado se ficar abaixo de $5/mes de uso.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Codex CLI：真正的 GPT-5 编码指南（附 Cursor 的秘密提示词）]]></title><description><![CDATA[泄露：Cursor 如何用 GPT-5 在 Tau-Bench 上达到 78.2% 的准确率。另外，让模型写出比大多数开发者更好的代码的确切提示词。]]></description><link>https://vibecodingwithfred.com/zh/blog/codex-cli-ultimate-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/zh/blog/codex-cli-ultimate-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;平台：&lt;/strong&gt; Codex CLI | &lt;strong&gt;提供商：&lt;/strong&gt; OpenAI | &lt;strong&gt;模型：&lt;/strong&gt; GPT-5 with Responses API&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;没人告诉你的数据&quot;&gt;没人告诉你的数据&lt;/h2&gt;
&lt;p&gt;以下是 OpenAI 内部测试揭示的关于 GPT-5 的内容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;**Tau-Bench 零售分数：**仅通过使用 Responses API 就从 73.9% 跃升至 78.2%&lt;/li&gt;
&lt;li&gt;**SWE-Bench 性能：**在真实世界编码任务中击败所有前沿模型&lt;/li&gt;
&lt;li&gt;**工具调用效率：**通过适当的提示词，减少 50% 的不必要调用&lt;/li&gt;
&lt;li&gt;**上下文窗口利用：**处理大型代码库而不会丢失跟踪&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cursor 团队花了几个月时间为 GPT-5 调整他们的提示词。他们发现写得不好的提示词可能导致性能下降 40%。以下是确切有效的内容。&lt;/p&gt;
&lt;h2 id=&quot;正确入门&quot;&gt;正确入门&lt;/h2&gt;
&lt;p&gt;安装 Codex CLI：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 通过 npm 安装（推荐）&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; @openai/codex-cli

&lt;span class=&quot;token comment&quot;&gt;# 或使用直接安装程序&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# curl -fsSL https://cli.openai.com/install.sh | sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 使用 ChatGPT 账户认证&lt;/span&gt;
codex login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;但这是关键部分：立即配置你的推理强度：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 对于复杂的多文件重构&lt;/span&gt;
codex --reasoning-effort high

&lt;span class=&quot;token comment&quot;&gt;# 对于快速修复和简单任务&lt;/span&gt;
codex --reasoning-effort minimal

&lt;span class=&quot;token comment&quot;&gt;# 默认（适合大多数编码）&lt;/span&gt;
codex --reasoning-effort medium&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;cursor-的生产提示词实际在他们的编辑器中使用&quot;&gt;Cursor 的生产提示词（实际在他们的编辑器中使用）&lt;/h2&gt;
&lt;p&gt;Cursor 团队发现 GPT-5 最初太啰嗦了。他们的修复方法？全局将详细程度设置为低，然后为代码覆盖：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;首先为清晰度编写代码。优先选择可读、可维护的解决方案，
具有清晰的名称、需要时的注释和直接的控制流。
除非明确要求，否则不要产生代码高尔夫或过于聪明的单行代码。
为编写代码和代码工具使用高详细程度。&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这个单一的提示词更改使他们的代码可读性提高了 3 倍，同时保持状态消息简洁。&lt;/p&gt;
&lt;h2 id=&quot;改变一切的上下文收集模式&quot;&gt;改变一切的上下文收集模式&lt;/h2&gt;
&lt;p&gt;GPT-5 的默认行为是彻底的——有时太彻底了。以下是将延迟减少 60% 同时保持准确性的确切提示词：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;context_gathering&gt;
目标：快速获取足够的上下文。并行化发现并在可以行动时立即停止。

方法：
- 从广泛开始，然后扩展到聚焦的子查询
- 并行启动多种查询；读取每个查询的顶部命中
- 避免过度搜索上下文

早期停止标准：
- 你可以命名要更改的确切内容
- 顶部命中（约 70%）收敛到一个区域/路径

深度：
- 只追踪你将修改的符号或你依赖的契约
- 除非必要，否则避免传递扩展

搜索深度：在继续之前最多 2 次工具调用
&amp;lt;/context_gathering&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;结果？GPT-5 停止在无关搜索上浪费时间，更快地开始编码。&lt;/p&gt;
&lt;h2 id=&quot;工具前言为什么你的代理感觉很笨&quot;&gt;工具前言：为什么你的代理感觉很笨&lt;/h2&gt;
&lt;p&gt;有没有想过为什么 AI 编码助手似乎会丢失他们正在做什么的跟踪？这是因为他们没有解释他们的计划。GPT-5 被训练为提供&quot;工具前言&quot;——前期计划，大大提高成功率。&lt;/p&gt;
&lt;p&gt;用以下方式启用它们：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;tool_preambles&gt;
- 始终以清晰、简洁的方式重新表述用户的目标开始
- 立即概述详细每个逻辑步骤的结构化计划
- 在执行时，简洁地叙述每个步骤，标记进度
- 通过总结已完成的工作来结束，与前期计划明显区分
&amp;lt;/tool_preambles&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;仅这一项更改就在 Cursor 的测试中将用户满意度分数提高了 35%。&lt;/p&gt;
&lt;h2 id=&quot;gpt-5-最了解的前端技术栈&quot;&gt;GPT-5 最了解的前端技术栈&lt;/h2&gt;
&lt;p&gt;OpenAI 用特定框架训练了 GPT-5。使用这些可以开箱即用地获得 40% 更好的代码质量：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最佳技术栈：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;框架：Next.js (TypeScript)、React、HTML&lt;/li&gt;
&lt;li&gt;样式：Tailwind CSS、shadcn/ui、Radix Themes&lt;/li&gt;
&lt;li&gt;图标：Material Symbols、Heroicons、Lucide&lt;/li&gt;
&lt;li&gt;动画：Motion&lt;/li&gt;
&lt;li&gt;字体：Sans Serif、Inter、Geist&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不要与之对抗。GPT-5 写出漂亮的 Tailwind 组件，但在它没见过的自定义 CSS 框架上会挣扎。&lt;/p&gt;
&lt;h2 id=&quot;编写完美应用的自我反思提示词&quot;&gt;编写完美应用的自我反思提示词&lt;/h2&gt;
&lt;p&gt;GPT-5 可以一次性构建整个应用程序——如果你正确提示它。这种模式始终如一地产生生产质量的代码：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;self_reflection&gt;
- 首先，花时间思考评分标准直到你有信心
- 深入思考世界级一次性 web 应用的每个方面
- 创建一个包含 5-7 个类别的评分标准（不要向用户展示这个）
- 使用评分标准在内部迭代最佳可能的解决方案
- 如果响应在所有类别中没有达到最高分，重新开始
&amp;lt;/self_reflection&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;用户报告仅此提示词就将新项目的代码质量提高了 50%。&lt;/p&gt;
&lt;h2 id=&quot;持久性问题和解决方案&quot;&gt;持久性问题（和解决方案）&lt;/h2&gt;
&lt;p&gt;GPT-5 有时过早放弃或问不必要的澄清问题。Cursor 通过积极的持久性提示来解决这个问题：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;persistence&gt;
- 你是一个代理——继续直到查询完全解决
- 只有在你确定问题已解决时才终止
- 永远不要在不确定时停止——研究或推断最合理的方法
- 不要要求人类确认假设——记录它们并继续
- 安全操作（搜索、读取）：澄清的阈值极高
- 风险操作（删除、支付）：用户确认的阈值较低
&amp;lt;/persistence&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这在生产中减少了 80% 的&quot;交还&quot;事件。&lt;/p&gt;
&lt;h2 id=&quot;有效的真实生产示例&quot;&gt;有效的真实生产示例&lt;/h2&gt;
&lt;h3 id=&quot;认证系统在生产中测试&quot;&gt;认证系统（在生产中测试）&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;创建一个完整的 JWT 认证系统，包括：
- 使用 nodemailer 的邮件验证用户注册
- 基于 Redis 的速率限制登录（每 15 分钟 5 次尝试）
- 通过时间限制令牌的密码重置（15 分钟过期）
- 带家族检测的刷新令牌轮换
- PostgreSQL 模式：users、sessions、refresh_tokens 表
- 检查访问令牌和刷新令牌的 Express 中间件
- 正确的 HTTP 状态码（401 表示过期，403 表示无效）
- 时间安全的密码比较以防止时序攻击&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;实时功能目前大规模运行&quot;&gt;实时功能（目前大规模运行）&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;构建一个 WebSocket 通知系统，包括：
- 带 Redis 适配器的 Socket.io 用于水平扩展
- 基于房间的广播与用户在线跟踪
- 离线用户的消息队列（Redis 有序集合）
- 带错过消息重放的重连
- 客户端指数退避（1s、2s、4s、8s、16s 上限）
- 服务器端每个 socket 的速率限制（100 消息/分钟）
- 优雅关闭保留连接状态&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;成本现实&quot;&gt;成本现实&lt;/h2&gt;
&lt;p&gt;以下是 Codex/GPT-5 在生产中的实际成本：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;订阅模式：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT Plus（20 美元/月）：80% 的开发者永远不需要更多&lt;/li&gt;
&lt;li&gt;ChatGPT Pro（200 美元/月）：如果你每天编码 4+ 小时值得&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;API 定价（实际使用）：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;简单 CRUD 端点：0.02-0.05 美元&lt;/li&gt;
&lt;li&gt;完整认证系统：0.15-0.25 美元&lt;/li&gt;
&lt;li&gt;复杂重构（1000+ 行）：0.50-1.00 美元&lt;/li&gt;
&lt;li&gt;从头开始完整应用：2.00-5.00 美元&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;每天使用的普通开发者：约 30-50 美元/月的 API 成本。&lt;/p&gt;
&lt;h2 id=&quot;最小推理秘密&quot;&gt;最小推理秘密&lt;/h2&gt;
&lt;p&gt;对于延迟敏感的应用程序，GPT-5 的最小推理模式是改变游戏规则的。但它需要不同的提示：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# 对于最小推理，要明确关于规划
记住，你是一个代理——继续直到完全解决。
将查询分解为所有必需的子请求并确认每个完成。
在函数调用之前广泛计划，反思结果。

# 关键：给它一个不确定时的&quot;出路&quot;
强烈倾向于快速提供正确答案，
即使它可能不完全正确。&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这种模式快 3 倍，同时保持 85% 的准确性。&lt;/p&gt;
&lt;h2 id=&quot;cursor-在-100-万次-gpt-5-查询后学到的&quot;&gt;Cursor 在 100 万次 GPT-5 查询后学到的&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;矛盾的提示词会杀死性能&lt;/strong&gt; - 一条冲突的指令可能导致 40% 的退化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XML 标签比 markdown 更好&lt;/strong&gt; - &lt;code class=&quot;language-text&quot;&gt;&amp;lt;instruction&gt;&lt;/code&gt; 每次都胜过 &lt;code class=&quot;language-text&quot;&gt;## Instruction&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;详细程度参数 + 提示词覆盖&lt;/strong&gt; - 全局设置低，代码特定设置高&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具预算约束有效&lt;/strong&gt; - &quot;最多 2 次工具调用&quot;强制效率&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apply_patch 胜过直接编辑&lt;/strong&gt; - 他们的自定义 diff 格式减少了 60% 的错误&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;没人使用的隐藏功能&quot;&gt;没人使用的隐藏功能&lt;/h2&gt;
&lt;p&gt;**Responses API：**在工具调用之间保持推理。仅此一项就将多步骤任务提高了 25%。&lt;/p&gt;
&lt;p&gt;**推理强度缩放：**大多数人从不改变中等设置。高强度用于复杂重构，最小强度用于简单修复。&lt;/p&gt;
&lt;p&gt;**并行工具调用：**GPT-5 可以同时运行多个搜索。明确请求这个以获得 2 倍速度。&lt;/p&gt;
&lt;h2 id=&quot;今天开始使用这些模式&quot;&gt;今天开始使用这些模式&lt;/h2&gt;
&lt;p&gt;停止写模糊的提示词。从这些经过测试的模式开始：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;始终包含停止条件：&lt;/strong&gt;&quot;只有当 X 完成时才终止&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;指定工具调用预算：&lt;/strong&gt;&quot;在继续之前最多 2 次搜索&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定义输出契约：&lt;/strong&gt;&quot;必须返回：修改的文件、测试结果、错误处理&quot;&lt;/li&gt;
&lt;li&gt;**明确使用框架名称：**GPT-5 深入了解 Next.js，对随机框架了解较少&lt;/li&gt;
&lt;li&gt;**启用前言：**让模型在行动前解释其计划&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;相关资源&quot;&gt;相关资源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/claude-code-cli-guide/&quot;&gt;Claude Code CLI 终端助手&lt;/a&gt;&lt;/strong&gt; - 擅长终端工作流和对话式开发的替代 AI 编码助手。不同的模型优势使其值得比较。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/move-to-tdd-today/&quot;&gt;今天转向 TDD&lt;/a&gt;&lt;/strong&gt; - 为你的 AI 生成代码写更好的测试&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;注意：性能指标来自 OpenAI 的 GPT-5 技术文档和 Cursor 的生产部署。你的结果可能因提示词质量而异。&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[为什么 Fly.io 是你没在使用的最佳免费 Docker 托管]]></title><description><![CDATA[Fly.io 每月给你 5 美元的托管额度，永久有效。那是 3 个 Docker 容器、一个 PostgreSQL 数据库和 160GB 的带宽。这就是为什么它非常适合副项目。]]></description><link>https://vibecodingwithfred.com/zh/blog/flyio-free-tier-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/zh/blog/flyio-free-tier-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;平台：&lt;/strong&gt; Fly.io | &lt;strong&gt;提供商：&lt;/strong&gt; Fly.io | &lt;strong&gt;免费层级：&lt;/strong&gt; 每月 5 美元额度永久有效&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;没人谈论的秘密&quot;&gt;没人谈论的秘密&lt;/h2&gt;
&lt;p&gt;这是 Fly.io 的特别之处：他们每个月给你 5 美元的免费额度，永久有效。不是试用，不是限时优惠——为你的 Docker 容器提供永久免费托管。如果你的使用量保持在 5 美元以下（剧透：大多数项目都会），你不用付任何钱。&lt;/p&gt;
&lt;p&gt;更好的是？与其他每个声称&quot;免费&quot;的平台不同，Fly.io 将你的 Docker 容器作为真正的 VM 运行。这不是无服务器，你的应用不会在 5 分钟后休眠。你的容器保持 24/7 运行，即时响应请求。&lt;/p&gt;
&lt;p&gt;我在 Fly.io 上运行了三个生产 API 超过一年。总成本？零美元。以下是具体操作方法。&lt;/p&gt;
&lt;h2 id=&quot;你免费获得什么&quot;&gt;你免费获得什么&lt;/h2&gt;
&lt;p&gt;那 5 美元的月度额度转化为严肃的基础设施：&lt;/p&gt;
&lt;p&gt;你获得三个 256MB RAM 的 VM，可以在世界任何地方运行。添加一个 1GB 存储的 PostgreSQL 数据库。再加上 160GB 的出站带宽。所有这些都舒适地在你的免费额度内，还有富余空间。&lt;/p&gt;
&lt;p&gt;数学很简单：单个 256MB VM 每月约 1.94 美元。三个加上一个小数据库大约 5 美元。只要你保持在这些限制内，Fly.io 的月度额度就覆盖了一切。&lt;/p&gt;
&lt;h2 id=&quot;入门只需-5-分钟&quot;&gt;入门只需 5 分钟&lt;/h2&gt;
&lt;p&gt;首先，安装 Fly CLI。在 Mac 上，只需一个 brew 命令。在 Linux 上，curl 他们的安装脚本。Windows 用户获得 PowerShell。整个过程需要 30 秒。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# macOS&lt;/span&gt;
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flyctl

&lt;span class=&quot;token comment&quot;&gt;# Linux&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Windows&lt;/span&gt;
pwsh &lt;span class=&quot;token parameter variable&quot;&gt;-Command&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iwr https://fly.io/install.ps1 -useb | iex&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;只需用电子邮件注册——他们最终会要求信用卡，但你可以在没有信用卡的情况下部署你的第一个应用：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl auth signup&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;你的第一次部署简单得离谱&quot;&gt;你的第一次部署（简单得离谱）&lt;/h2&gt;
&lt;p&gt;这是 Fly.io 发光的地方。有 Dockerfile？很好，它会工作。没有？Fly.io 会自己搞定。我是认真的——它会检测你的框架并自动生成一切。&lt;/p&gt;
&lt;p&gt;让我给你展示一个真实的例子。这是我上周部署的一个 Node.js API：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// index.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; express &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; port &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;这个 API 免费 24/7 运行&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toISOString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/health&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;healthy&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;0.0.0.0&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;在端口 &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;port&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; 上运行&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;要部署这个，我只是运行了：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl launch&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;就这样。Fly 检测到 Node.js，创建了 Dockerfile，构建了镜像，并全球部署。整个过程大约 2 分钟。我的 API 在 *.fly.dev URL 上线，具有自动 HTTPS，从最近的数据中心响应请求。&lt;/p&gt;
&lt;h2 id=&quot;没人提到的-docker-优势&quot;&gt;没人提到的 Docker 优势&lt;/h2&gt;
&lt;p&gt;这是 Fly.io 与 Vercel、Netlify 等的区别：你正在部署实际的 Docker 容器。这意味着你可以运行任何东西——Python 脚本、Go 二进制文件、Rust 服务器、PHP 应用程序、Ruby on Rails，你能想到的。&lt;/p&gt;
&lt;p&gt;我有一个处理 webhook 的 Python Flask API，一个运行计划任务的 Node.js 机器人，和一个处理图像调整大小的 Go 服务。都在免费层级上运行。试试在 Vercel 的业余计划上这样做。&lt;/p&gt;
&lt;p&gt;你的容器作为 Firecracker 微 VM 运行，与 Amazon 用于 Lambda 的技术相同。它们在毫秒内启动，但像真正的服务器一样运行。没有冷启动，没有 10 秒超时，没有无服务器限制。只是你的代码完全按照你期望的方式运行。&lt;/p&gt;
&lt;h2 id=&quot;让-256mb-工作比你想象的容易&quot;&gt;让 256MB 工作（比你想象的容易）&lt;/h2&gt;
&lt;p&gt;免费层级给你每个 VM 256MB 的 RAM。我知道你在想什么——这太少了！但你会惊讶的。一个轻量级的 Express.js API 使用大约 50MB。一个带有几个端点的 Flask 应用大约 80MB。即使是一个小的 Rails 应用也可以在 200MB 内压缩，如果你小心的话。&lt;/p&gt;
&lt;p&gt;以下是在 256MB 上运行良好的内容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;API 后端（REST 或 GraphQL）&lt;/li&gt;
&lt;li&gt;Webhook 处理器&lt;/li&gt;
&lt;li&gt;计划作业运行器&lt;/li&gt;
&lt;li&gt;具有动态功能的静态网站&lt;/li&gt;
&lt;li&gt;Discord/Slack 机器人&lt;/li&gt;
&lt;li&gt;使用 SQLite 的小型数据库&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以下是不行的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Next.js（至少需要 512MB）&lt;/li&gt;
&lt;li&gt;大型 Django 应用程序&lt;/li&gt;
&lt;li&gt;Java Spring Boot 应用&lt;/li&gt;
&lt;li&gt;任何将大数据集加载到内存中的东西&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你遇到内存限制，你有两个选择。首先，优化你的代码——流式传输文件而不是将它们加载到内存中，使用分页进行数据库查询，延迟加载依赖项。大多数&quot;内存问题&quot;只是低效的代码。&lt;/p&gt;
&lt;p&gt;第二个选择：扩展到 512MB。这让你稍微超出免费层级，每月可能花费 2-3 美元。仍然比一杯咖啡便宜，而且更有用。&lt;/p&gt;
&lt;h2 id=&quot;开箱即用的-postgresql&quot;&gt;开箱即用的 PostgreSQL&lt;/h2&gt;
&lt;p&gt;添加数据库简单得愚蠢：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres create&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;出现提示时选择&quot;Development&quot;配置。这给你一个具有 256MB RAM 和 1GB 存储的 PostgreSQL 实例，非常适合小型应用。数据库与你的应用在同一区域运行，以实现最小延迟。&lt;/p&gt;
&lt;p&gt;将其连接到你的应用：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl postgres attach &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;database-name&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这会自动设置 DATABASE_URL 环境变量。你的应用可以立即连接：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Pool &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;pg&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pool &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;connectionString&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DATABASE_URL&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 就这样。你有了数据库。&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;我正在运行一个有 500+ 帖子的博客，一个有 1000+ 账户的用户系统，和一个跟踪 50k 事件的分析仪表板——都在免费层级数据库上。除非你正在构建下一个 Twitter，否则 1GB 足够了。&lt;/p&gt;
&lt;h2 id=&quot;不用尝试就能全球化&quot;&gt;不用尝试就能全球化&lt;/h2&gt;
&lt;p&gt;用一个命令部署到多个区域：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; lhr  &lt;span class=&quot;token comment&quot;&gt;# 伦敦&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; nrt  &lt;span class=&quot;token comment&quot;&gt;# 东京&lt;/span&gt;
flyctl regions &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; syd  &lt;span class=&quot;token comment&quot;&gt;# 悉尼&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fly.io 自动将用户路由到最近的实例。你的欧洲用户命中伦敦，亚洲用户命中东京，一切都正常工作。没有配置，没有 CDN 设置，什么都没有。&lt;/p&gt;
&lt;p&gt;有了三个免费的 VM，你可以在每个区域放一个以获得真正的全球覆盖。或者将所有三个都保留在一个区域以获得冗余——如果一个崩溃，其他的继续服务请求。&lt;/p&gt;
&lt;h2 id=&quot;注意事项没有很多&quot;&gt;注意事项（没有很多）&lt;/h2&gt;
&lt;p&gt;让我们对限制坦诚。5 美元的额度不会逐月滚动。用它或失去它。但老实说，24/7 运行三个小型 VM 反正会用完全部额度。&lt;/p&gt;
&lt;p&gt;你最终需要添加信用卡来解锁某些功能，如自定义域名，并防止在超过限制时服务中断。但问题是——Fly.io 在收费之前会给你发邮件。不会有因为忘记关闭测试服务器而收到 500 美元账单的惊喜。&lt;/p&gt;
&lt;p&gt;256MB RAM 限制是真实的。你不能只是把低效的代码扔给它并期待奇迹。但这个约束迫使你写更好的代码，这不是坏事。&lt;/p&gt;
&lt;h2 id=&quot;何时使用-flyio-vs-其他所有东西&quot;&gt;何时使用 Fly.io vs 其他所有东西&lt;/h2&gt;
&lt;p&gt;当你想要永不休眠的真正服务器时使用 Fly.io。非常适合 API、webhook、机器人和任何需要即时响应的东西。Docker 支持意味着你可以运行任何语言或框架。&lt;/p&gt;
&lt;p&gt;当你正在构建 Next.js 站点并想要完美的开发者体验时使用 Vercel。他们的预览部署是无与伦比的。&lt;/p&gt;
&lt;p&gt;当你需要在 50+ 个位置运行零冷启动的边缘函数时使用 Cloudflare Workers。&lt;/p&gt;
&lt;p&gt;当你想要更漂亮的 UI 并且不介意从第一天开始付费时使用 Railway。&lt;/p&gt;
&lt;p&gt;但对于让真正的应用在线、免费、保持运行？Fly.io 每次都赢。&lt;/p&gt;
&lt;h2 id=&quot;轮到你部署了&quot;&gt;轮到你部署了&lt;/h2&gt;
&lt;p&gt;停止阅读并尝试它。认真的，只需要 5 分钟：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;安装 CLI&lt;/li&gt;
&lt;li&gt;创建一个简单的应用（或使用你已有的）&lt;/li&gt;
&lt;li&gt;运行 &lt;code class=&quot;language-text&quot;&gt;flyctl launch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;观看你的应用上线&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;就这样。没有复杂的配置，没有 yaml 地狱，没有账单惊喜。只是你的代码运行在真正的基础设施上。&lt;/p&gt;
&lt;h2 id=&quot;构建一些东西来部署&quot;&gt;构建一些东西来部署&lt;/h2&gt;
&lt;p&gt;准备好将你的第一个应用部署到 Fly.io 了吗？从使用这些实践教程构建一个真正的项目开始：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;使用 Flask 构建博客&lt;/a&gt;&lt;/strong&gt; - 创建一个非常适合 Fly.io 部署的完整 Flask 博客&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;使用 Flask 构建作品集&lt;/a&gt;&lt;/strong&gt; - 通过可部署的作品集网站学习 Flask 基础知识&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;使用 Flask 构建电子商务&lt;/a&gt;&lt;/strong&gt; - 通过完整的购物车应用程序掌握 Flask&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;每个教程都包含 Docker 配置和部署步骤，使你可以轻松地将项目从开发带到 Fly.io 免费层级的生产环境。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;已经有 Flask 应用了？&lt;/strong&gt; 按照我们的 &lt;strong&gt;&lt;a href=&quot;/blog/dockerize-flask-blog/&quot;&gt;完整 Docker 和 Fly.io 部署教程&lt;/a&gt;&lt;/strong&gt;，获取关于使用 PostgreSQL 容器化 Flask 应用程序并以零停机迁移部署到 Fly.io 的分步说明。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;技术细节&quot;&gt;技术细节&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;平台：&lt;/strong&gt; Fly.io
&lt;strong&gt;月度额度：&lt;/strong&gt; 5 美元（覆盖 3 个 VM + 数据库）
&lt;strong&gt;部署：&lt;/strong&gt; Docker 容器作为微 VM
&lt;strong&gt;区域：&lt;/strong&gt; 全球 30+ 个
&lt;strong&gt;每个 VM 的 RAM：&lt;/strong&gt; 256MB（可升级）
&lt;strong&gt;数据库：&lt;/strong&gt; PostgreSQL 具有 1GB 存储
&lt;strong&gt;带宽：&lt;/strong&gt; 每月包含 160GB&lt;/p&gt;
&lt;p&gt;&lt;em&gt;注意：在初始测试后你需要在文件上添加信用卡，但如果你保持在每月 5 美元的使用量以下，不会被收费。&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Vercel 入门：5 分钟部署你的第一个项目]]></title><description><![CDATA[Vercel 完整初学者指南。了解什么是 Vercel、它如何工作，并在几分钟内部署你的第一个项目。涵盖免费层级限制、自动部署、自定义域名，以及何时使用 Vercel 而非其他平台。]]></description><link>https://vibecodingwithfred.com/zh/blog/getting-started-vercel/</link><guid isPermaLink="false">https://vibecodingwithfred.com/zh/blog/getting-started-vercel/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Vercel 是将网站和 Web 应用部署到互联网上最简单的方式之一。在本指南中，你将了解什么是 Vercel、它如何工作，并部署你的第一个项目——全部只需大约 5 分钟。&lt;/p&gt;
&lt;h2 id=&quot;什么是-vercel&quot;&gt;什么是 Vercel？&lt;/h2&gt;
&lt;p&gt;Vercel 是一个&lt;strong&gt;用于部署网站和 Web 应用的云平台&lt;/strong&gt;。它由 Next.js 背后的团队开发，专注于使部署快速且轻松。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;把 Vercel 想象成：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;托管你网站的地方（就像代码的房东）&lt;/li&gt;
&lt;li&gt;将你的代码转换为在线网站的构建系统&lt;/li&gt;
&lt;li&gt;让你的网站在世界任何地方都快速加载的全球 CDN&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Vercel 的特别之处：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;零配置&lt;/strong&gt;：只需连接你的 Git 仓库并部署&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自动部署&lt;/strong&gt;：将代码推送到 Git，Vercel 自动重建&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;全球边缘网络&lt;/strong&gt;：你的网站从全球 70 多个位置快速加载&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;免费层级&lt;/strong&gt;：对个人和小型项目有慷慨的限制&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;你可以在-vercel-上部署什么&quot;&gt;你可以在 Vercel 上部署什么？&lt;/h2&gt;
&lt;p&gt;Vercel 最适合：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;前端框架：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;React（使用 Vite、Create React App 等）&lt;/li&gt;
&lt;li&gt;Next.js（Vercel 自己的框架）&lt;/li&gt;
&lt;li&gt;Vue.js、Svelte、Angular&lt;/li&gt;
&lt;li&gt;静态 HTML/CSS/JavaScript 网站&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;全栈应用：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;带有 API 路由的 Next.js&lt;/li&gt;
&lt;li&gt;任何前端 + serverless 函数&lt;/li&gt;
&lt;li&gt;Jamstack 网站&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Vercel 不支持的：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;传统的后端服务器（24/7 运行的 Express.js、Django、Rails）&lt;/li&gt;
&lt;li&gt;长时间运行的进程&lt;/li&gt;
&lt;li&gt;WebSocket 服务器&lt;/li&gt;
&lt;li&gt;数据库（你需要使用外部服务如 Supabase、PlanetScale 等）&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Vercel 是为&lt;strong&gt;前端和 serverless 应用&lt;/strong&gt;设计的，而不是传统的后端服务器。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;vercel-免费层级包含什么&quot;&gt;Vercel 免费层级：包含什么？&lt;/h2&gt;
&lt;p&gt;免费的&quot;Hobby&quot;计划包括：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;资源&lt;/th&gt;
&lt;th&gt;免费层级限制&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;带宽&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;100GB/月&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;构建执行&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;6,000 分钟/月&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Serverless 函数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;100GB-小时/月&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Edge 函数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;500,000 次调用/月&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;项目&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;无限&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;部署&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;无限&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;团队成员&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1（只有你）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;自定义域名&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;无限（带免费 SSL）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;这对以下情况完全足够：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;个人项目&lt;/li&gt;
&lt;li&gt;作品集网站&lt;/li&gt;
&lt;li&gt;副项目&lt;/li&gt;
&lt;li&gt;小型企业网站&lt;/li&gt;
&lt;li&gt;大多数业余项目&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在达到任何限制之前，你会收到警告。&lt;/p&gt;
&lt;h2 id=&quot;vercel-如何工作部署流程&quot;&gt;Vercel 如何工作：部署流程&lt;/h2&gt;
&lt;p&gt;当你部署到 Vercel 时会发生什么：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;你将代码推送到 Git&lt;/strong&gt;（GitHub、GitLab 或 Bitbucket）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vercel 自动检测推送&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vercel 运行你的构建&lt;/strong&gt;（&lt;code class=&quot;language-text&quot;&gt;npm run build&lt;/code&gt; 或类似的）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vercel 部署到边缘&lt;/strong&gt; - 跨全球 70 多个位置&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;你得到一个在线 URL&lt;/strong&gt;（&lt;code class=&quot;language-text&quot;&gt;.vercel.app&lt;/code&gt; 域名）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;每次推送到 Git 都会触发新的部署。这是完全自动的。&lt;/p&gt;
&lt;h3 id=&quot;预览部署&quot;&gt;预览部署&lt;/h3&gt;
&lt;p&gt;每个分支和拉取请求都会得到自己的预览 URL：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主分支&lt;/strong&gt; → 生产部署（&lt;code class=&quot;language-text&quot;&gt;your-site.vercel.app&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;功能分支&lt;/strong&gt; → 预览部署（&lt;code class=&quot;language-text&quot;&gt;your-site-git-feature-branch.vercel.app&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;拉取请求&lt;/strong&gt; → 带有可分享 URL 的预览&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这使得在合并之前测试更改变得非常容易。&lt;/p&gt;
&lt;h2 id=&quot;你的第一次部署逐步指南&quot;&gt;你的第一次部署：逐步指南&lt;/h2&gt;
&lt;p&gt;让我们将一个简单的网站部署到 Vercel。我们将使用一个基本的 React 应用，但对于任何框架，过程都是相同的。&lt;/p&gt;
&lt;h3 id=&quot;前提条件&quot;&gt;前提条件&lt;/h3&gt;
&lt;p&gt;你需要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个 GitHub 账户（免费）&lt;/li&gt;
&lt;li&gt;一个 Vercel 账户（免费 - 你将在步骤 2 中创建）&lt;/li&gt;
&lt;li&gt;一个要部署的项目（Git 仓库中的代码）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;没有项目？&lt;/strong&gt; 使用这个入门模板：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 创建新的 Vite React 应用&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; create vite@latest my-first-vercel-app -- &lt;span class=&quot;token parameter variable&quot;&gt;--template&lt;/span&gt; react

&lt;span class=&quot;token comment&quot;&gt;# 进入目录&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; my-first-vercel-app

&lt;span class=&quot;token comment&quot;&gt;# 安装依赖&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 本地测试&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run dev&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;访问 &lt;code class=&quot;language-text&quot;&gt;http://localhost:5173&lt;/code&gt; 查看它在本地运行。&lt;/p&gt;
&lt;h3 id=&quot;步骤-1将代码推送到-github&quot;&gt;步骤 1：将代码推送到 GitHub&lt;/h3&gt;
&lt;p&gt;如果你的项目还没有在 GitHub 上：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 初始化 Git（如果尚未完成）&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init

&lt;span class=&quot;token comment&quot;&gt;# 添加所有文件&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 提交&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial commit&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 在 GitHub 上创建仓库，然后：&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; origin https://github.com/YOUR-USERNAME/YOUR-REPO-NAME.git
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch &lt;span class=&quot;token parameter variable&quot;&gt;-M&lt;/span&gt; main
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; origin main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;你的代码现在在 GitHub 上了。&lt;/p&gt;
&lt;h3 id=&quot;步骤-2注册-vercel&quot;&gt;步骤 2：注册 Vercel&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;前往 &lt;a href=&quot;https://vercel.com/signup&quot;&gt;vercel.com/signup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;点击 &lt;strong&gt;&quot;Continue with GitHub&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;授权 Vercel 访问你的 GitHub 账户&lt;/li&gt;
&lt;li&gt;完成你的个人资料（姓名、团队名称等）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;你现在已登录 Vercel 仪表板。&lt;/p&gt;
&lt;h3 id=&quot;步骤-3导入你的项目&quot;&gt;步骤 3：导入你的项目&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;点击 &lt;strong&gt;&quot;Add New...&quot;&lt;/strong&gt; 按钮&lt;/li&gt;
&lt;li&gt;选择 &lt;strong&gt;&quot;Project&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;你会看到你的 GitHub 仓库列表&lt;/li&gt;
&lt;li&gt;找到你的项目并点击 &lt;strong&gt;&quot;Import&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Vercel 将分析你的仓库。&lt;/p&gt;
&lt;h3 id=&quot;步骤-4配置项目设置&quot;&gt;步骤 4：配置项目设置&lt;/h3&gt;
&lt;p&gt;Vercel 自动检测你的框架。对于我们的 Vite React 应用：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;框架预设&lt;/strong&gt;：Vite（自动检测）✅&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;根目录&lt;/strong&gt;：（留空）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;构建命令&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;（自动检测）✅&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输出目录&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;（自动检测）✅&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;安装命令&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;（自动检测）✅&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;环境变量&lt;/strong&gt;：（暂时跳过——我们稍后会介绍）&lt;/p&gt;
&lt;h3 id=&quot;步骤-5部署&quot;&gt;步骤 5：部署&lt;/h3&gt;
&lt;p&gt;点击 &lt;strong&gt;&quot;Deploy&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Vercel 将：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;克隆你的仓库&lt;/li&gt;
&lt;li&gt;安装依赖&lt;/li&gt;
&lt;li&gt;运行构建命令&lt;/li&gt;
&lt;li&gt;部署到边缘网络&lt;/li&gt;
&lt;li&gt;给你一个在线 URL&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;查看构建日志&lt;/strong&gt; - Vercel 工作时。你会看到：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Installing dependencies...
Building project...
Deploying...
✓ Deployment ready&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;部署时间&lt;/strong&gt;：对于简单项目通常 30-90 秒。&lt;/p&gt;
&lt;h3 id=&quot;步骤-6查看你的在线网站&quot;&gt;步骤 6：查看你的在线网站&lt;/h3&gt;
&lt;p&gt;部署完成后，你会看到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;生产 URL&lt;/strong&gt;：&lt;code class=&quot;language-text&quot;&gt;https://your-project.vercel.app&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;部署状态&lt;/strong&gt;：✅ Ready&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;构建时间&lt;/strong&gt;：~45 秒&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;点击 URL 查看你的在线网站！&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;恭喜！&lt;/strong&gt; 你刚刚将第一个项目部署到了 Vercel。&lt;/p&gt;
&lt;h2 id=&quot;进行更新&quot;&gt;进行更新&lt;/h2&gt;
&lt;p&gt;现在让我们进行更改并看看自动部署的效果：&lt;/p&gt;
&lt;h3 id=&quot;在本地编辑代码&quot;&gt;在本地编辑代码&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/App.jsx（或任何文件）&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;我的第一个 Vercel 部署！&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;这是从 Git 自动部署的！&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;推送到-git&quot;&gt;推送到 Git&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Update homepage message&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push origin main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;vercel-自动重建&quot;&gt;Vercel 自动重建&lt;/h3&gt;
&lt;p&gt;几秒钟内，Vercel：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;检测到你的推送&lt;/li&gt;
&lt;li&gt;开始新的构建&lt;/li&gt;
&lt;li&gt;部署更新后的网站&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;无需手动操作。&lt;/strong&gt; 访问你的仪表板观看部署。&lt;/p&gt;
&lt;h3 id=&quot;查看更新&quot;&gt;查看更新&lt;/h3&gt;
&lt;p&gt;刷新你的在线网站（&lt;code class=&quot;language-text&quot;&gt;your-project.vercel.app&lt;/code&gt;）并看到你的更改。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这就是 Vercel 的强大之处&lt;/strong&gt;：推送到 Git，你的网站自动更新。&lt;/p&gt;
&lt;h2 id=&quot;添加自定义域名&quot;&gt;添加自定义域名&lt;/h2&gt;
&lt;p&gt;你的 &lt;code class=&quot;language-text&quot;&gt;.vercel.app&lt;/code&gt; URL 可以工作，但你可能想要自己的域名。&lt;/p&gt;
&lt;h3 id=&quot;步骤-1购买域名&quot;&gt;步骤 1：购买域名&lt;/h3&gt;
&lt;p&gt;从以下获取域名：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.namecheap.com&quot;&gt;Namecheap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.godaddy.com&quot;&gt;GoDaddy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cloudflare.com/products/registrar/&quot;&gt;Cloudflare Registrar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;域名通常每年 10-20 美元。&lt;/p&gt;
&lt;h3 id=&quot;步骤-2将域名添加到-vercel&quot;&gt;步骤 2：将域名添加到 Vercel&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;在你的 Vercel 项目中，前往 &lt;strong&gt;Settings&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;点击侧边栏中的 &lt;strong&gt;Domains&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;输入你的域名（例如 &lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;点击 &lt;strong&gt;Add&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;步骤-3配置-dns&quot;&gt;步骤 3：配置 DNS&lt;/h3&gt;
&lt;p&gt;Vercel 将显示要添加的 DNS 记录：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;对于顶级域名&lt;/strong&gt;（&lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt;）：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;类型：A
名称：@
值：76.76.21.21&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;对于 www 子域名&lt;/strong&gt;（&lt;code class=&quot;language-text&quot;&gt;www.example.com&lt;/code&gt;）：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;类型：CNAME
名称：www
值：cname.vercel-dns.com&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;在你的域名注册商处添加这些：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;登录你的注册商&lt;/li&gt;
&lt;li&gt;找到 DNS 设置（通常称为&quot;DNS 管理&quot;或&quot;域名服务器&quot;）&lt;/li&gt;
&lt;li&gt;添加 A 记录和/或 CNAME 记录&lt;/li&gt;
&lt;li&gt;保存更改&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;步骤-4等待-dns-传播&quot;&gt;步骤 4：等待 DNS 传播&lt;/h3&gt;
&lt;p&gt;DNS 更改需要时间传播：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;最少&lt;/strong&gt;：5-10 分钟&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;典型&lt;/strong&gt;：30 分钟 - 2 小时&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最多&lt;/strong&gt;：24-48 小时&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在 &lt;a href=&quot;https://www.whatsmydns.net&quot;&gt;whatsmydns.net&lt;/a&gt; 检查状态&lt;/p&gt;
&lt;p&gt;传播完成后，Vercel 自动提供 SSL 证书。你的网站将在自定义域名上使用 HTTPS 上线。&lt;/p&gt;
&lt;h2 id=&quot;何时使用-vercel-vs-其他平台&quot;&gt;何时使用 Vercel vs 其他平台&lt;/h2&gt;
&lt;h3 id=&quot;使用-vercel-当&quot;&gt;使用 Vercel 当：&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;你正在构建前端应用（React、Vue、Svelte 等）&lt;/li&gt;
&lt;li&gt;你想要从 Git 自动部署&lt;/li&gt;
&lt;li&gt;你重视开发者体验和速度&lt;/li&gt;
&lt;li&gt;你使用 Next.js（Vercel 就是为它设计的）&lt;/li&gt;
&lt;li&gt;你需要 serverless 函数用于 API&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;使用-cloudflare-workers-当&quot;&gt;使用 Cloudflare Workers 当：&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;你想要**&lt;a href=&quot;/blog/cloudflare-workers-deployment/&quot;&gt;无限带宽和更多部署控制&lt;/a&gt;**&lt;/li&gt;
&lt;li&gt;你有非常高的流量（Vercel 免费层级限制 100GB）&lt;/li&gt;
&lt;li&gt;你更喜欢最快的全球性能（300+ 区域）&lt;/li&gt;
&lt;li&gt;你想将静态网站与边缘函数结合&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;使用-flyio-当&quot;&gt;使用 Fly.io 当：&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;你需要**&lt;a href=&quot;/blog/flyio-free-tier-guide/&quot;&gt;24/7 运行的真正 Docker 容器&lt;/a&gt;**&lt;/li&gt;
&lt;li&gt;你正在部署传统后端服务器（Flask、Express、Rails）&lt;/li&gt;
&lt;li&gt;你想完全控制运行时环境&lt;/li&gt;
&lt;li&gt;你需要数据库或长时间运行的进程&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;对于大多数现代 Web 应用，Vercel 是最简单的选择。&lt;/strong&gt; 但如果你需要无限带宽，探索 Cloudflare Workers。如果你需要真正的后端服务器，Fly.io 在其免费层级上运行实际的 Docker 容器。&lt;/p&gt;
&lt;h2 id=&quot;结论&quot;&gt;结论&lt;/h2&gt;
&lt;p&gt;Vercel 使部署 Web 应用变得轻而易举：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;将代码推送到 Git&lt;/li&gt;
&lt;li&gt;Vercel 自动构建和部署&lt;/li&gt;
&lt;li&gt;你的网站在几秒钟内在全球上线&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;免费层级对大多数个人项目来说足够慷慨，开发者体验非常出色。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;亲自尝试&lt;/strong&gt;：今天就部署你的第一个项目，看看为什么开发者喜欢 Vercel。&lt;/p&gt;
&lt;h2 id=&quot;构建你的第一个项目来部署&quot;&gt;构建你的第一个项目来部署&lt;/h2&gt;
&lt;p&gt;还没有准备好部署的项目？通过这些全面的教程从头开始构建一个：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-scratch/&quot;&gt;从头开始构建博客&lt;/a&gt;&lt;/strong&gt; - 使用原生 JavaScript 创建一个完整的博客，非常适合 Vercel 部署&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-scratch/&quot;&gt;从头开始构建作品集&lt;/a&gt;&lt;/strong&gt; - 在构建专业作品集网站的同时学习 Web 基础知识&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-scratch/&quot;&gt;从头开始构建电子商务&lt;/a&gt;&lt;/strong&gt; - 通过购物车应用掌握 JavaScript 状态管理&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;每个教程都教你现代 Web 开发的基础知识，完成的项目将准备好部署到 Vercel 的免费层级。&lt;/p&gt;
&lt;p&gt;有问题？在下方留言！&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;相关指南：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/3-ways-to-move-lovable-website/&quot;&gt;Lovable 到 Vercel：完整部署指南&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/lovable-to-cloudflare&quot;&gt;完整指南：将你的 Lovable 项目部署到 Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Orchids: The AI That Builds Complete Apps From a Conversation]]></title><description><![CDATA[Orchids turns natural language conversations into fully functional web applications with backend, database, payments, and hosting in under 20 minutes.]]></description><link>https://vibecodingwithfred.com/blog/orchids-ai-fullstack-platform/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/orchids-ai-fullstack-platform/</guid><dc:creator><![CDATA[Technology Analysis]]></dc:creator><pubDate>Thu, 23 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Platform:&lt;/strong&gt; Orchids | &lt;strong&gt;Starting Price:&lt;/strong&gt; $25/month | &lt;strong&gt;Speed:&lt;/strong&gt; Full app in ~15 minutes&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;what-makes-orchids-different&quot;&gt;What Makes Orchids Different&lt;/h2&gt;
&lt;p&gt;Imagine describing an app idea to someone and having them build the entire thing while you watch. Database, authentication, payment processing, everything ready to deploy in fifteen minutes. That&apos;s Orchids.&lt;/p&gt;
&lt;p&gt;Other AI tools generate frontend mockups and leave you to figure out the backend. Orchids builds complete, production-ready applications from natural language. You describe what you want in plain English. It builds a working application with real functionality, not just a pretty interface.&lt;/p&gt;
&lt;p&gt;The platform recently claimed top rankings on design quality benchmarks, producing applications that don&apos;t have that generic &quot;AI-generated&quot; look that plagues most automated builders. Whether these claims hold up in practice is something users need to evaluate, but the approach differs fundamentally from template-based systems.&lt;/p&gt;
&lt;h2 id=&quot;how-it-works&quot;&gt;How It Works&lt;/h2&gt;
&lt;p&gt;Here&apos;s the workflow: You type something like &quot;Build me a project management tool where teams can create tasks, assign them to members, track time spent, and generate weekly reports. Make it look modern and minimal.&quot;&lt;/p&gt;
&lt;p&gt;Orchids then builds the entire application. Not a mockup, but a functioning system with user accounts, a database storing all the tasks and time entries, the logic for generating reports, and the interface to tie it all together. The whole process takes 10-20 minutes depending on complexity.&lt;/p&gt;
&lt;p&gt;The conversation continues as you refine. &quot;Make the dashboard cards smaller.&quot; &quot;Add a dark mode.&quot; &quot;Include Slack notifications when tasks are assigned.&quot; Each adjustment happens in real-time through the chat interface. No code editing, no deployment cycles, just describe what you want changed.&lt;/p&gt;
&lt;h2 id=&quot;the-full-stack-reality&quot;&gt;The Full-Stack Reality&lt;/h2&gt;
&lt;p&gt;Most AI builders stop at the frontend. They&apos;ll generate a nice-looking interface, then tell you to figure out authentication, set up your own database, integrate Stripe yourself, and find hosting. Orchids handles all of this within the platform.&lt;/p&gt;
&lt;p&gt;When you ask for a subscription-based SaaS, it doesn&apos;t just create payment buttons. It integrates payment processing. When you request user accounts, it implements real authentication with secure password handling. The database isn&apos;t just planned; it&apos;s created and connected. This comprehensive approach means you can launch what you build, not just prototype it.&lt;/p&gt;
&lt;h2 id=&quot;website-cloning-as-a-design-starting-point&quot;&gt;Website Cloning as a Design Starting Point&lt;/h2&gt;
&lt;p&gt;One interesting feature lets you reference existing websites as design inspiration. You can tell Orchids to &quot;create a task management app with Linear&apos;s design aesthetic but built for freelancers&quot; and it will analyze the referenced site&apos;s visual language and apply it to your custom application. This isn&apos;t copying code or assets. It&apos;s using design patterns as a foundation for something new.&lt;/p&gt;
&lt;h2 id=&quot;what-you-can-build&quot;&gt;What You Can Build&lt;/h2&gt;
&lt;p&gt;The platform handles several categories of applications reasonably well based on user reports and documentation. SaaS applications with subscription billing, user management, and multi-tenant architecture are within scope. Marketing websites and landing pages with forms, animations, and responsive designs work as expected. Internal business tools like CRMs, inventory systems, and reporting dashboards are buildable. Mobile-responsive web applications that work across devices are supported, though native mobile apps are not.&lt;/p&gt;
&lt;p&gt;The sweet spot appears to be applications that would take a small development team several weeks to build from scratch. Think MVP versions of SaaS products, custom internal tools that replace spreadsheets, or client projects that need quick delivery.&lt;/p&gt;
&lt;h2 id=&quot;real-limitations-to-consider&quot;&gt;Real Limitations to Consider&lt;/h2&gt;
&lt;p&gt;Orchids isn&apos;t magic, and understanding its boundaries matters. Complex business logic with numerous edge cases (think financial modeling with regulatory compliance or sophisticated algorithms) will likely hit the platform&apos;s ceiling. If you need pixel-perfect adherence to an existing brand guide or custom UI components, you&apos;ll probably need to export the code and modify it manually.&lt;/p&gt;
&lt;p&gt;Large-scale applications with hundreds of pages or complex content management needs might overwhelm the system. The platform seems optimized for focused applications rather than sprawling enterprise systems. Performance at scale and long-term reliability remain open questions given the platform&apos;s newness.&lt;/p&gt;
&lt;p&gt;The conversational interface, while intuitive, can become cumbersome for specific technical requirements. Sometimes you know exactly what database index you need or which React pattern to implement, and describing this in natural language might be slower than just coding it.&lt;/p&gt;
&lt;h2 id=&quot;who-benefits-most&quot;&gt;Who Benefits Most&lt;/h2&gt;
&lt;p&gt;Non-technical founders validating ideas benefit from the speed of going from concept to testable product. Instead of spending months finding and managing developers for an MVP, they can build something functional in an afternoon and start getting user feedback.&lt;/p&gt;
&lt;p&gt;Freelancers and agencies can increase their project throughput, especially for straightforward client requests. A freelancer who previously turned down website projects due to technical limitations could now deliver functional web applications.&lt;/p&gt;
&lt;p&gt;Product managers can create working prototypes instead of static mockups, making stakeholder buy-in and user testing more meaningful. Technical teams might use it for rapid prototyping before committing engineering resources to the final build.&lt;/p&gt;
&lt;h2 id=&quot;the-cost-benefit-analysis&quot;&gt;The Cost-Benefit Analysis&lt;/h2&gt;
&lt;p&gt;At $25/month for the basic tier, Orchids costs more than simple website builders but far less than hiring developers or using enterprise low-code platforms. The real cost consideration isn&apos;t the subscription but the potential technical debt and vendor lock-in. Can you export and modify the code if needed? What happens if Orchids shuts down or dramatically changes its pricing? How difficult would migration be?&lt;/p&gt;
&lt;p&gt;For MVP validation and short-term projects, these risks might be acceptable. For long-term, mission-critical applications, they require careful consideration.&lt;/p&gt;
&lt;h2 id=&quot;getting-started-intelligently&quot;&gt;Getting Started Intelligently&lt;/h2&gt;
&lt;p&gt;If you&apos;re considering Orchids, start with something non-critical. Build an internal tool your team needs or a side project you&apos;ve been putting off. This lets you evaluate the platform&apos;s actual capabilities versus its marketing claims without risking important projects.&lt;/p&gt;
&lt;p&gt;Pay attention to how much time you spend fighting the platform versus building. If you&apos;re constantly working around limitations or the conversational interface becomes more hindrance than help, that&apos;s valuable data. Some projects will be perfect fits; others will reveal why traditional development still has its place.&lt;/p&gt;
&lt;h2 id=&quot;bottom-line&quot;&gt;Bottom Line&lt;/h2&gt;
&lt;p&gt;Orchids represents an interesting evolution in no-code platforms, one that attempts to bridge the gap between quick website builders and full application development. The conversational interface and comprehensive stack handling remove significant technical barriers, which could democratize application development in meaningful ways.&lt;/p&gt;
&lt;p&gt;Whether it delivers on these promises consistently enough to justify adoption depends on your specific use case, technical requirements, and risk tolerance. The platform&apos;s approach is innovative, but innovation doesn&apos;t mean it&apos;s the right solution for every project.&lt;/p&gt;
&lt;p&gt;For rapid prototyping, MVP development, and straightforward applications where speed matters more than perfect customization, Orchids offers compelling capabilities. For complex, highly customized, or mission-critical applications, traditional development or more established platforms might still be the wiser choice.&lt;/p&gt;
&lt;p&gt;The key is understanding what you&apos;re trading: complete control and customization for speed and accessibility. Determine whether that trade makes sense for your specific situation.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Official Website&lt;/strong&gt;: orchids.app&lt;br&gt;
&lt;strong&gt;Community&lt;/strong&gt;: Discord (accessible through official channels)&lt;br&gt;
&lt;strong&gt;Pricing&lt;/strong&gt;: Starts at $25/month with free tier available&lt;br&gt;
&lt;strong&gt;Founded&lt;/strong&gt;: Y Combinator Winter 2025 batch&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This analysis is based on available documentation and reported user experiences. Actual performance should be verified through direct testing.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Orchids: La IA Que Construye Aplicaciones Completas Desde una Conversacion]]></title><description><![CDATA[Orchids convierte conversaciones en lenguaje natural en aplicaciones web completamente funcionales con backend, base de datos, pagos y hosting en menos de 20 minutos.]]></description><link>https://vibecodingwithfred.com/es/blog/orchids-ai-fullstack-platform/</link><guid isPermaLink="false">https://vibecodingwithfred.com/es/blog/orchids-ai-fullstack-platform/</guid><dc:creator><![CDATA[Technology Analysis]]></dc:creator><pubDate>Thu, 23 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Plataforma:&lt;/strong&gt; Orchids | &lt;strong&gt;Precio Inicial:&lt;/strong&gt; $25/mes | &lt;strong&gt;Velocidad:&lt;/strong&gt; App completa en ~15 minutos&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;que-hace-diferente-a-orchids&quot;&gt;Que Hace Diferente a Orchids&lt;/h2&gt;
&lt;p&gt;Imagina describir una idea de app a alguien y que construyan toda la cosa mientras miras. Base de datos, autenticacion, procesamiento de pagos, todo listo para desplegar en quince minutos. Eso es Orchids.&lt;/p&gt;
&lt;p&gt;Otras herramientas de IA generan mockups de frontend y te dejan descubrir el backend. Orchids construye aplicaciones completas, listas para produccion desde lenguaje natural. Describes lo que quieres en espanol simple. Construye una aplicacion funcionando con funcionalidad real, no solo una interfaz bonita.&lt;/p&gt;
&lt;p&gt;La plataforma recientemente afirmo rankings top en benchmarks de calidad de diseno, produciendo aplicaciones que no tienen ese aspecto generico &quot;generado por IA&quot; que afecta a la mayoria de constructores automatizados. Si estas afirmaciones se mantienen en la practica es algo que los usuarios necesitan evaluar, pero el enfoque difiere fundamentalmente de los sistemas basados en plantillas.&lt;/p&gt;
&lt;h2 id=&quot;como-funciona&quot;&gt;Como Funciona&lt;/h2&gt;
&lt;p&gt;Aqui esta el flujo de trabajo: Escribes algo como &quot;Construyeme una herramienta de gestion de proyectos donde los equipos puedan crear tareas, asignarlas a miembros, rastrear tiempo invertido y generar reportes semanales. Hazla lucir moderna y minimalista.&quot;&lt;/p&gt;
&lt;p&gt;Orchids entonces construye toda la aplicacion. No un mockup, sino un sistema funcionando con cuentas de usuario, una base de datos almacenando todas las tareas y entradas de tiempo, la logica para generar reportes, y la interfaz para conectar todo. Todo el proceso toma 10-20 minutos dependiendo de la complejidad.&lt;/p&gt;
&lt;p&gt;La conversacion continua mientras refinas. &quot;Haz las tarjetas del dashboard mas pequenas.&quot; &quot;Agrega modo oscuro.&quot; &quot;Incluye notificaciones de Slack cuando se asignen tareas.&quot; Cada ajuste sucede en tiempo real a traves de la interfaz de chat. Sin edicion de codigo, sin ciclos de despliegue, solo describe lo que quieres cambiar.&lt;/p&gt;
&lt;h2 id=&quot;la-realidad-full-stack&quot;&gt;La Realidad Full-Stack&lt;/h2&gt;
&lt;p&gt;La mayoria de constructores de IA se detienen en el frontend. Generaran una interfaz bonita, luego te dicen que descubras la autenticacion, configures tu propia base de datos, integres Stripe tu mismo, y encuentres hosting. Orchids maneja todo esto dentro de la plataforma.&lt;/p&gt;
&lt;p&gt;Cuando pides un SaaS basado en suscripcion, no solo crea botones de pago. Integra procesamiento de pagos. Cuando solicitas cuentas de usuario, implementa autenticacion real con manejo seguro de contrasenas. La base de datos no solo esta planeada; esta creada y conectada. Este enfoque integral significa que puedes lanzar lo que construyes, no solo prototiparlo.&lt;/p&gt;
&lt;h2 id=&quot;clonacion-de-sitios-web-como-punto-de-partida-de-diseno&quot;&gt;Clonacion de Sitios Web como Punto de Partida de Diseno&lt;/h2&gt;
&lt;p&gt;Una funcion interesante te permite referenciar sitios web existentes como inspiracion de diseno. Puedes decirle a Orchids &quot;crea una app de gestion de tareas con la estetica de diseno de Linear pero construida para freelancers&quot; y analizara el lenguaje visual del sitio referenciado y lo aplicara a tu aplicacion personalizada. Esto no es copiar codigo o assets. Es usar patrones de diseno como fundamento para algo nuevo.&lt;/p&gt;
&lt;h2 id=&quot;que-puedes-construir&quot;&gt;Que Puedes Construir&lt;/h2&gt;
&lt;p&gt;La plataforma maneja varias categorias de aplicaciones razonablemente bien segun reportes de usuarios y documentacion. Aplicaciones SaaS con facturacion de suscripciones, gestion de usuarios y arquitectura multi-tenant estan dentro del alcance. Sitios web de marketing y landing pages con formularios, animaciones y disenos responsivos funcionan como se espera. Herramientas de negocio internas como CRMs, sistemas de inventario y dashboards de reportes son construibles. Aplicaciones web responsivas para moviles que funcionan en todos los dispositivos estan soportadas, aunque apps nativas para moviles no.&lt;/p&gt;
&lt;p&gt;El punto dulce parecen ser aplicaciones que tomarian a un equipo pequeno de desarrollo varias semanas construir desde cero. Piensa en versiones MVP de productos SaaS, herramientas internas personalizadas que reemplazan hojas de calculo, o proyectos de clientes que necesitan entrega rapida.&lt;/p&gt;
&lt;h2 id=&quot;limitaciones-reales-a-considerar&quot;&gt;Limitaciones Reales a Considerar&lt;/h2&gt;
&lt;p&gt;Orchids no es magia, y entender sus limites importa. Logica de negocio compleja con numerosos casos extremos (piensa en modelado financiero con cumplimiento regulatorio o algoritmos sofisticados) probablemente llegara al techo de la plataforma. Si necesitas adherencia pixel-perfect a una guia de marca existente o componentes UI personalizados, probablemente necesitaras exportar el codigo y modificarlo manualmente.&lt;/p&gt;
&lt;p&gt;Aplicaciones a gran escala con cientos de paginas o necesidades complejas de gestion de contenido podrian abrumar el sistema. La plataforma parece optimizada para aplicaciones enfocadas en lugar de sistemas empresariales extensos. El rendimiento a escala y la confiabilidad a largo plazo siguen siendo preguntas abiertas dada la novedad de la plataforma.&lt;/p&gt;
&lt;p&gt;La interfaz conversacional, aunque intuitiva, puede volverse engorrosa para requerimientos tecnicos especificos. A veces sabes exactamente que indice de base de datos necesitas o que patron de React implementar, y describir esto en lenguaje natural podria ser mas lento que simplemente codificarlo.&lt;/p&gt;
&lt;h2 id=&quot;quien-se-beneficia-mas&quot;&gt;Quien Se Beneficia Mas&lt;/h2&gt;
&lt;p&gt;Fundadores no tecnicos validando ideas se benefician de la velocidad de ir de concepto a producto testeable. En lugar de pasar meses encontrando y gestionando desarrolladores para un MVP, pueden construir algo funcional en una tarde y empezar a obtener feedback de usuarios.&lt;/p&gt;
&lt;p&gt;Freelancers y agencias pueden aumentar su throughput de proyectos, especialmente para solicitudes de clientes directas. Un freelancer que antes rechazaba proyectos web debido a limitaciones tecnicas ahora podria entregar aplicaciones web funcionales.&lt;/p&gt;
&lt;p&gt;Product managers pueden crear prototipos funcionando en lugar de mockups estaticos, haciendo que la aprobacion de stakeholders y las pruebas de usuario sean mas significativas. Equipos tecnicos podrian usarlo para prototipado rapido antes de comprometer recursos de ingenieria para la construccion final.&lt;/p&gt;
&lt;h2 id=&quot;el-analisis-costo-beneficio&quot;&gt;El Analisis Costo-Beneficio&lt;/h2&gt;
&lt;p&gt;A $25/mes para el nivel basico, Orchids cuesta mas que constructores de sitios web simples pero mucho menos que contratar desarrolladores o usar plataformas low-code empresariales. La consideracion real de costo no es la suscripcion sino la deuda tecnica potencial y el bloqueo de proveedor. Puedes exportar y modificar el codigo si es necesario? Que pasa si Orchids cierra o cambia dramaticamente sus precios? Que tan dificil seria la migracion?&lt;/p&gt;
&lt;p&gt;Para validacion de MVP y proyectos a corto plazo, estos riesgos podrian ser aceptables. Para aplicaciones a largo plazo y de mision critica, requieren consideracion cuidadosa.&lt;/p&gt;
&lt;h2 id=&quot;comenzando-inteligentemente&quot;&gt;Comenzando Inteligentemente&lt;/h2&gt;
&lt;p&gt;Si estas considerando Orchids, empieza con algo no critico. Construye una herramienta interna que tu equipo necesite o un proyecto paralelo que has pospuesto. Esto te permite evaluar las capacidades reales de la plataforma versus sus afirmaciones de marketing sin arriesgar proyectos importantes.&lt;/p&gt;
&lt;p&gt;Presta atencion a cuanto tiempo pasas peleando contra la plataforma versus construyendo. Si constantemente estas trabajando alrededor de limitaciones o la interfaz conversacional se vuelve mas obstaculo que ayuda, esa es informacion valiosa. Algunos proyectos seran ajustes perfectos; otros revelaran por que el desarrollo tradicional aun tiene su lugar.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Orchids representa una evolucion interesante en plataformas no-code, una que intenta cerrar la brecha entre constructores rapidos de sitios web y desarrollo completo de aplicaciones. La interfaz conversacional y el manejo integral del stack eliminan barreras tecnicas significativas, lo cual podria democratizar el desarrollo de aplicaciones de maneras significativas.&lt;/p&gt;
&lt;p&gt;Si cumple consistentemente con estas promesas lo suficiente para justificar la adopcion depende de tu caso de uso especifico, requerimientos tecnicos y tolerancia al riesgo. El enfoque de la plataforma es innovador, pero innovacion no significa que sea la solucion correcta para cada proyecto.&lt;/p&gt;
&lt;p&gt;Para prototipado rapido, desarrollo de MVP y aplicaciones directas donde la velocidad importa mas que la personalizacion perfecta, Orchids ofrece capacidades convincentes. Para aplicaciones complejas, altamente personalizadas o de mision critica, el desarrollo tradicional o plataformas mas establecidas podrian seguir siendo la eleccion mas sabia.&lt;/p&gt;
&lt;p&gt;La clave es entender que estas intercambiando: control completo y personalizacion por velocidad y accesibilidad. Determina si ese intercambio tiene sentido para tu situacion especifica.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;recursos&quot;&gt;Recursos&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Sitio Web Oficial&lt;/strong&gt;: orchids.app
&lt;strong&gt;Comunidad&lt;/strong&gt;: Discord (accesible a traves de canales oficiales)
&lt;strong&gt;Precios&lt;/strong&gt;: Desde $25/mes con nivel gratuito disponible
&lt;strong&gt;Fundada&lt;/strong&gt;: Y Combinator Winter 2025 batch&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Este analisis esta basado en documentacion disponible y experiencias reportadas por usuarios. El rendimiento real debe verificarse a traves de pruebas directas.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Orchids: L'AI Che Costruisce App Complete Da Una Conversazione]]></title><description><![CDATA[Orchids trasforma conversazioni in linguaggio naturale in applicazioni web completamente funzionali con backend, database, pagamenti e hosting in meno di 20 minuti.]]></description><link>https://vibecodingwithfred.com/it/blog/orchids-ai-fullstack-platform/</link><guid isPermaLink="false">https://vibecodingwithfred.com/it/blog/orchids-ai-fullstack-platform/</guid><dc:creator><![CDATA[Technology Analysis]]></dc:creator><pubDate>Thu, 23 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Piattaforma:&lt;/strong&gt; Orchids | &lt;strong&gt;Prezzo Iniziale:&lt;/strong&gt; $25/mese | &lt;strong&gt;Velocita:&lt;/strong&gt; App completa in ~15 minuti&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;cosa-rende-orchids-diverso&quot;&gt;Cosa Rende Orchids Diverso&lt;/h2&gt;
&lt;p&gt;Immagina di descrivere un&apos;idea per un&apos;app a qualcuno e vederlo costruire l&apos;intera cosa mentre guardi. Database, autenticazione, elaborazione pagamenti, tutto pronto per il deploy in quindici minuti. Questo e Orchids.&lt;/p&gt;
&lt;p&gt;Altri strumenti AI generano mockup frontend e ti lasciano a capire il backend. Orchids costruisce applicazioni complete, pronte per la produzione, dal linguaggio naturale. Descrivi cosa vuoi in italiano semplice. Costruisce un&apos;applicazione funzionante con funzionalita reali, non solo un&apos;interfaccia carina.&lt;/p&gt;
&lt;p&gt;La piattaforma ha recentemente dichiarato i primi posti nei benchmark di qualita del design, producendo applicazioni che non hanno quel look generico &quot;generato dall&apos;AI&quot; che affligge la maggior parte dei builder automatici. Se queste affermazioni reggono nella pratica e qualcosa che gli utenti devono valutare, ma l&apos;approccio differisce fondamentalmente dai sistemi basati su template.&lt;/p&gt;
&lt;h2 id=&quot;come-funziona&quot;&gt;Come Funziona&lt;/h2&gt;
&lt;p&gt;Ecco il workflow: Scrivi qualcosa come &quot;Costruiscimi uno strumento di gestione progetti dove i team possono creare task, assegnarli ai membri, tracciare il tempo speso e generare report settimanali. Fallo sembrare moderno e minimale.&quot;&lt;/p&gt;
&lt;p&gt;Orchids poi costruisce l&apos;intera applicazione. Non un mockup, ma un sistema funzionante con account utente, un database che memorizza tutti i task e le voci di tempo, la logica per generare report, e l&apos;interfaccia per collegare tutto. L&apos;intero processo richiede 10-20 minuti a seconda della complessita.&lt;/p&gt;
&lt;p&gt;La conversazione continua mentre raffini. &quot;Rendi le card della dashboard piu piccole.&quot; &quot;Aggiungi una modalita scura.&quot; &quot;Includi notifiche Slack quando vengono assegnati i task.&quot; Ogni modifica avviene in tempo reale attraverso l&apos;interfaccia di chat. Nessuna modifica di codice, nessun ciclo di deployment, descrivi solo cosa vuoi cambiare.&lt;/p&gt;
&lt;h2 id=&quot;la-realta-full-stack&quot;&gt;La Realta Full-Stack&lt;/h2&gt;
&lt;p&gt;La maggior parte dei builder AI si ferma al frontend. Generano un&apos;interfaccia bella, poi ti dicono di capire l&apos;autenticazione, configurare il tuo database, integrare Stripe da solo, e trovare l&apos;hosting. Orchids gestisce tutto questo all&apos;interno della piattaforma.&lt;/p&gt;
&lt;p&gt;Quando chiedi un SaaS basato su abbonamento, non crea solo pulsanti di pagamento. Integra l&apos;elaborazione dei pagamenti. Quando richiedi account utente, implementa autenticazione reale con gestione sicura delle password. Il database non e solo pianificato; e creato e connesso. Questo approccio completo significa che puoi lanciare quello che costruisci, non solo prototiparlo.&lt;/p&gt;
&lt;h2 id=&quot;clonazione-di-siti-web-come-punto-di-partenza-per-il-design&quot;&gt;Clonazione di Siti Web Come Punto di Partenza per il Design&lt;/h2&gt;
&lt;p&gt;Una funzionalita interessante ti permette di fare riferimento a siti web esistenti come ispirazione per il design. Puoi dire a Orchids di &quot;creare un&apos;app di gestione task con l&apos;estetica del design di Linear ma costruita per freelancer&quot; e analizzerai il linguaggio visivo del sito di riferimento e lo applichera alla tua applicazione personalizzata. Questo non e copiare codice o asset. E usare pattern di design come base per qualcosa di nuovo.&lt;/p&gt;
&lt;h2 id=&quot;cosa-puoi-costruire&quot;&gt;Cosa Puoi Costruire&lt;/h2&gt;
&lt;p&gt;La piattaforma gestisce diverse categorie di applicazioni ragionevolmente bene in base ai report degli utenti e alla documentazione. Le applicazioni SaaS con fatturazione in abbonamento, gestione utenti e architettura multi-tenant sono nel campo di applicazione. I siti web di marketing e le landing page con form, animazioni e design responsive funzionano come previsto. Gli strumenti aziendali interni come CRM, sistemi di inventario e dashboard di reporting sono costruibili. Le applicazioni web mobile-responsive che funzionano su tutti i dispositivi sono supportate, anche se le app mobile native non lo sono.&lt;/p&gt;
&lt;p&gt;Il punto forte sembra essere le applicazioni che richiederebbero a un piccolo team di sviluppo diverse settimane per costruire da zero. Pensa a versioni MVP di prodotti SaaS, strumenti interni personalizzati che sostituiscono i fogli di calcolo, o progetti client che necessitano di consegna rapida.&lt;/p&gt;
&lt;h2 id=&quot;limitazioni-reali-da-considerare&quot;&gt;Limitazioni Reali da Considerare&lt;/h2&gt;
&lt;p&gt;Orchids non e magia, e capire i suoi limiti conta. Logica di business complessa con numerosi casi limite (pensa a modellazione finanziaria con conformita normativa o algoritmi sofisticati) probabilmente raggiungera il tetto della piattaforma. Se hai bisogno di aderenza pixel-perfect a una guida di brand esistente o componenti UI personalizzati, probabilmente dovrai esportare il codice e modificarlo manualmente.&lt;/p&gt;
&lt;p&gt;Applicazioni su larga scala con centinaia di pagine o esigenze di gestione contenuti complesse potrebbero sovraccaricare il sistema. La piattaforma sembra ottimizzata per applicazioni focalizzate piuttosto che sistemi enterprise tentacolari. Le prestazioni su scala e l&apos;affidabilita a lungo termine rimangono domande aperte data la novita della piattaforma.&lt;/p&gt;
&lt;p&gt;L&apos;interfaccia conversazionale, sebbene intuitiva, puo diventare ingombrante per requisiti tecnici specifici. A volte sai esattamente quale indice di database ti serve o quale pattern React implementare, e descriverlo in linguaggio naturale potrebbe essere piu lento che semplicemente programmarlo.&lt;/p&gt;
&lt;h2 id=&quot;chi-ne-beneficia-di-piu&quot;&gt;Chi Ne Beneficia Di Piu&lt;/h2&gt;
&lt;p&gt;I founder non tecnici che validano idee beneficiano della velocita di passare dal concetto al prodotto testabile. Invece di passare mesi a trovare e gestire sviluppatori per un MVP, possono costruire qualcosa di funzionale in un pomeriggio e iniziare a ricevere feedback dagli utenti.&lt;/p&gt;
&lt;p&gt;Freelancer e agenzie possono aumentare il throughput dei loro progetti, specialmente per richieste client semplici. Un freelancer che precedentemente rifiutava progetti di siti web a causa di limitazioni tecniche potrebbe ora consegnare applicazioni web funzionali.&lt;/p&gt;
&lt;p&gt;I product manager possono creare prototipi funzionanti invece di mockup statici, rendendo il buy-in degli stakeholder e i test utente piu significativi. I team tecnici potrebbero usarlo per prototipazione rapida prima di impegnare risorse di ingegneria nella build finale.&lt;/p&gt;
&lt;h2 id=&quot;lanalisi-costi-benefici&quot;&gt;L&apos;Analisi Costi-Benefici&lt;/h2&gt;
&lt;p&gt;A $25/mese per il tier base, Orchids costa piu dei semplici website builder ma molto meno che assumere sviluppatori o usare piattaforme low-code enterprise. La vera considerazione sui costi non e l&apos;abbonamento ma il potenziale debito tecnico e il vendor lock-in. Puoi esportare e modificare il codice se necessario? Cosa succede se Orchids chiude o cambia drasticamente i suoi prezzi? Quanto sarebbe difficile la migrazione?&lt;/p&gt;
&lt;p&gt;Per la validazione MVP e i progetti a breve termine, questi rischi potrebbero essere accettabili. Per applicazioni a lungo termine e mission-critical, richiedono un&apos;attenta considerazione.&lt;/p&gt;
&lt;h2 id=&quot;iniziare-in-modo-intelligente&quot;&gt;Iniziare in Modo Intelligente&lt;/h2&gt;
&lt;p&gt;Se stai considerando Orchids, inizia con qualcosa di non critico. Costruisci uno strumento interno di cui il tuo team ha bisogno o un side project che stavi rimandando. Questo ti permette di valutare le capacita effettive della piattaforma rispetto alle sue affermazioni di marketing senza rischiare progetti importanti.&lt;/p&gt;
&lt;p&gt;Presta attenzione a quanto tempo passi a combattere la piattaforma rispetto a costruire. Se stai costantemente aggirando limitazioni o l&apos;interfaccia conversazionale diventa piu un ostacolo che un aiuto, questi sono dati preziosi. Alcuni progetti saranno perfetti; altri riveleranno perche lo sviluppo tradizionale ha ancora il suo posto.&lt;/p&gt;
&lt;h2 id=&quot;in-conclusione&quot;&gt;In Conclusione&lt;/h2&gt;
&lt;p&gt;Orchids rappresenta un&apos;evoluzione interessante nelle piattaforme no-code, una che tenta di colmare il divario tra quick website builder e sviluppo di applicazioni complete. L&apos;interfaccia conversazionale e la gestione completa dello stack rimuovono barriere tecniche significative, il che potrebbe democratizzare lo sviluppo di applicazioni in modi significativi.&lt;/p&gt;
&lt;p&gt;Se mantiene queste promesse in modo abbastanza consistente da giustificare l&apos;adozione dipende dal tuo caso d&apos;uso specifico, requisiti tecnici e tolleranza al rischio. L&apos;approccio della piattaforma e innovativo, ma innovazione non significa che sia la soluzione giusta per ogni progetto.&lt;/p&gt;
&lt;p&gt;Per prototipazione rapida, sviluppo MVP e applicazioni semplici dove la velocita conta piu della personalizzazione perfetta, Orchids offre capacita convincenti. Per applicazioni complesse, altamente personalizzate o mission-critical, lo sviluppo tradizionale o piattaforme piu consolidate potrebbero ancora essere la scelta piu saggia.&lt;/p&gt;
&lt;p&gt;La chiave e capire cosa stai scambiando: controllo completo e personalizzazione per velocita e accessibilita. Determina se quello scambio ha senso per la tua situazione specifica.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;risorse&quot;&gt;Risorse&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Sito Ufficiale&lt;/strong&gt;: orchids.app
&lt;strong&gt;Community&lt;/strong&gt;: Discord (accessibile attraverso i canali ufficiali)
&lt;strong&gt;Prezzi&lt;/strong&gt;: Parte da $25/mese con tier gratuito disponibile
&lt;strong&gt;Fondato&lt;/strong&gt;: Y Combinator Winter 2025 batch&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Questa analisi e basata sulla documentazione disponibile e sulle esperienze utente riportate. Le prestazioni effettive dovrebbero essere verificate attraverso test diretti.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Orchids: 会話から完全なアプリを構築するAI]]></title><description><![CDATA[Orchidsは自然言語の会話を、バックエンド、データベース、決済、ホスティングを備えた完全に機能するWebアプリケーションに20分以内で変換します。]]></description><link>https://vibecodingwithfred.com/ja/blog/orchids-ai-fullstack-platform/</link><guid isPermaLink="false">https://vibecodingwithfred.com/ja/blog/orchids-ai-fullstack-platform/</guid><dc:creator><![CDATA[Technology Analysis]]></dc:creator><pubDate>Thu, 23 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;プラットフォーム:&lt;/strong&gt; Orchids | &lt;strong&gt;開始価格:&lt;/strong&gt; $25/月 | &lt;strong&gt;速度:&lt;/strong&gt; 約15分でフルアプリ&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;orchidsの違い&quot;&gt;Orchidsの違い&lt;/h2&gt;
&lt;p&gt;誰かにアプリのアイデアを説明して、見ている間にその人が全体を構築するところを想像してください。データベース、認証、決済処理、すべてが15分でデプロイ準備完了。それがOrchidsです。&lt;/p&gt;
&lt;p&gt;他のAIツールはフロントエンドのモックアップを生成し、バックエンドは自分で解決するよう任せます。Orchidsは自然言語から完全で本番対応のアプリケーションを構築します。欲しいものを平易な英語で説明します。実際の機能を持つ動作するアプリケーションを構築します。きれいなインターフェースだけではありません。&lt;/p&gt;
&lt;p&gt;プラットフォームは最近、デザイン品質ベンチマークでトップランキングを主張し、ほとんどの自動ビルダーを悩ませるあの一般的な「AI生成」の見た目がないアプリケーションを生成しています。これらの主張が実際に成り立つかはユーザーが評価する必要がありますが、アプローチはテンプレートベースのシステムとは根本的に異なります。&lt;/p&gt;
&lt;h2 id=&quot;動作の仕組み&quot;&gt;動作の仕組み&lt;/h2&gt;
&lt;p&gt;ワークフローはこうです：「チームがタスクを作成し、メンバーに割り当て、費やした時間を追跡し、週次レポートを生成できるプロジェクト管理ツールを構築して。モダンでミニマルに見えるようにして。」のように入力します。&lt;/p&gt;
&lt;p&gt;Orchidsはアプリケーション全体を構築します。モックアップではなく、ユーザーアカウント、すべてのタスクと時間エントリを保存するデータベース、レポート生成のロジック、すべてをつなぎ合わせるインターフェースを備えた機能するシステムです。複雑さに応じて全プロセスは10〜20分かかります。&lt;/p&gt;
&lt;p&gt;会話は洗練を続けます。「ダッシュボードカードを小さくして。」「ダークモードを追加して。」「タスクが割り当てられたときにSlack通知を含めて。」各調整はチャットインターフェースを通じてリアルタイムで行われます。コード編集なし、デプロイサイクルなし、変更したいことを説明するだけです。&lt;/p&gt;
&lt;h2 id=&quot;フルスタックの現実&quot;&gt;フルスタックの現実&lt;/h2&gt;
&lt;p&gt;ほとんどのAIビルダーはフロントエンドで止まります。見栄えの良いインターフェースを生成し、認証を解決し、自分でデータベースをセットアップし、Stripeを自分で統合し、ホスティングを見つけるように言います。Orchidsはこれらすべてをプラットフォーム内で処理します。&lt;/p&gt;
&lt;p&gt;サブスクリプションベースのSaaSを求めると、単に決済ボタンを作成するだけではありません。決済処理を統合します。ユーザーアカウントをリクエストすると、安全なパスワード処理を備えた本物の認証を実装します。データベースは計画されるだけでなく、作成されて接続されます。この包括的なアプローチは、構築したものを実際に立ち上げられることを意味します。プロトタイプだけではありません。&lt;/p&gt;
&lt;h2 id=&quot;デザインの出発点としてのwebサイトクローン&quot;&gt;デザインの出発点としてのWebサイトクローン&lt;/h2&gt;
&lt;p&gt;興味深い機能の一つは、既存のWebサイトをデザインのインスピレーションとして参照できることです。Orchidsに「Linearのデザイン美学でフリーランサー向けに構築されたタスク管理アプリを作成して」と伝えると、参照されたサイトの視覚的言語を分析し、カスタムアプリケーションに適用します。これはコードやアセットのコピーではありません。デザインパターンを新しいものの基盤として使用しています。&lt;/p&gt;
&lt;h2 id=&quot;構築できるもの&quot;&gt;構築できるもの&lt;/h2&gt;
&lt;p&gt;プラットフォームはユーザーレポートとドキュメントに基づいて、いくつかのカテゴリのアプリケーションを合理的にうまく処理します。サブスクリプション課金、ユーザー管理、マルチテナントアーキテクチャを備えたSaaSアプリケーションが範囲内です。フォーム、アニメーション、レスポンシブデザインを備えたマーケティングWebサイトとランディングページは期待通りに動作します。CRM、在庫システム、レポートダッシュボードなどの内部ビジネスツールも構築可能です。デバイス間で動作するモバイルレスポンシブWebアプリケーションはサポートされていますが、ネイティブモバイルアプリはサポートされていません。&lt;/p&gt;
&lt;p&gt;スイートスポットは、小規模な開発チームがゼロから構築するのに数週間かかるようなアプリケーションのようです。SaaS製品のMVPバージョン、スプレッドシートを置き換えるカスタム内部ツール、迅速な納品が必要なクライアントプロジェクトを考えてください。&lt;/p&gt;
&lt;h2 id=&quot;考慮すべき実際の制限&quot;&gt;考慮すべき実際の制限&lt;/h2&gt;
&lt;p&gt;Orchidsは魔法ではなく、その境界を理解することが重要です。多数のエッジケースを持つ複雑なビジネスロジック（規制遵守を伴う財務モデリングや洗練されたアルゴリズムを考えてください）は、おそらくプラットフォームの限界に達するでしょう。既存のブランドガイドへのピクセルパーフェクトな準拠やカスタムUIコンポーネントが必要な場合は、おそらくコードをエクスポートして手動で変更する必要があります。&lt;/p&gt;
&lt;p&gt;数百ページや複雑なコンテンツ管理が必要な大規模アプリケーションは、システムを圧倒する可能性があります。プラットフォームは広大なエンタープライズシステムよりも、焦点を絞ったアプリケーションに最適化されているようです。プラットフォームの新しさを考えると、スケールでのパフォーマンスと長期的な信頼性は未解決の疑問として残ります。&lt;/p&gt;
&lt;p&gt;会話インターフェースは直感的ですが、特定の技術要件に対しては煩わしくなる可能性があります。どのデータベースインデックスが必要か、どのReactパターンを実装するかを正確に知っている場合があり、これを自然言語で説明するのは単にコーディングするより遅いかもしれません。&lt;/p&gt;
&lt;h2 id=&quot;最も恩恵を受ける人&quot;&gt;最も恩恵を受ける人&lt;/h2&gt;
&lt;p&gt;アイデアを検証する非技術系創業者は、コンセプトからテスト可能な製品への速さから恩恵を受けます。MVPのために開発者を見つけて管理するのに数ヶ月を費やす代わりに、午後に機能的なものを構築し、ユーザーフィードバックを得始めることができます。&lt;/p&gt;
&lt;p&gt;フリーランサーや代理店は、特に簡単なクライアントリクエストに対して、プロジェクトスループットを増やすことができます。技術的な制限のためにWebサイトプロジェクトを断っていたフリーランサーが、今では機能的なWebアプリケーションを納品できるようになります。&lt;/p&gt;
&lt;p&gt;プロダクトマネージャーは静的なモックアップの代わりに動作するプロトタイプを作成でき、ステークホルダーの賛同とユーザーテストをより意味のあるものにします。技術チームは最終ビルドにエンジニアリングリソースをコミットする前の高速プロトタイピングに使用するかもしれません。&lt;/p&gt;
&lt;h2 id=&quot;コスト対効果分析&quot;&gt;コスト対効果分析&lt;/h2&gt;
&lt;p&gt;基本ティアで月額$25で、Orchidsはシンプルなウェブサイトビルダーより高価ですが、開発者を雇ったりエンタープライズローコードプラットフォームを使用したりするよりはるかに安価です。真のコスト考慮はサブスクリプションではなく、潜在的な技術的負債とベンダーロックインです。必要に応じてコードをエクスポートして変更できますか？Orchidsがシャットダウンしたり、価格設定を大幅に変更したりしたらどうなりますか？移行はどれくらい難しいでしょうか？&lt;/p&gt;
&lt;p&gt;MVP検証や短期プロジェクトでは、これらのリスクは許容できるかもしれません。長期的でミッションクリティカルなアプリケーションでは、慎重な検討が必要です。&lt;/p&gt;
&lt;h2 id=&quot;インテリジェントに始める&quot;&gt;インテリジェントに始める&lt;/h2&gt;
&lt;p&gt;Orchidsを検討しているなら、重要でないものから始めてください。チームが必要とする内部ツールや、延期していたサイドプロジェクトを構築してください。これにより、重要なプロジェクトをリスクにさらすことなく、プラットフォームの実際の機能とマーケティング上の主張を評価できます。&lt;/p&gt;
&lt;p&gt;プラットフォームと戦う時間と構築する時間の比率に注意を払ってください。常に制限を回避しているか、会話インターフェースが助けよりも障害になっている場合、それは価値あるデータです。一部のプロジェクトは完璧なフィットになり、他は従来の開発がまだその場所を持っている理由を明らかにします。&lt;/p&gt;
&lt;h2 id=&quot;結論&quot;&gt;結論&lt;/h2&gt;
&lt;p&gt;Orchidsはノーコードプラットフォームの興味深い進化を表しています。クイックウェブサイトビルダーとフルアプリケーション開発の間のギャップを埋めようとするものです。会話インターフェースと包括的なスタック処理は、重要な技術的障壁を取り除き、アプリケーション開発を意味のある方法で民主化する可能性があります。&lt;/p&gt;
&lt;p&gt;これらの約束を十分に一貫して提供し、採用を正当化するかどうかは、あなたの具体的なユースケース、技術要件、リスク許容度によります。プラットフォームのアプローチは革新的ですが、革新はすべてのプロジェクトに適した解決策であることを意味しません。&lt;/p&gt;
&lt;p&gt;高速なプロトタイピング、MVP開発、完璧なカスタマイズよりもスピードが重要な簡単なアプリケーションに対して、Orchidsは魅力的な機能を提供します。複雑で高度にカスタマイズされた、またはミッションクリティカルなアプリケーションには、従来の開発またはより確立されたプラットフォームがまだ賢明な選択かもしれません。&lt;/p&gt;
&lt;p&gt;重要なのは、何をトレードしているかを理解することです：スピードとアクセシビリティのために完全な制御とカスタマイズを交換しています。そのトレードがあなたの具体的な状況に意味があるかどうかを判断してください。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;リソース&quot;&gt;リソース&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;公式ウェブサイト&lt;/strong&gt;: orchids.app
&lt;strong&gt;コミュニティ&lt;/strong&gt;: Discord（公式チャンネルからアクセス可能）
&lt;strong&gt;価格&lt;/strong&gt;: $25/月から、無料ティアあり
&lt;strong&gt;設立&lt;/strong&gt;: Y Combinator Winter 2025バッチ&lt;/p&gt;
&lt;p&gt;&lt;em&gt;この分析は利用可能なドキュメントと報告されたユーザー体験に基づいています。実際のパフォーマンスは直接テストで確認する必要があります。&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Claude Code: Terminal-Based AI Coding Assistant]]></title><description><![CDATA[Claude Code is a terminal-based AI coding assistant that lets developers build applications through natural language conversations.]]></description><link>https://vibecodingwithfred.com/blog/claude-code-cli-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/claude-code-cli-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 22 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Platform:&lt;/strong&gt; Claude Code | &lt;strong&gt;Provider:&lt;/strong&gt; Anthropic | &lt;strong&gt;Interface:&lt;/strong&gt; Terminal/CLI&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;what-claude-code-is&quot;&gt;What Claude Code Is&lt;/h2&gt;
&lt;p&gt;Claude Code is Anthropic&apos;s terminal-based coding assistant that runs in your command line. You interact with it through natural language to generate code, debug issues, refactor existing code, and manage development tasks. It operates within your project directory and can read, write, and modify files based on your instructions.&lt;/p&gt;
&lt;p&gt;The tool integrates with your existing development workflow rather than replacing it. You still use your preferred editor, version control, and deployment tools. Claude Code acts as an assistant that handles the implementation details while you focus on architecture and requirements.&lt;/p&gt;
&lt;h2 id=&quot;how-it-works&quot;&gt;How It Works&lt;/h2&gt;
&lt;p&gt;Claude Code operates through a conversational interface in your terminal. You describe what you need in plain English, and it generates or modifies code accordingly. The tool maintains context about your project structure, coding patterns, and previous interactions within a session.&lt;/p&gt;
&lt;p&gt;When you start Claude Code in a project directory, it can analyze your codebase to understand the architecture, frameworks, and patterns you&apos;re using. This context helps it generate code that matches your existing style and integrates properly with your project.&lt;/p&gt;
&lt;p&gt;The basic workflow involves describing a feature or fix you need, reviewing the generated code, testing it, and then iterating based on results. Claude Code can handle multi-file changes, understand dependencies between components, and maintain consistency across your codebase.&lt;/p&gt;
&lt;h2 id=&quot;core-capabilities&quot;&gt;Core Capabilities&lt;/h2&gt;
&lt;p&gt;Claude Code can generate new code files from descriptions, creating complete components, API endpoints, database models, and test suites. It understands common frameworks and libraries, generating idiomatic code for React, Vue, Express, Django, Rails, and other popular tools.&lt;/p&gt;
&lt;p&gt;For existing code, it can refactor functions and classes, update deprecated APIs, improve performance, fix bugs, and add error handling. The tool can analyze code for potential issues, suggest improvements, and implement fixes.&lt;/p&gt;
&lt;p&gt;Test generation is another key feature. Claude Code can create unit tests, integration tests, and end-to-end tests based on your existing code. It understands testing frameworks like Jest, Pytest, RSpec, and others.&lt;/p&gt;
&lt;p&gt;The tool also handles documentation tasks, generating README files, API documentation, inline comments, and docstrings that explain complex code sections.&lt;/p&gt;
&lt;h2 id=&quot;technical-requirements&quot;&gt;Technical Requirements&lt;/h2&gt;
&lt;p&gt;Claude Code requires an Anthropic API key to function. This means you need an account with Anthropic and will be charged based on API usage. The pricing model follows Anthropic&apos;s standard API rates for the Claude model you&apos;re using.&lt;/p&gt;
&lt;p&gt;The tool runs on macOS, Linux, and Windows (through WSL). It requires Node.js 18+ if installing via npm, though native installers are available for direct installation. Your terminal needs to support standard Unix commands for file operations.&lt;/p&gt;
&lt;h2 id=&quot;practical-limitations&quot;&gt;Practical Limitations&lt;/h2&gt;
&lt;p&gt;Claude Code operates within the context window limits of the underlying Claude model. For large codebases, it may not be able to consider every file simultaneously. You need to be strategic about which files and context you provide for complex operations.&lt;/p&gt;
&lt;p&gt;The tool cannot directly execute code or run tests. You still need to run your development server, execute test suites, and verify that generated code works as expected. Claude Code generates code but doesn&apos;t validate that it runs correctly.&lt;/p&gt;
&lt;p&gt;Complex architectural decisions, system design, and business logic still require human judgment. Claude Code implements based on your specifications but won&apos;t independently decide how to structure your application or what features to build.&lt;/p&gt;
&lt;p&gt;Generated code may need adjustment for production use. While Claude Code produces functional code, you should review it for security, performance, and adherence to your team&apos;s standards before deploying.&lt;/p&gt;
&lt;h2 id=&quot;who-should-use-it&quot;&gt;Who Should Use It&lt;/h2&gt;
&lt;p&gt;Developers comfortable with terminal interfaces will find Claude Code fits naturally into their workflow. It&apos;s particularly useful for those who spend most of their time in the command line and prefer text-based interfaces over GUIs.&lt;/p&gt;
&lt;p&gt;Teams working on greenfield projects benefit from rapid prototyping capabilities. You can quickly generate boilerplate code, set up project structures, and implement standard features without manual coding.&lt;/p&gt;
&lt;p&gt;Developers learning new frameworks or languages can use Claude Code to understand patterns and best practices. The generated code serves as examples of idiomatic implementations in unfamiliar technologies.&lt;/p&gt;
&lt;p&gt;Those working on legacy codebases can leverage Claude Code for modernization tasks like updating dependencies, refactoring old patterns, and adding tests to untested code.&lt;/p&gt;
&lt;h2 id=&quot;integration-points&quot;&gt;Integration Points&lt;/h2&gt;
&lt;p&gt;Claude Code works alongside your existing tools rather than replacing them. You continue using Git for version control, with Claude Code generating code that you then commit. Your IDE or text editor remains your primary interface for reviewing and editing code.&lt;/p&gt;
&lt;p&gt;Testing frameworks, build tools, and deployment pipelines operate independently of Claude Code. The tool generates code that works with these systems but doesn&apos;t control them directly.&lt;/p&gt;
&lt;p&gt;For teams, Claude Code fits into existing development processes. One developer might use it to generate initial implementations that others review through normal code review processes.&lt;/p&gt;
&lt;h2 id=&quot;cost-considerations&quot;&gt;Cost Considerations&lt;/h2&gt;
&lt;p&gt;Usage costs depend on the amount of context you provide and the length of responses. Each interaction consumes API tokens based on the size of your prompts and the generated code. Large refactoring operations or extensive code generation sessions can accumulate significant token usage.&lt;/p&gt;
&lt;p&gt;Projects with many files or complex requirements may require multiple interactions to achieve desired results, increasing costs. You should monitor your API usage and set appropriate limits based on your budget.&lt;/p&gt;
&lt;p&gt;The value proposition depends on your use case. If Claude Code saves hours of development time, the API costs may be negligible compared to developer salaries. For hobby projects or learning, costs need more careful consideration.&lt;/p&gt;
&lt;h2 id=&quot;getting-real-value&quot;&gt;Getting Real Value&lt;/h2&gt;
&lt;p&gt;Focus on specific, well-defined tasks rather than vague requests. &quot;Add error handling to the user authentication endpoints&quot; produces better results than &quot;improve the code.&quot; Clear specifications lead to more accurate implementations.&lt;/p&gt;
&lt;p&gt;Build incrementally rather than attempting massive changes at once. Generate one component, test it, then move to the next. This approach helps maintain code quality and makes debugging easier when issues arise.&lt;/p&gt;
&lt;p&gt;Maintain project documentation that Claude Code can reference. README files, API specifications, and architecture documents provide context that improves code generation quality.&lt;/p&gt;
&lt;p&gt;Review generated code before committing. While Claude Code produces functional implementations, human review catches edge cases, ensures security best practices, and maintains code quality standards.&lt;/p&gt;
&lt;h2 id=&quot;bottom-line&quot;&gt;Bottom Line&lt;/h2&gt;
&lt;p&gt;Claude Code is a practical tool for developers who want AI assistance without leaving their terminal. It handles routine coding tasks, helps with refactoring, and accelerates development when used appropriately.&lt;/p&gt;
&lt;p&gt;The tool works best as an assistant rather than a replacement for developer expertise. You still need to understand your architecture, make design decisions, and ensure code quality. Claude Code handles implementation details based on your guidance.&lt;/p&gt;
&lt;p&gt;For developers comfortable with terminal workflows and clear about their requirements, Claude Code can significantly accelerate development. The key is understanding its capabilities and limitations, then applying it where it provides the most value.&lt;/p&gt;
&lt;h3 id=&quot;comparing-ai-coding-assistants&quot;&gt;Comparing AI Coding Assistants&lt;/h3&gt;
&lt;p&gt;If you&apos;re evaluating different AI coding tools, you might also want to explore &lt;strong&gt;&lt;a href=&quot;/blog/codex-cli-ultimate-guide/&quot;&gt;Codex CLI with GPT-5&lt;/a&gt;&lt;/strong&gt;, which offers different strengths including leaked Cursor production prompts and specialized reasoning modes. Each tool has unique capabilities—Claude Code excels at terminal integration and natural conversation, while Codex leverages GPT-5&apos;s advanced reasoning for complex refactors.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;technical-information&quot;&gt;Technical Information&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Provider&lt;/strong&gt;: Anthropic&lt;br&gt;
&lt;strong&gt;Interface&lt;/strong&gt;: Command-line interface (CLI)&lt;br&gt;
&lt;strong&gt;Platforms&lt;/strong&gt;: macOS, Linux, Windows (WSL)&lt;br&gt;
&lt;strong&gt;Requirements&lt;/strong&gt;: Anthropic API key, Node.js 18+ (for npm installation)&lt;br&gt;
&lt;strong&gt;Documentation&lt;/strong&gt;: Available at docs.anthropic.com&lt;br&gt;
&lt;strong&gt;API Pricing&lt;/strong&gt;: Based on Anthropic&apos;s standard rates per token&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: This analysis reflects Claude Code&apos;s capabilities as a terminal-based coding assistant. Actual performance depends on specific use cases and implementation approach.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Claude Code: Terminal-basierter KI-Coding-Assistent]]></title><description><![CDATA[Claude Code ist ein terminal-basierter KI-Coding-Assistent, der Entwicklern ermoeglicht, Anwendungen durch natuerlichsprachliche Konversationen zu erstellen.]]></description><link>https://vibecodingwithfred.com/de/blog/claude-code-cli-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/de/blog/claude-code-cli-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 22 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Plattform:&lt;/strong&gt; Claude Code | &lt;strong&gt;Anbieter:&lt;/strong&gt; Anthropic | &lt;strong&gt;Schnittstelle:&lt;/strong&gt; Terminal/CLI&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;was-claude-code-ist&quot;&gt;Was Claude Code ist&lt;/h2&gt;
&lt;p&gt;Claude Code ist Anthropics terminal-basierter Coding-Assistent, der in Ihrer Kommandozeile laeuft. Sie interagieren mit ihm durch natuerliche Sprache, um Code zu generieren, Probleme zu debuggen, bestehenden Code zu refaktorieren und Entwicklungsaufgaben zu verwalten. Er operiert in Ihrem Projektverzeichnis und kann Dateien basierend auf Ihren Anweisungen lesen, schreiben und modifizieren.&lt;/p&gt;
&lt;p&gt;Das Tool integriert sich in Ihren bestehenden Entwicklungs-Workflow, anstatt ihn zu ersetzen. Sie verwenden weiterhin Ihren bevorzugten Editor, Versionskontrolle und Deployment-Tools. Claude Code agiert als Assistent, der die Implementierungsdetails handhabt, waehrend Sie sich auf Architektur und Anforderungen konzentrieren.&lt;/p&gt;
&lt;h2 id=&quot;wie-es-funktioniert&quot;&gt;Wie es funktioniert&lt;/h2&gt;
&lt;p&gt;Claude Code operiert durch eine konversationelle Schnittstelle in Ihrem Terminal. Sie beschreiben, was Sie benoetigen, in einfachem Deutsch, und es generiert oder modifiziert Code entsprechend. Das Tool behaelt den Kontext ueber Ihre Projektstruktur, Coding-Muster und fruehere Interaktionen innerhalb einer Sitzung.&lt;/p&gt;
&lt;p&gt;Wenn Sie Claude Code in einem Projektverzeichnis starten, kann es Ihre Codebase analysieren, um die Architektur, Frameworks und Muster zu verstehen, die Sie verwenden. Dieser Kontext hilft ihm, Code zu generieren, der Ihrem bestehenden Stil entspricht und sich richtig in Ihr Projekt integriert.&lt;/p&gt;
&lt;p&gt;Der grundlegende Workflow beinhaltet das Beschreiben eines Features oder Fixes, das Sie benoetigen, das Ueberpruefen des generierten Codes, das Testen und dann das Iterieren basierend auf Ergebnissen. Claude Code kann Multi-Datei-Aenderungen handhaben, Abhaengigkeiten zwischen Komponenten verstehen und Konsistenz ueber Ihre Codebase hinweg aufrechterhalten.&lt;/p&gt;
&lt;h2 id=&quot;kernfaehigkeiten&quot;&gt;Kernfaehigkeiten&lt;/h2&gt;
&lt;p&gt;Claude Code kann neue Code-Dateien aus Beschreibungen generieren und vollstaendige Komponenten, API-Endpunkte, Datenbankmodelle und Test-Suites erstellen. Es versteht gaengige Frameworks und Bibliotheken und generiert idiomatischen Code fuer React, Vue, Express, Django, Rails und andere beliebte Tools.&lt;/p&gt;
&lt;p&gt;Fuer bestehenden Code kann es Funktionen und Klassen refaktorieren, veraltete APIs aktualisieren, Performance verbessern, Bugs beheben und Fehlerbehandlung hinzufuegen. Das Tool kann Code auf potenzielle Probleme analysieren, Verbesserungen vorschlagen und Fixes implementieren.&lt;/p&gt;
&lt;p&gt;Test-Generierung ist eine weitere Schluesselfunktion. Claude Code kann Unit-Tests, Integrationstests und End-to-End-Tests basierend auf Ihrem bestehenden Code erstellen. Es versteht Test-Frameworks wie Jest, Pytest, RSpec und andere.&lt;/p&gt;
&lt;p&gt;Das Tool handhabt auch Dokumentationsaufgaben, generiert README-Dateien, API-Dokumentation, Inline-Kommentare und Docstrings, die komplexe Code-Abschnitte erklaeren.&lt;/p&gt;
&lt;h2 id=&quot;technische-anforderungen&quot;&gt;Technische Anforderungen&lt;/h2&gt;
&lt;p&gt;Claude Code benoetigt einen Anthropic API-Schluessel zum Funktionieren. Das bedeutet, Sie benoetigen ein Konto bei Anthropic und werden basierend auf API-Nutzung abgerechnet. Das Preismodell folgt Anthropics Standard-API-Tarifen fuer das Claude-Modell, das Sie verwenden.&lt;/p&gt;
&lt;p&gt;Das Tool laeuft auf macOS, Linux und Windows (ueber WSL). Es benoetigt Node.js 18+, wenn Sie ueber npm installieren, obwohl native Installer fuer direkte Installation verfuegbar sind. Ihr Terminal muss Standard-Unix-Befehle fuer Dateioperationen unterstuetzen.&lt;/p&gt;
&lt;h2 id=&quot;praktische-einschraenkungen&quot;&gt;Praktische Einschraenkungen&lt;/h2&gt;
&lt;p&gt;Claude Code operiert innerhalb der Kontextfenster-Grenzen des zugrunde liegenden Claude-Modells. Fuer grosse Codebasen ist es moeglicherweise nicht in der Lage, jede Datei gleichzeitig zu beruecksichtigen. Sie muessen strategisch vorgehen, welche Dateien und welchen Kontext Sie fuer komplexe Operationen bereitstellen.&lt;/p&gt;
&lt;p&gt;Das Tool kann Code nicht direkt ausfuehren oder Tests laufen lassen. Sie muessen immer noch Ihren Entwicklungsserver starten, Test-Suites ausfuehren und verifizieren, dass generierter Code wie erwartet funktioniert. Claude Code generiert Code, validiert aber nicht, dass er korrekt laeuft.&lt;/p&gt;
&lt;p&gt;Komplexe architektonische Entscheidungen, Systemdesign und Geschaeftslogik erfordern immer noch menschliches Urteil. Claude Code implementiert basierend auf Ihren Spezifikationen, entscheidet aber nicht eigenstaendig, wie Ihre Anwendung strukturiert werden soll oder welche Features zu bauen sind.&lt;/p&gt;
&lt;p&gt;Generierter Code kann Anpassungen fuer den Produktionseinsatz benoetigen. Waehrend Claude Code funktionalen Code produziert, sollten Sie ihn auf Sicherheit, Performance und Einhaltung Ihrer Team-Standards ueberpruefen, bevor Sie deployen.&lt;/p&gt;
&lt;h2 id=&quot;wer-sollte-es-nutzen&quot;&gt;Wer sollte es nutzen&lt;/h2&gt;
&lt;p&gt;Entwickler, die mit Terminal-Schnittstellen vertraut sind, werden feststellen, dass Claude Code natuerlich in ihren Workflow passt. Es ist besonders nuetzlich fuer diejenigen, die die meiste Zeit in der Kommandozeile verbringen und text-basierte Schnittstellen gegenueber GUIs bevorzugen.&lt;/p&gt;
&lt;p&gt;Teams, die an Greenfield-Projekten arbeiten, profitieren von schnellen Prototyping-Faehigkeiten. Sie koennen schnell Boilerplate-Code generieren, Projektstrukturen einrichten und Standard-Features ohne manuelles Coding implementieren.&lt;/p&gt;
&lt;p&gt;Entwickler, die neue Frameworks oder Sprachen lernen, koennen Claude Code verwenden, um Muster und Best Practices zu verstehen. Der generierte Code dient als Beispiele fuer idiomatische Implementierungen in unbekannten Technologien.&lt;/p&gt;
&lt;p&gt;Diejenigen, die an Legacy-Codebasen arbeiten, koennen Claude Code fuer Modernisierungsaufgaben nutzen, wie das Aktualisieren von Abhaengigkeiten, das Refaktorieren alter Muster und das Hinzufuegen von Tests zu ungetestetem Code.&lt;/p&gt;
&lt;h2 id=&quot;integrationspunkte&quot;&gt;Integrationspunkte&lt;/h2&gt;
&lt;p&gt;Claude Code arbeitet neben Ihren bestehenden Tools, anstatt sie zu ersetzen. Sie verwenden weiterhin Git fuer Versionskontrolle, wobei Claude Code Code generiert, den Sie dann committen. Ihre IDE oder Ihr Texteditor bleibt Ihre primaere Schnittstelle fuer das Ueberpruefen und Bearbeiten von Code.&lt;/p&gt;
&lt;p&gt;Test-Frameworks, Build-Tools und Deployment-Pipelines operieren unabhaengig von Claude Code. Das Tool generiert Code, der mit diesen Systemen funktioniert, kontrolliert sie aber nicht direkt.&lt;/p&gt;
&lt;p&gt;Fuer Teams passt Claude Code in bestehende Entwicklungsprozesse. Ein Entwickler koennte es verwenden, um initiale Implementierungen zu generieren, die andere durch normale Code-Review-Prozesse ueberpruefen.&lt;/p&gt;
&lt;h2 id=&quot;kostenerwaegungen&quot;&gt;Kostenerwaegungen&lt;/h2&gt;
&lt;p&gt;Nutzungskosten haengen von der Menge des Kontexts ab, den Sie bereitstellen, und der Laenge der Antworten. Jede Interaktion verbraucht API-Tokens basierend auf der Groesse Ihrer Prompts und des generierten Codes. Grosse Refactoring-Operationen oder umfangreiche Code-Generierungssitzungen koennen erheblichen Token-Verbrauch akkumulieren.&lt;/p&gt;
&lt;p&gt;Projekte mit vielen Dateien oder komplexen Anforderungen erfordern moeglicherweise mehrere Interaktionen, um gewuenschte Ergebnisse zu erzielen, was die Kosten erhoeht. Sie sollten Ihre API-Nutzung ueberwachen und angemessene Limits basierend auf Ihrem Budget setzen.&lt;/p&gt;
&lt;p&gt;Das Wertversprechen haengt von Ihrem Anwendungsfall ab. Wenn Claude Code Stunden an Entwicklungszeit spart, sind die API-Kosten moeglicherweise vernachlaessigbar im Vergleich zu Entwicklergehaeltern. Fuer Hobby-Projekte oder Lernen erfordern Kosten sorgfaeltigere Ueberlegung.&lt;/p&gt;
&lt;h2 id=&quot;echten-wert-erzielen&quot;&gt;Echten Wert erzielen&lt;/h2&gt;
&lt;p&gt;Konzentrieren Sie sich auf spezifische, klar definierte Aufgaben anstatt vager Anfragen. &quot;Fuege Fehlerbehandlung zu den Benutzerauthentifizierungs-Endpunkten hinzu&quot; produziert bessere Ergebnisse als &quot;verbessere den Code.&quot; Klare Spezifikationen fuehren zu genaueren Implementierungen.&lt;/p&gt;
&lt;p&gt;Bauen Sie inkrementell, anstatt massive Aenderungen auf einmal zu versuchen. Generieren Sie eine Komponente, testen Sie sie, dann gehen Sie zur naechsten ueber. Dieser Ansatz hilft, Code-Qualitaet aufrechtzuerhalten und erleichtert das Debuggen, wenn Probleme auftreten.&lt;/p&gt;
&lt;p&gt;Pflegen Sie Projektdokumentation, auf die Claude Code verweisen kann. README-Dateien, API-Spezifikationen und Architektur-Dokumente bieten Kontext, der die Code-Generierungsqualitaet verbessert.&lt;/p&gt;
&lt;p&gt;Ueberpruefen Sie generierten Code vor dem Committen. Waehrend Claude Code funktionale Implementierungen produziert, erkennt menschliche Ueberpruefung Randfaelle, stellt Sicherheits-Best-Practices sicher und erhaelt Code-Qualitaetsstandards.&lt;/p&gt;
&lt;h2 id=&quot;fazit&quot;&gt;Fazit&lt;/h2&gt;
&lt;p&gt;Claude Code ist ein praktisches Tool fuer Entwickler, die KI-Unterstuetzung wollen, ohne ihr Terminal zu verlassen. Es handhabt Routine-Coding-Aufgaben, hilft beim Refactoring und beschleunigt die Entwicklung, wenn es angemessen eingesetzt wird.&lt;/p&gt;
&lt;p&gt;Das Tool funktioniert am besten als Assistent und nicht als Ersatz fuer Entwickler-Expertise. Sie muessen immer noch Ihre Architektur verstehen, Design-Entscheidungen treffen und Code-Qualitaet sicherstellen. Claude Code handhabt Implementierungsdetails basierend auf Ihrer Anleitung.&lt;/p&gt;
&lt;p&gt;Fuer Entwickler, die mit Terminal-Workflows vertraut sind und klare Anforderungen haben, kann Claude Code die Entwicklung erheblich beschleunigen. Der Schluessel ist, seine Faehigkeiten und Grenzen zu verstehen und es dann dort anzuwenden, wo es den meisten Wert bietet.&lt;/p&gt;
&lt;h3 id=&quot;vergleich-von-ki-coding-assistenten&quot;&gt;Vergleich von KI-Coding-Assistenten&lt;/h3&gt;
&lt;p&gt;Wenn Sie verschiedene KI-Coding-Tools evaluieren, moechten Sie vielleicht auch &lt;strong&gt;&lt;a href=&quot;/blog/codex-cli-ultimate-guide/&quot;&gt;Codex CLI mit GPT-5&lt;/a&gt;&lt;/strong&gt; erkunden, das verschiedene Staerken bietet, einschliesslich geleakter Cursor-Produktionsprompts und spezialisierter Reasoning-Modi. Jedes Tool hat einzigartige Faehigkeiten - Claude Code exzelliert bei Terminal-Integration und natuerlicher Konversation, waehrend Codex GPT-5s fortgeschrittenes Reasoning fuer komplexe Refaktors nutzt.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;technische-informationen&quot;&gt;Technische Informationen&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Anbieter&lt;/strong&gt;: Anthropic
&lt;strong&gt;Schnittstelle&lt;/strong&gt;: Kommandozeilen-Interface (CLI)
&lt;strong&gt;Plattformen&lt;/strong&gt;: macOS, Linux, Windows (WSL)
&lt;strong&gt;Anforderungen&lt;/strong&gt;: Anthropic API-Schluessel, Node.js 18+ (fuer npm-Installation)
&lt;strong&gt;Dokumentation&lt;/strong&gt;: Verfuegbar unter docs.anthropic.com
&lt;strong&gt;API-Preise&lt;/strong&gt;: Basierend auf Anthropics Standard-Tarifen pro Token&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Hinweis: Diese Analyse spiegelt Claude Codes Faehigkeiten als terminal-basierter Coding-Assistent wider. Tatsaechliche Performance haengt von spezifischen Anwendungsfaellen und Implementierungsansatz ab.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Claude Code: Asistente de Codificacion con IA Basado en Terminal]]></title><description><![CDATA[Claude Code es un asistente de codificacion con IA basado en terminal que permite a los desarrolladores construir aplicaciones a traves de conversaciones en lenguaje natural.]]></description><link>https://vibecodingwithfred.com/es/blog/claude-code-cli-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/es/blog/claude-code-cli-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 22 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Plataforma:&lt;/strong&gt; Claude Code | &lt;strong&gt;Proveedor:&lt;/strong&gt; Anthropic | &lt;strong&gt;Interfaz:&lt;/strong&gt; Terminal/CLI&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;que-es-claude-code&quot;&gt;Que es Claude Code&lt;/h2&gt;
&lt;p&gt;Claude Code es el asistente de codificacion basado en terminal de Anthropic que se ejecuta en tu linea de comandos. Interactuas con el a traves de lenguaje natural para generar codigo, depurar problemas, refactorizar codigo existente y gestionar tareas de desarrollo. Opera dentro del directorio de tu proyecto y puede leer, escribir y modificar archivos basandose en tus instrucciones.&lt;/p&gt;
&lt;p&gt;La herramienta se integra con tu flujo de trabajo de desarrollo existente en lugar de reemplazarlo. Sigues usando tu editor preferido, control de versiones y herramientas de despliegue. Claude Code actua como un asistente que maneja los detalles de implementacion mientras te enfocas en arquitectura y requerimientos.&lt;/p&gt;
&lt;h2 id=&quot;como-funciona&quot;&gt;Como Funciona&lt;/h2&gt;
&lt;p&gt;Claude Code opera a traves de una interfaz conversacional en tu terminal. Describes lo que necesitas en espanol simple, y genera o modifica codigo en consecuencia. La herramienta mantiene contexto sobre la estructura de tu proyecto, patrones de codificacion e interacciones previas dentro de una sesion.&lt;/p&gt;
&lt;p&gt;Cuando inicias Claude Code en un directorio de proyecto, puede analizar tu codebase para entender la arquitectura, frameworks y patrones que estas usando. Este contexto le ayuda a generar codigo que coincida con tu estilo existente y se integre correctamente con tu proyecto.&lt;/p&gt;
&lt;p&gt;El flujo de trabajo basico involucra describir una funcion o correccion que necesitas, revisar el codigo generado, probarlo, y luego iterar basandose en los resultados. Claude Code puede manejar cambios en multiples archivos, entender dependencias entre componentes y mantener consistencia a traves de tu codebase.&lt;/p&gt;
&lt;h2 id=&quot;capacidades-principales&quot;&gt;Capacidades Principales&lt;/h2&gt;
&lt;p&gt;Claude Code puede generar nuevos archivos de codigo desde descripciones, creando componentes completos, endpoints de API, modelos de base de datos y suites de tests. Entiende frameworks y librerias comunes, generando codigo idiomatico para React, Vue, Express, Django, Rails y otras herramientas populares.&lt;/p&gt;
&lt;p&gt;Para codigo existente, puede refactorizar funciones y clases, actualizar APIs deprecadas, mejorar rendimiento, corregir bugs y agregar manejo de errores. La herramienta puede analizar codigo por problemas potenciales, sugerir mejoras e implementar correcciones.&lt;/p&gt;
&lt;p&gt;La generacion de tests es otra funcion clave. Claude Code puede crear tests unitarios, tests de integracion y tests end-to-end basandose en tu codigo existente. Entiende frameworks de testing como Jest, Pytest, RSpec y otros.&lt;/p&gt;
&lt;p&gt;La herramienta tambien maneja tareas de documentacion, generando archivos README, documentacion de API, comentarios en linea y docstrings que explican secciones complejas de codigo.&lt;/p&gt;
&lt;h2 id=&quot;requerimientos-tecnicos&quot;&gt;Requerimientos Tecnicos&lt;/h2&gt;
&lt;p&gt;Claude Code requiere una clave de API de Anthropic para funcionar. Esto significa que necesitas una cuenta con Anthropic y se te cobrara basandose en el uso de la API. El modelo de precios sigue las tarifas estandar de la API de Anthropic para el modelo Claude que estas usando.&lt;/p&gt;
&lt;p&gt;La herramienta corre en macOS, Linux y Windows (a traves de WSL). Requiere Node.js 18+ si se instala via npm, aunque hay instaladores nativos disponibles para instalacion directa. Tu terminal necesita soportar comandos Unix estandar para operaciones de archivos.&lt;/p&gt;
&lt;h2 id=&quot;limitaciones-practicas&quot;&gt;Limitaciones Practicas&lt;/h2&gt;
&lt;p&gt;Claude Code opera dentro de los limites de ventana de contexto del modelo Claude subyacente. Para codebases grandes, puede no ser capaz de considerar cada archivo simultaneamente. Necesitas ser estrategico sobre que archivos y contexto proporcionas para operaciones complejas.&lt;/p&gt;
&lt;p&gt;La herramienta no puede ejecutar codigo directamente o correr tests. Aun necesitas ejecutar tu servidor de desarrollo, ejecutar suites de tests y verificar que el codigo generado funcione como se espera. Claude Code genera codigo pero no valida que corra correctamente.&lt;/p&gt;
&lt;p&gt;Las decisiones arquitectonicas complejas, diseno de sistemas y logica de negocio aun requieren juicio humano. Claude Code implementa basandose en tus especificaciones pero no decidira independientemente como estructurar tu aplicacion o que funciones construir.&lt;/p&gt;
&lt;p&gt;El codigo generado puede necesitar ajustes para uso en produccion. Mientras Claude Code produce codigo funcional, deberias revisarlo por seguridad, rendimiento y adherencia a los estandares de tu equipo antes de desplegarlo.&lt;/p&gt;
&lt;h2 id=&quot;quien-deberia-usarlo&quot;&gt;Quien Deberia Usarlo&lt;/h2&gt;
&lt;p&gt;Los desarrolladores comodos con interfaces de terminal encontraran que Claude Code encaja naturalmente en su flujo de trabajo. Es particularmente util para aquellos que pasan la mayor parte de su tiempo en la linea de comandos y prefieren interfaces basadas en texto sobre GUIs.&lt;/p&gt;
&lt;p&gt;Los equipos trabajando en proyectos greenfield se benefician de las capacidades de prototipado rapido. Puedes generar rapidamente codigo boilerplate, configurar estructuras de proyecto e implementar funciones estandar sin codificacion manual.&lt;/p&gt;
&lt;p&gt;Los desarrolladores aprendiendo nuevos frameworks o lenguajes pueden usar Claude Code para entender patrones y mejores practicas. El codigo generado sirve como ejemplos de implementaciones idiomaticas en tecnologias desconocidas.&lt;/p&gt;
&lt;p&gt;Aquellos trabajando en codebases legacy pueden aprovechar Claude Code para tareas de modernizacion como actualizar dependencias, refactorizar patrones viejos y agregar tests a codigo sin probar.&lt;/p&gt;
&lt;h2 id=&quot;puntos-de-integracion&quot;&gt;Puntos de Integracion&lt;/h2&gt;
&lt;p&gt;Claude Code trabaja junto a tus herramientas existentes en lugar de reemplazarlas. Continuas usando Git para control de versiones, con Claude Code generando codigo que luego commiteas. Tu IDE o editor de texto sigue siendo tu interfaz principal para revisar y editar codigo.&lt;/p&gt;
&lt;p&gt;Los frameworks de testing, herramientas de build y pipelines de despliegue operan independientemente de Claude Code. La herramienta genera codigo que funciona con estos sistemas pero no los controla directamente.&lt;/p&gt;
&lt;p&gt;Para equipos, Claude Code encaja en procesos de desarrollo existentes. Un desarrollador podria usarlo para generar implementaciones iniciales que otros revisan a traves de procesos normales de revision de codigo.&lt;/p&gt;
&lt;h2 id=&quot;consideraciones-de-costo&quot;&gt;Consideraciones de Costo&lt;/h2&gt;
&lt;p&gt;Los costos de uso dependen de la cantidad de contexto que proporcionas y la longitud de las respuestas. Cada interaccion consume tokens de API basandose en el tamano de tus prompts y el codigo generado. Las operaciones de refactorizacion grandes o sesiones extensas de generacion de codigo pueden acumular uso significativo de tokens.&lt;/p&gt;
&lt;p&gt;Los proyectos con muchos archivos o requerimientos complejos pueden requerir multiples interacciones para lograr los resultados deseados, aumentando los costos. Deberias monitorear tu uso de API y establecer limites apropiados basados en tu presupuesto.&lt;/p&gt;
&lt;p&gt;La propuesta de valor depende de tu caso de uso. Si Claude Code te ahorra horas de tiempo de desarrollo, los costos de API pueden ser insignificantes comparados con los salarios de desarrolladores. Para proyectos hobby o aprendizaje, los costos necesitan consideracion mas cuidadosa.&lt;/p&gt;
&lt;h2 id=&quot;obteniendo-valor-real&quot;&gt;Obteniendo Valor Real&lt;/h2&gt;
&lt;p&gt;Enfocate en tareas especificas y bien definidas en lugar de solicitudes vagas. &quot;Agrega manejo de errores a los endpoints de autenticacion de usuario&quot; produce mejores resultados que &quot;mejora el codigo.&quot; Especificaciones claras llevan a implementaciones mas precisas.&lt;/p&gt;
&lt;p&gt;Construye incrementalmente en lugar de intentar cambios masivos de una vez. Genera un componente, pruebalo, luego pasa al siguiente. Este enfoque ayuda a mantener calidad de codigo y hace el debugging mas facil cuando surgen problemas.&lt;/p&gt;
&lt;p&gt;Mantiene documentacion del proyecto que Claude Code pueda referenciar. Archivos README, especificaciones de API y documentos de arquitectura proporcionan contexto que mejora la calidad de generacion de codigo.&lt;/p&gt;
&lt;p&gt;Revisa el codigo generado antes de commitear. Mientras Claude Code produce implementaciones funcionales, la revision humana atrapa casos extremos, asegura mejores practicas de seguridad y mantiene estandares de calidad de codigo.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Claude Code es una herramienta practica para desarrolladores que quieren asistencia de IA sin dejar su terminal. Maneja tareas de codificacion rutinarias, ayuda con refactorizacion y acelera el desarrollo cuando se usa apropiadamente.&lt;/p&gt;
&lt;p&gt;La herramienta funciona mejor como un asistente en lugar de un reemplazo de la experiencia del desarrollador. Aun necesitas entender tu arquitectura, tomar decisiones de diseno y asegurar calidad de codigo. Claude Code maneja detalles de implementacion basandose en tu guia.&lt;/p&gt;
&lt;p&gt;Para desarrolladores comodos con flujos de trabajo en terminal y claros sobre sus requerimientos, Claude Code puede acelerar significativamente el desarrollo. La clave es entender sus capacidades y limitaciones, luego aplicarlo donde proporcione el mayor valor.&lt;/p&gt;
&lt;h3 id=&quot;comparando-asistentes-de-codificacion-con-ia&quot;&gt;Comparando Asistentes de Codificacion con IA&lt;/h3&gt;
&lt;p&gt;Si estas evaluando diferentes herramientas de codificacion con IA, tambien podrias querer explorar &lt;strong&gt;&lt;a href=&quot;/blog/codex-cli-ultimate-guide/&quot;&gt;Codex CLI con GPT-5&lt;/a&gt;&lt;/strong&gt;, que ofrece diferentes fortalezas incluyendo prompts de produccion filtrados de Cursor y modos de razonamiento especializados. Cada herramienta tiene capacidades unicas—Claude Code sobresale en integracion con terminal y conversacion natural, mientras que Codex aprovecha el razonamiento avanzado de GPT-5 para refactorizaciones complejas.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;informacion-tecnica&quot;&gt;Informacion Tecnica&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Proveedor&lt;/strong&gt;: Anthropic
&lt;strong&gt;Interfaz&lt;/strong&gt;: Interfaz de linea de comandos (CLI)
&lt;strong&gt;Plataformas&lt;/strong&gt;: macOS, Linux, Windows (WSL)
&lt;strong&gt;Requerimientos&lt;/strong&gt;: Clave API de Anthropic, Node.js 18+ (para instalacion npm)
&lt;strong&gt;Documentacion&lt;/strong&gt;: Disponible en docs.anthropic.com
&lt;strong&gt;Precios de API&lt;/strong&gt;: Basados en tarifas estandar de Anthropic por token&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Nota: Este analisis refleja las capacidades de Claude Code como asistente de codificacion basado en terminal. El rendimiento real depende de casos de uso especificos y enfoque de implementacion.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Claude Code : Assistant de codage IA base sur le terminal]]></title><description><![CDATA[Claude Code est un assistant de codage IA base sur le terminal qui permet aux developpeurs de creer des applications via des conversations en langage naturel.]]></description><link>https://vibecodingwithfred.com/fr/blog/claude-code-cli-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/fr/blog/claude-code-cli-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 22 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Plateforme :&lt;/strong&gt; Claude Code | &lt;strong&gt;Fournisseur :&lt;/strong&gt; Anthropic | &lt;strong&gt;Interface :&lt;/strong&gt; Terminal/CLI&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;quest-ce-que-claude-code&quot;&gt;Qu&apos;est-ce que Claude Code&lt;/h2&gt;
&lt;p&gt;Claude Code est l&apos;assistant de codage base sur le terminal d&apos;Anthropic qui s&apos;execute dans votre ligne de commande. Vous interagissez avec lui en langage naturel pour generer du code, deboguer des problemes, refactoriser du code existant et gerer des taches de developpement. Il opere dans le repertoire de votre projet et peut lire, ecrire et modifier des fichiers selon vos instructions.&lt;/p&gt;
&lt;p&gt;L&apos;outil s&apos;integre a votre flux de travail de developpement existant plutot que de le remplacer. Vous utilisez toujours votre editeur prefere, votre controle de version et vos outils de deploiement. Claude Code agit comme un assistant qui gere les details d&apos;implementation pendant que vous vous concentrez sur l&apos;architecture et les exigences.&lt;/p&gt;
&lt;h2 id=&quot;comment-ca-fonctionne&quot;&gt;Comment ca fonctionne&lt;/h2&gt;
&lt;p&gt;Claude Code opere via une interface conversationnelle dans votre terminal. Vous decrivez ce dont vous avez besoin en anglais simple, et il genere ou modifie le code en consequence. L&apos;outil maintient le contexte sur la structure de votre projet, les patterns de codage et les interactions precedentes au sein d&apos;une session.&lt;/p&gt;
&lt;p&gt;Quand vous demarrez Claude Code dans un repertoire de projet, il peut analyser votre base de code pour comprendre l&apos;architecture, les frameworks et les patterns que vous utilisez. Ce contexte l&apos;aide a generer du code qui correspond a votre style existant et s&apos;integre correctement a votre projet.&lt;/p&gt;
&lt;p&gt;Le flux de travail de base consiste a decrire une fonctionnalite ou une correction dont vous avez besoin, examiner le code genere, le tester, puis iterer en fonction des resultats. Claude Code peut gerer des changements multi-fichiers, comprendre les dependances entre les composants et maintenir la coherence dans votre base de code.&lt;/p&gt;
&lt;h2 id=&quot;capacites-principales&quot;&gt;Capacites principales&lt;/h2&gt;
&lt;p&gt;Claude Code peut generer de nouveaux fichiers de code a partir de descriptions, creant des composants complets, des points de terminaison API, des modeles de base de donnees et des suites de tests. Il comprend les frameworks et bibliotheques courants, generant du code idiomatique pour React, Vue, Express, Django, Rails et d&apos;autres outils populaires.&lt;/p&gt;
&lt;p&gt;Pour le code existant, il peut refactoriser des fonctions et des classes, mettre a jour des API obsoletes, ameliorer les performances, corriger des bugs et ajouter la gestion des erreurs. L&apos;outil peut analyser le code pour des problemes potentiels, suggerer des ameliorations et implementer des corrections.&lt;/p&gt;
&lt;p&gt;La generation de tests est une autre fonctionnalite cle. Claude Code peut creer des tests unitaires, des tests d&apos;integration et des tests de bout en bout bases sur votre code existant. Il comprend les frameworks de test comme Jest, Pytest, RSpec et autres.&lt;/p&gt;
&lt;p&gt;L&apos;outil gere egalement les taches de documentation, generant des fichiers README, de la documentation API, des commentaires en ligne et des docstrings qui expliquent les sections de code complexes.&lt;/p&gt;
&lt;h2 id=&quot;exigences-techniques&quot;&gt;Exigences techniques&lt;/h2&gt;
&lt;p&gt;Claude Code necessite une cle API Anthropic pour fonctionner. Cela signifie que vous avez besoin d&apos;un compte chez Anthropic et serez facture en fonction de l&apos;utilisation de l&apos;API. Le modele de tarification suit les tarifs API standard d&apos;Anthropic pour le modele Claude que vous utilisez.&lt;/p&gt;
&lt;p&gt;L&apos;outil fonctionne sur macOS, Linux et Windows (via WSL). Il necessite Node.js 18+ si vous installez via npm, bien que des installateurs natifs soient disponibles pour une installation directe. Votre terminal doit supporter les commandes Unix standard pour les operations sur les fichiers.&lt;/p&gt;
&lt;h2 id=&quot;limitations-pratiques&quot;&gt;Limitations pratiques&lt;/h2&gt;
&lt;p&gt;Claude Code opere dans les limites de la fenetre de contexte du modele Claude sous-jacent. Pour les grandes bases de code, il peut ne pas etre en mesure de considerer chaque fichier simultanement. Vous devez etre strategique quant aux fichiers et au contexte que vous fournissez pour les operations complexes.&lt;/p&gt;
&lt;p&gt;L&apos;outil ne peut pas executer directement du code ou lancer des tests. Vous devez toujours executer votre serveur de developpement, executer les suites de tests et verifier que le code genere fonctionne comme prevu. Claude Code genere du code mais ne valide pas qu&apos;il s&apos;execute correctement.&lt;/p&gt;
&lt;p&gt;Les decisions architecturales complexes, la conception de systemes et la logique metier necessitent toujours un jugement humain. Claude Code implemente selon vos specifications mais ne decidera pas independamment comment structurer votre application ou quelles fonctionnalites construire.&lt;/p&gt;
&lt;p&gt;Le code genere peut necessiter des ajustements pour une utilisation en production. Bien que Claude Code produise du code fonctionnel, vous devriez le revoir pour la securite, les performances et l&apos;adherence aux standards de votre equipe avant le deploiement.&lt;/p&gt;
&lt;h2 id=&quot;qui-devrait-lutiliser&quot;&gt;Qui devrait l&apos;utiliser&lt;/h2&gt;
&lt;p&gt;Les developpeurs a l&apos;aise avec les interfaces terminal trouveront que Claude Code s&apos;integre naturellement dans leur flux de travail. C&apos;est particulierement utile pour ceux qui passent la plupart de leur temps dans la ligne de commande et preferent les interfaces textuelles aux GUI.&lt;/p&gt;
&lt;p&gt;Les equipes travaillant sur des projets greenfield beneficient des capacites de prototypage rapide. Vous pouvez rapidement generer du code standard, configurer des structures de projet et implementer des fonctionnalites standard sans codage manuel.&lt;/p&gt;
&lt;p&gt;Les developpeurs qui apprennent de nouveaux frameworks ou langages peuvent utiliser Claude Code pour comprendre les patterns et les meilleures pratiques. Le code genere sert d&apos;exemples d&apos;implementations idiomatiques dans des technologies inconnues.&lt;/p&gt;
&lt;p&gt;Ceux qui travaillent sur des bases de code legacy peuvent tirer parti de Claude Code pour des taches de modernisation comme la mise a jour des dependances, la refactorisation d&apos;anciens patterns et l&apos;ajout de tests au code non teste.&lt;/p&gt;
&lt;h2 id=&quot;points-dintegration&quot;&gt;Points d&apos;integration&lt;/h2&gt;
&lt;p&gt;Claude Code fonctionne aux cotes de vos outils existants plutot que de les remplacer. Vous continuez a utiliser Git pour le controle de version, avec Claude Code generant du code que vous commitez ensuite. Votre IDE ou editeur de texte reste votre interface principale pour examiner et editer le code.&lt;/p&gt;
&lt;p&gt;Les frameworks de test, les outils de build et les pipelines de deploiement operent independamment de Claude Code. L&apos;outil genere du code qui fonctionne avec ces systemes mais ne les controle pas directement.&lt;/p&gt;
&lt;p&gt;Pour les equipes, Claude Code s&apos;integre dans les processus de developpement existants. Un developpeur peut l&apos;utiliser pour generer des implementations initiales que d&apos;autres examinent via les processus de revue de code normaux.&lt;/p&gt;
&lt;h2 id=&quot;considerations-de-cout&quot;&gt;Considerations de cout&lt;/h2&gt;
&lt;p&gt;Les couts d&apos;utilisation dependent de la quantite de contexte que vous fournissez et de la longueur des reponses. Chaque interaction consomme des tokens API bases sur la taille de vos prompts et du code genere. Les grandes operations de refactorisation ou les sessions de generation de code extensives peuvent accumuler une utilisation significative de tokens.&lt;/p&gt;
&lt;p&gt;Les projets avec de nombreux fichiers ou des exigences complexes peuvent necessiter plusieurs interactions pour atteindre les resultats souhaites, augmentant les couts. Vous devriez surveiller votre utilisation de l&apos;API et definir des limites appropriees en fonction de votre budget.&lt;/p&gt;
&lt;p&gt;La proposition de valeur depend de votre cas d&apos;utilisation. Si Claude Code vous fait economiser des heures de temps de developpement, les couts API peuvent etre negligeables par rapport aux salaires des developpeurs. Pour les projets personnels ou l&apos;apprentissage, les couts necessitent une consideration plus attentive.&lt;/p&gt;
&lt;h2 id=&quot;obtenir-une-vraie-valeur&quot;&gt;Obtenir une vraie valeur&lt;/h2&gt;
&lt;p&gt;Concentrez-vous sur des taches specifiques et bien definies plutot que sur des demandes vagues. &quot;Ajouter la gestion des erreurs aux points de terminaison d&apos;authentification utilisateur&quot; produit de meilleurs resultats que &quot;ameliorer le code&quot;. Des specifications claires menent a des implementations plus precises.&lt;/p&gt;
&lt;p&gt;Construisez incrementalement plutot que de tenter des changements massifs d&apos;un coup. Generez un composant, testez-le, puis passez au suivant. Cette approche aide a maintenir la qualite du code et facilite le debogage quand des problemes surviennent.&lt;/p&gt;
&lt;p&gt;Maintenez la documentation du projet que Claude Code peut referencer. Les fichiers README, les specifications API et les documents d&apos;architecture fournissent un contexte qui ameliore la qualite de la generation de code.&lt;/p&gt;
&lt;p&gt;Examinez le code genere avant de commiter. Bien que Claude Code produise des implementations fonctionnelles, la revue humaine detecte les cas limites, assure les meilleures pratiques de securite et maintient les standards de qualite du code.&lt;/p&gt;
&lt;h2 id=&quot;en-resume&quot;&gt;En resume&lt;/h2&gt;
&lt;p&gt;Claude Code est un outil pratique pour les developpeurs qui veulent une assistance IA sans quitter leur terminal. Il gere les taches de codage de routine, aide avec la refactorisation et accelere le developpement quand il est utilise de maniere appropriee.&lt;/p&gt;
&lt;p&gt;L&apos;outil fonctionne mieux comme un assistant plutot qu&apos;un remplacement de l&apos;expertise du developpeur. Vous devez toujours comprendre votre architecture, prendre des decisions de conception et assurer la qualite du code. Claude Code gere les details d&apos;implementation selon vos directives.&lt;/p&gt;
&lt;p&gt;Pour les developpeurs a l&apos;aise avec les flux de travail terminal et clairs sur leurs exigences, Claude Code peut accelerer significativement le developpement. La cle est de comprendre ses capacites et limitations, puis de l&apos;appliquer la ou il fournit le plus de valeur.&lt;/p&gt;
&lt;h3 id=&quot;comparer-les-assistants-de-codage-ia&quot;&gt;Comparer les assistants de codage IA&lt;/h3&gt;
&lt;p&gt;Si vous evaluez differents outils de codage IA, vous pourriez aussi vouloir explorer &lt;strong&gt;&lt;a href=&quot;/blog/codex-cli-ultimate-guide/&quot;&gt;Codex CLI avec GPT-5&lt;/a&gt;&lt;/strong&gt;, qui offre differentes forces incluant des prompts de production Cursor fuites et des modes de raisonnement specialises. Chaque outil a des capacites uniques - Claude Code excelle dans l&apos;integration terminal et la conversation naturelle, tandis que Codex exploite le raisonnement avance de GPT-5 pour les refactorisations complexes.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;informations-techniques&quot;&gt;Informations techniques&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Fournisseur&lt;/strong&gt; : Anthropic
&lt;strong&gt;Interface&lt;/strong&gt; : Interface en ligne de commande (CLI)
&lt;strong&gt;Plateformes&lt;/strong&gt; : macOS, Linux, Windows (WSL)
&lt;strong&gt;Exigences&lt;/strong&gt; : Cle API Anthropic, Node.js 18+ (pour l&apos;installation npm)
&lt;strong&gt;Documentation&lt;/strong&gt; : Disponible sur docs.anthropic.com
&lt;strong&gt;Tarification API&lt;/strong&gt; : Basee sur les tarifs standard d&apos;Anthropic par token&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note : Cette analyse reflete les capacites de Claude Code en tant qu&apos;assistant de codage base sur le terminal. Les performances reelles dependent des cas d&apos;utilisation specifiques et de l&apos;approche d&apos;implementation.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Claude Code: Assistente di Coding AI Basato su Terminale]]></title><description><![CDATA[Claude Code e un assistente di coding AI basato su terminale che permette agli sviluppatori di costruire applicazioni attraverso conversazioni in linguaggio naturale.]]></description><link>https://vibecodingwithfred.com/it/blog/claude-code-cli-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/it/blog/claude-code-cli-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 22 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Piattaforma:&lt;/strong&gt; Claude Code | &lt;strong&gt;Provider:&lt;/strong&gt; Anthropic | &lt;strong&gt;Interfaccia:&lt;/strong&gt; Terminal/CLI&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;cose-claude-code&quot;&gt;Cos&apos;e Claude Code&lt;/h2&gt;
&lt;p&gt;Claude Code e l&apos;assistente di coding basato su terminale di Anthropic che gira nella tua riga di comando. Interagisci con esso attraverso linguaggio naturale per generare codice, debuggare problemi, refactorare codice esistente e gestire attivita di sviluppo. Opera all&apos;interno della directory del tuo progetto e puo leggere, scrivere e modificare file in base alle tue istruzioni.&lt;/p&gt;
&lt;p&gt;Lo strumento si integra con il tuo workflow di sviluppo esistente invece di sostituirlo. Continui a usare il tuo editor preferito, il controllo versione e gli strumenti di deployment. Claude Code agisce come un assistente che gestisce i dettagli implementativi mentre tu ti concentri su architettura e requisiti.&lt;/p&gt;
&lt;h2 id=&quot;come-funziona&quot;&gt;Come Funziona&lt;/h2&gt;
&lt;p&gt;Claude Code opera attraverso un&apos;interfaccia conversazionale nel tuo terminale. Descrivi cosa ti serve in inglese semplice, e genera o modifica il codice di conseguenza. Lo strumento mantiene il contesto sulla struttura del tuo progetto, i pattern di coding e le interazioni precedenti all&apos;interno di una sessione.&lt;/p&gt;
&lt;p&gt;Quando avvii Claude Code in una directory di progetto, puo analizzare la tua codebase per capire l&apos;architettura, i framework e i pattern che stai usando. Questo contesto lo aiuta a generare codice che corrisponde al tuo stile esistente e si integra correttamente con il tuo progetto.&lt;/p&gt;
&lt;p&gt;Il workflow di base prevede di descrivere una feature o fix di cui hai bisogno, revisionare il codice generato, testarlo, e poi iterare in base ai risultati. Claude Code puo gestire modifiche multi-file, capire le dipendenze tra componenti e mantenere la coerenza in tutta la tua codebase.&lt;/p&gt;
&lt;h2 id=&quot;capacita-principali&quot;&gt;Capacita Principali&lt;/h2&gt;
&lt;p&gt;Claude Code puo generare nuovi file di codice da descrizioni, creando componenti completi, endpoint API, modelli di database e suite di test. Capisce framework e librerie comuni, generando codice idiomatico per React, Vue, Express, Django, Rails e altri strumenti popolari.&lt;/p&gt;
&lt;p&gt;Per codice esistente, puo refactorare funzioni e classi, aggiornare API deprecate, migliorare le prestazioni, correggere bug e aggiungere gestione degli errori. Lo strumento puo analizzare il codice per potenziali problemi, suggerire miglioramenti e implementare correzioni.&lt;/p&gt;
&lt;p&gt;La generazione di test e un&apos;altra feature chiave. Claude Code puo creare unit test, test di integrazione e test end-to-end basati sul tuo codice esistente. Capisce framework di testing come Jest, Pytest, RSpec e altri.&lt;/p&gt;
&lt;p&gt;Lo strumento gestisce anche attivita di documentazione, generando file README, documentazione API, commenti inline e docstring che spiegano sezioni di codice complesse.&lt;/p&gt;
&lt;h2 id=&quot;requisiti-tecnici&quot;&gt;Requisiti Tecnici&lt;/h2&gt;
&lt;p&gt;Claude Code richiede una chiave API Anthropic per funzionare. Questo significa che hai bisogno di un account con Anthropic e ti verra addebitato in base all&apos;uso dell&apos;API. Il modello di pricing segue le tariffe API standard di Anthropic per il modello Claude che stai usando.&lt;/p&gt;
&lt;p&gt;Lo strumento funziona su macOS, Linux e Windows (tramite WSL). Richiede Node.js 18+ se installato via npm, anche se sono disponibili installer nativi per l&apos;installazione diretta. Il tuo terminale deve supportare i comandi Unix standard per le operazioni sui file.&lt;/p&gt;
&lt;h2 id=&quot;limitazioni-pratiche&quot;&gt;Limitazioni Pratiche&lt;/h2&gt;
&lt;p&gt;Claude Code opera entro i limiti della finestra di contesto del modello Claude sottostante. Per codebase grandi, potrebbe non essere in grado di considerare ogni file simultaneamente. Devi essere strategico su quali file e contesto fornisci per operazioni complesse.&lt;/p&gt;
&lt;p&gt;Lo strumento non puo eseguire direttamente codice o eseguire test. Devi comunque avviare il tuo server di sviluppo, eseguire le suite di test e verificare che il codice generato funzioni come previsto. Claude Code genera codice ma non valida che funzioni correttamente.&lt;/p&gt;
&lt;p&gt;Decisioni architetturali complesse, system design e logica di business richiedono ancora giudizio umano. Claude Code implementa in base alle tue specifiche ma non decidera autonomamente come strutturare la tua applicazione o quali feature costruire.&lt;/p&gt;
&lt;p&gt;Il codice generato potrebbe necessitare di aggiustamenti per l&apos;uso in produzione. Mentre Claude Code produce codice funzionante, dovresti revisionarlo per sicurezza, prestazioni e aderenza agli standard del tuo team prima del deployment.&lt;/p&gt;
&lt;h2 id=&quot;chi-dovrebbe-usarlo&quot;&gt;Chi Dovrebbe Usarlo&lt;/h2&gt;
&lt;p&gt;Gli sviluppatori a proprio agio con le interfacce terminale troveranno che Claude Code si integra naturalmente nel loro workflow. E particolarmente utile per chi passa la maggior parte del tempo nella riga di comando e preferisce interfacce basate su testo rispetto alle GUI.&lt;/p&gt;
&lt;p&gt;I team che lavorano su progetti greenfield beneficiano delle capacita di prototipazione rapida. Puoi generare rapidamente codice boilerplate, configurare strutture di progetto e implementare feature standard senza coding manuale.&lt;/p&gt;
&lt;p&gt;Gli sviluppatori che imparano nuovi framework o linguaggi possono usare Claude Code per capire pattern e best practice. Il codice generato serve come esempi di implementazioni idiomatiche in tecnologie non familiari.&lt;/p&gt;
&lt;p&gt;Chi lavora su codebase legacy puo sfruttare Claude Code per attivita di modernizzazione come aggiornare dipendenze, refactorare vecchi pattern e aggiungere test a codice non testato.&lt;/p&gt;
&lt;h2 id=&quot;punti-di-integrazione&quot;&gt;Punti di Integrazione&lt;/h2&gt;
&lt;p&gt;Claude Code funziona insieme ai tuoi strumenti esistenti invece di sostituirli. Continui a usare Git per il controllo versione, con Claude Code che genera codice che poi committi. Il tuo IDE o editor di testo rimane la tua interfaccia principale per revisionare e modificare il codice.&lt;/p&gt;
&lt;p&gt;Framework di testing, strumenti di build e pipeline di deployment operano indipendentemente da Claude Code. Lo strumento genera codice che funziona con questi sistemi ma non li controlla direttamente.&lt;/p&gt;
&lt;p&gt;Per i team, Claude Code si inserisce nei processi di sviluppo esistenti. Uno sviluppatore potrebbe usarlo per generare implementazioni iniziali che altri revisionano attraverso i normali processi di code review.&lt;/p&gt;
&lt;h2 id=&quot;considerazioni-sui-costi&quot;&gt;Considerazioni sui Costi&lt;/h2&gt;
&lt;p&gt;I costi di utilizzo dipendono dalla quantita di contesto che fornisci e dalla lunghezza delle risposte. Ogni interazione consuma token API in base alla dimensione dei tuoi prompt e del codice generato. Operazioni di refactoring grandi o sessioni estese di generazione di codice possono accumulare un uso significativo di token.&lt;/p&gt;
&lt;p&gt;Progetti con molti file o requisiti complessi potrebbero richiedere interazioni multiple per ottenere i risultati desiderati, aumentando i costi. Dovresti monitorare il tuo uso dell&apos;API e impostare limiti appropriati in base al tuo budget.&lt;/p&gt;
&lt;p&gt;La proposta di valore dipende dal tuo caso d&apos;uso. Se Claude Code risparmia ore di tempo di sviluppo, i costi dell&apos;API potrebbero essere trascurabili rispetto agli stipendi degli sviluppatori. Per progetti hobby o apprendimento, i costi richiedono una considerazione piu attenta.&lt;/p&gt;
&lt;h2 id=&quot;ottenere-valore-reale&quot;&gt;Ottenere Valore Reale&lt;/h2&gt;
&lt;p&gt;Concentrati su attivita specifiche e ben definite invece di richieste vaghe. &quot;Aggiungi gestione errori agli endpoint di autenticazione utente&quot; produce risultati migliori di &quot;migliora il codice.&quot; Specifiche chiare portano a implementazioni piu accurate.&lt;/p&gt;
&lt;p&gt;Costruisci incrementalmente invece di tentare modifiche massive tutte insieme. Genera un componente, testalo, poi passa al successivo. Questo approccio aiuta a mantenere la qualita del codice e rende il debugging piu facile quando sorgono problemi.&lt;/p&gt;
&lt;p&gt;Mantieni la documentazione del progetto che Claude Code puo consultare. File README, specifiche API e documenti di architettura forniscono contesto che migliora la qualita della generazione del codice.&lt;/p&gt;
&lt;p&gt;Revisiona il codice generato prima di committarlo. Mentre Claude Code produce implementazioni funzionanti, la revisione umana cattura casi limite, assicura le best practice di sicurezza e mantiene gli standard di qualita del codice.&lt;/p&gt;
&lt;h2 id=&quot;in-sintesi&quot;&gt;In Sintesi&lt;/h2&gt;
&lt;p&gt;Claude Code e uno strumento pratico per sviluppatori che vogliono assistenza AI senza lasciare il loro terminale. Gestisce attivita di coding di routine, aiuta con il refactoring e accelera lo sviluppo quando usato appropriatamente.&lt;/p&gt;
&lt;p&gt;Lo strumento funziona meglio come assistente invece che come sostituto dell&apos;esperienza dello sviluppatore. Devi comunque capire la tua architettura, prendere decisioni di design e assicurare la qualita del codice. Claude Code gestisce i dettagli implementativi in base alla tua guida.&lt;/p&gt;
&lt;p&gt;Per sviluppatori a proprio agio con i workflow da terminale e chiari sui loro requisiti, Claude Code puo accelerare significativamente lo sviluppo. La chiave e capire le sue capacita e limitazioni, poi applicarlo dove fornisce il maggior valore.&lt;/p&gt;
&lt;h3 id=&quot;confrontare-assistenti-di-coding-ai&quot;&gt;Confrontare Assistenti di Coding AI&lt;/h3&gt;
&lt;p&gt;Se stai valutando diversi strumenti di coding AI, potresti anche voler esplorare &lt;strong&gt;&lt;a href=&quot;/blog/codex-cli-ultimate-guide/&quot;&gt;Codex CLI con GPT-5&lt;/a&gt;&lt;/strong&gt;, che offre punti di forza diversi inclusi prompt di produzione Cursor trapelati e modalita di ragionamento specializzate. Ogni strumento ha capacita uniche - Claude Code eccelle nell&apos;integrazione terminale e nella conversazione naturale, mentre Codex sfrutta il ragionamento avanzato di GPT-5 per refactor complessi.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;informazioni-tecniche&quot;&gt;Informazioni Tecniche&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Provider&lt;/strong&gt;: Anthropic
&lt;strong&gt;Interfaccia&lt;/strong&gt;: Interfaccia a riga di comando (CLI)
&lt;strong&gt;Piattaforme&lt;/strong&gt;: macOS, Linux, Windows (WSL)
&lt;strong&gt;Requisiti&lt;/strong&gt;: Chiave API Anthropic, Node.js 18+ (per installazione npm)
&lt;strong&gt;Documentazione&lt;/strong&gt;: Disponibile su docs.anthropic.com
&lt;strong&gt;Pricing API&lt;/strong&gt;: Basato sulle tariffe standard Anthropic per token&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Nota: Questa analisi riflette le capacita di Claude Code come assistente di coding basato su terminale. Le prestazioni effettive dipendono da casi d&apos;uso specifici e approccio implementativo.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Claude Code: ターミナルベースのAIコーディングアシスタント]]></title><description><![CDATA[Claude Codeは、開発者が自然言語での会話を通じてアプリケーションを構築できるターミナルベースのAIコーディングアシスタントです。]]></description><link>https://vibecodingwithfred.com/ja/blog/claude-code-cli-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/ja/blog/claude-code-cli-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 22 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;プラットフォーム:&lt;/strong&gt; Claude Code | &lt;strong&gt;提供元:&lt;/strong&gt; Anthropic | &lt;strong&gt;インターフェース:&lt;/strong&gt; Terminal/CLI&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;claude-codeとは&quot;&gt;Claude Codeとは&lt;/h2&gt;
&lt;p&gt;Claude CodeはAnthropicのターミナルベースのコーディングアシスタントで、コマンドラインで動作します。自然言語を通じて対話し、コードの生成、問題のデバッグ、既存コードのリファクタリング、開発タスクの管理を行います。プロジェクトディレクトリ内で動作し、指示に基づいてファイルの読み取り、書き込み、変更が可能です。&lt;/p&gt;
&lt;p&gt;このツールは既存の開発ワークフローに統合されるもので、置き換えるものではありません。好みのエディタ、バージョン管理、デプロイツールはそのまま使用できます。Claude Codeは、あなたがアーキテクチャと要件に集中している間、実装の詳細を処理するアシスタントとして機能します。&lt;/p&gt;
&lt;h2 id=&quot;動作の仕組み&quot;&gt;動作の仕組み&lt;/h2&gt;
&lt;p&gt;Claude Codeはターミナル内の会話インターフェースを通じて動作します。必要なことを平易な英語で説明すると、それに応じてコードを生成または修正します。このツールはセッション内でプロジェクト構造、コーディングパターン、以前のやり取りに関するコンテキストを維持します。&lt;/p&gt;
&lt;p&gt;プロジェクトディレクトリでClaude Codeを起動すると、コードベースを分析して、使用しているアーキテクチャ、フレームワーク、パターンを理解できます。このコンテキストにより、既存のスタイルに合致し、プロジェクトと適切に統合されるコードを生成できます。&lt;/p&gt;
&lt;p&gt;基本的なワークフローは、必要な機能や修正を説明し、生成されたコードをレビューし、テストして、結果に基づいて反復することです。Claude Codeは複数ファイルの変更を処理し、コンポーネント間の依存関係を理解し、コードベース全体で一貫性を維持できます。&lt;/p&gt;
&lt;h2 id=&quot;主要な機能&quot;&gt;主要な機能&lt;/h2&gt;
&lt;p&gt;Claude Codeは説明から新しいコードファイルを生成でき、完全なコンポーネント、APIエンドポイント、データベースモデル、テストスイートを作成します。React、Vue、Express、Django、Railsなどの一般的なフレームワークやライブラリを理解し、慣用的なコードを生成します。&lt;/p&gt;
&lt;p&gt;既存のコードについては、関数やクラスのリファクタリング、非推奨APIの更新、パフォーマンスの改善、バグの修正、エラーハンドリングの追加が可能です。このツールはコードの潜在的な問題を分析し、改善を提案し、修正を実装できます。&lt;/p&gt;
&lt;p&gt;テスト生成も主要な機能の一つです。Claude Codeは既存のコードに基づいてユニットテスト、統合テスト、エンドツーエンドテストを作成できます。Jest、Pytest、RSpecなどのテストフレームワークを理解しています。&lt;/p&gt;
&lt;p&gt;このツールはドキュメントタスクも処理し、READMEファイル、APIドキュメント、インラインコメント、複雑なコードセクションを説明するdocstringを生成します。&lt;/p&gt;
&lt;h2 id=&quot;技術要件&quot;&gt;技術要件&lt;/h2&gt;
&lt;p&gt;Claude Codeを機能させるにはAnthropic APIキーが必要です。つまり、Anthropicのアカウントが必要で、API使用量に基づいて課金されます。価格モデルは、使用しているClaudeモデルのAnthropicの標準APIレートに従います。&lt;/p&gt;
&lt;p&gt;このツールはmacOS、Linux、Windows（WSL経由）で動作します。npmでインストールする場合はNode.js 18以上が必要ですが、直接インストール用のネイティブインストーラーも利用可能です。ターミナルはファイル操作用の標準Unixコマンドをサポートする必要があります。&lt;/p&gt;
&lt;h2 id=&quot;実用上の制限&quot;&gt;実用上の制限&lt;/h2&gt;
&lt;p&gt;Claude Codeは基盤となるClaudeモデルのコンテキストウィンドウ制限内で動作します。大規模なコードベースの場合、すべてのファイルを同時に考慮できない場合があります。複雑な操作のためにどのファイルとコンテキストを提供するかについて戦略的である必要があります。&lt;/p&gt;
&lt;p&gt;このツールはコードを直接実行したりテストを実行したりすることはできません。開発サーバーを実行し、テストスイートを実行し、生成されたコードが期待通りに動作することを確認する必要があります。Claude Codeはコードを生成しますが、それが正しく実行されることを検証しません。&lt;/p&gt;
&lt;p&gt;複雑なアーキテクチャの決定、システム設計、ビジネスロジックには依然として人間の判断が必要です。Claude Codeはあなたの仕様に基づいて実装しますが、アプリケーションの構造や構築する機能を独自に決定することはありません。&lt;/p&gt;
&lt;p&gt;生成されたコードは本番使用のために調整が必要な場合があります。Claude Codeは機能するコードを生成しますが、デプロイ前にセキュリティ、パフォーマンス、チームの標準への準拠についてレビューする必要があります。&lt;/p&gt;
&lt;h2 id=&quot;対象ユーザー&quot;&gt;対象ユーザー&lt;/h2&gt;
&lt;p&gt;ターミナルインターフェースに慣れている開発者は、Claude Codeが自然にワークフローに適合することに気づくでしょう。コマンドラインで大部分の時間を過ごし、GUIよりもテキストベースのインターフェースを好む人に特に有用です。&lt;/p&gt;
&lt;p&gt;グリーンフィールドプロジェクトに取り組むチームは、高速なプロトタイピング機能の恩恵を受けます。ボイラープレートコードを素早く生成し、プロジェクト構造をセットアップし、手動コーディングなしで標準機能を実装できます。&lt;/p&gt;
&lt;p&gt;新しいフレームワークや言語を学んでいる開発者は、パターンとベストプラクティスを理解するためにClaude Codeを使用できます。生成されたコードは、馴染みのない技術における慣用的な実装の例として機能します。&lt;/p&gt;
&lt;p&gt;レガシーコードベースで作業している人は、依存関係の更新、古いパターンのリファクタリング、テストされていないコードへのテスト追加などの近代化タスクにClaude Codeを活用できます。&lt;/p&gt;
&lt;h2 id=&quot;統合ポイント&quot;&gt;統合ポイント&lt;/h2&gt;
&lt;p&gt;Claude Codeは既存のツールを置き換えるのではなく、一緒に動作します。バージョン管理にはGitを使い続け、Claude Codeが生成したコードをコミットします。IDEまたはテキストエディタは、コードのレビューと編集のための主要なインターフェースとして残ります。&lt;/p&gt;
&lt;p&gt;テストフレームワーク、ビルドツール、デプロイパイプラインはClaude Codeから独立して動作します。このツールはこれらのシステムで動作するコードを生成しますが、直接制御することはありません。&lt;/p&gt;
&lt;p&gt;チームにとって、Claude Codeは既存の開発プロセスに適合します。ある開発者がそれを使用して初期実装を生成し、他の開発者が通常のコードレビュープロセスを通じてレビューするかもしれません。&lt;/p&gt;
&lt;h2 id=&quot;コストの考慮事項&quot;&gt;コストの考慮事項&lt;/h2&gt;
&lt;p&gt;使用コストは、提供するコンテキストの量と応答の長さによって異なります。各やり取りは、プロンプトのサイズと生成されたコードに基づいてAPIトークンを消費します。大規模なリファクタリング操作や広範なコード生成セッションは、かなりのトークン使用量を蓄積する可能性があります。&lt;/p&gt;
&lt;p&gt;多くのファイルや複雑な要件を持つプロジェクトは、望ましい結果を達成するために複数のやり取りが必要になり、コストが増加する場合があります。API使用量を監視し、予算に基づいて適切な制限を設定する必要があります。&lt;/p&gt;
&lt;p&gt;価値提案はユースケースによって異なります。Claude Codeが何時間もの開発時間を節約するなら、APIコストは開発者の給与に比べて無視できる程度かもしれません。趣味のプロジェクトや学習の場合、コストはより慎重に検討する必要があります。&lt;/p&gt;
&lt;h2 id=&quot;真の価値を得る&quot;&gt;真の価値を得る&lt;/h2&gt;
&lt;p&gt;漠然としたリクエストではなく、具体的で明確に定義されたタスクに焦点を当てます。「コードを改善して」よりも「ユーザー認証エンドポイントにエラーハンドリングを追加して」の方が良い結果を生みます。明確な仕様はより正確な実装につながります。&lt;/p&gt;
&lt;p&gt;一度に大規模な変更を試みるのではなく、段階的に構築します。1つのコンポーネントを生成し、テストしてから次に進みます。このアプローチはコード品質の維持に役立ち、問題が発生した際のデバッグが容易になります。&lt;/p&gt;
&lt;p&gt;Claude Codeが参照できるプロジェクトドキュメントを維持します。READMEファイル、API仕様、アーキテクチャドキュメントは、コード生成品質を向上させるコンテキストを提供します。&lt;/p&gt;
&lt;p&gt;コミット前に生成されたコードをレビューします。Claude Codeは機能する実装を生成しますが、人間によるレビューがエッジケースを捕捉し、セキュリティのベストプラクティスを確保し、コード品質基準を維持します。&lt;/p&gt;
&lt;h2 id=&quot;結論&quot;&gt;結論&lt;/h2&gt;
&lt;p&gt;Claude Codeは、ターミナルを離れることなくAI支援を望む開発者のための実用的なツールです。ルーチンのコーディングタスクを処理し、リファクタリングを支援し、適切に使用すれば開発を加速します。&lt;/p&gt;
&lt;p&gt;このツールは、開発者の専門知識の代替としてではなく、アシスタントとして最も効果的に機能します。アーキテクチャを理解し、設計上の決定を下し、コード品質を確保する必要があります。Claude Codeはあなたの指導に基づいて実装の詳細を処理します。&lt;/p&gt;
&lt;p&gt;ターミナルワークフローに慣れており、要件が明確な開発者にとって、Claude Codeは開発を大幅に加速できます。重要なのは、その機能と制限を理解し、最も価値を提供する場所に適用することです。&lt;/p&gt;
&lt;h3 id=&quot;aiコーディングアシスタントの比較&quot;&gt;AIコーディングアシスタントの比較&lt;/h3&gt;
&lt;p&gt;異なるAIコーディングツールを評価している場合は、**&lt;a href=&quot;/blog/codex-cli-ultimate-guide/&quot;&gt;GPT-5搭載のCodex CLI&lt;/a&gt;**も探索してみてください。リークされたCursorの本番プロンプトや専門的な推論モードなど、異なる強みを提供しています。各ツールには独自の機能があります。Claude Codeはターミナル統合と自然な会話に優れ、Codexは複雑なリファクタリングにGPT-5の高度な推論を活用します。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;技術情報&quot;&gt;技術情報&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;提供元&lt;/strong&gt;: Anthropic
&lt;strong&gt;インターフェース&lt;/strong&gt;: コマンドラインインターフェース（CLI）
&lt;strong&gt;プラットフォーム&lt;/strong&gt;: macOS、Linux、Windows（WSL）
&lt;strong&gt;要件&lt;/strong&gt;: Anthropic APIキー、Node.js 18以上（npmインストールの場合）
&lt;strong&gt;ドキュメント&lt;/strong&gt;: docs.anthropic.comで利用可能
&lt;strong&gt;API料金&lt;/strong&gt;: Anthropicの標準トークン単価に基づく&lt;/p&gt;
&lt;p&gt;&lt;em&gt;注：この分析はClaude Codeのターミナルベースのコーディングアシスタントとしての機能を反映しています。実際のパフォーマンスは、具体的なユースケースと実装アプローチによって異なります。&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Claude Code: 터미널 기반 AI 코딩 어시스턴트]]></title><description><![CDATA[Claude Code는 개발자가 자연어 대화를 통해 애플리케이션을 구축할 수 있게 해주는 터미널 기반 AI 코딩 어시스턴트입니다.]]></description><link>https://vibecodingwithfred.com/ko/blog/claude-code-cli-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/ko/blog/claude-code-cli-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 22 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;플랫폼:&lt;/strong&gt; Claude Code | &lt;strong&gt;제공자:&lt;/strong&gt; Anthropic | &lt;strong&gt;인터페이스:&lt;/strong&gt; Terminal/CLI&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;claude-code란&quot;&gt;Claude Code란&lt;/h2&gt;
&lt;p&gt;Claude Code는 명령줄에서 실행되는 Anthropic의 터미널 기반 코딩 어시스턴트입니다. 자연어를 통해 상호작용하여 코드를 생성하고, 문제를 디버그하고, 기존 코드를 리팩토링하고, 개발 작업을 관리합니다. 프로젝트 디렉토리 내에서 작동하며 지시에 따라 파일을 읽고, 쓰고, 수정할 수 있습니다.&lt;/p&gt;
&lt;p&gt;이 도구는 기존 개발 워크플로우를 대체하는 것이 아니라 통합됩니다. 여전히 선호하는 에디터, 버전 관리, 배포 도구를 사용합니다. Claude Code는 당신이 아키텍처와 요구사항에 집중하는 동안 구현 세부사항을 처리하는 어시스턴트 역할을 합니다.&lt;/p&gt;
&lt;h2 id=&quot;작동-방식&quot;&gt;작동 방식&lt;/h2&gt;
&lt;p&gt;Claude Code는 터미널에서 대화형 인터페이스를 통해 작동합니다. 필요한 것을 평범한 영어로 설명하면 그에 따라 코드를 생성하거나 수정합니다. 이 도구는 세션 내에서 프로젝트 구조, 코딩 패턴, 이전 상호작용에 대한 컨텍스트를 유지합니다.&lt;/p&gt;
&lt;p&gt;프로젝트 디렉토리에서 Claude Code를 시작하면 코드베이스를 분석하여 사용 중인 아키텍처, 프레임워크, 패턴을 이해할 수 있습니다. 이 컨텍스트는 기존 스타일에 맞고 프로젝트와 제대로 통합되는 코드를 생성하는 데 도움이 됩니다.&lt;/p&gt;
&lt;p&gt;기본 워크플로우는 필요한 기능이나 수정 사항을 설명하고, 생성된 코드를 검토하고, 테스트한 다음, 결과에 따라 반복하는 것입니다. Claude Code는 다중 파일 변경을 처리하고, 컴포넌트 간의 종속성을 이해하며, 코드베이스 전체에서 일관성을 유지할 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;핵심-기능&quot;&gt;핵심 기능&lt;/h2&gt;
&lt;p&gt;Claude Code는 설명에서 새 코드 파일을 생성하여 완전한 컴포넌트, API 엔드포인트, 데이터베이스 모델, 테스트 스위트를 만들 수 있습니다. React, Vue, Express, Django, Rails 및 기타 인기 있는 도구에 대한 관용적인 코드를 생성하는 일반적인 프레임워크와 라이브러리를 이해합니다.&lt;/p&gt;
&lt;p&gt;기존 코드의 경우 함수와 클래스를 리팩토링하고, 더 이상 사용되지 않는 API를 업데이트하고, 성능을 개선하고, 버그를 수정하고, 에러 처리를 추가할 수 있습니다. 이 도구는 잠재적인 문제에 대해 코드를 분석하고, 개선 사항을 제안하고, 수정 사항을 구현할 수 있습니다.&lt;/p&gt;
&lt;p&gt;테스트 생성은 또 다른 핵심 기능입니다. Claude Code는 기존 코드를 기반으로 단위 테스트, 통합 테스트, 엔드투엔드 테스트를 만들 수 있습니다. Jest, Pytest, RSpec 등의 테스팅 프레임워크를 이해합니다.&lt;/p&gt;
&lt;p&gt;이 도구는 또한 문서화 작업을 처리하여 README 파일, API 문서, 인라인 주석, 복잡한 코드 섹션을 설명하는 docstring을 생성합니다.&lt;/p&gt;
&lt;h2 id=&quot;기술-요구사항&quot;&gt;기술 요구사항&lt;/h2&gt;
&lt;p&gt;Claude Code가 작동하려면 Anthropic API 키가 필요합니다. 이는 Anthropic 계정이 필요하고 API 사용량에 따라 비용이 청구된다는 의미입니다. 가격 모델은 사용 중인 Claude 모델에 대한 Anthropic의 표준 API 요금을 따릅니다.&lt;/p&gt;
&lt;p&gt;이 도구는 macOS, Linux, Windows(WSL을 통해)에서 실행됩니다. npm을 통해 설치하는 경우 Node.js 18+가 필요하지만 직접 설치를 위한 네이티브 설치 프로그램도 사용할 수 있습니다. 터미널은 파일 작업을 위한 표준 Unix 명령을 지원해야 합니다.&lt;/p&gt;
&lt;h2 id=&quot;실제-한계&quot;&gt;실제 한계&lt;/h2&gt;
&lt;p&gt;Claude Code는 기본 Claude 모델의 컨텍스트 윈도우 제한 내에서 작동합니다. 대규모 코드베이스의 경우 모든 파일을 동시에 고려하지 못할 수 있습니다. 복잡한 작업을 위해 어떤 파일과 컨텍스트를 제공할지 전략적으로 결정해야 합니다.&lt;/p&gt;
&lt;p&gt;이 도구는 코드를 직접 실행하거나 테스트를 실행할 수 없습니다. 여전히 개발 서버를 실행하고, 테스트 스위트를 실행하고, 생성된 코드가 예상대로 작동하는지 확인해야 합니다. Claude Code는 코드를 생성하지만 올바르게 실행되는지 검증하지 않습니다.&lt;/p&gt;
&lt;p&gt;복잡한 아키텍처 결정, 시스템 설계, 비즈니스 로직은 여전히 인간의 판단이 필요합니다. Claude Code는 사양에 따라 구현하지만 애플리케이션을 어떻게 구조화할지 또는 어떤 기능을 빌드할지 독립적으로 결정하지 않습니다.&lt;/p&gt;
&lt;p&gt;생성된 코드는 프로덕션 사용을 위해 조정이 필요할 수 있습니다. Claude Code는 기능적인 코드를 생성하지만 배포 전에 보안, 성능, 팀 표준 준수 여부를 검토해야 합니다.&lt;/p&gt;
&lt;h2 id=&quot;누가-사용해야-하는가&quot;&gt;누가 사용해야 하는가&lt;/h2&gt;
&lt;p&gt;터미널 인터페이스에 익숙한 개발자는 Claude Code가 워크플로우에 자연스럽게 맞는다고 느낄 것입니다. 대부분의 시간을 명령줄에서 보내고 GUI보다 텍스트 기반 인터페이스를 선호하는 사람들에게 특히 유용합니다.&lt;/p&gt;
&lt;p&gt;그린필드 프로젝트를 진행하는 팀은 빠른 프로토타이핑 기능의 이점을 얻습니다. 보일러플레이트 코드를 빠르게 생성하고, 프로젝트 구조를 설정하고, 수동 코딩 없이 표준 기능을 구현할 수 있습니다.&lt;/p&gt;
&lt;p&gt;새로운 프레임워크나 언어를 배우는 개발자는 Claude Code를 사용하여 패턴과 모범 사례를 이해할 수 있습니다. 생성된 코드는 익숙하지 않은 기술에서 관용적인 구현의 예시 역할을 합니다.&lt;/p&gt;
&lt;p&gt;레거시 코드베이스를 다루는 사람들은 종속성 업데이트, 오래된 패턴 리팩토링, 테스트되지 않은 코드에 테스트 추가와 같은 현대화 작업에 Claude Code를 활용할 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;통합-포인트&quot;&gt;통합 포인트&lt;/h2&gt;
&lt;p&gt;Claude Code는 기존 도구를 대체하는 것이 아니라 함께 작동합니다. Git을 버전 관리에 계속 사용하며, Claude Code가 코드를 생성하면 커밋합니다. IDE나 텍스트 에디터는 코드 검토 및 편집을 위한 기본 인터페이스로 남습니다.&lt;/p&gt;
&lt;p&gt;테스팅 프레임워크, 빌드 도구, 배포 파이프라인은 Claude Code와 독립적으로 작동합니다. 이 도구는 이러한 시스템과 작동하는 코드를 생성하지만 직접 제어하지는 않습니다.&lt;/p&gt;
&lt;p&gt;팀의 경우 Claude Code는 기존 개발 프로세스에 맞습니다. 한 개발자가 초기 구현을 생성하는 데 사용하고 다른 사람들이 일반적인 코드 리뷰 프로세스를 통해 검토할 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;비용-고려사항&quot;&gt;비용 고려사항&lt;/h2&gt;
&lt;p&gt;사용 비용은 제공하는 컨텍스트의 양과 응답 길이에 따라 다릅니다. 각 상호작용은 프롬프트 크기와 생성된 코드에 따라 API 토큰을 소비합니다. 대규모 리팩토링 작업이나 광범위한 코드 생성 세션은 상당한 토큰 사용량을 누적할 수 있습니다.&lt;/p&gt;
&lt;p&gt;파일이 많거나 복잡한 요구사항이 있는 프로젝트는 원하는 결과를 달성하기 위해 여러 번의 상호작용이 필요할 수 있어 비용이 증가합니다. API 사용량을 모니터링하고 예산에 따라 적절한 제한을 설정해야 합니다.&lt;/p&gt;
&lt;p&gt;가치 제안은 사용 사례에 따라 다릅니다. Claude Code가 개발 시간을 몇 시간 절약한다면 API 비용은 개발자 급여에 비해 무시할 수 있습니다. 취미 프로젝트나 학습의 경우 비용을 더 신중하게 고려해야 합니다.&lt;/p&gt;
&lt;h2 id=&quot;실제-가치-얻기&quot;&gt;실제 가치 얻기&lt;/h2&gt;
&lt;p&gt;모호한 요청보다 구체적이고 잘 정의된 작업에 집중하세요. &quot;사용자 인증 엔드포인트에 에러 처리 추가&quot;가 &quot;코드 개선&quot;보다 더 나은 결과를 냅니다. 명확한 사양이 더 정확한 구현으로 이어집니다.&lt;/p&gt;
&lt;p&gt;한 번에 대규모 변경을 시도하는 것보다 점진적으로 빌드하세요. 하나의 컴포넌트를 생성하고, 테스트한 다음, 다음으로 이동합니다. 이 접근 방식은 코드 품질을 유지하고 문제가 발생할 때 디버깅을 더 쉽게 만듭니다.&lt;/p&gt;
&lt;p&gt;Claude Code가 참조할 수 있는 프로젝트 문서를 유지하세요. README 파일, API 사양, 아키텍처 문서는 코드 생성 품질을 향상시키는 컨텍스트를 제공합니다.&lt;/p&gt;
&lt;p&gt;커밋하기 전에 생성된 코드를 검토하세요. Claude Code는 기능적인 구현을 생성하지만 인간 검토가 엣지 케이스를 잡고, 보안 모범 사례를 보장하고, 코드 품질 표준을 유지합니다.&lt;/p&gt;
&lt;h2 id=&quot;결론&quot;&gt;결론&lt;/h2&gt;
&lt;p&gt;Claude Code는 터미널을 떠나지 않고 AI 지원을 원하는 개발자를 위한 실용적인 도구입니다. 적절하게 사용할 때 일상적인 코딩 작업을 처리하고, 리팩토링을 돕고, 개발을 가속화합니다.&lt;/p&gt;
&lt;p&gt;이 도구는 개발자 전문성을 대체하는 것이 아니라 어시스턴트로서 가장 잘 작동합니다. 여전히 아키텍처를 이해하고, 설계 결정을 내리고, 코드 품질을 보장해야 합니다. Claude Code는 당신의 지시에 따라 구현 세부사항을 처리합니다.&lt;/p&gt;
&lt;p&gt;터미널 워크플로우에 익숙하고 요구사항이 명확한 개발자에게 Claude Code는 개발을 상당히 가속화할 수 있습니다. 핵심은 그 기능과 한계를 이해한 다음 가장 많은 가치를 제공하는 곳에 적용하는 것입니다.&lt;/p&gt;
&lt;h3 id=&quot;ai-코딩-어시스턴트-비교&quot;&gt;AI 코딩 어시스턴트 비교&lt;/h3&gt;
&lt;p&gt;다양한 AI 코딩 도구를 평가하고 있다면 **&lt;a href=&quot;/blog/codex-cli-ultimate-guide/&quot;&gt;GPT-5를 사용하는 Codex CLI&lt;/a&gt;**도 탐색해보세요. 유출된 Cursor 프로덕션 프롬프트와 특화된 추론 모드를 포함한 다양한 강점을 제공합니다. 각 도구에는 고유한 기능이 있습니다—Claude Code는 터미널 통합과 자연스러운 대화에 뛰어나고, Codex는 복잡한 리팩터를 위해 GPT-5의 고급 추론을 활용합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;기술-정보&quot;&gt;기술 정보&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;제공자&lt;/strong&gt;: Anthropic
&lt;strong&gt;인터페이스&lt;/strong&gt;: 명령줄 인터페이스 (CLI)
&lt;strong&gt;플랫폼&lt;/strong&gt;: macOS, Linux, Windows (WSL)
&lt;strong&gt;요구사항&lt;/strong&gt;: Anthropic API 키, Node.js 18+ (npm 설치용)
&lt;strong&gt;문서&lt;/strong&gt;: docs.anthropic.com에서 제공
&lt;strong&gt;API 가격&lt;/strong&gt;: 토큰당 Anthropic의 표준 요금 기준&lt;/p&gt;
&lt;p&gt;&lt;em&gt;참고: 이 분석은 터미널 기반 코딩 어시스턴트로서 Claude Code의 기능을 반영합니다. 실제 성능은 특정 사용 사례와 구현 접근 방식에 따라 다릅니다.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Claude Code: Terminal-Gebaseerde AI Coding Assistent]]></title><description><![CDATA[Claude Code is een terminal-gebaseerde AI coding assistent waarmee ontwikkelaars applicaties kunnen bouwen via natuurlijke taalgesprekken.]]></description><link>https://vibecodingwithfred.com/nl/blog/claude-code-cli-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/nl/blog/claude-code-cli-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 22 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Platform:&lt;/strong&gt; Claude Code | &lt;strong&gt;Provider:&lt;/strong&gt; Anthropic | &lt;strong&gt;Interface:&lt;/strong&gt; Terminal/CLI&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;wat-claude-code-is&quot;&gt;Wat Claude Code Is&lt;/h2&gt;
&lt;p&gt;Claude Code is Anthropic&apos;s terminal-gebaseerde coding assistent die in je commandoregel draait. Je interacteert ermee via natuurlijke taal om code te genereren, problemen te debuggen, bestaande code te refactoren en ontwikkeltaken te beheren. Het werkt binnen je projectdirectory en kan bestanden lezen, schrijven en wijzigen op basis van je instructies.&lt;/p&gt;
&lt;p&gt;De tool integreert met je bestaande ontwikkelworkflow in plaats van deze te vervangen. Je gebruikt nog steeds je favoriete editor, versiebeheer en deployment tools. Claude Code fungeert als assistent die de implementatiedetails afhandelt terwijl jij je focust op architectuur en requirements.&lt;/p&gt;
&lt;h2 id=&quot;hoe-het-werkt&quot;&gt;Hoe Het Werkt&lt;/h2&gt;
&lt;p&gt;Claude Code werkt via een conversatie-interface in je terminal. Je beschrijft wat je nodig hebt in gewoon Nederlands, en het genereert of wijzigt code dienovereenkomstig. De tool behoudt context over je projectstructuur, codeerpatronen en eerdere interacties binnen een sessie.&lt;/p&gt;
&lt;p&gt;Wanneer je Claude Code start in een projectdirectory, kan het je codebase analyseren om de architectuur, frameworks en patronen die je gebruikt te begrijpen. Deze context helpt bij het genereren van code die past bij je bestaande stijl en correct integreert met je project.&lt;/p&gt;
&lt;p&gt;De basisworkflow omvat het beschrijven van een feature of fix die je nodig hebt, het reviewen van de gegenereerde code, het testen ervan, en vervolgens itereren op basis van resultaten. Claude Code kan multi-file wijzigingen aan, begrijpt afhankelijkheden tussen componenten en behoudt consistentie door je codebase.&lt;/p&gt;
&lt;h2 id=&quot;kernmogelijkheden&quot;&gt;Kernmogelijkheden&lt;/h2&gt;
&lt;p&gt;Claude Code kan nieuwe codebestanden genereren uit beschrijvingen, complete componenten, API endpoints, database modellen en test suites creëren. Het begrijpt veelvoorkomende frameworks en bibliotheken en genereert idiomatische code voor React, Vue, Express, Django, Rails en andere populaire tools.&lt;/p&gt;
&lt;p&gt;Voor bestaande code kan het functies en klassen refactoren, verouderde API&apos;s updaten, prestaties verbeteren, bugs fixen en error handling toevoegen. De tool kan code analyseren op potentiële problemen, verbeteringen suggereren en fixes implementeren.&lt;/p&gt;
&lt;p&gt;Testgeneratie is een andere kernfeature. Claude Code kan unit tests, integratietests en end-to-end tests maken gebaseerd op je bestaande code. Het begrijpt testframeworks zoals Jest, Pytest, RSpec en anderen.&lt;/p&gt;
&lt;p&gt;De tool handelt ook documentatietaken af, genereert README-bestanden, API-documentatie, inline comments en docstrings die complexe codesecties uitleggen.&lt;/p&gt;
&lt;h2 id=&quot;technische-vereisten&quot;&gt;Technische Vereisten&lt;/h2&gt;
&lt;p&gt;Claude Code vereist een Anthropic API-sleutel om te functioneren. Dit betekent dat je een account bij Anthropic nodig hebt en wordt gefactureerd op basis van API-gebruik. Het prijsmodel volgt Anthropic&apos;s standaard API-tarieven voor het Claude-model dat je gebruikt.&lt;/p&gt;
&lt;p&gt;De tool draait op macOS, Linux en Windows (via WSL). Het vereist Node.js 18+ bij installatie via npm, hoewel native installers beschikbaar zijn voor directe installatie. Je terminal moet standaard Unix-commando&apos;s ondersteunen voor bestandsoperaties.&lt;/p&gt;
&lt;h2 id=&quot;praktische-beperkingen&quot;&gt;Praktische Beperkingen&lt;/h2&gt;
&lt;p&gt;Claude Code werkt binnen de context window-limieten van het onderliggende Claude-model. Voor grote codebases kan het mogelijk niet elk bestand tegelijk in overweging nemen. Je moet strategisch zijn over welke bestanden en context je biedt voor complexe operaties.&lt;/p&gt;
&lt;p&gt;De tool kan niet direct code uitvoeren of tests draaien. Je moet nog steeds je development server draaien, test suites uitvoeren en verifiëren dat gegenereerde code werkt zoals verwacht. Claude Code genereert code maar valideert niet dat het correct draait.&lt;/p&gt;
&lt;p&gt;Complexe architectuurbeslissingen, systeemontwerp en business logic vereisen nog steeds menselijk oordeel. Claude Code implementeert op basis van jouw specificaties maar beslist niet zelfstandig hoe je applicatie te structureren of welke features te bouwen.&lt;/p&gt;
&lt;p&gt;Gegenereerde code heeft mogelijk aanpassing nodig voor productiegebruik. Hoewel Claude Code functionele code produceert, moet je het reviewen op security, prestaties en naleving van je team&apos;s standaarden voordat je deployt.&lt;/p&gt;
&lt;h2 id=&quot;wie-het-zou-moeten-gebruiken&quot;&gt;Wie Het Zou Moeten Gebruiken&lt;/h2&gt;
&lt;p&gt;Ontwikkelaars die comfortabel zijn met terminal-interfaces zullen merken dat Claude Code natuurlijk in hun workflow past. Het is bijzonder nuttig voor degenen die het grootste deel van hun tijd in de commandoregel doorbrengen en de voorkeur geven aan tekstgebaseerde interfaces boven GUI&apos;s.&lt;/p&gt;
&lt;p&gt;Teams die werken aan greenfield projecten profiteren van snelle prototyping-mogelijkheden. Je kunt snel boilerplate code genereren, projectstructuren opzetten en standaardfeatures implementeren zonder handmatig coderen.&lt;/p&gt;
&lt;p&gt;Ontwikkelaars die nieuwe frameworks of talen leren kunnen Claude Code gebruiken om patronen en best practices te begrijpen. De gegenereerde code dient als voorbeelden van idiomatische implementaties in onbekende technologieën.&lt;/p&gt;
&lt;p&gt;Degenen die werken aan legacy codebases kunnen Claude Code inzetten voor moderniseringstaken zoals het updaten van dependencies, refactoren van oude patronen en toevoegen van tests aan ongeteste code.&lt;/p&gt;
&lt;h2 id=&quot;integratiepunten&quot;&gt;Integratiepunten&lt;/h2&gt;
&lt;p&gt;Claude Code werkt naast je bestaande tools in plaats van ze te vervangen. Je blijft Git gebruiken voor versiebeheer, waarbij Claude Code code genereert die je vervolgens commit. Je IDE of teksteditor blijft je primaire interface voor het reviewen en bewerken van code.&lt;/p&gt;
&lt;p&gt;Testframeworks, build tools en deployment pipelines werken onafhankelijk van Claude Code. De tool genereert code die met deze systemen werkt maar controleert ze niet direct.&lt;/p&gt;
&lt;p&gt;Voor teams past Claude Code in bestaande ontwikkelprocessen. Eén ontwikkelaar kan het gebruiken om initiële implementaties te genereren die anderen reviewen via normale code review processen.&lt;/p&gt;
&lt;h2 id=&quot;kostenafwegingen&quot;&gt;Kostenafwegingen&lt;/h2&gt;
&lt;p&gt;Gebruikskosten hangen af van de hoeveelheid context die je biedt en de lengte van responses. Elke interactie verbruikt API-tokens gebaseerd op de grootte van je prompts en de gegenereerde code. Grote refactoring-operaties of uitgebreide codegeneratiesessies kunnen aanzienlijk tokengebruik opleveren.&lt;/p&gt;
&lt;p&gt;Projecten met veel bestanden of complexe requirements kunnen meerdere interacties vereisen om gewenste resultaten te bereiken, wat kosten verhoogt. Je moet je API-gebruik monitoren en passende limieten instellen gebaseerd op je budget.&lt;/p&gt;
&lt;p&gt;De waardepropositie hangt af van je use case. Als Claude Code uren ontwikkeltijd bespaart, kunnen de API-kosten verwaarloosbaar zijn vergeleken met ontwikkelaarssalarissen. Voor hobby-projecten of leren vereisen kosten zorgvuldigere overweging.&lt;/p&gt;
&lt;h2 id=&quot;echte-waarde-krijgen&quot;&gt;Echte Waarde Krijgen&lt;/h2&gt;
&lt;p&gt;Focus op specifieke, goed gedefinieerde taken in plaats van vage verzoeken. &quot;Voeg error handling toe aan de user authentication endpoints&quot; produceert betere resultaten dan &quot;verbeter de code.&quot; Duidelijke specificaties leiden tot accuratere implementaties.&lt;/p&gt;
&lt;p&gt;Bouw incrementeel in plaats van massale wijzigingen in één keer te proberen. Genereer één component, test het, ga dan naar de volgende. Deze aanpak helpt codekwaliteit te behouden en maakt debuggen makkelijker wanneer problemen ontstaan.&lt;/p&gt;
&lt;p&gt;Onderhoud projectdocumentatie waar Claude Code naar kan verwijzen. README-bestanden, API-specificaties en architectuurdocumenten bieden context die de kwaliteit van codegeneratie verbetert.&lt;/p&gt;
&lt;p&gt;Review gegenereerde code voordat je commit. Hoewel Claude Code functionele implementaties produceert, vangt menselijke review edge cases, zorgt voor security best practices en behoudt codekwaliteitsstandaarden.&lt;/p&gt;
&lt;h2 id=&quot;conclusie&quot;&gt;Conclusie&lt;/h2&gt;
&lt;p&gt;Claude Code is een praktische tool voor ontwikkelaars die AI-assistentie willen zonder hun terminal te verlaten. Het handelt routinematige codingtaken af, helpt bij refactoring en versnelt ontwikkeling wanneer het gepast wordt gebruikt.&lt;/p&gt;
&lt;p&gt;De tool werkt het beste als assistent voor implementatie in plaats van vervanging voor ontwikkelaarexpertise. Je moet nog steeds je architectuur begrijpen, designbeslissingen nemen en codekwaliteit waarborgen. Claude Code handelt implementatiedetails af op basis van jouw begeleiding.&lt;/p&gt;
&lt;p&gt;Voor ontwikkelaars die comfortabel zijn met terminal workflows en duidelijk zijn over hun requirements, kan Claude Code ontwikkeling aanzienlijk versnellen. De sleutel is het begrijpen van zijn mogelijkheden en beperkingen, en het vervolgens toepassen waar het de meeste waarde biedt.&lt;/p&gt;
&lt;h3 id=&quot;ai-coding-assistants-vergelijken&quot;&gt;AI Coding Assistants Vergelijken&lt;/h3&gt;
&lt;p&gt;Als je verschillende AI coding tools evalueert, wil je misschien ook &lt;strong&gt;&lt;a href=&quot;/blog/codex-cli-ultimate-guide/&quot;&gt;Codex CLI met GPT-5&lt;/a&gt;&lt;/strong&gt; verkennen, die andere sterke punten biedt inclusief gelekte Cursor productie-prompts en gespecialiseerde redenering-modi. Elke tool heeft unieke mogelijkheden—Claude Code blinkt uit in terminal-integratie en natuurlijk gesprek, terwijl Codex GPT-5&apos;s geavanceerde redenering benut voor complexe refactors.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;technische-informatie&quot;&gt;Technische Informatie&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Provider&lt;/strong&gt;: Anthropic
&lt;strong&gt;Interface&lt;/strong&gt;: Command-line interface (CLI)
&lt;strong&gt;Platforms&lt;/strong&gt;: macOS, Linux, Windows (WSL)
&lt;strong&gt;Vereisten&lt;/strong&gt;: Anthropic API-sleutel, Node.js 18+ (voor npm installatie)
&lt;strong&gt;Documentatie&lt;/strong&gt;: Beschikbaar op docs.anthropic.com
&lt;strong&gt;API Prijzen&lt;/strong&gt;: Gebaseerd op Anthropic&apos;s standaardtarieven per token&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Opmerking: Deze analyse reflecteert Claude Code&apos;s mogelijkheden als terminal-gebaseerde coding assistent. Daadwerkelijke prestaties hangen af van specifieke use cases en implementatieaanpak.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Claude Code: Asystent kodowania AI oparty na terminalu]]></title><description><![CDATA[Claude Code to terminalowy asystent kodowania AI, który pozwala programistom budować aplikacje poprzez rozmowy w języku naturalnym.]]></description><link>https://vibecodingwithfred.com/pl/blog/claude-code-cli-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pl/blog/claude-code-cli-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 22 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Platforma:&lt;/strong&gt; Claude Code | &lt;strong&gt;Dostawca:&lt;/strong&gt; Anthropic | &lt;strong&gt;Interfejs:&lt;/strong&gt; Terminal/CLI&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;czym-jest-claude-code&quot;&gt;Czym jest Claude Code&lt;/h2&gt;
&lt;p&gt;Claude Code to terminalowy asystent kodowania od Anthropic, który działa w linii poleceń. Komunikujesz się z nim w języku naturalnym, aby generować kod, debugować problemy, refaktoryzować istniejący kod i zarządzać zadaniami programistycznymi. Działa w katalogu projektu i może czytać, pisać oraz modyfikować pliki na podstawie Twoich instrukcji.&lt;/p&gt;
&lt;p&gt;Narzędzie integruje się z istniejącym workflow zamiast go zastępować. Nadal używasz preferowanego edytora, kontroli wersji i narzędzi wdrożeniowych. Claude Code działa jako asystent obsługujący szczegóły implementacji, podczas gdy Ty koncentrujesz się na architekturze i wymaganiach.&lt;/p&gt;
&lt;h2 id=&quot;jak-to-dziala&quot;&gt;Jak to działa&lt;/h2&gt;
&lt;p&gt;Claude Code działa poprzez konwersacyjny interfejs w terminalu. Opisujesz czego potrzebujesz zwykłym językiem, a on generuje lub modyfikuje kod odpowiednio. Narzędzie utrzymuje kontekst o strukturze projektu, wzorcach kodowania i poprzednich interakcjach w ramach sesji.&lt;/p&gt;
&lt;p&gt;Gdy uruchomisz Claude Code w katalogu projektu, może przeanalizować bazę kodu, aby zrozumieć architekturę, frameworki i wzorce których używasz. Ten kontekst pomaga generować kod pasujący do istniejącego stylu i prawidłowo integrujący się z projektem.&lt;/p&gt;
&lt;p&gt;Podstawowy workflow polega na opisaniu funkcji lub poprawki której potrzebujesz, przejrzeniu wygenerowanego kodu, przetestowaniu go, a następnie iterowaniu na podstawie wyników. Claude Code może obsługiwać zmiany w wielu plikach, rozumieć zależności między komponentami i utrzymywać spójność w całej bazie kodu.&lt;/p&gt;
&lt;h2 id=&quot;podstawowe-mozliwosci&quot;&gt;Podstawowe możliwości&lt;/h2&gt;
&lt;p&gt;Claude Code może generować nowe pliki kodu z opisów, tworząc kompletne komponenty, endpointy API, modele baz danych i zestawy testów. Rozumie popularne frameworki i biblioteki, generując idiomatyczny kod dla React, Vue, Express, Django, Rails i innych popularnych narzędzi.&lt;/p&gt;
&lt;p&gt;Dla istniejącego kodu może refaktoryzować funkcje i klasy, aktualizować przestarzałe API, poprawiać wydajność, naprawiać błędy i dodawać obsługę błędów. Narzędzie może analizować kod pod kątem potencjalnych problemów, sugerować ulepszenia i implementować poprawki.&lt;/p&gt;
&lt;p&gt;Generowanie testów to kolejna kluczowa funkcja. Claude Code może tworzyć testy jednostkowe, integracyjne i end-to-end na podstawie istniejącego kodu. Rozumie frameworki testowe jak Jest, Pytest, RSpec i inne.&lt;/p&gt;
&lt;p&gt;Narzędzie obsługuje również zadania dokumentacyjne, generując pliki README, dokumentację API, komentarze inline i docstringi wyjaśniające złożone sekcje kodu.&lt;/p&gt;
&lt;h2 id=&quot;wymagania-techniczne&quot;&gt;Wymagania techniczne&lt;/h2&gt;
&lt;p&gt;Claude Code wymaga klucza API Anthropic do działania. Oznacza to, że potrzebujesz konta w Anthropic i będziesz obciążany na podstawie użycia API. Model cenowy podąża za standardowymi stawkami API Anthropic dla używanego modelu Claude.&lt;/p&gt;
&lt;p&gt;Narzędzie działa na macOS, Linux i Windows (przez WSL). Wymaga Node.js 18+ przy instalacji przez npm, choć dostępne są natywne instalatory do bezpośredniej instalacji. Terminal musi obsługiwać standardowe polecenia Unix do operacji na plikach.&lt;/p&gt;
&lt;h2 id=&quot;praktyczne-ograniczenia&quot;&gt;Praktyczne ograniczenia&lt;/h2&gt;
&lt;p&gt;Claude Code działa w ramach limitów okna kontekstowego bazowego modelu Claude. Dla dużych baz kodu może nie być w stanie rozważać wszystkich plików jednocześnie. Musisz być strategiczny w tym jakie pliki i kontekst dostarczasz dla złożonych operacji.&lt;/p&gt;
&lt;p&gt;Narzędzie nie może bezpośrednio wykonywać kodu ani uruchamiać testów. Nadal musisz uruchamiać serwer deweloperski, wykonywać zestawy testowe i weryfikować że wygenerowany kod działa zgodnie z oczekiwaniami. Claude Code generuje kod, ale nie waliduje czy działa poprawnie.&lt;/p&gt;
&lt;p&gt;Złożone decyzje architektoniczne, projektowanie systemów i logika biznesowa nadal wymagają ludzkiego osądu. Claude Code implementuje na podstawie Twoich specyfikacji, ale nie będzie niezależnie decydował jak ustrukturyzować aplikację czy jakie funkcje budować.&lt;/p&gt;
&lt;p&gt;Wygenerowany kod może wymagać dostosowania do użytku produkcyjnego. Chociaż Claude Code produkuje funkcjonalny kod, powinieneś go przejrzeć pod kątem bezpieczeństwa, wydajności i zgodności ze standardami zespołu przed wdrożeniem.&lt;/p&gt;
&lt;h2 id=&quot;kto-powinien-go-uzywac&quot;&gt;Kto powinien go używać&lt;/h2&gt;
&lt;p&gt;Programiści komfortowo pracujący z interfejsami terminala uznają że Claude Code naturalnie wpasowuje się w ich workflow. Jest szczególnie użyteczny dla tych, którzy spędzają większość czasu w linii poleceń i preferują tekstowe interfejsy nad GUI.&lt;/p&gt;
&lt;p&gt;Zespoły pracujące nad nowymi projektami korzystają z możliwości szybkiego prototypowania. Możesz szybko generować boilerplate kod, konfigurować struktury projektów i implementować standardowe funkcje bez ręcznego kodowania.&lt;/p&gt;
&lt;p&gt;Programiści uczący się nowych frameworków lub języków mogą używać Claude Code do zrozumienia wzorców i najlepszych praktyk. Wygenerowany kod służy jako przykłady idiomatycznych implementacji w nieznanych technologiach.&lt;/p&gt;
&lt;p&gt;Ci pracujący nad legacy bazami kodu mogą wykorzystać Claude Code do zadań modernizacyjnych jak aktualizacja zależności, refaktoryzacja starych wzorców i dodawanie testów do nieprzetestowanego kodu.&lt;/p&gt;
&lt;h2 id=&quot;punkty-integracji&quot;&gt;Punkty integracji&lt;/h2&gt;
&lt;p&gt;Claude Code działa obok istniejących narzędzi zamiast je zastępować. Kontynuujesz używanie Git do kontroli wersji, a Claude Code generuje kod który następnie commitujesz. Twoje IDE lub edytor tekstu pozostaje głównym interfejsem do przeglądania i edycji kodu.&lt;/p&gt;
&lt;p&gt;Frameworki testowe, narzędzia budowania i pipeline&apos;y wdrożeniowe działają niezależnie od Claude Code. Narzędzie generuje kod który działa z tymi systemami, ale nie kontroluje ich bezpośrednio.&lt;/p&gt;
&lt;p&gt;Dla zespołów, Claude Code wpasowuje się w istniejące procesy deweloperskie. Jeden programista może go użyć do generowania początkowych implementacji które inni przeglądają przez normalne procesy code review.&lt;/p&gt;
&lt;h2 id=&quot;rozwazania-kosztowe&quot;&gt;Rozważania kosztowe&lt;/h2&gt;
&lt;p&gt;Koszty użycia zależą od ilości dostarczanego kontekstu i długości odpowiedzi. Każda interakcja zużywa tokeny API na podstawie rozmiaru promptów i wygenerowanego kodu. Duże operacje refaktoryzacji lub rozległe sesje generowania kodu mogą akumulować znaczące użycie tokenów.&lt;/p&gt;
&lt;p&gt;Projekty z wieloma plikami lub złożonymi wymaganiami mogą wymagać wielu interakcji do osiągnięcia pożądanych rezultatów, zwiększając koszty. Powinieneś monitorować użycie API i ustawiać odpowiednie limity na podstawie budżetu.&lt;/p&gt;
&lt;p&gt;Propozycja wartości zależy od przypadku użycia. Jeśli Claude Code oszczędza godziny czasu programowania, koszty API mogą być znikome w porównaniu do wynagrodzeń programistów. Dla projektów hobbystycznych lub nauki, koszty wymagają bardziej starannego rozważenia.&lt;/p&gt;
&lt;h2 id=&quot;uzyskiwanie-realnej-wartosci&quot;&gt;Uzyskiwanie realnej wartości&lt;/h2&gt;
&lt;p&gt;Skup się na konkretnych, dobrze zdefiniowanych zadaniach zamiast niejasnych próśb. &quot;Dodaj obsługę błędów do endpointów uwierzytelniania użytkownika&quot; daje lepsze rezultaty niż &quot;ulepsz kod.&quot; Jasne specyfikacje prowadzą do dokładniejszych implementacji.&lt;/p&gt;
&lt;p&gt;Buduj przyrostowo zamiast próbować masowych zmian na raz. Wygeneruj jeden komponent, przetestuj go, potem przejdź do następnego. To podejście pomaga utrzymać jakość kodu i ułatwia debugowanie gdy pojawiają się problemy.&lt;/p&gt;
&lt;p&gt;Utrzymuj dokumentację projektu do której Claude Code może się odwoływać. Pliki README, specyfikacje API i dokumenty architektury dostarczają kontekstu poprawiającego jakość generowania kodu.&lt;/p&gt;
&lt;p&gt;Przeglądaj wygenerowany kod przed commitowaniem. Chociaż Claude Code produkuje funkcjonalne implementacje, ludzka recenzja wyłapuje przypadki brzegowe, zapewnia najlepsze praktyki bezpieczeństwa i utrzymuje standardy jakości kodu.&lt;/p&gt;
&lt;h2 id=&quot;podsumowanie&quot;&gt;Podsumowanie&lt;/h2&gt;
&lt;p&gt;Claude Code to praktyczne narzędzie dla programistów chcących asysty AI bez opuszczania terminala. Obsługuje rutynowe zadania kodowania, pomaga przy refaktoryzacji i przyspiesza rozwój gdy używane odpowiednio.&lt;/p&gt;
&lt;p&gt;Narzędzie działa najlepiej jako asystent a nie zamiennik ekspertyzy programistycznej. Nadal musisz rozumieć architekturę, podejmować decyzje projektowe i zapewniać jakość kodu. Claude Code obsługuje szczegóły implementacji na podstawie Twoich wskazówek.&lt;/p&gt;
&lt;p&gt;Dla programistów komfortowych z workflow terminalowym i jasnych co do swoich wymagań, Claude Code może znacząco przyspieszyć rozwój. Kluczem jest zrozumienie jego możliwości i ograniczeń, a następnie stosowanie go tam gdzie dostarcza najwięcej wartości.&lt;/p&gt;
&lt;h3 id=&quot;porownanie-asystentow-kodowania-ai&quot;&gt;Porównanie asystentów kodowania AI&lt;/h3&gt;
&lt;p&gt;Jeśli oceniasz różne narzędzia AI do kodowania, możesz też chcieć poznać &lt;strong&gt;&lt;a href=&quot;/blog/codex-cli-ultimate-guide/&quot;&gt;Codex CLI z GPT-5&lt;/a&gt;&lt;/strong&gt;, które oferuje inne mocne strony w tym ujawnione prompty produkcyjne Cursor i specjalistyczne tryby rozumowania. Każde narzędzie ma unikalne możliwości - Claude Code wyróżnia się integracją z terminalem i naturalną konwersacją, podczas gdy Codex wykorzystuje zaawansowane rozumowanie GPT-5 do złożonych refaktoryzacji.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;informacje-techniczne&quot;&gt;Informacje techniczne&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Dostawca&lt;/strong&gt;: Anthropic
&lt;strong&gt;Interfejs&lt;/strong&gt;: Interfejs linii poleceń (CLI)
&lt;strong&gt;Platformy&lt;/strong&gt;: macOS, Linux, Windows (WSL)
&lt;strong&gt;Wymagania&lt;/strong&gt;: Klucz API Anthropic, Node.js 18+ (dla instalacji npm)
&lt;strong&gt;Dokumentacja&lt;/strong&gt;: Dostępna na docs.anthropic.com
&lt;strong&gt;Cennik API&lt;/strong&gt;: Na podstawie standardowych stawek Anthropic za token&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Uwaga: Ta analiza odzwierciedla możliwości Claude Code jako terminalowego asystenta kodowania. Rzeczywista wydajność zależy od konkretnych przypadków użycia i podejścia implementacyjnego.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Claude Code: Assistente de Codigo IA Baseado em Terminal]]></title><description><![CDATA[Claude Code e um assistente de codigo IA baseado em terminal que permite desenvolvedores construir aplicacoes atraves de conversas em linguagem natural.]]></description><link>https://vibecodingwithfred.com/pt/blog/claude-code-cli-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pt/blog/claude-code-cli-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 22 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Plataforma:&lt;/strong&gt; Claude Code | &lt;strong&gt;Provedor:&lt;/strong&gt; Anthropic | &lt;strong&gt;Interface:&lt;/strong&gt; Terminal/CLI&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;o-que-e-o-claude-code&quot;&gt;O Que e o Claude Code&lt;/h2&gt;
&lt;p&gt;Claude Code e o assistente de codigo baseado em terminal da Anthropic que roda na sua linha de comando. Voce interage com ele atraves de linguagem natural para gerar codigo, depurar problemas, refatorar codigo existente e gerenciar tarefas de desenvolvimento. Ele opera dentro do diretorio do seu projeto e pode ler, escrever e modificar arquivos baseado nas suas instrucoes.&lt;/p&gt;
&lt;p&gt;A ferramenta se integra ao seu fluxo de trabalho de desenvolvimento existente em vez de substitui-lo. Voce ainda usa seu editor preferido, controle de versao e ferramentas de deployment. O Claude Code atua como um assistente que lida com os detalhes de implementacao enquanto voce foca em arquitetura e requisitos.&lt;/p&gt;
&lt;h2 id=&quot;como-funciona&quot;&gt;Como Funciona&lt;/h2&gt;
&lt;p&gt;O Claude Code opera atraves de uma interface conversacional no seu terminal. Voce descreve o que precisa em portugues simples, e ele gera ou modifica codigo de acordo. A ferramenta mantem contexto sobre a estrutura do seu projeto, padroes de codigo e interacoes anteriores dentro de uma sessao.&lt;/p&gt;
&lt;p&gt;Quando voce inicia o Claude Code em um diretorio de projeto, ele pode analisar seu codebase para entender a arquitetura, frameworks e padroes que voce esta usando. Esse contexto ajuda a gerar codigo que corresponde ao seu estilo existente e se integra adequadamente ao seu projeto.&lt;/p&gt;
&lt;p&gt;O fluxo de trabalho basico envolve descrever uma funcionalidade ou correcao que voce precisa, revisar o codigo gerado, testa-lo e iterar baseado nos resultados. O Claude Code pode lidar com mudancas em multiplos arquivos, entender dependencias entre componentes e manter consistencia em todo seu codebase.&lt;/p&gt;
&lt;h2 id=&quot;capacidades-principais&quot;&gt;Capacidades Principais&lt;/h2&gt;
&lt;p&gt;O Claude Code pode gerar novos arquivos de codigo a partir de descricoes, criando componentes completos, endpoints de API, modelos de banco de dados e suites de teste. Ele entende frameworks e bibliotecas comuns, gerando codigo idiomatico para React, Vue, Express, Django, Rails e outras ferramentas populares.&lt;/p&gt;
&lt;p&gt;Para codigo existente, ele pode refatorar funcoes e classes, atualizar APIs deprecadas, melhorar performance, corrigir bugs e adicionar tratamento de erros. A ferramenta pode analisar codigo para problemas potenciais, sugerir melhorias e implementar correcoes.&lt;/p&gt;
&lt;p&gt;Geracao de testes e outra funcionalidade chave. O Claude Code pode criar testes unitarios, testes de integracao e testes end-to-end baseados no seu codigo existente. Ele entende frameworks de teste como Jest, Pytest, RSpec e outros.&lt;/p&gt;
&lt;p&gt;A ferramenta tambem lida com tarefas de documentacao, gerando arquivos README, documentacao de API, comentarios inline e docstrings que explicam secoes de codigo complexas.&lt;/p&gt;
&lt;h2 id=&quot;requisitos-tecnicos&quot;&gt;Requisitos Tecnicos&lt;/h2&gt;
&lt;p&gt;O Claude Code requer uma chave de API da Anthropic para funcionar. Isso significa que voce precisa de uma conta com a Anthropic e sera cobrado baseado no uso da API. O modelo de precos segue as taxas padrao de API da Anthropic para o modelo Claude que voce esta usando.&lt;/p&gt;
&lt;p&gt;A ferramenta roda em macOS, Linux e Windows (atraves de WSL). Requer Node.js 18+ se instalando via npm, embora instaladores nativos estejam disponiveis para instalacao direta. Seu terminal precisa suportar comandos Unix padrao para operacoes de arquivo.&lt;/p&gt;
&lt;h2 id=&quot;limitacoes-praticas&quot;&gt;Limitacoes Praticas&lt;/h2&gt;
&lt;p&gt;O Claude Code opera dentro dos limites de janela de contexto do modelo Claude subjacente. Para codebases grandes, ele pode nao conseguir considerar cada arquivo simultaneamente. Voce precisa ser estrategico sobre quais arquivos e contexto voce fornece para operacoes complexas.&lt;/p&gt;
&lt;p&gt;A ferramenta nao pode executar codigo diretamente ou rodar testes. Voce ainda precisa rodar seu servidor de desenvolvimento, executar suites de teste e verificar que o codigo gerado funciona como esperado. O Claude Code gera codigo mas nao valida que ele roda corretamente.&lt;/p&gt;
&lt;p&gt;Decisoes arquiteturais complexas, design de sistemas e logica de negocios ainda requerem julgamento humano. O Claude Code implementa baseado nas suas especificacoes mas nao decidira independentemente como estruturar sua aplicacao ou quais funcionalidades construir.&lt;/p&gt;
&lt;p&gt;Codigo gerado pode precisar de ajuste para uso em producao. Enquanto o Claude Code produz codigo funcional, voce deve revisa-lo para seguranca, performance e aderencia aos padroes da sua equipe antes de fazer deploy.&lt;/p&gt;
&lt;h2 id=&quot;quem-deve-usar&quot;&gt;Quem Deve Usar&lt;/h2&gt;
&lt;p&gt;Desenvolvedores confortaveis com interfaces de terminal acharao que o Claude Code se encaixa naturalmente em seu fluxo de trabalho. E particularmente util para aqueles que passam a maior parte do tempo na linha de comando e preferem interfaces baseadas em texto em vez de GUIs.&lt;/p&gt;
&lt;p&gt;Equipes trabalhando em projetos greenfield se beneficiam das capacidades de prototipagem rapida. Voce pode rapidamente gerar codigo boilerplate, configurar estruturas de projeto e implementar funcionalidades padrao sem codificacao manual.&lt;/p&gt;
&lt;p&gt;Desenvolvedores aprendendo novos frameworks ou linguagens podem usar o Claude Code para entender padroes e melhores praticas. O codigo gerado serve como exemplos de implementacoes idiomaticas em tecnologias nao familiares.&lt;/p&gt;
&lt;p&gt;Aqueles trabalhando em codebases legados podem aproveitar o Claude Code para tarefas de modernizacao como atualizar dependencias, refatorar padroes antigos e adicionar testes a codigo nao testado.&lt;/p&gt;
&lt;h2 id=&quot;pontos-de-integracao&quot;&gt;Pontos de Integracao&lt;/h2&gt;
&lt;p&gt;O Claude Code trabalha junto com suas ferramentas existentes em vez de substitui-las. Voce continua usando Git para controle de versao, com o Claude Code gerando codigo que voce entao commita. Seu IDE ou editor de texto permanece sua interface principal para revisar e editar codigo.&lt;/p&gt;
&lt;p&gt;Frameworks de teste, ferramentas de build e pipelines de deployment operam independentemente do Claude Code. A ferramenta gera codigo que funciona com esses sistemas mas nao os controla diretamente.&lt;/p&gt;
&lt;p&gt;Para equipes, o Claude Code se encaixa em processos de desenvolvimento existentes. Um desenvolvedor pode usa-lo para gerar implementacoes iniciais que outros revisam atraves de processos normais de code review.&lt;/p&gt;
&lt;h2 id=&quot;consideracoes-de-custo&quot;&gt;Consideracoes de Custo&lt;/h2&gt;
&lt;p&gt;Custos de uso dependem da quantidade de contexto que voce fornece e do tamanho das respostas. Cada interacao consome tokens de API baseado no tamanho dos seus prompts e do codigo gerado. Grandes operacoes de refatoracao ou sessoes extensas de geracao de codigo podem acumular uso significativo de tokens.&lt;/p&gt;
&lt;p&gt;Projetos com muitos arquivos ou requisitos complexos podem requerer multiplas interacoes para alcancar os resultados desejados, aumentando os custos. Voce deve monitorar seu uso de API e definir limites apropriados baseados no seu orcamento.&lt;/p&gt;
&lt;p&gt;A proposta de valor depende do seu caso de uso. Se o Claude Code economiza horas de tempo de desenvolvimento, os custos de API podem ser negligenciaveis comparados a salarios de desenvolvedores. Para projetos de hobby ou aprendizado, custos precisam de consideracao mais cuidadosa.&lt;/p&gt;
&lt;h2 id=&quot;obtendo-valor-real&quot;&gt;Obtendo Valor Real&lt;/h2&gt;
&lt;p&gt;Foque em tarefas especificas e bem definidas em vez de requisicoes vagas. &quot;Adicione tratamento de erros aos endpoints de autenticacao de usuario&quot; produz melhores resultados do que &quot;melhore o codigo.&quot; Especificacoes claras levam a implementacoes mais precisas.&lt;/p&gt;
&lt;p&gt;Construa incrementalmente em vez de tentar mudancas massivas de uma vez. Gere um componente, teste-o, depois passe para o proximo. Essa abordagem ajuda a manter a qualidade do codigo e torna a depuracao mais facil quando problemas surgem.&lt;/p&gt;
&lt;p&gt;Mantenha documentacao do projeto que o Claude Code pode referenciar. Arquivos README, especificacoes de API e documentos de arquitetura fornecem contexto que melhora a qualidade da geracao de codigo.&lt;/p&gt;
&lt;p&gt;Revise o codigo gerado antes de commitar. Enquanto o Claude Code produz implementacoes funcionais, revisao humana captura casos extremos, garante melhores praticas de seguranca e mantem padroes de qualidade de codigo.&lt;/p&gt;
&lt;h2 id=&quot;conclusao&quot;&gt;Conclusao&lt;/h2&gt;
&lt;p&gt;O Claude Code e uma ferramenta pratica para desenvolvedores que querem assistencia de IA sem sair do terminal. Ele lida com tarefas de codificacao rotineiras, ajuda com refatoracao e acelera o desenvolvimento quando usado apropriadamente.&lt;/p&gt;
&lt;p&gt;A ferramenta funciona melhor como um assistente em vez de um substituto para expertise de desenvolvedor. Voce ainda precisa entender sua arquitetura, tomar decisoes de design e garantir a qualidade do codigo. O Claude Code lida com detalhes de implementacao baseado na sua orientacao.&lt;/p&gt;
&lt;p&gt;Para desenvolvedores confortaveis com fluxos de trabalho de terminal e claros sobre seus requisitos, o Claude Code pode acelerar significativamente o desenvolvimento. A chave e entender suas capacidades e limitacoes, depois aplica-lo onde fornece mais valor.&lt;/p&gt;
&lt;h3 id=&quot;comparando-assistentes-de-codigo-ia&quot;&gt;Comparando Assistentes de Codigo IA&lt;/h3&gt;
&lt;p&gt;Se voce esta avaliando diferentes ferramentas de codigo IA, voce tambem pode querer explorar &lt;strong&gt;&lt;a href=&quot;/blog/codex-cli-ultimate-guide/&quot;&gt;Codex CLI com GPT-5&lt;/a&gt;&lt;/strong&gt;, que oferece diferentes forcas incluindo prompts de producao vazados do Cursor e modos de raciocinio especializados. Cada ferramenta tem capacidades unicas—Claude Code se destaca em integracao de terminal e conversa natural, enquanto Codex aproveita o raciocinio avancado do GPT-5 para refatoracoes complexas.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;informacoes-tecnicas&quot;&gt;Informacoes Tecnicas&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Provedor&lt;/strong&gt;: Anthropic
&lt;strong&gt;Interface&lt;/strong&gt;: Interface de linha de comando (CLI)
&lt;strong&gt;Plataformas&lt;/strong&gt;: macOS, Linux, Windows (WSL)
&lt;strong&gt;Requisitos&lt;/strong&gt;: Chave de API da Anthropic, Node.js 18+ (para instalacao npm)
&lt;strong&gt;Documentacao&lt;/strong&gt;: Disponivel em docs.anthropic.com
&lt;strong&gt;Precos de API&lt;/strong&gt;: Baseado nas taxas padrao da Anthropic por token&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Nota: Esta analise reflete as capacidades do Claude Code como um assistente de codigo baseado em terminal. O desempenho real depende de casos de uso especificos e abordagem de implementacao.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Claude Code：基于终端的 AI 编码助手]]></title><description><![CDATA[Claude Code 是一个基于终端的 AI 编码助手，让开发者通过自然语言对话来构建应用程序。]]></description><link>https://vibecodingwithfred.com/zh/blog/claude-code-cli-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/zh/blog/claude-code-cli-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Wed, 22 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;平台：&lt;/strong&gt; Claude Code | &lt;strong&gt;提供商：&lt;/strong&gt; Anthropic | &lt;strong&gt;界面：&lt;/strong&gt; 终端/CLI&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;claude-code-是什么&quot;&gt;Claude Code 是什么&lt;/h2&gt;
&lt;p&gt;Claude Code 是 Anthropic 的基于终端的编码助手，运行在你的命令行中。你通过自然语言与它互动，生成代码、调试问题、重构现有代码和管理开发任务。它在你的项目目录中运行，可以根据你的指令读取、写入和修改文件。&lt;/p&gt;
&lt;p&gt;该工具与你现有的开发工作流程集成，而不是取代它。你仍然使用你喜欢的编辑器、版本控制和部署工具。Claude Code 作为助手处理实现细节，而你专注于架构和需求。&lt;/p&gt;
&lt;h2 id=&quot;工作原理&quot;&gt;工作原理&lt;/h2&gt;
&lt;p&gt;Claude Code 通过终端中的对话界面运行。你用简单的英语描述你需要什么，它会相应地生成或修改代码。该工具在会话中保持对项目结构、编码模式和之前交互的上下文。&lt;/p&gt;
&lt;p&gt;当你在项目目录中启动 Claude Code 时，它可以分析你的代码库以了解你正在使用的架构、框架和模式。这个上下文帮助它生成与你现有风格匹配并正确集成到项目中的代码。&lt;/p&gt;
&lt;p&gt;基本工作流程包括描述你需要的功能或修复、审查生成的代码、测试它，然后根据结果进行迭代。Claude Code 可以处理多文件更改，理解组件之间的依赖关系，并在整个代码库中保持一致性。&lt;/p&gt;
&lt;h2 id=&quot;核心功能&quot;&gt;核心功能&lt;/h2&gt;
&lt;p&gt;Claude Code 可以从描述生成新的代码文件，创建完整的组件、API 端点、数据库模型和测试套件。它理解常见的框架和库，为 React、Vue、Express、Django、Rails 和其他流行工具生成惯用代码。&lt;/p&gt;
&lt;p&gt;对于现有代码，它可以重构函数和类、更新已弃用的 API、改善性能、修复 bug 和添加错误处理。该工具可以分析代码中的潜在问题，建议改进并实施修复。&lt;/p&gt;
&lt;p&gt;测试生成是另一个关键功能。Claude Code 可以根据你现有的代码创建单元测试、集成测试和端到端测试。它理解 Jest、Pytest、RSpec 等测试框架。&lt;/p&gt;
&lt;p&gt;该工具还处理文档任务，生成 README 文件、API 文档、内联注释和解释复杂代码段的文档字符串。&lt;/p&gt;
&lt;h2 id=&quot;技术要求&quot;&gt;技术要求&lt;/h2&gt;
&lt;p&gt;Claude Code 需要 Anthropic API 密钥才能运行。这意味着你需要一个 Anthropic 账户，并将根据 API 使用量收费。定价模式遵循 Anthropic 对你使用的 Claude 模型的标准 API 费率。&lt;/p&gt;
&lt;p&gt;该工具可在 macOS、Linux 和 Windows（通过 WSL）上运行。如果通过 npm 安装，需要 Node.js 18+，不过也有原生安装程序可供直接安装。你的终端需要支持标准 Unix 命令进行文件操作。&lt;/p&gt;
&lt;h2 id=&quot;实际局限性&quot;&gt;实际局限性&lt;/h2&gt;
&lt;p&gt;Claude Code 在底层 Claude 模型的上下文窗口限制内运行。对于大型代码库，它可能无法同时考虑每个文件。对于复杂操作，你需要战略性地考虑提供哪些文件和上下文。&lt;/p&gt;
&lt;p&gt;该工具无法直接执行代码或运行测试。你仍然需要运行开发服务器、执行测试套件并验证生成的代码是否按预期工作。Claude Code 生成代码但不验证它是否正确运行。&lt;/p&gt;
&lt;p&gt;复杂的架构决策、系统设计和业务逻辑仍需要人类判断。Claude Code 根据你的规范实现，但不会独立决定如何构建你的应用程序或构建什么功能。&lt;/p&gt;
&lt;p&gt;生成的代码可能需要调整才能用于生产。虽然 Claude Code 生成功能代码，但你应该在部署前审查它的安全性、性能和对团队标准的遵守情况。&lt;/p&gt;
&lt;h2 id=&quot;谁应该使用它&quot;&gt;谁应该使用它&lt;/h2&gt;
&lt;p&gt;熟悉终端界面的开发者会发现 Claude Code 自然地融入他们的工作流程。它特别适合那些大部分时间在命令行中度过、喜欢文本界面而非 GUI 的人。&lt;/p&gt;
&lt;p&gt;从事全新项目的团队可以从快速原型设计能力中受益。你可以快速生成样板代码、设置项目结构和实现标准功能，无需手动编码。&lt;/p&gt;
&lt;p&gt;学习新框架或语言的开发者可以使用 Claude Code 来理解模式和最佳实践。生成的代码作为不熟悉技术中惯用实现的示例。&lt;/p&gt;
&lt;p&gt;处理遗留代码库的人可以利用 Claude Code 进行现代化任务，如更新依赖项、重构旧模式和为未测试的代码添加测试。&lt;/p&gt;
&lt;h2 id=&quot;集成点&quot;&gt;集成点&lt;/h2&gt;
&lt;p&gt;Claude Code 与你现有的工具一起工作，而不是取代它们。你继续使用 Git 进行版本控制，Claude Code 生成的代码由你提交。你的 IDE 或文本编辑器仍然是审查和编辑代码的主要界面。&lt;/p&gt;
&lt;p&gt;测试框架、构建工具和部署管道独立于 Claude Code 运行。该工具生成与这些系统配合工作的代码，但不直接控制它们。&lt;/p&gt;
&lt;p&gt;对于团队，Claude Code 融入现有的开发流程。一个开发者可能使用它生成初始实现，然后其他人通过正常的代码审查流程进行审查。&lt;/p&gt;
&lt;h2 id=&quot;成本考虑&quot;&gt;成本考虑&lt;/h2&gt;
&lt;p&gt;使用成本取决于你提供的上下文量和响应长度。每次交互根据提示大小和生成代码的长度消耗 API 令牌。大型重构操作或大量代码生成会话可能会累积大量令牌使用。&lt;/p&gt;
&lt;p&gt;文件多或需求复杂的项目可能需要多次交互才能达到预期结果，从而增加成本。你应该监控 API 使用情况并根据预算设置适当的限制。&lt;/p&gt;
&lt;p&gt;价值主张取决于你的用例。如果 Claude Code 节省了数小时的开发时间，API 成本与开发者工资相比可能微不足道。对于业余项目或学习，成本需要更仔细的考虑。&lt;/p&gt;
&lt;h2 id=&quot;获得真正价值&quot;&gt;获得真正价值&lt;/h2&gt;
&lt;p&gt;专注于具体、明确定义的任务而不是模糊的请求。&quot;为用户认证端点添加错误处理&quot;比&quot;改进代码&quot;产生更好的结果。清晰的规范导致更准确的实现。&lt;/p&gt;
&lt;p&gt;逐步构建而不是一次尝试大规模更改。生成一个组件，测试它，然后继续下一个。这种方法有助于保持代码质量，并在出现问题时更容易调试。&lt;/p&gt;
&lt;p&gt;维护 Claude Code 可以参考的项目文档。README 文件、API 规范和架构文档提供的上下文可以提高代码生成质量。&lt;/p&gt;
&lt;p&gt;提交前审查生成的代码。虽然 Claude Code 生成功能实现，但人工审查可以捕获边缘情况、确保安全最佳实践并维护代码质量标准。&lt;/p&gt;
&lt;h2 id=&quot;底线&quot;&gt;底线&lt;/h2&gt;
&lt;p&gt;Claude Code 是一个实用工具，适合想要在不离开终端的情况下获得 AI 辅助的开发者。在适当使用时，它可以处理日常编码任务、帮助重构并加速开发。&lt;/p&gt;
&lt;p&gt;该工具最适合作为助手而不是开发者专业知识的替代品。你仍然需要理解你的架构、做设计决策并确保代码质量。Claude Code 根据你的指导处理实现细节。&lt;/p&gt;
&lt;p&gt;对于熟悉终端工作流程并清楚自己需求的开发者，Claude Code 可以显著加速开发。关键是理解其功能和局限性，然后在它提供最大价值的地方应用它。&lt;/p&gt;
&lt;h3 id=&quot;比较-ai-编码助手&quot;&gt;比较 AI 编码助手&lt;/h3&gt;
&lt;p&gt;如果你正在评估不同的 AI 编码工具，你可能还想探索 &lt;strong&gt;&lt;a href=&quot;/blog/codex-cli-ultimate-guide/&quot;&gt;使用 GPT-5 的 Codex CLI&lt;/a&gt;&lt;/strong&gt;，它提供不同的优势，包括泄露的 Cursor 生产提示和专门的推理模式。每个工具都有独特的功能——Claude Code 擅长终端集成和自然对话，而 Codex 利用 GPT-5 的高级推理进行复杂重构。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;技术信息&quot;&gt;技术信息&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;提供商&lt;/strong&gt;：Anthropic
&lt;strong&gt;界面&lt;/strong&gt;：命令行界面 (CLI)
&lt;strong&gt;平台&lt;/strong&gt;：macOS、Linux、Windows (WSL)
&lt;strong&gt;要求&lt;/strong&gt;：Anthropic API 密钥，Node.js 18+（npm 安装）
&lt;strong&gt;文档&lt;/strong&gt;：可在 docs.anthropic.com 获取
&lt;strong&gt;API 定价&lt;/strong&gt;：基于 Anthropic 每令牌的标准费率&lt;/p&gt;
&lt;p&gt;&lt;em&gt;注意：本分析反映了 Claude Code 作为基于终端的编码助手的功能。实际性能取决于具体用例和实现方法。&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Cursor: Editor de Codigo Potenciado por IA]]></title><description><![CDATA[Cursor es un fork de VS Code que integra modelos de IA directamente en la experiencia de edicion para generacion de codigo, refactorizacion y debugging.]]></description><link>https://vibecodingwithfred.com/es/blog/ultimate-vibe-coding-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/es/blog/ultimate-vibe-coding-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 21 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Plataforma:&lt;/strong&gt; Cursor | &lt;strong&gt;Base:&lt;/strong&gt; Fork de VS Code | &lt;strong&gt;Precios:&lt;/strong&gt; Nivel gratuito disponible, Pro a $20/mes&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;que-es-cursor&quot;&gt;Que Es Cursor&lt;/h2&gt;
&lt;p&gt;Cursor es un editor de codigo construido sobre VS Code que integra capacidades de IA directamente en la experiencia de edicion. En lugar de alternar entre tu editor y ChatGPT, interactuas con modelos de IA dentro de tu entorno de desarrollo. El editor puede leer tu codebase, entender contexto entre archivos, y generar o modificar codigo basandose en instrucciones en lenguaje natural.&lt;/p&gt;
&lt;p&gt;La diferencia clave de VS Code estandar es la integracion profunda de IA. Cursor proporciona multiples formas de interactuar con IA: generacion de codigo inline, interfaz de chat, y comandos contextuales. Mantiene conciencia de la estructura de tu proyecto y puede referenciar multiples archivos al generar codigo.&lt;/p&gt;
&lt;h2 id=&quot;como-funciona&quot;&gt;Como Funciona&lt;/h2&gt;
&lt;p&gt;Cursor opera a traves de varios modos de interaccion. El panel de chat te permite tener conversaciones sobre tu codigo mientras referencias archivos o selecciones especificas. La generacion inline (Cmd+K en Mac, Ctrl+K en Windows/Linux) te permite describir cambios directamente en tu editor, y Cursor modifica el codigo en su lugar. El modo composer permite ediciones de multiples archivos desde un solo prompt.&lt;/p&gt;
&lt;p&gt;El editor usa un sistema de contexto para entender tu proyecto. Puedes incluir explicitamente archivos en prompts usando menciones @, o dejar que Cursor determine automaticamente el contexto relevante. Esta conciencia de contexto ayuda a generar codigo que se ajusta a tus patrones y arquitectura existentes.&lt;/p&gt;
&lt;p&gt;Cursor se conecta a varios modelos de IA incluyendo GPT-4, Claude, y otros a traves de API keys. Puedes alternar entre modelos dependiendo de tus necesidades y presupuesto. La suscripcion Pro incluye algo de uso de API, aunque usuarios intensivos podrian necesitar proporcionar sus propias API keys.&lt;/p&gt;
&lt;h2 id=&quot;funciones-principales&quot;&gt;Funciones Principales&lt;/h2&gt;
&lt;p&gt;El archivo &lt;code class=&quot;language-text&quot;&gt;.cursorrules&lt;/code&gt; te permite definir instrucciones especificas del proyecto que aplican a todas las interacciones de IA. Esto incluye estandares de codificacion, patrones arquitectonicos, requerimientos de seguridad, y otras guias. Estas reglas persisten entre sesiones y ayudan a mantener consistencia.&lt;/p&gt;
&lt;p&gt;La gestion de contexto es una funcion significativa. Cursor puede indexar todo tu codebase y usar busqueda semantica para encontrar codigo relevante para cualquier consulta. Este indexado ocurre localmente y no envia tu codigo a servidores externos a menos que lo incluyas explicitamente en un prompt.&lt;/p&gt;
&lt;p&gt;El editor incluye funciones estandar de VS Code como debugging, integracion Git, extensiones, y acceso a terminal. Tu configuracion existente de VS Code, extensiones, y keybindings funcionan en Cursor con ajustes minimos.&lt;/p&gt;
&lt;h2 id=&quot;capacidades-practicas&quot;&gt;Capacidades Practicas&lt;/h2&gt;
&lt;p&gt;Cursor puede generar nuevo codigo desde descripciones, creando componentes completos, funciones, o archivos basandose en tus especificaciones. Entiende frameworks comunes y puede producir codigo idiomatico para React, Python, Node.js, y otras tecnologias populares.&lt;/p&gt;
&lt;p&gt;Para codigo existente, Cursor puede refactorizar funciones, actualizar APIs, corregir bugs, y mejorar rendimiento. Describes el cambio que quieres, y modifica el codigo en consecuencia. La vista de diff te permite revisar cambios antes de aceptarlos.&lt;/p&gt;
&lt;p&gt;La interfaz de chat ayuda con debugging analizando mensajes de error, sugiriendo correcciones, y explicando codigo complejo. Puedes pegar trazas de errores y obtener soluciones especificas basadas en el contexto de tu codebase.&lt;/p&gt;
&lt;h2 id=&quot;limitaciones-y-consideraciones&quot;&gt;Limitaciones y Consideraciones&lt;/h2&gt;
&lt;p&gt;Cursor requiere acceso API a modelos de IA, lo que significa costos continuos mas alla de la suscripcion. El uso intensivo puede resultar en cargos significativos de API, especialmente con modelos premium como GPT-4. El nivel gratuito y los creditos API incluidos en Pro podrian no ser suficientes para desarrollo intensivo.&lt;/p&gt;
&lt;p&gt;La calidad del codigo generado varia basandose en la claridad del prompt y el modelo de IA usado. Logica de negocio compleja, decisiones arquitectonicas, y requerimientos matizados aun necesitan juicio humano. Cursor genera codigo basado en patrones que ha visto, lo cual podria no siempre ajustarse a tus necesidades especificas.&lt;/p&gt;
&lt;p&gt;El editor envia codigo a proveedores externos de IA cuando lo incluyes en prompts. Aunque las conexiones estan encriptadas, esto podria no ser aceptable para codebases propietarios o sensibles. Algunas organizaciones prohiben herramientas que transmiten codigo externamente.&lt;/p&gt;
&lt;p&gt;El rendimiento puede degradarse con codebases muy grandes. El sistema de indexado tiene limites, e incluir demasiado contexto en prompts puede llevar a respuestas mas lentas o errores de limite de tokens.&lt;/p&gt;
&lt;h2 id=&quot;quien-se-beneficia-mas&quot;&gt;Quien Se Beneficia Mas&lt;/h2&gt;
&lt;p&gt;Desarrolladores trabajando en aplicaciones web estandar se benefician de la familiaridad de Cursor con patrones comunes. Construir operaciones CRUD, APIs, y componentes UI estandar se vuelve significativamente mas rapido cuando la IA entiende bien estos patrones.&lt;/p&gt;
&lt;p&gt;Aquellos aprendiendo nuevos frameworks o lenguajes pueden usar Cursor para entender patrones y generar codigo de ejemplo. La IA puede explicar sintaxis desconocida y sugerir implementaciones idiomaticas.&lt;/p&gt;
&lt;p&gt;Equipos trabajando en proyectos greenfield pueden prototipar e iterar rapidamente. Cursor ayuda a generar codigo boilerplate, configurar estructura de proyecto, e implementar funciones comunes sin codificacion manual.&lt;/p&gt;
&lt;p&gt;Desarrolladores tratando con tareas repetitivas encuentran valor en la habilidad de Cursor de reconocer patrones y aplicarlos entre archivos. Refactorizar, actualizar APIs deprecadas, y mantener consistencia se vuelven menos tediosos.&lt;/p&gt;
&lt;h2 id=&quot;integracion-de-flujo-de-trabajo&quot;&gt;Integracion de Flujo de Trabajo&lt;/h2&gt;
&lt;p&gt;Cursor funciona como reemplazo directo de VS Code en la mayoria de flujos de trabajo. Continuas usando Git para control de versiones, con Cursor generando codigo que luego commiteas. Tu IDE o editor de texto sigue siendo tu interfaz principal para revisar y editar codigo.&lt;/p&gt;
&lt;p&gt;Frameworks de testing, herramientas de build, y pipelines de despliegue operan independientemente de Cursor. La herramienta genera codigo que funciona con estos sistemas pero no los controla directamente.&lt;/p&gt;
&lt;p&gt;Los procesos de revision de codigo siguen siendo importantes. Aunque Cursor puede generar codigo funcional, la revision humana asegura que cumpla con los estandares del equipo, maneje casos extremos correctamente, y se alinee con decisiones arquitectonicas.&lt;/p&gt;
&lt;p&gt;Los flujos de trabajo de testing no cambian, pero Cursor puede ayudar a generar tests. Aun necesitas ejecutar suites de tests, verificar cobertura, y asegurar que se cumplan los estandares de calidad.&lt;/p&gt;
&lt;h2 id=&quot;analisis-de-costos&quot;&gt;Analisis de Costos&lt;/h2&gt;
&lt;p&gt;El nivel gratuito proporciona interacciones de IA limitadas, adecuadas para probar Cursor o uso ocasional. La mayoria de desarrolladores necesitaran la suscripcion Pro a $20/mes, que incluye algo de uso de API pero podria requerir API keys adicionales para uso intensivo.&lt;/p&gt;
&lt;p&gt;Los costos de API varian por modelo y uso. GPT-4 cuesta mas que GPT-3.5-turbo, mientras que los modelos Claude tienen diferentes precios. Un dia tipico de desarrollo activo podria consumir $5-20 en costos de API dependiendo de la eleccion de modelo y patrones de uso.&lt;/p&gt;
&lt;p&gt;Compara esto con el tiempo de desarrollador ahorrado. Si Cursor te ahorra varias horas por semana, el costo se justifica facilmente para desarrollo profesional. Para proyectos de aprendizaje o hobby, los costos necesitan consideracion mas cuidadosa.&lt;/p&gt;
&lt;h2 id=&quot;haciendolo-funcionar-efectivamente&quot;&gt;Haciendolo Funcionar Efectivamente&lt;/h2&gt;
&lt;p&gt;Escribe prompts claros y especificos con suficiente contexto. Instrucciones vagas producen resultados poco confiables. Incluye codigo de ejemplo, especifica frameworks y patrones, y se explicito sobre los requerimientos.&lt;/p&gt;
&lt;p&gt;Usa el archivo &lt;code class=&quot;language-text&quot;&gt;.cursorrules&lt;/code&gt; para establecer estandares del proyecto. Esto reduce la repeticion y ayuda a mantener consistencia en el codigo generado por IA.&lt;/p&gt;
&lt;p&gt;Revisa el codigo generado antes de commitear. Aunque Cursor produce codigo funcional, podria no manejar casos extremos, preocupaciones de seguridad, u optimizacion de rendimiento sin instruccion explicita.&lt;/p&gt;
&lt;p&gt;Construye incrementalmente en lugar de generar grandes chunks de una vez. Crea un componente, pruebaelo, luego procede. Este enfoque mantiene calidad de codigo y hace el debugging mas facil.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Cursor es una herramienta practica para desarrolladores que quieren asistencia de IA integrada en su editor. Acelera tareas de desarrollo comunes y reduce codificacion boilerplate cuando se usa apropiadamente.&lt;/p&gt;
&lt;p&gt;La herramienta funciona mejor como asistente para implementacion en lugar de reemplazo para pensamiento arquitectonico y decisiones de diseno. Aun necesitas entender tu sistema, planificar funciones, y asegurar calidad de codigo.&lt;/p&gt;
&lt;p&gt;Para desarrolladores comodos con VS Code y claros sobre sus requerimientos, Cursor puede acelerar significativamente el desarrollo. La clave es entender sus capacidades y limitaciones, luego aplicarlo donde proporcione mayor valor.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;informacion-tecnica&quot;&gt;Informacion Tecnica&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Editor Base&lt;/strong&gt;: Fork de VS Code
&lt;strong&gt;Modelos de IA&lt;/strong&gt;: GPT-5, Claude, y otros via API
&lt;strong&gt;Plataformas&lt;/strong&gt;: Windows, macOS, Linux
&lt;strong&gt;Precios&lt;/strong&gt;: Nivel gratuito disponible, Pro a $20/mes mas costos de API
&lt;strong&gt;Ventana de Contexto&lt;/strong&gt;: Varia por modelo (8k-128k tokens)
&lt;strong&gt;Sitio Web&lt;/strong&gt;: cursor.com&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Nota: Este analisis refleja las capacidades de Cursor como entorno de desarrollo integrado con IA. El rendimiento real depende del caso de uso, calidad de prompt, y seleccion de modelo.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Cursor: Editor di Codice Potenziato dall'AI]]></title><description><![CDATA[Cursor e un fork di VS Code che integra modelli AI direttamente nell'esperienza di editing per generazione di codice, refactoring e debugging.]]></description><link>https://vibecodingwithfred.com/it/blog/ultimate-vibe-coding-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/it/blog/ultimate-vibe-coding-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 21 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Piattaforma:&lt;/strong&gt; Cursor | &lt;strong&gt;Base:&lt;/strong&gt; Fork di VS Code | &lt;strong&gt;Prezzi:&lt;/strong&gt; Tier gratuito disponibile, Pro a $20/mese&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;cose-cursor&quot;&gt;Cos&apos;e Cursor&lt;/h2&gt;
&lt;p&gt;Cursor e un editor di codice costruito su VS Code che integra capacita AI direttamente nell&apos;esperienza di editing. Invece di passare tra il tuo editor e ChatGPT, interagisci con modelli AI all&apos;interno del tuo ambiente di sviluppo. L&apos;editor puo leggere la tua codebase, capire il contesto tra i file e generare o modificare codice basandosi su istruzioni in linguaggio naturale.&lt;/p&gt;
&lt;p&gt;La differenza chiave rispetto a VS Code standard e l&apos;integrazione AI profonda. Cursor fornisce piu modi per interagire con l&apos;AI: generazione di codice inline, interfaccia chat e comandi contestuali. Mantiene la consapevolezza della struttura del tuo progetto e puo fare riferimento a piu file quando genera codice.&lt;/p&gt;
&lt;h2 id=&quot;come-funziona&quot;&gt;Come Funziona&lt;/h2&gt;
&lt;p&gt;Cursor opera attraverso diverse modalita di interazione. Il pannello chat ti permette di avere conversazioni sul tuo codice mentre fai riferimento a file o selezioni specifiche. La generazione inline (Cmd+K su Mac, Ctrl+K su Windows/Linux) ti permette di descrivere modifiche direttamente nel tuo editor, e Cursor modifica il codice sul posto. La modalita composer permette modifiche multi-file da un singolo prompt.&lt;/p&gt;
&lt;p&gt;L&apos;editor usa un sistema di contesto per capire il tuo progetto. Puoi includere esplicitamente file nei prompt usando menzioni @, o lasciare che Cursor determini automaticamente il contesto rilevante. Questa consapevolezza del contesto aiuta a generare codice che corrisponde ai tuoi pattern esistenti e si integra correttamente con il tuo progetto.&lt;/p&gt;
&lt;p&gt;Cursor si connette a vari modelli AI inclusi GPT-4, Claude e altri attraverso chiavi API. Puoi passare tra modelli a seconda delle tue esigenze e budget. L&apos;abbonamento Pro include un po&apos; di utilizzo API, anche se gli utenti pesanti potrebbero dover fornire le proprie chiavi API.&lt;/p&gt;
&lt;h2 id=&quot;funzionalita-principali&quot;&gt;Funzionalita Principali&lt;/h2&gt;
&lt;p&gt;Il file &lt;code class=&quot;language-text&quot;&gt;.cursorrules&lt;/code&gt; ti permette di definire istruzioni specifiche per il progetto che si applicano a tutte le interazioni AI. Questo include standard di coding, pattern architetturali, requisiti di sicurezza e altre linee guida. Queste regole persistono tra le sessioni e aiutano a mantenere la coerenza.&lt;/p&gt;
&lt;p&gt;La gestione del contesto e una funzionalita significativa. Cursor puo indicizzare l&apos;intera codebase e usare la ricerca semantica per trovare codice rilevante per qualsiasi query. Questa indicizzazione avviene localmente e non invia il tuo codice a server esterni a meno che tu non lo includa esplicitamente in un prompt.&lt;/p&gt;
&lt;p&gt;L&apos;editor include funzionalita standard di VS Code come debugging, integrazione Git, estensioni e accesso al terminale. La tua configurazione VS Code esistente, estensioni e keybinding funzionano in Cursor con minimo aggiustamento.&lt;/p&gt;
&lt;h2 id=&quot;capacita-pratiche&quot;&gt;Capacita Pratiche&lt;/h2&gt;
&lt;p&gt;Cursor puo generare nuovo codice da descrizioni, creando interi componenti, funzioni o file basandosi sulle tue specifiche. Capisce framework comuni e puo produrre codice idiomatico per React, Python, Node.js e altre tecnologie popolari.&lt;/p&gt;
&lt;p&gt;Per codice esistente, Cursor puo refactorare funzioni, aggiornare API, correggere bug e migliorare le prestazioni. Descrivi il cambiamento che vuoi e modifica il codice di conseguenza. La vista diff ti permette di revisionare le modifiche prima di accettarle.&lt;/p&gt;
&lt;p&gt;L&apos;interfaccia chat aiuta con il debugging analizzando messaggi di errore, suggerendo correzioni e spiegando codice complesso. Puoi incollare tracce di errore e ottenere soluzioni specifiche basate sul contesto della tua codebase.&lt;/p&gt;
&lt;h2 id=&quot;limitazioni-e-considerazioni&quot;&gt;Limitazioni e Considerazioni&lt;/h2&gt;
&lt;p&gt;Cursor richiede accesso API ai modelli AI, il che significa costi continui oltre all&apos;abbonamento. L&apos;uso pesante puo risultare in carichi API significativi, specialmente con modelli premium come GPT-4. Il tier gratuito e i crediti API inclusi nel Pro potrebbero non bastare per lo sviluppo intensivo.&lt;/p&gt;
&lt;p&gt;La qualita del codice generato varia in base alla chiarezza del prompt e al modello AI usato. Logica di business complessa, decisioni architetturali e requisiti sfumati richiedono ancora giudizio umano. Cursor genera codice basandosi su pattern che ha visto, che potrebbero non sempre adattarsi alle tue esigenze specifiche.&lt;/p&gt;
&lt;p&gt;L&apos;editor invia codice a provider AI esterni quando lo includi nei prompt. Sebbene le connessioni siano criptate, questo potrebbe non essere accettabile per codebase proprietarie o sensibili. Alcune organizzazioni proibiscono strumenti che trasmettono codice esternamente.&lt;/p&gt;
&lt;p&gt;Le prestazioni possono degradare con codebase molto grandi. Il sistema di indicizzazione ha limiti, e includere troppo contesto nei prompt puo portare a risposte piu lente o errori di limite token.&lt;/p&gt;
&lt;h2 id=&quot;chi-ne-beneficia-di-piu&quot;&gt;Chi Ne Beneficia Di Piu&lt;/h2&gt;
&lt;p&gt;Gli sviluppatori che lavorano su applicazioni web standard beneficiano dalla familiarita di Cursor con i pattern comuni. Costruire operazioni CRUD, API e componenti UI standard diventa significativamente piu veloce quando l&apos;AI capisce bene questi pattern.&lt;/p&gt;
&lt;p&gt;Chi sta imparando nuovi framework o linguaggi puo usare Cursor per capire pattern e generare codice di esempio. L&apos;AI puo spiegare sintassi non familiare e suggerire implementazioni idiomatiche.&lt;/p&gt;
&lt;p&gt;I team che lavorano su progetti greenfield possono prototipare e iterare rapidamente. Cursor aiuta a generare codice boilerplate, configurare strutture di progetto e implementare feature comuni senza coding manuale.&lt;/p&gt;
&lt;p&gt;Gli sviluppatori che affrontano task ripetitivi trovano valore nella capacita di Cursor di riconoscere pattern e applicarli tra i file. Refactoring, aggiornamento di API deprecate e mantenimento della coerenza diventano meno noiosi.&lt;/p&gt;
&lt;h2 id=&quot;integrazione-nel-workflow&quot;&gt;Integrazione nel Workflow&lt;/h2&gt;
&lt;p&gt;Cursor funziona come sostituto drop-in per VS Code nella maggior parte dei workflow. Puoi aprire progetti esistenti, usare il controllo versione, eseguire tool di build e deployare applicazioni come al solito. Le funzionalita AI complementano invece di sostituire le pratiche di sviluppo standard.&lt;/p&gt;
&lt;p&gt;I processi di code review rimangono importanti. Mentre Cursor puo generare codice funzionale, la revisione umana assicura che soddisfi gli standard del team, gestisca i casi limite correttamente e sia allineato con le decisioni architetturali.&lt;/p&gt;
&lt;p&gt;I workflow di testing non cambiano, ma Cursor puo aiutare a generare test. Devi comunque eseguire le suite di test, verificare la copertura e assicurare che gli standard di qualita siano soddisfatti.&lt;/p&gt;
&lt;h2 id=&quot;analisi-dei-costi&quot;&gt;Analisi dei Costi&lt;/h2&gt;
&lt;p&gt;Il tier gratuito fornisce interazioni AI limitate, adatte per provare Cursor o uso occasionale. La maggior parte degli sviluppatori avra bisogno dell&apos;abbonamento Pro a $20/mese, che include un po&apos; di utilizzo API ma potrebbe richiedere chiavi API aggiuntive per uso pesante.&lt;/p&gt;
&lt;p&gt;I costi API variano per modello e utilizzo. GPT-4 costa piu di GPT-3.5-turbo, mentre i modelli Claude hanno prezzi diversi. Una giornata tipica di sviluppo attivo potrebbe consumare $5-20 in costi API a seconda della scelta del modello e dei pattern di utilizzo.&lt;/p&gt;
&lt;p&gt;Confronta questo con il tempo sviluppatore risparmiato. Se Cursor risparmia diverse ore a settimana, il costo e facilmente giustificato per lo sviluppo professionale. Per apprendimento o progetti hobby, i costi richiedono una considerazione piu attenta.&lt;/p&gt;
&lt;h2 id=&quot;farlo-funzionare-efficacemente&quot;&gt;Farlo Funzionare Efficacemente&lt;/h2&gt;
&lt;p&gt;Scrivi prompt chiari e specifici con abbastanza contesto. Istruzioni vaghe producono risultati inaffidabili. Includi codice di esempio, specifica framework e pattern, e sii esplicito sui requisiti.&lt;/p&gt;
&lt;p&gt;Usa il file &lt;code class=&quot;language-text&quot;&gt;.cursorrules&lt;/code&gt; per stabilire standard di progetto. Questo riduce la ripetizione e aiuta a mantenere la coerenza nel codice generato dall&apos;AI.&lt;/p&gt;
&lt;p&gt;Revisiona il codice generato prima di committare. Mentre Cursor produce codice funzionale, potrebbe non gestire casi limite, preoccupazioni di sicurezza o ottimizzazione delle prestazioni senza istruzioni esplicite.&lt;/p&gt;
&lt;p&gt;Costruisci incrementalmente invece di generare grandi blocchi tutto in una volta. Crea un componente, testalo, poi procedi. Questo approccio mantiene la qualita del codice e rende il debugging piu facile quando sorgono problemi.&lt;/p&gt;
&lt;h2 id=&quot;in-conclusione&quot;&gt;In Conclusione&lt;/h2&gt;
&lt;p&gt;Cursor e uno strumento pratico per sviluppatori che vogliono assistenza AI integrata nel loro editor. Accelera i task di sviluppo comuni e riduce il coding boilerplate quando usato appropriatamente.&lt;/p&gt;
&lt;p&gt;Lo strumento funziona meglio come assistente per l&apos;implementazione invece che come sostituto del pensiero architetturale e delle decisioni di design. Devi comunque capire il tuo sistema, pianificare le feature e assicurare la qualita del codice.&lt;/p&gt;
&lt;p&gt;Per sviluppatori a proprio agio con VS Code e chiari sui loro requisiti, Cursor puo accelerare significativamente lo sviluppo. La chiave e capire le sue capacita e limitazioni, poi applicarlo dove fornisce valore.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;informazioni-tecniche&quot;&gt;Informazioni Tecniche&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Editor Base&lt;/strong&gt;: Fork di VS Code
&lt;strong&gt;Modelli AI&lt;/strong&gt;: GPT-5, Claude e altri via API
&lt;strong&gt;Piattaforme&lt;/strong&gt;: Windows, macOS, Linux
&lt;strong&gt;Prezzi&lt;/strong&gt;: Tier gratuito disponibile, Pro a $20/mese piu costi API
&lt;strong&gt;Finestra di Contesto&lt;/strong&gt;: Varia per modello (8k-128k token)
&lt;strong&gt;Sito Web&lt;/strong&gt;: cursor.com&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Nota: Questa analisi riflette le capacita di Cursor come ambiente di sviluppo integrato con AI. Le prestazioni effettive dipendono dal caso d&apos;uso, qualita del prompt e selezione del modello.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Cursor: AIパワードコードエディタ]]></title><description><![CDATA[CursorはAIモデルを直接編集体験に統合したVS Codeのフォークで、コード生成、リファクタリング、デバッグに使用できます。]]></description><link>https://vibecodingwithfred.com/ja/blog/ultimate-vibe-coding-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/ja/blog/ultimate-vibe-coding-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 21 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;プラットフォーム:&lt;/strong&gt; Cursor | &lt;strong&gt;ベース:&lt;/strong&gt; VS Codeフォーク | &lt;strong&gt;価格:&lt;/strong&gt; 無料ティアあり、Proは$20/月&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;cursorとは&quot;&gt;Cursorとは&lt;/h2&gt;
&lt;p&gt;CursorはVS Codeをベースに構築されたコードエディタで、AI機能を直接編集体験に統合しています。エディタとChatGPTを切り替える代わりに、開発環境内でAIモデルと対話します。エディタはコードベースを読み、ファイル間のコンテキストを理解し、自然言語の指示に基づいてコードを生成または変更できます。&lt;/p&gt;
&lt;p&gt;標準のVS Codeとの主な違いは、深いAI統合です。Cursorは、AIと対話するための複数の方法を提供します：インラインコード生成、チャットインターフェース、コンテキストコマンド。プロジェクト構造の認識を維持し、コードを生成する際に複数のファイルを参照できます。&lt;/p&gt;
&lt;h2 id=&quot;機能の仕組み&quot;&gt;機能の仕組み&lt;/h2&gt;
&lt;p&gt;Cursorはいくつかの対話モードで動作します。チャットパネルでは、特定のファイルや選択を参照しながらコードについて会話できます。インライン生成（Macでは Cmd+K、Windows/LinuxではCtrl+K）では、エディタ内で直接変更を説明でき、Cursorがコードをその場で変更します。コンポーザーモードでは、単一のプロンプトから複数ファイルの編集が可能です。&lt;/p&gt;
&lt;p&gt;エディタはプロジェクトを理解するためのコンテキストシステムを使用します。@メンションを使用してプロンプトにファイルを明示的に含めるか、Cursorに関連するコンテキストを自動的に判断させることができます。このコンテキスト認識は、既存のパターンとアーキテクチャに合ったコードを生成するのに役立ちます。&lt;/p&gt;
&lt;p&gt;CursorはAPIキーを通じてGPT-4、Claudeなどの様々なAIモデルに接続します。ニーズと予算に応じてモデルを切り替えることができます。Proサブスクリプションには一部のAPI使用が含まれていますが、ヘビーユーザーは自分のAPIキーを提供する必要があるかもしれません。&lt;/p&gt;
&lt;h2 id=&quot;コア機能&quot;&gt;コア機能&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;.cursorrules&lt;/code&gt;ファイルでは、すべてのAI対話に適用されるプロジェクト固有の指示を定義できます。これには、コーディング標準、アーキテクチャパターン、セキュリティ要件、その他のガイドラインが含まれます。これらのルールはセッション間で持続し、一貫性を維持するのに役立ちます。&lt;/p&gt;
&lt;p&gt;コンテキスト管理は重要な機能です。Cursorはコードベース全体をインデックスし、任意のクエリに関連するコードを見つけるためにセマンティック検索を使用できます。このインデックス作成はローカルで行われ、プロンプトに明示的に含めない限り、コードが外部サーバーに送信されることはありません。&lt;/p&gt;
&lt;p&gt;エディタには、デバッグ、Git統合、拡張機能、ターミナルアクセスなどの標準的なVS Code機能が含まれています。既存のVS Code設定、拡張機能、キーバインディングは最小限の調整でCursorで動作します。&lt;/p&gt;
&lt;h2 id=&quot;実用的な機能&quot;&gt;実用的な機能&lt;/h2&gt;
&lt;p&gt;Cursorは説明から新しいコードを生成でき、仕様に基づいて完全なコンポーネント、関数、またはファイルを作成します。一般的なフレームワークを理解し、React、Python、Node.jsなどの人気技術向けの慣用的なコードを生成できます。&lt;/p&gt;
&lt;p&gt;既存のコードについては、Cursorは関数をリファクタリングし、APIを更新し、バグを修正し、パフォーマンスを改善できます。変更したいことを説明すると、それに応じてコードを変更します。差分ビューでは、受け入れる前に変更をレビューできます。&lt;/p&gt;
&lt;p&gt;チャットインターフェースは、エラーメッセージを分析し、修正を提案し、複雑なコードを説明することでデバッグを支援します。エラートレースを貼り付けて、コードベースのコンテキストに基づいた具体的な解決策を得ることができます。&lt;/p&gt;
&lt;h2 id=&quot;制限と考慮事項&quot;&gt;制限と考慮事項&lt;/h2&gt;
&lt;p&gt;CursorはAIモデルへのAPIアクセスが必要で、サブスクリプション以外の継続的なコストを意味します。特にGPT-4のようなプレミアムモデルでは、大量使用は大きなAPI料金につながる可能性があります。無料ティアとProに含まれるAPIクレジットは、集中的な開発には十分でないかもしれません。&lt;/p&gt;
&lt;p&gt;生成されるコードの品質は、プロンプトの明確さと使用されるAIモデルによって異なります。複雑なビジネスロジック、アーキテクチャの決定、微妙な要件には、依然として人間の判断が必要です。Cursorは見てきたパターンに基づいてコードを生成しますが、それが常にあなたの具体的なニーズに合うとは限りません。&lt;/p&gt;
&lt;p&gt;エディタはプロンプトに含めるとコードを外部AIプロバイダーに送信します。接続は暗号化されていますが、これは独自または機密性の高いコードベースには許容できないかもしれません。一部の組織では、コードを外部に送信するツールを禁止しています。&lt;/p&gt;
&lt;p&gt;非常に大きなコードベースではパフォーマンスが低下する可能性があります。インデックスシステムには制限があり、プロンプトに含めるコンテキストが多すぎると、応答が遅くなったりトークン制限エラーが発生したりする可能性があります。&lt;/p&gt;
&lt;h2 id=&quot;最も恩恵を受ける人&quot;&gt;最も恩恵を受ける人&lt;/h2&gt;
&lt;p&gt;標準的なWebアプリケーションで作業する開発者は、Cursorが一般的なパターンに精通していることから恩恵を受けます。CRUD操作、API、標準UIコンポーネントの構築は、AIがこれらのパターンをよく理解していると大幅に速くなります。&lt;/p&gt;
&lt;p&gt;新しいフレームワークや言語を学んでいる人は、パターンを理解しサンプルコードを生成するためにCursorを使用できます。AIは馴染みのない構文を説明し、慣用的な実装を提案できます。&lt;/p&gt;
&lt;p&gt;グリーンフィールドプロジェクトに取り組むチームは、素早くプロトタイプを作成して反復できます。Cursorはボイラープレートコードの生成、プロジェクト構造のセットアップ、手動コーディングなしで一般的な機能の実装を支援します。&lt;/p&gt;
&lt;p&gt;繰り返しタスクを扱う開発者は、Cursorがパターンを認識しファイル間で適用する能力に価値を見出します。リファクタリング、非推奨APIの更新、一貫性の維持がより面倒でなくなります。&lt;/p&gt;
&lt;h2 id=&quot;ワークフロー統合&quot;&gt;ワークフロー統合&lt;/h2&gt;
&lt;p&gt;Cursorはほとんどのワークフローでのほぼそのままの VS Code代替として機能します。既存のプロジェクトを開き、バージョン管理を使用し、ビルドツールを実行し、通常通りアプリケーションをデプロイできます。AI機能は標準的な開発プラクティスを補完し、置き換えるものではありません。&lt;/p&gt;
&lt;p&gt;コードレビュープロセスは引き続き重要です。Cursorは機能するコードを生成できますが、人間によるレビューがチームの標準を満たし、エッジケースを適切に処理し、アーキテクチャの決定と一致することを確認します。&lt;/p&gt;
&lt;p&gt;テストワークフローは変わりませんが、Cursorはテストの生成を支援できます。それでもテストスイートを実行し、カバレッジを確認し、品質基準を満たすことを確認する必要があります。&lt;/p&gt;
&lt;h2 id=&quot;コスト分析&quot;&gt;コスト分析&lt;/h2&gt;
&lt;p&gt;無料ティアは限られたAI対話を提供し、Cursorを試すか、たまに使用するのに適しています。ほとんどの開発者は月額$20のProサブスクリプションが必要で、一部のAPI使用が含まれていますが、大量使用には追加のAPIキーが必要かもしれません。&lt;/p&gt;
&lt;p&gt;APIコストはモデルと使用量によって異なります。GPT-4はGPT-3.5-turboより高く、Claudeモデルには異なる価格設定があります。アクティブな開発の典型的な1日は、モデルの選択と使用パターンに応じて$5-20のAPIコストを消費するかもしれません。&lt;/p&gt;
&lt;p&gt;これを節約される開発者の時間と比較してください。Cursorが週に数時間節約するなら、プロフェッショナルな開発にはコストが容易に正当化されます。学習や趣味のプロジェクトでは、コストをより慎重に検討する必要があります。&lt;/p&gt;
&lt;h2 id=&quot;効果的に機能させる&quot;&gt;効果的に機能させる&lt;/h2&gt;
&lt;p&gt;十分なコンテキストを持つ明確で具体的なプロンプトを書いてください。曖昧な指示は信頼性の低い結果を生みます。サンプルコードを含め、フレームワークとパターンを指定し、要件を明示してください。&lt;/p&gt;
&lt;p&gt;プロジェクト標準を確立するために&lt;code class=&quot;language-text&quot;&gt;.cursorrules&lt;/code&gt;ファイルを使用してください。これにより繰り返しが減り、AI生成コード全体の一貫性を維持するのに役立ちます。&lt;/p&gt;
&lt;p&gt;コミットする前に生成されたコードをレビューしてください。Cursorは機能するコードを生成しますが、明示的な指示がなければエッジケース、セキュリティの懸念、パフォーマンスの最適化を処理しないかもしれません。&lt;/p&gt;
&lt;p&gt;一度に大きなチャンクを生成するのではなく、段階的に構築してください。1つのコンポーネントを作成し、テストしてから進んでください。このアプローチはコード品質を維持し、デバッグを容易にします。&lt;/p&gt;
&lt;h2 id=&quot;結論&quot;&gt;結論&lt;/h2&gt;
&lt;p&gt;Cursorは、エディタに統合されたAI支援を望む開発者のための実用的なツールです。適切に使用すれば、一般的な開発タスクを加速し、ボイラープレートコーディングを減らします。&lt;/p&gt;
&lt;p&gt;このツールは、アーキテクチャ思考や設計決定の代替としてではなく、実装のアシスタントとして最も効果的に機能します。それでもシステムを理解し、機能を計画し、コード品質を確保する必要があります。&lt;/p&gt;
&lt;p&gt;VS Codeに慣れており、要件が明確な開発者にとって、Cursorは開発を意味のある形で加速できます。重要なのは、その機能と制限を理解し、価値を提供する場所に適用することです。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;技術情報&quot;&gt;技術情報&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;ベースエディタ&lt;/strong&gt;: VS Codeフォーク
&lt;strong&gt;AIモデル&lt;/strong&gt;: GPT-5、Claudeなど、API経由
&lt;strong&gt;プラットフォーム&lt;/strong&gt;: Windows、macOS、Linux
&lt;strong&gt;価格&lt;/strong&gt;: 無料ティアあり、Proは$20/月 + APIコスト
&lt;strong&gt;コンテキストウィンドウ&lt;/strong&gt;: モデルにより異なる（8k-128kトークン）
&lt;strong&gt;ウェブサイト&lt;/strong&gt;: cursor.com&lt;/p&gt;
&lt;p&gt;&lt;em&gt;注：この分析はAI統合開発環境としてのCursorの機能を反映しています。実際のパフォーマンスは、ユースケース、プロンプトの品質、モデル選択によって異なります。&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Cursor: AI-Powered Code Editor]]></title><description><![CDATA[Cursor is a fork of VS Code that integrates AI models directly into the editing experience for code generation, refactoring, and debugging.]]></description><link>https://vibecodingwithfred.com/blog/ultimate-vibe-coding-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/ultimate-vibe-coding-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 21 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Platform:&lt;/strong&gt; Cursor | &lt;strong&gt;Base:&lt;/strong&gt; VS Code fork | &lt;strong&gt;Pricing:&lt;/strong&gt; Free tier available, Pro at $20/month&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;what-cursor-is&quot;&gt;What Cursor Is&lt;/h2&gt;
&lt;p&gt;Cursor is a code editor built on VS Code that integrates AI capabilities directly into the editing experience. Instead of switching between your editor and ChatGPT, you interact with AI models within your development environment. The editor can read your codebase, understand context across files, and generate or modify code based on natural language instructions.&lt;/p&gt;
&lt;p&gt;The key difference from standard VS Code is the deep AI integration. Cursor provides multiple ways to interact with AI: inline code generation, chat interface, and contextual commands. It maintains awareness of your project structure and can reference multiple files when generating code.&lt;/p&gt;
&lt;h2 id=&quot;how-it-functions&quot;&gt;How It Functions&lt;/h2&gt;
&lt;p&gt;Cursor operates through several interaction modes. The chat panel lets you have conversations about your code while referencing specific files or selections. Inline generation (Cmd+K on Mac, Ctrl+K on Windows/Linux) allows you to describe changes directly in your editor, and Cursor modifies the code in place. The composer mode enables multi-file edits from a single prompt.&lt;/p&gt;
&lt;p&gt;The editor uses a context system to understand your project. You can explicitly include files in prompts using @ mentions, or let Cursor automatically determine relevant context. This context awareness helps generate code that fits your existing patterns and architecture.&lt;/p&gt;
&lt;p&gt;Cursor connects to various AI models including GPT-4, Claude, and others through API keys. You can switch between models depending on your needs and budget. The Pro subscription includes some API usage, though heavy users may need to provide their own API keys.&lt;/p&gt;
&lt;h2 id=&quot;core-features&quot;&gt;Core Features&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;.cursorrules&lt;/code&gt; file lets you define project-specific instructions that apply to all AI interactions. This includes coding standards, architectural patterns, security requirements, and other guidelines. These rules persist across sessions and help maintain consistency.&lt;/p&gt;
&lt;p&gt;Context management is a significant feature. Cursor can index your entire codebase and use semantic search to find relevant code for any query. This indexing happens locally and doesn&apos;t send your code to external servers unless you explicitly include it in a prompt.&lt;/p&gt;
&lt;p&gt;The editor includes standard VS Code features like debugging, Git integration, extensions, and terminal access. Your existing VS Code configuration, extensions, and keybindings work in Cursor with minimal adjustment.&lt;/p&gt;
&lt;h2 id=&quot;practical-capabilities&quot;&gt;Practical Capabilities&lt;/h2&gt;
&lt;p&gt;Cursor can generate new code from descriptions, creating entire components, functions, or files based on your specifications. It understands common frameworks and can produce idiomatic code for React, Python, Node.js, and other popular technologies.&lt;/p&gt;
&lt;p&gt;For existing code, Cursor can refactor functions, update APIs, fix bugs, and improve performance. You describe the change you want, and it modifies the code accordingly. The diff view lets you review changes before accepting them.&lt;/p&gt;
&lt;p&gt;The chat interface helps with debugging by analyzing error messages, suggesting fixes, and explaining complex code. You can paste error traces and get specific solutions based on your codebase context.&lt;/p&gt;
&lt;h2 id=&quot;limitations-and-considerations&quot;&gt;Limitations and Considerations&lt;/h2&gt;
&lt;p&gt;Cursor requires API access to AI models, which means ongoing costs beyond the subscription. Heavy usage can result in significant API charges, especially with premium models like GPT-4. The free tier and included API credits in Pro may not suffice for intensive development.&lt;/p&gt;
&lt;p&gt;Generated code quality varies based on prompt clarity and the AI model used. Complex business logic, architectural decisions, and nuanced requirements still need human judgment. Cursor generates code based on patterns it has seen, which may not always fit your specific needs.&lt;/p&gt;
&lt;p&gt;The editor sends code to external AI providers when you include it in prompts. While connections are encrypted, this may not be acceptable for proprietary or sensitive codebases. Some organizations prohibit tools that transmit code externally.&lt;/p&gt;
&lt;p&gt;Performance can degrade with very large codebases. The indexing system has limits, and including too much context in prompts can lead to slower responses or token limit errors.&lt;/p&gt;
&lt;h2 id=&quot;who-benefits-most&quot;&gt;Who Benefits Most&lt;/h2&gt;
&lt;p&gt;Developers working on standard web applications benefit from Cursor&apos;s familiarity with common patterns. Building CRUD operations, APIs, and standard UI components becomes significantly faster when the AI understands these patterns well.&lt;/p&gt;
&lt;p&gt;Those learning new frameworks or languages can use Cursor to understand patterns and generate example code. The AI can explain unfamiliar syntax and suggest idiomatic implementations.&lt;/p&gt;
&lt;p&gt;Teams working on greenfield projects can rapidly prototype and iterate. Cursor helps generate boilerplate code, set up project structure, and implement common features without manual coding.&lt;/p&gt;
&lt;p&gt;Developers dealing with repetitive tasks find value in Cursor&apos;s ability to recognize patterns and apply them across files. Refactoring, updating deprecated APIs, and maintaining consistency become less tedious.&lt;/p&gt;
&lt;h2 id=&quot;workflow-integration&quot;&gt;Workflow Integration&lt;/h2&gt;
&lt;p&gt;Cursor works as a drop-in replacement for VS Code in most workflows. You can open existing projects, use version control, run build tools, and deploy applications as usual. The AI features complement rather than replace standard development practices.&lt;/p&gt;
&lt;p&gt;Code review processes remain important. While Cursor can generate functional code, human review ensures it meets team standards, handles edge cases properly, and aligns with architectural decisions.&lt;/p&gt;
&lt;p&gt;Testing workflows don&apos;t change, but Cursor can help generate tests. You still need to run test suites, verify coverage, and ensure quality standards are met.&lt;/p&gt;
&lt;h2 id=&quot;cost-analysis&quot;&gt;Cost Analysis&lt;/h2&gt;
&lt;p&gt;The free tier provides limited AI interactions, suitable for trying Cursor or occasional use. Most developers will need the Pro subscription at $20/month, which includes some API usage but may require additional API keys for heavy use.&lt;/p&gt;
&lt;p&gt;API costs vary by model and usage. GPT-4 costs more than GPT-3.5-turbo, while Claude models have different pricing. A typical day of active development might consume $5-20 in API costs depending on model choice and usage patterns.&lt;/p&gt;
&lt;p&gt;Compare this to developer time saved. If Cursor saves several hours per week, the cost is easily justified for professional development. For learning or hobby projects, costs need more careful consideration.&lt;/p&gt;
&lt;h2 id=&quot;making-it-work-effectively&quot;&gt;Making It Work Effectively&lt;/h2&gt;
&lt;p&gt;Write clear, specific prompts with enough context. Vague instructions produce unreliable results. Include example code, specify frameworks and patterns, and be explicit about requirements.&lt;/p&gt;
&lt;p&gt;Use the &lt;code class=&quot;language-text&quot;&gt;.cursorrules&lt;/code&gt; file to establish project standards. This reduces repetition and helps maintain consistency across AI-generated code.&lt;/p&gt;
&lt;p&gt;Review generated code before committing. While Cursor produces functional code, it may not handle edge cases, security concerns, or performance optimization without explicit instruction.&lt;/p&gt;
&lt;p&gt;Build incrementally rather than generating large chunks at once. Create one component, test it, then proceed. This approach maintains code quality and makes debugging easier.&lt;/p&gt;
&lt;h2 id=&quot;bottom-line&quot;&gt;Bottom Line&lt;/h2&gt;
&lt;p&gt;Cursor is a practical tool for developers who want AI assistance integrated into their editor. It accelerates common development tasks and reduces boilerplate coding when used appropriately.&lt;/p&gt;
&lt;p&gt;The tool works best as an assistant for implementation rather than a replacement for architectural thinking and design decisions. You still need to understand your system, plan features, and ensure code quality.&lt;/p&gt;
&lt;p&gt;For developers comfortable with VS Code and clear about their requirements, Cursor can meaningfully accelerate development. The key is understanding its capabilities and limitations, then applying it where it provides value.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;technical-information&quot;&gt;Technical Information&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Base Editor&lt;/strong&gt;: VS Code fork&lt;br&gt;
&lt;strong&gt;AI Models&lt;/strong&gt;: GPT-5, Claude, and others via API&lt;br&gt;
&lt;strong&gt;Platforms&lt;/strong&gt;: Windows, macOS, Linux&lt;br&gt;
&lt;strong&gt;Pricing&lt;/strong&gt;: Free tier available, Pro at $20/month plus API costs&lt;br&gt;
&lt;strong&gt;Context Window&lt;/strong&gt;: Varies by model (8k-128k tokens)&lt;br&gt;
&lt;strong&gt;Website&lt;/strong&gt;: cursor.com&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: This analysis reflects Cursor&apos;s capabilities as an AI-integrated development environment. Actual performance depends on use case, prompt quality, and model selection.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Cursor: Editor de Codigo com IA]]></title><description><![CDATA[Cursor e um fork do VS Code que integra modelos de IA diretamente na experiencia de edicao para geracao de codigo, refatoracao e debugging.]]></description><link>https://vibecodingwithfred.com/pt/blog/ultimate-vibe-coding-guide/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pt/blog/ultimate-vibe-coding-guide/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Tue, 21 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Plataforma:&lt;/strong&gt; Cursor | &lt;strong&gt;Base:&lt;/strong&gt; Fork do VS Code | &lt;strong&gt;Precos:&lt;/strong&gt; Nivel gratuito disponivel, Pro a $20/mes&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;o-que-e-o-cursor&quot;&gt;O Que e o Cursor&lt;/h2&gt;
&lt;p&gt;Cursor e um editor de codigo construido sobre VS Code que integra capacidades de IA diretamente na experiencia de edicao. Em vez de alternar entre seu editor e ChatGPT, voce interage com modelos de IA dentro do seu ambiente de desenvolvimento. O editor pode ler seu codebase, entender contexto entre arquivos e gerar ou modificar codigo baseado em instrucoes em linguagem natural.&lt;/p&gt;
&lt;p&gt;A diferenca chave do VS Code padrao e a integracao profunda de IA. Cursor fornece multiplas formas de interagir com IA: geracao de codigo inline, interface de chat e comandos contextuais. Mantem consciencia da estrutura do seu projeto e pode referenciar multiplos arquivos ao gerar codigo.&lt;/p&gt;
&lt;h2 id=&quot;como-funciona&quot;&gt;Como Funciona&lt;/h2&gt;
&lt;p&gt;Cursor opera atraves de varios modos de interacao. O painel de chat permite que voce tenha conversas sobre seu codigo enquanto referencia arquivos ou selecoes especificas. Geracao inline (Cmd+K no Mac, Ctrl+K no Windows/Linux) permite descrever mudancas diretamente no seu editor, e Cursor modifica o codigo no local. O modo composer permite edicoes em multiplos arquivos a partir de um unico prompt.&lt;/p&gt;
&lt;p&gt;O editor usa um sistema de contexto para entender seu projeto. Voce pode incluir explicitamente arquivos em prompts usando mencoes @, ou deixar o Cursor determinar automaticamente o contexto relevante. Essa consciencia de contexto ajuda a gerar codigo que se encaixa nos seus padroes e arquitetura existentes.&lt;/p&gt;
&lt;p&gt;Cursor se conecta a varios modelos de IA incluindo GPT-4, Claude e outros atraves de chaves de API. Voce pode alternar entre modelos dependendo das suas necessidades e orcamento. A assinatura Pro inclui algum uso de API, embora usuarios intensivos possam precisar fornecer suas proprias chaves de API.&lt;/p&gt;
&lt;h2 id=&quot;recursos-principais&quot;&gt;Recursos Principais&lt;/h2&gt;
&lt;p&gt;O arquivo &lt;code class=&quot;language-text&quot;&gt;.cursorrules&lt;/code&gt; permite definir instrucoes especificas do projeto que se aplicam a todas as interacoes de IA. Isso inclui padroes de codificacao, padroes arquiteturais, requisitos de seguranca e outras diretrizes. Essas regras persistem entre sessoes e ajudam a manter consistencia.&lt;/p&gt;
&lt;p&gt;Gerenciamento de contexto e um recurso significativo. Cursor pode indexar todo seu codebase e usar busca semantica para encontrar codigo relevante para qualquer consulta. Essa indexacao acontece localmente e nao envia seu codigo para servidores externos a menos que voce o inclua explicitamente em um prompt.&lt;/p&gt;
&lt;p&gt;O editor inclui recursos padrao do VS Code como debugging, integracao Git, extensoes e acesso ao terminal. Sua configuracao existente do VS Code, extensoes e atalhos de teclado funcionam no Cursor com ajuste minimo.&lt;/p&gt;
&lt;h2 id=&quot;capacidades-praticas&quot;&gt;Capacidades Praticas&lt;/h2&gt;
&lt;p&gt;Cursor pode gerar novo codigo a partir de descricoes, criando componentes inteiros, funcoes ou arquivos baseados nas suas especificacoes. Ele entende frameworks comuns e pode produzir codigo idiomatico para React, Python, Node.js e outras tecnologias populares.&lt;/p&gt;
&lt;p&gt;Para codigo existente, Cursor pode refatorar funcoes, atualizar APIs, corrigir bugs e melhorar performance. Voce descreve a mudanca que quer, e ele modifica o codigo de acordo. A visualizacao de diff permite revisar mudancas antes de aceita-las.&lt;/p&gt;
&lt;p&gt;A interface de chat ajuda com debugging analisando mensagens de erro, sugerindo correcoes e explicando codigo complexo. Voce pode colar stack traces de erro e obter solucoes especificas baseadas no contexto do seu codebase.&lt;/p&gt;
&lt;h2 id=&quot;limitacoes-e-consideracoes&quot;&gt;Limitacoes e Consideracoes&lt;/h2&gt;
&lt;p&gt;Cursor requer acesso a API de modelos de IA, o que significa custos continuos alem da assinatura. Uso intensivo pode resultar em cobracas de API significativas, especialmente com modelos premium como GPT-4. O nivel gratuito e creditos de API incluidos no Pro podem nao ser suficientes para desenvolvimento intensivo.&lt;/p&gt;
&lt;p&gt;Qualidade do codigo gerado varia baseado na clareza do prompt e no modelo de IA usado. Logica de negocios complexa, decisoes arquiteturais e requisitos nuanceados ainda precisam de julgamento humano. Cursor gera codigo baseado em padroes que viu, o que pode nem sempre se encaixar nas suas necessidades especificas.&lt;/p&gt;
&lt;p&gt;O editor envia codigo para provedores de IA externos quando voce o inclui em prompts. Embora conexoes sejam criptografadas, isso pode nao ser aceitavel para codebases proprietarios ou sensiveis. Algumas organizacoes proibem ferramentas que transmitem codigo externamente.&lt;/p&gt;
&lt;p&gt;Performance pode degradar com codebases muito grandes. O sistema de indexacao tem limites, e incluir muito contexto em prompts pode levar a respostas mais lentas ou erros de limite de tokens.&lt;/p&gt;
&lt;h2 id=&quot;quem-se-beneficia-mais&quot;&gt;Quem Se Beneficia Mais&lt;/h2&gt;
&lt;p&gt;Desenvolvedores trabalhando em aplicacoes web padrao se beneficiam da familiaridade do Cursor com padroes comuns. Construir operacoes CRUD, APIs e componentes de UI padrao se torna significativamente mais rapido quando a IA entende bem esses padroes.&lt;/p&gt;
&lt;p&gt;Aqueles aprendendo novos frameworks ou linguagens podem usar Cursor para entender padroes e gerar codigo de exemplo. A IA pode explicar sintaxe desconhecida e sugerir implementacoes idiomaticas.&lt;/p&gt;
&lt;p&gt;Equipes trabalhando em projetos greenfield podem rapidamente prototipar e iterar. Cursor ajuda a gerar codigo boilerplate, configurar estrutura de projeto e implementar recursos comuns sem codificacao manual.&lt;/p&gt;
&lt;p&gt;Desenvolvedores lidando com tarefas repetitivas encontram valor na capacidade do Cursor de reconhecer padroes e aplica-los entre arquivos. Refatoracao, atualizacao de APIs deprecadas e manutencao de consistencia se tornam menos tediosas.&lt;/p&gt;
&lt;h2 id=&quot;integracao-de-fluxo-de-trabalho&quot;&gt;Integracao de Fluxo de Trabalho&lt;/h2&gt;
&lt;p&gt;Cursor funciona como substituto direto do VS Code na maioria dos fluxos de trabalho. Voce pode abrir projetos existentes, usar controle de versao, rodar ferramentas de build e fazer deploy de aplicacoes como de costume. Os recursos de IA complementam em vez de substituir praticas de desenvolvimento padrao.&lt;/p&gt;
&lt;p&gt;Processos de code review permanecem importantes. Enquanto Cursor pode gerar codigo funcional, revisao humana garante que ele atende padroes da equipe, lida adequadamente com casos extremos e se alinha com decisoes arquiteturais.&lt;/p&gt;
&lt;p&gt;Fluxos de trabalho de teste nao mudam, mas Cursor pode ajudar a gerar testes. Voce ainda precisa rodar suites de teste, verificar cobertura e garantir que padroes de qualidade sejam atendidos.&lt;/p&gt;
&lt;h2 id=&quot;analise-de-custo&quot;&gt;Analise de Custo&lt;/h2&gt;
&lt;p&gt;O nivel gratuito fornece interacoes de IA limitadas, adequado para experimentar Cursor ou uso ocasional. A maioria dos desenvolvedores precisara da assinatura Pro a $20/mes, que inclui algum uso de API mas pode requerer chaves de API adicionais para uso intensivo.&lt;/p&gt;
&lt;p&gt;Custos de API variam por modelo e uso. GPT-4 custa mais que GPT-3.5-turbo, enquanto modelos Claude tem precos diferentes. Um dia tipico de desenvolvimento ativo pode consumir $5-20 em custos de API dependendo da escolha do modelo e padroes de uso.&lt;/p&gt;
&lt;p&gt;Compare isso com tempo de desenvolvedor economizado. Se Cursor economiza varias horas por semana, o custo e facilmente justificado para desenvolvimento profissional. Para aprendizado ou projetos hobby, custos precisam de consideracao mais cuidadosa.&lt;/p&gt;
&lt;h2 id=&quot;tornando-o-eficaz&quot;&gt;Tornando-o Eficaz&lt;/h2&gt;
&lt;p&gt;Escreva prompts claros e especificos com contexto suficiente. Instrucoes vagas produzem resultados nao confiaveis. Inclua codigo de exemplo, especifique frameworks e padroes, e seja explicito sobre requisitos.&lt;/p&gt;
&lt;p&gt;Use o arquivo &lt;code class=&quot;language-text&quot;&gt;.cursorrules&lt;/code&gt; para estabelecer padroes do projeto. Isso reduz repeticao e ajuda a manter consistencia entre codigo gerado por IA.&lt;/p&gt;
&lt;p&gt;Revise codigo gerado antes de commitar. Enquanto Cursor produz codigo funcional, pode nao lidar com casos extremos, preocupacoes de seguranca ou otimizacao de performance sem instrucao explicita.&lt;/p&gt;
&lt;p&gt;Construa incrementalmente em vez de gerar grandes pedacos de uma vez. Crie um componente, teste-o, depois prossiga. Essa abordagem mantem qualidade de codigo e torna debugging mais facil.&lt;/p&gt;
&lt;h2 id=&quot;conclusao&quot;&gt;Conclusao&lt;/h2&gt;
&lt;p&gt;Cursor e uma ferramenta pratica para desenvolvedores que querem assistencia de IA integrada ao seu editor. Ele acelera tarefas de desenvolvimento comuns e reduz codificacao boilerplate quando usado apropriadamente.&lt;/p&gt;
&lt;p&gt;A ferramenta funciona melhor como assistente para implementacao em vez de substituto para pensamento arquitetural e decisoes de design. Voce ainda precisa entender seu sistema, planejar recursos e garantir qualidade de codigo.&lt;/p&gt;
&lt;p&gt;Para desenvolvedores confortaveis com VS Code e claros sobre seus requisitos, Cursor pode acelerar significativamente o desenvolvimento. A chave e entender suas capacidades e limitacoes, depois aplica-lo onde fornece valor.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;informacoes-tecnicas&quot;&gt;Informacoes Tecnicas&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Editor Base&lt;/strong&gt;: Fork do VS Code
&lt;strong&gt;Modelos de IA&lt;/strong&gt;: GPT-5, Claude e outros via API
&lt;strong&gt;Plataformas&lt;/strong&gt;: Windows, macOS, Linux
&lt;strong&gt;Precos&lt;/strong&gt;: Nivel gratuito disponivel, Pro a $20/mes mais custos de API
&lt;strong&gt;Janela de Contexto&lt;/strong&gt;: Varia por modelo (8k-128k tokens)
&lt;strong&gt;Website&lt;/strong&gt;: cursor.com&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Nota: Esta analise reflete as capacidades do Cursor como ambiente de desenvolvimento integrado com IA. Performance real depende do caso de uso, qualidade do prompt e selecao do modelo.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Dockerize Your Flask Blog: Complete Guide + Fly.io Deployment]]></title><description><![CDATA[Learn to containerize a Flask blog application with Docker and deploy it to Fly.io. Covers Dockerfile creation, Docker Compose for local development, PostgreSQL integration, and production deployment. Works with any Flask app.]]></description><link>https://vibecodingwithfred.com/blog/dockerize-flask-blog/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/dockerize-flask-blog/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Mon, 20 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Last verified:&lt;/strong&gt; October 2025 | &lt;strong&gt;Docker:&lt;/strong&gt; 24.x | &lt;strong&gt;Flask:&lt;/strong&gt; 3.0.0 | &lt;strong&gt;PostgreSQL:&lt;/strong&gt; 15 | &lt;strong&gt;Python:&lt;/strong&gt; 3.11&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Deployment is frustrating. You get your Flask app working perfectly on your machine, then spend hours fighting with server configuration, Python versions, and missing dependencies when you try to deploy it. Docker fixes this by packaging everything your app needs into a container that runs the same way everywhere.&lt;/p&gt;
&lt;p&gt;This guide shows you how to containerize a Flask blog and deploy it to Fly.io. The whole process takes about 15 minutes once you know what you&apos;re doing. No server configuration, no dependency hell, just your app running in production.&lt;/p&gt;
&lt;h2 id=&quot;who-this-guide-is-for&quot;&gt;Who This Guide Is For&lt;/h2&gt;
&lt;p&gt;If you have a Flask app that works locally and you want to deploy it without the usual headaches, this is for you. Maybe you&apos;re tired of debugging why something works on your laptop but breaks in production. Maybe you want to use modern deployment practices without spending weeks learning DevOps.&lt;/p&gt;
&lt;p&gt;You&apos;ll need basic Python and Flask knowledge. If you&apos;ve built a Flask app before, you&apos;re ready. You should be comfortable with the command line, and you&apos;ll need Docker Desktop installed. That&apos;s it.&lt;/p&gt;
&lt;p&gt;By the end, you&apos;ll have local development that matches production exactly, deployments that take minutes instead of hours, and no more Python version conflicts.&lt;/p&gt;
&lt;h2 id=&quot;why-docker-helps&quot;&gt;Why Docker Helps&lt;/h2&gt;
&lt;p&gt;Docker gets a bad rap for being complex, but the core idea is simple: it&apos;s a box for your code. Your app goes in the box with everything it needs to run. That box runs the same way on your laptop, on CI servers, and in production.&lt;/p&gt;
&lt;p&gt;This consistency eliminates entire categories of bugs. No more &quot;but it works on my machine&quot; discussions. No more discovering that production has Python 3.8 when you developed on 3.11. No more missing system libraries that you forgot to document.&lt;/p&gt;
&lt;p&gt;The real win is deployment speed. Once you have a working Docker setup, deploying becomes trivial. Push your code, build the image, deploy. Rollbacks are just as easy: redeploy the previous image and you&apos;re back in business in seconds.&lt;/p&gt;
&lt;h2 id=&quot;what-were-building&quot;&gt;What We&apos;re Building&lt;/h2&gt;
&lt;p&gt;We&apos;re going to take your existing Flask blog and containerize it properly. You&apos;ll get local development with hot reloading so you can see changes instantly. We&apos;ll use PostgreSQL because SQLite isn&apos;t meant for production, no matter what anyone tells you. Then we&apos;ll deploy the whole thing to Fly.io because they have a generous free tier and run your Docker containers as-is.&lt;/p&gt;
&lt;h2 id=&quot;prepping-your-flask-app&quot;&gt;Prepping Your Flask App&lt;/h2&gt;
&lt;p&gt;First, let&apos;s fix your requirements.txt. If yours just says &quot;Flask&quot; with no version number, you&apos;re asking for trouble. Here&apos;s what you need for production:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;txt&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-txt line-numbers&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;Flask==3.0.0
Flask-SQLAlchemy==3.1.1
Flask-Migrate==4.0.5
psycopg2-binary==2.9.9
python-dotenv==1.0.0
gunicorn==21.2.0&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Flask&apos;s built-in server is for development only. Gunicorn is a production-ready WSGI server that can handle real traffic. The psycopg2-binary package lets you talk to PostgreSQL. Everything has version numbers because &quot;Flask&quot; without a version means you might get different versions in different environments, which defeats the whole point.&lt;/p&gt;
&lt;p&gt;Create a wsgi.py file as your application entry point:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; app &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; create_app
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os

app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; create_app&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; __name__ &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;run&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        port&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;PORT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That host=&quot;0.0.0.0&quot; is important. It means &quot;listen on all network interfaces.&quot; The default 127.0.0.1 only listens locally, which doesn&apos;t work inside a container. This tiny detail has caused hours of debugging for many developers.&lt;/p&gt;
&lt;p&gt;Your config.py should use environment variables for anything sensitive:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; dotenv &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; load_dotenv

basedir &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;abspath&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dirname&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__file__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
load_dotenv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;basedir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.env&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    SECRET_KEY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;SECRET_KEY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dev-secret-key-change-in-production&apos;&lt;/span&gt;
    
    SQLALCHEMY_DATABASE_URI &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;DATABASE_URL&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; \
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;sqlite:///&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;basedir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;app.db&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;
    
    SQLALCHEMY_TRACK_MODIFICATIONS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;# Some services use postgres:// but SQLAlchemy needs postgresql://&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; SQLALCHEMY_DATABASE_URI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;startswith&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;postgres://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        SQLALCHEMY_DATABASE_URI &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; SQLALCHEMY_DATABASE_URI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;replace&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;postgres://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;postgresql://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Never hardcode secrets. Use environment variables. Your future self will thank you when you don&apos;t accidentally commit your production database password to GitHub.&lt;/p&gt;
&lt;h2 id=&quot;writing-a-dockerfile-that-works&quot;&gt;Writing a Dockerfile That Works&lt;/h2&gt;
&lt;p&gt;Here&apos;s a Dockerfile that works in production:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;dockerfile&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-dockerfile line-numbers&quot;&gt;&lt;code class=&quot;language-dockerfile&quot;&gt;&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; python:3.11-slim &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; base&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Python buffering can cause issues in containers&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ENV&lt;/span&gt; PYTHONUNBUFFERED=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PYTHONDONTWRITEBYTECODE=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PIP_NO_CACHE_DIR=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PIP_DISABLE_PIP_VERSION_CHECK=1&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;WORKDIR&lt;/span&gt; /app&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Install system dependencies&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; apt-get update &amp;amp;&amp;amp; apt-get install -y &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    gcc &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    postgresql-client &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Copy requirements first for better caching&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; requirements.txt .&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; pip install --no-cache-dir -r requirements.txt&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; . .&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Create non-root user for security&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; useradd -m -u 1000 flaskuser &amp;amp;&amp;amp; &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    chown -R flaskuser:flaskuser /app&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;USER&lt;/span&gt; flaskuser&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;EXPOSE&lt;/span&gt; 8080&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;CMD&lt;/span&gt; [&lt;span class=&quot;token string&quot;&gt;&quot;gunicorn&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;--bind&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0:8080&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;--workers&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;2&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;wsgi:app&quot;&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The order matters here. Copying requirements.txt before copying your code means Docker can cache the pip install layer. When you change your code but not your dependencies, Docker reuses the cached layer with all your packages already installed. This turns a 5-minute rebuild into a 10-second one.&lt;/p&gt;
&lt;p&gt;Running as a non-root user is a security best practice. If someone compromises your app, they won&apos;t have root access to the container.&lt;/p&gt;
&lt;h2 id=&quot;docker-compose-for-local-development&quot;&gt;Docker Compose for Local Development&lt;/h2&gt;
&lt;p&gt;Docker Compose lets you run multiple containers together. Here&apos;s a docker-compose.yml that sets up your Flask app with PostgreSQL:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;3.8&apos;&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;web&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; .
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;8080:8080&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; DATABASE_URL=postgresql&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//postgres&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;postgres@db&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;5432/flask_blog
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; SECRET_KEY=dev&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;secret&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;key
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; FLASK_ENV=development
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; .&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/app  &lt;span class=&quot;token comment&quot;&gt;# Mount your code for hot reloading&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; db
    &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; flask run &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;host=0.0.0.0 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;port=8080 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;reload

  &lt;span class=&quot;token key atrule&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; postgres&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;15&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;alpine
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_USER=postgres
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_PASSWORD=postgres
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_DB=flask_blog
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;5432:5432&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; postgres_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/var/lib/postgresql/data

&lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  postgres_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The volume mount (&lt;code class=&quot;language-text&quot;&gt;.:/app&lt;/code&gt;) means changes to your code are reflected immediately without rebuilding the container. The postgres_data volume ensures your database persists even when you stop the containers.&lt;/p&gt;
&lt;p&gt;That depends_on just controls startup order. It doesn&apos;t wait for PostgreSQL to be ready, so your Flask app might crash on first startup. Just restart it; this is normal and only happens once.&lt;/p&gt;
&lt;h2 id=&quot;running-everything&quot;&gt;Running Everything&lt;/h2&gt;
&lt;p&gt;Build your image first:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; build&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first build takes a while as it downloads base images and installs packages. Subsequent builds are much faster thanks to Docker&apos;s layer caching.&lt;/p&gt;
&lt;p&gt;Start the database:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; up &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; db&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Initialize your database migrations if you haven&apos;t already:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db init
&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db migrate &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial migration&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db upgrade&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now start everything:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; up&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Visit localhost:8080 and your blog should be running. If something&apos;s wrong, the logs will tell you exactly what. Docker shows you everything, which is way better than mysterious production failures with no error messages.&lt;/p&gt;
&lt;p&gt;To see just your app logs without PostgreSQL noise, use &lt;code class=&quot;language-text&quot;&gt;docker-compose logs -f web&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;deploying-to-flyio&quot;&gt;Deploying to Fly.io&lt;/h2&gt;
&lt;p&gt;Fly.io runs your actual Docker container, not some interpreted version of it. They have a free tier that doesn&apos;t require a credit card, which is refreshing in 2025. For a deeper dive into &lt;strong&gt;&lt;a href=&quot;/blog/flyio-free-tier-guide/&quot;&gt;Fly.io&apos;s free tier capabilities and limitations&lt;/a&gt;&lt;/strong&gt;, including performance comparisons and scaling strategies, check out our complete guide.&lt;/p&gt;
&lt;p&gt;Install their CLI first.&lt;/p&gt;
&lt;p&gt;On Mac:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flyctl&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;On Windows, download the installer from their website or use PowerShell:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;powershell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-powershell line-numbers&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;pwsh &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;Command &lt;span class=&quot;token string&quot;&gt;&quot;iwr https://fly.io/install.ps1 -useb | iex&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;On Linux:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You might need to add flyctl to your PATH. The installer will tell you if this is needed and show you the exact command to run.&lt;/p&gt;
&lt;p&gt;Launch your app with &lt;code class=&quot;language-text&quot;&gt;flyctl launch&lt;/code&gt;. When it asks, give your app a name (or let it generate one), pick a region close to you or your users, say yes to PostgreSQL (pick development for free tier), and say no to deploying immediately because we need to set secrets first.&lt;/p&gt;
&lt;p&gt;This creates a fly.toml file that configures your deployment:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token key property&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;your-app-name&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;primary_region&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iad&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;8080&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;http_service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;internal_port&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;force_https&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;auto_stop_machines&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;auto_start_machines&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;min_machines_running&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;cpu_kind&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;shared&quot;&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;cpus&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;memory_mb&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The auto_stop_machines setting stops your app when nobody&apos;s using it, which helps you stay within free tier limits. It starts again automatically when someone visits.&lt;/p&gt;
&lt;p&gt;Set your secret key:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl secrets &lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;SECRET_KEY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;openssl rand &lt;span class=&quot;token parameter variable&quot;&gt;-hex&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Deploy your app:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This builds your Docker image and deploys it. Takes about 2 minutes. When it&apos;s done, run your database migrations:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl &lt;span class=&quot;token function&quot;&gt;ssh&lt;/span&gt; console &lt;span class=&quot;token parameter variable&quot;&gt;-C&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;flask db upgrade&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Open your deployed app with &lt;code class=&quot;language-text&quot;&gt;flyctl open&lt;/code&gt;. You now have a production Flask app with HTTPS, automatic restarts, and database backups. No server configuration needed.&lt;/p&gt;
&lt;h2 id=&quot;common-issues-and-solutions&quot;&gt;Common Issues and Solutions&lt;/h2&gt;
&lt;p&gt;When you see &quot;Port already in use&quot;, you probably have another container running. Run &lt;code class=&quot;language-text&quot;&gt;docker-compose down&lt;/code&gt; to stop everything, or just change the port. Sometimes Docker Desktop gets confused and a restart fixes it.&lt;/p&gt;
&lt;p&gt;Database connection errors on startup usually mean Flask is trying to connect before PostgreSQL is ready. Just restart the Flask container. You could add retry logic to your database connection code, but for local development, a simple restart works fine.&lt;/p&gt;
&lt;p&gt;If Docker Desktop says it can&apos;t connect to the Docker daemon, restart Docker Desktop. If that doesn&apos;t work, restart your computer. Docker Desktop has quirks.&lt;/p&gt;
&lt;p&gt;The Fly.io free tier gives you 256MB of RAM. If your app needs more, run &lt;code class=&quot;language-text&quot;&gt;flyctl scale memory 512&lt;/code&gt;. Or optimize your app; you probably don&apos;t need to load everything into memory at once.&lt;/p&gt;
&lt;p&gt;When changes aren&apos;t showing up locally, check that volume mount in docker-compose.yml. In production, you need to rebuild and deploy with &lt;code class=&quot;language-text&quot;&gt;flyctl deploy&lt;/code&gt;. Docker doesn&apos;t automatically detect code changes in production.&lt;/p&gt;
&lt;h2 id=&quot;tips-that-save-time&quot;&gt;Tips That Save Time&lt;/h2&gt;
&lt;p&gt;Docker images can get huge. Use slim base images and add a .dockerignore file:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;__pycache__
*.pyc
.git
.env
venv/
node_modules/
*.db
.DS_Store&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Add proper logging to your app. When something breaks in production, logs are your only window into what happened:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; logging
logging&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;basicConfig&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;level&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;logging&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;INFO&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;info&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;App starting up&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The Docker setup you just created is the same one many companies use in production. This isn&apos;t a toy setup; it&apos;s professional-grade deployment that happens to be free.&lt;/p&gt;
&lt;h2 id=&quot;you-made-it&quot;&gt;You Made It&lt;/h2&gt;
&lt;p&gt;You&apos;ve successfully containerized a Flask application with a production database, local hot reloading, and one-command deployment. Your development environment now matches production exactly, eliminating an entire class of deployment bugs.&lt;/p&gt;
&lt;p&gt;This is the same workflow professional teams use. The same Docker, the same deployment process, the same everything. The gap between hobby projects and production applications is smaller than most people think. It&apos;s mostly just knowing the right tools.&lt;/p&gt;
&lt;h2 id=&quot;build-your-flask-application-first&quot;&gt;Build Your Flask Application First&lt;/h2&gt;
&lt;p&gt;Don&apos;t have a Flask blog to dockerize yet? Start here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Build a Blog with Flask&lt;/a&gt;&lt;/strong&gt; - Create a complete Flask blog from scratch with PostgreSQL and authentication&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Build a Portfolio with Flask&lt;/a&gt;&lt;/strong&gt; - Learn Flask fundamentals with a professional portfolio site&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Build E-Commerce with Flask&lt;/a&gt;&lt;/strong&gt; - Master Flask with a full shopping cart and payment integration&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each tutorial includes step-by-step AI prompts to guide you through building production-ready Flask applications. Once you&apos;ve built your app, come back to this guide to dockerize and deploy it.&lt;/p&gt;
&lt;p&gt;Now go build something cool.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Dockerisieren Sie Ihren Flask-Blog: Kompletter Guide + Fly.io Deployment]]></title><description><![CDATA[Lernen Sie, eine Flask-Blog-Anwendung mit Docker zu containerisieren und auf Fly.io zu deployen. Behandelt Dockerfile-Erstellung, Docker Compose fuer lokale Entwicklung, PostgreSQL-Integration und Produktions-Deployment. Funktioniert mit jeder Flask-App.]]></description><link>https://vibecodingwithfred.com/de/blog/dockerize-flask-blog/</link><guid isPermaLink="false">https://vibecodingwithfred.com/de/blog/dockerize-flask-blog/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Mon, 20 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Zuletzt verifiziert:&lt;/strong&gt; Oktober 2025 | &lt;strong&gt;Docker:&lt;/strong&gt; 24.x | &lt;strong&gt;Flask:&lt;/strong&gt; 3.0.0 | &lt;strong&gt;PostgreSQL:&lt;/strong&gt; 15 | &lt;strong&gt;Python:&lt;/strong&gt; 3.11&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Deployment ist frustrierend. Sie bekommen Ihre Flask-App auf Ihrem Rechner perfekt zum Laufen, dann verbringen Sie Stunden damit, mit Server-Konfiguration, Python-Versionen und fehlenden Abhaengigkeiten zu kaempfen, wenn Sie versuchen, sie zu deployen. Docker behebt das, indem es alles, was Ihre App braucht, in einen Container packt, der ueberall gleich laeuft.&lt;/p&gt;
&lt;p&gt;Dieser Guide zeigt Ihnen, wie Sie einen Flask-Blog containerisieren und auf Fly.io deployen. Der gesamte Prozess dauert etwa 15 Minuten, sobald Sie wissen, was Sie tun. Keine Server-Konfiguration, keine Abhaengigkeits-Hoelle, nur Ihre App, die in Produktion laeuft.&lt;/p&gt;
&lt;h2 id=&quot;fuer-wen-dieser-guide-ist&quot;&gt;Fuer wen dieser Guide ist&lt;/h2&gt;
&lt;p&gt;Wenn Sie eine Flask-App haben, die lokal funktioniert, und Sie sie ohne die ueblichen Kopfschmerzen deployen moechten, ist dies fuer Sie. Vielleicht sind Sie es leid zu debuggen, warum etwas auf Ihrem Laptop funktioniert, aber in Produktion kaputtgeht. Vielleicht moechten Sie moderne Deployment-Praktiken nutzen, ohne Wochen damit zu verbringen, DevOps zu lernen.&lt;/p&gt;
&lt;p&gt;Sie benoetigen grundlegende Python- und Flask-Kenntnisse. Wenn Sie schon einmal eine Flask-App gebaut haben, sind Sie bereit. Sie sollten mit der Kommandozeile vertraut sein, und Sie benoetigen Docker Desktop installiert. Das ist alles.&lt;/p&gt;
&lt;p&gt;Am Ende haben Sie lokale Entwicklung, die der Produktion genau entspricht, Deployments, die Minuten statt Stunden dauern, und keine Python-Versionskonflikte mehr.&lt;/p&gt;
&lt;h2 id=&quot;warum-docker-hilft&quot;&gt;Warum Docker hilft&lt;/h2&gt;
&lt;p&gt;Docker hat einen schlechten Ruf dafuer, komplex zu sein, aber die Kernidee ist einfach: Es ist eine Box fuer Ihren Code. Ihre App geht in die Box mit allem, was sie zum Laufen braucht. Diese Box laeuft gleich auf Ihrem Laptop, auf CI-Servern und in Produktion.&lt;/p&gt;
&lt;p&gt;Diese Konsistenz eliminiert ganze Kategorien von Bugs. Keine &quot;aber es funktioniert auf meinem Rechner&quot;-Diskussionen mehr. Kein Entdecken mehr, dass Produktion Python 3.8 hat, waehrend Sie auf 3.11 entwickelt haben. Keine fehlenden System-Bibliotheken mehr, die Sie vergessen haben zu dokumentieren.&lt;/p&gt;
&lt;p&gt;Der echte Gewinn ist die Deployment-Geschwindigkeit. Sobald Sie ein funktionierendes Docker-Setup haben, wird Deployen trivial. Code pushen, Image bauen, deployen. Rollbacks sind genauso einfach: das vorherige Image erneut deployen und Sie sind in Sekunden wieder im Geschaeft.&lt;/p&gt;
&lt;h2 id=&quot;was-wir-bauen&quot;&gt;Was wir bauen&lt;/h2&gt;
&lt;p&gt;Wir werden Ihren bestehenden Flask-Blog nehmen und ihn richtig containerisieren. Sie bekommen lokale Entwicklung mit Hot Reloading, damit Sie Aenderungen sofort sehen koennen. Wir verwenden PostgreSQL, weil SQLite nicht fuer Produktion gedacht ist, egal was jemand Ihnen sagt. Dann deployen wir das Ganze auf Fly.io, weil sie einen grosszuegigen Free Tier haben und Ihre Docker-Container unveraendert ausfuehren.&lt;/p&gt;
&lt;h2 id=&quot;ihre-flask-app-vorbereiten&quot;&gt;Ihre Flask-App vorbereiten&lt;/h2&gt;
&lt;p&gt;Zuerst korrigieren wir Ihre requirements.txt. Wenn Ihre nur &quot;Flask&quot; ohne Versionsnummer sagt, bitten Sie um Aerger. Hier ist, was Sie fuer Produktion brauchen:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;txt&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-txt line-numbers&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;Flask==3.0.0
Flask-SQLAlchemy==3.1.1
Flask-Migrate==4.0.5
psycopg2-binary==2.9.9
python-dotenv==1.0.0
gunicorn==21.2.0&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Flasks eingebauter Server ist nur fuer Entwicklung. Gunicorn ist ein produktionsreifer WSGI-Server, der echten Traffic handhaben kann. Das psycopg2-binary-Paket laesst Sie mit PostgreSQL kommunizieren. Alles hat Versionsnummern, weil &quot;Flask&quot; ohne Version bedeutet, dass Sie moeglicherweise verschiedene Versionen in verschiedenen Umgebungen bekommen, was den ganzen Sinn verfehlt.&lt;/p&gt;
&lt;p&gt;Erstellen Sie eine wsgi.py-Datei als Anwendungs-Einstiegspunkt:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; app &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; create_app
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os

app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; create_app&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; __name__ &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;run&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        port&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;PORT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Das host=&quot;0.0.0.0&quot; ist wichtig. Es bedeutet &quot;auf allen Netzwerkschnittstellen lauschen.&quot; Das Standard-127.0.0.1 lauscht nur lokal, was innerhalb eines Containers nicht funktioniert. Dieses winzige Detail hat vielen Entwicklern Stunden des Debuggens beschert.&lt;/p&gt;
&lt;p&gt;Ihre config.py sollte Umgebungsvariablen fuer alles Sensible verwenden:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; dotenv &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; load_dotenv

basedir &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;abspath&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dirname&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__file__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
load_dotenv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;basedir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.env&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    SECRET_KEY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;SECRET_KEY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dev-secret-key-change-in-production&apos;&lt;/span&gt;

    SQLALCHEMY_DATABASE_URI &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;DATABASE_URL&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; \
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;sqlite:///&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;basedir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;app.db&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;

    SQLALCHEMY_TRACK_MODIFICATIONS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Manche Services nutzen postgres:// aber SQLAlchemy braucht postgresql://&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; SQLALCHEMY_DATABASE_URI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;startswith&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;postgres://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        SQLALCHEMY_DATABASE_URI &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; SQLALCHEMY_DATABASE_URI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;replace&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;postgres://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;postgresql://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Hardcoden Sie niemals Secrets. Verwenden Sie Umgebungsvariablen. Ihr zukuenftiges Ich wird Ihnen danken, wenn Sie nicht versehentlich Ihr Produktions-Datenbankpasswort auf GitHub committen.&lt;/p&gt;
&lt;h2 id=&quot;ein-dockerfile-schreiben-das-funktioniert&quot;&gt;Ein Dockerfile schreiben, das funktioniert&lt;/h2&gt;
&lt;p&gt;Hier ist ein Dockerfile, das in Produktion funktioniert:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;dockerfile&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-dockerfile line-numbers&quot;&gt;&lt;code class=&quot;language-dockerfile&quot;&gt;&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; python:3.11-slim &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; base&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Python-Pufferung kann Probleme in Containern verursachen&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ENV&lt;/span&gt; PYTHONUNBUFFERED=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PYTHONDONTWRITEBYTECODE=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PIP_NO_CACHE_DIR=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PIP_DISABLE_PIP_VERSION_CHECK=1&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;WORKDIR&lt;/span&gt; /app&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# System-Abhaengigkeiten installieren&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; apt-get update &amp;amp;&amp;amp; apt-get install -y &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    gcc &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    postgresql-client &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Requirements zuerst kopieren fuer besseres Caching&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; requirements.txt .&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; pip install --no-cache-dir -r requirements.txt&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; . .&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Non-Root-Benutzer fuer Sicherheit erstellen&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; useradd -m -u 1000 flaskuser &amp;amp;&amp;amp; &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    chown -R flaskuser:flaskuser /app&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;USER&lt;/span&gt; flaskuser&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;EXPOSE&lt;/span&gt; 8080&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;CMD&lt;/span&gt; [&lt;span class=&quot;token string&quot;&gt;&quot;gunicorn&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;--bind&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0:8080&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;--workers&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;2&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;wsgi:app&quot;&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Die Reihenfolge ist hier wichtig. Das Kopieren von requirements.txt vor dem Kopieren Ihres Codes bedeutet, dass Docker die pip-Install-Schicht cachen kann. Wenn Sie Ihren Code aendern, aber nicht Ihre Abhaengigkeiten, verwendet Docker die gecachte Schicht mit all Ihren bereits installierten Paketen wieder. Das verwandelt einen 5-minuetigen Rebuild in einen 10-Sekunden-Rebuild.&lt;/p&gt;
&lt;p&gt;Als Non-Root-Benutzer zu laufen ist eine Sicherheits-Best-Practice. Wenn jemand Ihre App kompromittiert, hat er keinen Root-Zugang zum Container.&lt;/p&gt;
&lt;h2 id=&quot;docker-compose-fuer-lokale-entwicklung&quot;&gt;Docker Compose fuer lokale Entwicklung&lt;/h2&gt;
&lt;p&gt;Docker Compose laesst Sie mehrere Container zusammen ausfuehren. Hier ist eine docker-compose.yml, die Ihre Flask-App mit PostgreSQL einrichtet:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;3.8&apos;&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;web&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; .
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;8080:8080&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; DATABASE_URL=postgresql&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//postgres&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;postgres@db&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;5432/flask_blog
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; SECRET_KEY=dev&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;secret&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;key
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; FLASK_ENV=development
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; .&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/app  &lt;span class=&quot;token comment&quot;&gt;# Ihren Code fuer Hot Reloading mounten&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; db
    &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; flask run &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;host=0.0.0.0 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;port=8080 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;reload

  &lt;span class=&quot;token key atrule&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; postgres&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;15&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;alpine
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_USER=postgres
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_PASSWORD=postgres
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_DB=flask_blog
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;5432:5432&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; postgres_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/var/lib/postgresql/data

&lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  postgres_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Das Volume-Mount (&lt;code class=&quot;language-text&quot;&gt;.:/app&lt;/code&gt;) bedeutet, dass Aenderungen an Ihrem Code sofort reflektiert werden, ohne den Container neu zu bauen. Das postgres_data-Volume stellt sicher, dass Ihre Datenbank persistiert, auch wenn Sie die Container stoppen.&lt;/p&gt;
&lt;p&gt;Das depends_on kontrolliert nur die Startreihenfolge. Es wartet nicht darauf, dass PostgreSQL bereit ist, also koennte Ihre Flask-App beim ersten Start abstuerzen. Starten Sie sie einfach neu; das ist normal und passiert nur einmal.&lt;/p&gt;
&lt;h2 id=&quot;alles-ausfuehren&quot;&gt;Alles ausfuehren&lt;/h2&gt;
&lt;p&gt;Bauen Sie zuerst Ihr Image:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; build&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Der erste Build dauert eine Weile, waehrend Base-Images heruntergeladen und Pakete installiert werden. Nachfolgende Builds sind dank Dockers Layer-Caching viel schneller.&lt;/p&gt;
&lt;p&gt;Starten Sie die Datenbank:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; up &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; db&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Initialisieren Sie Ihre Datenbank-Migrationen, falls Sie das noch nicht getan haben:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db init
&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db migrate &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial migration&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db upgrade&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Starten Sie jetzt alles:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; up&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Besuchen Sie localhost:8080 und Ihr Blog sollte laufen. Wenn etwas nicht stimmt, werden Ihnen die Logs genau sagen, was. Docker zeigt Ihnen alles, was viel besser ist als mysteriöse Produktionsfehler ohne Fehlermeldungen.&lt;/p&gt;
&lt;p&gt;Um nur Ihre App-Logs ohne PostgreSQL-Rauschen zu sehen, verwenden Sie &lt;code class=&quot;language-text&quot;&gt;docker-compose logs -f web&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;auf-flyio-deployen&quot;&gt;Auf Fly.io deployen&lt;/h2&gt;
&lt;p&gt;Fly.io fuehrt Ihren tatsaechlichen Docker-Container aus, keine interpretierte Version davon. Sie haben einen Free Tier, der keine Kreditkarte erfordert, was erfrischend ist in 2025. Fuer einen tieferen Einblick in &lt;strong&gt;&lt;a href=&quot;/blog/flyio-free-tier-guide/&quot;&gt;Fly.ios Free-Tier-Faehigkeiten und -Einschraenkungen&lt;/a&gt;&lt;/strong&gt;, einschliesslich Performance-Vergleichen und Skalierungsstrategien, schauen Sie sich unseren kompletten Guide an.&lt;/p&gt;
&lt;p&gt;Installieren Sie zuerst ihre CLI.&lt;/p&gt;
&lt;p&gt;Auf Mac:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flyctl&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Auf Windows laden Sie den Installer von ihrer Website herunter oder verwenden Sie PowerShell:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;powershell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-powershell line-numbers&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;pwsh &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;Command &lt;span class=&quot;token string&quot;&gt;&quot;iwr https://fly.io/install.ps1 -useb | iex&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Auf Linux:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sie muessen moeglicherweise flyctl zu Ihrem PATH hinzufuegen. Der Installer wird Ihnen sagen, ob das noetig ist und Ihnen den genauen Befehl zeigen.&lt;/p&gt;
&lt;p&gt;Starten Sie Ihre App mit &lt;code class=&quot;language-text&quot;&gt;flyctl launch&lt;/code&gt;. Wenn es fragt, geben Sie Ihrer App einen Namen (oder lassen Sie einen generieren), waehlen Sie eine Region nah bei Ihnen oder Ihren Nutzern, sagen Sie ja zu PostgreSQL (waehlen Sie Development fuer Free Tier), und sagen Sie nein zum sofortigen Deployen, weil wir zuerst Secrets setzen muessen.&lt;/p&gt;
&lt;p&gt;Das erstellt eine fly.toml-Datei, die Ihr Deployment konfiguriert:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token key property&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;your-app-name&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;primary_region&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iad&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;8080&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;http_service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;internal_port&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;force_https&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;auto_stop_machines&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;auto_start_machines&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;min_machines_running&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;cpu_kind&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;shared&quot;&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;cpus&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;memory_mb&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Die auto_stop_machines-Einstellung stoppt Ihre App, wenn niemand sie nutzt, was Ihnen hilft, innerhalb der Free-Tier-Grenzen zu bleiben. Sie startet automatisch wieder, wenn jemand besucht.&lt;/p&gt;
&lt;p&gt;Setzen Sie Ihren Secret Key:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl secrets &lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;SECRET_KEY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;openssl rand &lt;span class=&quot;token parameter variable&quot;&gt;-hex&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Deployen Sie Ihre App:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Das baut Ihr Docker-Image und deployed es. Dauert etwa 2 Minuten. Wenn es fertig ist, fuehren Sie Ihre Datenbank-Migrationen aus:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl &lt;span class=&quot;token function&quot;&gt;ssh&lt;/span&gt; console &lt;span class=&quot;token parameter variable&quot;&gt;-C&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;flask db upgrade&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Oeffnen Sie Ihre deployede App mit &lt;code class=&quot;language-text&quot;&gt;flyctl open&lt;/code&gt;. Sie haben jetzt eine Produktions-Flask-App mit HTTPS, automatischen Neustarts und Datenbank-Backups. Keine Server-Konfiguration erforderlich.&lt;/p&gt;
&lt;h2 id=&quot;haeufige-probleme-und-loesungen&quot;&gt;Haeufige Probleme und Loesungen&lt;/h2&gt;
&lt;p&gt;Wenn Sie &quot;Port already in use&quot; sehen, haben Sie wahrscheinlich einen anderen Container laufen. Fuehren Sie &lt;code class=&quot;language-text&quot;&gt;docker-compose down&lt;/code&gt; aus, um alles zu stoppen, oder aendern Sie einfach den Port. Manchmal wird Docker Desktop verwirrt und ein Neustart behebt es.&lt;/p&gt;
&lt;p&gt;Datenbankverbindungsfehler beim Start bedeuten normalerweise, dass Flask versucht, sich zu verbinden, bevor PostgreSQL bereit ist. Starten Sie einfach den Flask-Container neu. Sie koennten Retry-Logik zu Ihrem Datenbankverbindungscode hinzufuegen, aber fuer lokale Entwicklung funktioniert ein einfacher Neustart gut.&lt;/p&gt;
&lt;p&gt;Wenn Docker Desktop sagt, es kann sich nicht mit dem Docker-Daemon verbinden, starten Sie Docker Desktop neu. Wenn das nicht funktioniert, starten Sie Ihren Computer neu. Docker Desktop hat Eigenheiten.&lt;/p&gt;
&lt;p&gt;Der Fly.io Free Tier gibt Ihnen 256MB RAM. Wenn Ihre App mehr braucht, fuehren Sie &lt;code class=&quot;language-text&quot;&gt;flyctl scale memory 512&lt;/code&gt; aus. Oder optimieren Sie Ihre App; Sie muessen wahrscheinlich nicht alles auf einmal in den Speicher laden.&lt;/p&gt;
&lt;p&gt;Wenn Aenderungen lokal nicht angezeigt werden, ueberpruefen Sie das Volume-Mount in docker-compose.yml. In Produktion muessen Sie mit &lt;code class=&quot;language-text&quot;&gt;flyctl deploy&lt;/code&gt; neu bauen und deployen. Docker erkennt nicht automatisch Code-Aenderungen in Produktion.&lt;/p&gt;
&lt;h2 id=&quot;tipps-die-zeit-sparen&quot;&gt;Tipps, die Zeit sparen&lt;/h2&gt;
&lt;p&gt;Docker-Images koennen riesig werden. Verwenden Sie Slim-Base-Images und fuegen Sie eine .dockerignore-Datei hinzu:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;__pycache__
*.pyc
.git
.env
venv/
node_modules/
*.db
.DS_Store&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fuegen Sie ordentliches Logging zu Ihrer App hinzu. Wenn etwas in Produktion kaputtgeht, sind Logs Ihr einziges Fenster in das, was passiert ist:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; logging
logging&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;basicConfig&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;level&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;logging&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;INFO&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;info&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;App starting up&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Das Docker-Setup, das Sie gerade erstellt haben, ist dasselbe, das viele Unternehmen in Produktion verwenden. Das ist kein Spielzeug-Setup; es ist professionelles Deployment, das zufaellig kostenlos ist.&lt;/p&gt;
&lt;h2 id=&quot;geschafft&quot;&gt;Geschafft&lt;/h2&gt;
&lt;p&gt;Sie haben erfolgreich eine Flask-Anwendung mit einer Produktions-Datenbank, lokalem Hot Reloading und Ein-Befehl-Deployment containerisiert. Ihre Entwicklungsumgebung entspricht jetzt genau der Produktion und eliminiert eine ganze Klasse von Deployment-Bugs.&lt;/p&gt;
&lt;p&gt;Das ist derselbe Workflow, den professionelle Teams verwenden. Dasselbe Docker, derselbe Deployment-Prozess, dasselbe alles. Die Luecke zwischen Hobby-Projekten und Produktionsanwendungen ist kleiner, als die meisten Leute denken. Es geht meistens nur darum, die richtigen Tools zu kennen.&lt;/p&gt;
&lt;h2 id=&quot;bauen-sie-zuerst-ihre-flask-anwendung&quot;&gt;Bauen Sie zuerst Ihre Flask-Anwendung&lt;/h2&gt;
&lt;p&gt;Haben Sie noch keinen Flask-Blog zum Dockerisieren? Beginnen Sie hier:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Einen Blog mit Flask bauen&lt;/a&gt;&lt;/strong&gt; - Erstellen Sie einen kompletten Flask-Blog von Grund auf mit PostgreSQL und Authentifizierung&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Ein Portfolio mit Flask bauen&lt;/a&gt;&lt;/strong&gt; - Lernen Sie Flask-Grundlagen mit einer professionellen Portfolio-Site&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;E-Commerce mit Flask bauen&lt;/a&gt;&lt;/strong&gt; - Meistern Sie Flask mit einem vollstaendigen Warenkorb und Zahlungsintegration&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Jedes Tutorial enthaelt Schritt-fuer-Schritt-KI-Prompts, die Sie durch den Bau produktionsreifer Flask-Anwendungen fuehren. Sobald Sie Ihre App gebaut haben, kommen Sie zu diesem Guide zurueck, um sie zu dockerisieren und zu deployen.&lt;/p&gt;
&lt;p&gt;Jetzt gehen Sie los und bauen Sie etwas Cooles.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Dockeriza Tu Blog Flask: Guia Completa + Despliegue en Fly.io]]></title><description><![CDATA[Aprende a containerizar una aplicacion de blog Flask con Docker y desplegarla en Fly.io. Cubre creacion de Dockerfile, Docker Compose para desarrollo local, integracion con PostgreSQL y despliegue en produccion. Funciona con cualquier app Flask.]]></description><link>https://vibecodingwithfred.com/es/blog/dockerize-flask-blog/</link><guid isPermaLink="false">https://vibecodingwithfred.com/es/blog/dockerize-flask-blog/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Mon, 20 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Ultima verificacion:&lt;/strong&gt; Octubre 2025 | &lt;strong&gt;Docker:&lt;/strong&gt; 24.x | &lt;strong&gt;Flask:&lt;/strong&gt; 3.0.0 | &lt;strong&gt;PostgreSQL:&lt;/strong&gt; 15 | &lt;strong&gt;Python:&lt;/strong&gt; 3.11&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;El despliegue es frustrante. Logras que tu app Flask funcione perfectamente en tu maquina, luego pasas horas peleando con la configuracion del servidor, versiones de Python y dependencias faltantes cuando intentas desplegarla. Docker arregla esto empaquetando todo lo que tu app necesita en un contenedor que corre igual en todos lados.&lt;/p&gt;
&lt;p&gt;Esta guia te muestra como containerizar un blog Flask y desplegarlo en Fly.io. Todo el proceso toma aproximadamente 15 minutos una vez que sabes lo que estas haciendo. Sin configuracion de servidor, sin infierno de dependencias, solo tu app corriendo en produccion.&lt;/p&gt;
&lt;h2 id=&quot;para-quien-es-esta-guia&quot;&gt;Para Quien Es Esta Guia&lt;/h2&gt;
&lt;p&gt;Si tienes una app Flask que funciona localmente y quieres desplegarla sin los dolores de cabeza usuales, esto es para ti. Quizas estas cansado de debuggear por que algo funciona en tu laptop pero se rompe en produccion. Quizas quieres usar practicas modernas de despliegue sin pasar semanas aprendiendo DevOps.&lt;/p&gt;
&lt;p&gt;Necesitaras conocimiento basico de Python y Flask. Si has construido una app Flask antes, estas listo. Deberias estar comodo con la linea de comandos, y necesitaras Docker Desktop instalado. Eso es todo.&lt;/p&gt;
&lt;p&gt;Al final, tendras desarrollo local que coincide con produccion exactamente, despliegues que toman minutos en lugar de horas, y no mas conflictos de version de Python.&lt;/p&gt;
&lt;h2 id=&quot;por-que-docker-ayuda&quot;&gt;Por Que Docker Ayuda&lt;/h2&gt;
&lt;p&gt;Docker tiene mala fama por ser complejo, pero la idea central es simple: es una caja para tu codigo. Tu app va en la caja con todo lo que necesita para correr. Esa caja corre igual en tu laptop, en servidores CI, y en produccion.&lt;/p&gt;
&lt;p&gt;Esta consistencia elimina categorias enteras de bugs. No mas discusiones de &quot;pero funciona en mi maquina&quot;. No mas descubrir que produccion tiene Python 3.8 cuando desarrollaste en 3.11. No mas librerias de sistema faltantes que olvidaste documentar.&lt;/p&gt;
&lt;p&gt;La verdadera victoria es la velocidad de despliegue. Una vez que tienes una configuracion Docker funcionando, desplegar se vuelve trivial. Sube tu codigo, construye la imagen, despliega. Los rollbacks son igual de faciles: redespliega la imagen anterior y vuelves a funcionar en segundos.&lt;/p&gt;
&lt;h2 id=&quot;que-estamos-construyendo&quot;&gt;Que Estamos Construyendo&lt;/h2&gt;
&lt;p&gt;Vamos a tomar tu blog Flask existente y containerizarlo correctamente. Tendras desarrollo local con hot reloading para que puedas ver cambios instantaneamente. Usaremos PostgreSQL porque SQLite no esta hecho para produccion, sin importar lo que alguien te diga. Luego desplegaremos todo a Fly.io porque tienen un nivel gratuito generoso y corren tus contenedores Docker tal cual.&lt;/p&gt;
&lt;h2 id=&quot;preparando-tu-app-flask&quot;&gt;Preparando Tu App Flask&lt;/h2&gt;
&lt;p&gt;Primero, arreglemos tu requirements.txt. Si el tuyo solo dice &quot;Flask&quot; sin numero de version, estas buscando problemas. Esto es lo que necesitas para produccion:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;txt&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-txt line-numbers&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;Flask==3.0.0
Flask-SQLAlchemy==3.1.1
Flask-Migrate==4.0.5
psycopg2-binary==2.9.9
python-dotenv==1.0.0
gunicorn==21.2.0&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;El servidor integrado de Flask es solo para desarrollo. Gunicorn es un servidor WSGI listo para produccion que puede manejar trafico real. El paquete psycopg2-binary te permite hablar con PostgreSQL. Todo tiene numeros de version porque &quot;Flask&quot; sin version significa que podrias obtener diferentes versiones en diferentes entornos, lo cual derrota todo el proposito.&lt;/p&gt;
&lt;p&gt;Crea un archivo wsgi.py como punto de entrada de tu aplicacion:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; app &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; create_app
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os

app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; create_app&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; __name__ &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;run&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        port&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;PORT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ese host=&quot;0.0.0.0&quot; es importante. Significa &quot;escuchar en todas las interfaces de red.&quot; El 127.0.0.1 por defecto solo escucha localmente, lo cual no funciona dentro de un contenedor. Este pequeno detalle ha causado horas de debugging para muchos desarrolladores.&lt;/p&gt;
&lt;p&gt;Tu config.py deberia usar variables de entorno para cualquier cosa sensible:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; dotenv &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; load_dotenv

basedir &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;abspath&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dirname&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__file__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
load_dotenv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;basedir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.env&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    SECRET_KEY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;SECRET_KEY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dev-secret-key-change-in-production&apos;&lt;/span&gt;

    SQLALCHEMY_DATABASE_URI &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;DATABASE_URL&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; \
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;sqlite:///&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;basedir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;app.db&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;

    SQLALCHEMY_TRACK_MODIFICATIONS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Algunos servicios usan postgres:// pero SQLAlchemy necesita postgresql://&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; SQLALCHEMY_DATABASE_URI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;startswith&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;postgres://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        SQLALCHEMY_DATABASE_URI &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; SQLALCHEMY_DATABASE_URI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;replace&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;postgres://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;postgresql://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Nunca hardcodees secretos. Usa variables de entorno. Tu yo futuro te lo agradecera cuando no subas accidentalmente tu contrasena de base de datos de produccion a GitHub.&lt;/p&gt;
&lt;h2 id=&quot;escribiendo-un-dockerfile-que-funciona&quot;&gt;Escribiendo un Dockerfile Que Funciona&lt;/h2&gt;
&lt;p&gt;Aqui hay un Dockerfile que funciona en produccion:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;dockerfile&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-dockerfile line-numbers&quot;&gt;&lt;code class=&quot;language-dockerfile&quot;&gt;&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; python:3.11-slim &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; base&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# El buffering de Python puede causar problemas en contenedores&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ENV&lt;/span&gt; PYTHONUNBUFFERED=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PYTHONDONTWRITEBYTECODE=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PIP_NO_CACHE_DIR=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PIP_DISABLE_PIP_VERSION_CHECK=1&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;WORKDIR&lt;/span&gt; /app&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Instalar dependencias del sistema&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; apt-get update &amp;amp;&amp;amp; apt-get install -y &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    gcc &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    postgresql-client &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Copiar requirements primero para mejor caching&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; requirements.txt .&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; pip install --no-cache-dir -r requirements.txt&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; . .&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Crear usuario no-root por seguridad&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; useradd -m -u 1000 flaskuser &amp;amp;&amp;amp; &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    chown -R flaskuser:flaskuser /app&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;USER&lt;/span&gt; flaskuser&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;EXPOSE&lt;/span&gt; 8080&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;CMD&lt;/span&gt; [&lt;span class=&quot;token string&quot;&gt;&quot;gunicorn&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;--bind&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0:8080&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;--workers&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;2&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;wsgi:app&quot;&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;El orden importa aqui. Copiar requirements.txt antes de copiar tu codigo significa que Docker puede cachear la capa de pip install. Cuando cambias tu codigo pero no tus dependencias, Docker reutiliza la capa cacheada con todos tus paquetes ya instalados. Esto convierte una reconstruccion de 5 minutos en una de 10 segundos.&lt;/p&gt;
&lt;p&gt;Correr como usuario no-root es una mejor practica de seguridad. Si alguien compromete tu app, no tendran acceso root al contenedor.&lt;/p&gt;
&lt;h2 id=&quot;docker-compose-para-desarrollo-local&quot;&gt;Docker Compose para Desarrollo Local&lt;/h2&gt;
&lt;p&gt;Docker Compose te permite correr multiples contenedores juntos. Aqui hay un docker-compose.yml que configura tu app Flask con PostgreSQL:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;3.8&apos;&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;web&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; .
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;8080:8080&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; DATABASE_URL=postgresql&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//postgres&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;postgres@db&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;5432/flask_blog
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; SECRET_KEY=dev&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;secret&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;key
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; FLASK_ENV=development
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; .&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/app  &lt;span class=&quot;token comment&quot;&gt;# Monta tu codigo para hot reloading&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; db
    &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; flask run &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;host=0.0.0.0 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;port=8080 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;reload

  &lt;span class=&quot;token key atrule&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; postgres&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;15&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;alpine
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_USER=postgres
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_PASSWORD=postgres
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_DB=flask_blog
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;5432:5432&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; postgres_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/var/lib/postgresql/data

&lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  postgres_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;El mount de volumen (&lt;code class=&quot;language-text&quot;&gt;.:/app&lt;/code&gt;) significa que los cambios a tu codigo se reflejan inmediatamente sin reconstruir el contenedor. El volumen postgres_data asegura que tu base de datos persista incluso cuando detienes los contenedores.&lt;/p&gt;
&lt;p&gt;Ese depends_on solo controla el orden de inicio. No espera a que PostgreSQL este listo, asi que tu app Flask podria crashear en el primer inicio. Solo reiniciala; esto es normal y solo pasa una vez.&lt;/p&gt;
&lt;h2 id=&quot;corriendo-todo&quot;&gt;Corriendo Todo&lt;/h2&gt;
&lt;p&gt;Construye tu imagen primero:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; build&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;La primera construccion toma un rato mientras descarga imagenes base e instala paquetes. Las construcciones subsecuentes son mucho mas rapidas gracias al caching de capas de Docker.&lt;/p&gt;
&lt;p&gt;Inicia la base de datos:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; up &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; db&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Inicializa tus migraciones de base de datos si no lo has hecho ya:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db init
&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db migrate &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial migration&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db upgrade&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ahora inicia todo:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; up&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Visita localhost:8080 y tu blog deberia estar corriendo. Si algo esta mal, los logs te diran exactamente que. Docker te muestra todo, lo cual es mucho mejor que fallas misteriosas de produccion sin mensajes de error.&lt;/p&gt;
&lt;p&gt;Para ver solo los logs de tu app sin el ruido de PostgreSQL, usa &lt;code class=&quot;language-text&quot;&gt;docker-compose logs -f web&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;desplegando-en-flyio&quot;&gt;Desplegando en Fly.io&lt;/h2&gt;
&lt;p&gt;Fly.io corre tu contenedor Docker real, no alguna version interpretada de el. Tienen un nivel gratuito que no requiere tarjeta de credito, lo cual es refrescante en 2025. Para una mirada mas profunda a las &lt;strong&gt;&lt;a href=&quot;/blog/flyio-free-tier-guide/&quot;&gt;capacidades y limitaciones del nivel gratuito de Fly.io&lt;/a&gt;&lt;/strong&gt;, incluyendo comparaciones de rendimiento y estrategias de escalado, revisa nuestra guia completa.&lt;/p&gt;
&lt;p&gt;Instala su CLI primero.&lt;/p&gt;
&lt;p&gt;En Mac:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flyctl&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;En Windows, descarga el instalador de su sitio web o usa PowerShell:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;powershell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-powershell line-numbers&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;pwsh &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;Command &lt;span class=&quot;token string&quot;&gt;&quot;iwr https://fly.io/install.ps1 -useb | iex&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;En Linux:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Podrias necesitar agregar flyctl a tu PATH. El instalador te dira si esto es necesario y te mostrara el comando exacto a ejecutar.&lt;/p&gt;
&lt;p&gt;Lanza tu app con &lt;code class=&quot;language-text&quot;&gt;flyctl launch&lt;/code&gt;. Cuando pregunte, dale a tu app un nombre (o deja que genere uno), elige una region cercana a ti o tus usuarios, di si a PostgreSQL (elige development para nivel gratuito), y di no a desplegar inmediatamente porque necesitamos configurar secretos primero.&lt;/p&gt;
&lt;p&gt;Esto crea un archivo fly.toml que configura tu despliegue:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token key property&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;your-app-name&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;primary_region&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iad&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;8080&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;http_service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;internal_port&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;force_https&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;auto_stop_machines&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;auto_start_machines&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;min_machines_running&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;cpu_kind&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;shared&quot;&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;cpus&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;memory_mb&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;La configuracion auto_stop_machines detiene tu app cuando nadie la esta usando, lo cual te ayuda a mantenerte dentro de los limites del nivel gratuito. Se inicia de nuevo automaticamente cuando alguien visita.&lt;/p&gt;
&lt;p&gt;Configura tu clave secreta:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl secrets &lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;SECRET_KEY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;openssl rand &lt;span class=&quot;token parameter variable&quot;&gt;-hex&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Despliega tu app:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Esto construye tu imagen Docker y la despliega. Toma aproximadamente 2 minutos. Cuando termine, ejecuta tus migraciones de base de datos:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl &lt;span class=&quot;token function&quot;&gt;ssh&lt;/span&gt; console &lt;span class=&quot;token parameter variable&quot;&gt;-C&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;flask db upgrade&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Abre tu app desplegada con &lt;code class=&quot;language-text&quot;&gt;flyctl open&lt;/code&gt;. Ahora tienes una app Flask en produccion con HTTPS, reinicios automaticos y respaldos de base de datos. Sin configuracion de servidor necesaria.&lt;/p&gt;
&lt;h2 id=&quot;problemas-comunes-y-soluciones&quot;&gt;Problemas Comunes y Soluciones&lt;/h2&gt;
&lt;p&gt;Cuando ves &quot;Port already in use&quot;, probablemente tienes otro contenedor corriendo. Ejecuta &lt;code class=&quot;language-text&quot;&gt;docker-compose down&lt;/code&gt; para detener todo, o simplemente cambia el puerto. A veces Docker Desktop se confunde y reiniciarlo lo arregla.&lt;/p&gt;
&lt;p&gt;Los errores de conexion de base de datos al iniciar usualmente significan que Flask esta intentando conectarse antes de que PostgreSQL este listo. Solo reinicia el contenedor Flask. Podrias agregar logica de reintento a tu codigo de conexion de base de datos, pero para desarrollo local, un simple reinicio funciona bien.&lt;/p&gt;
&lt;p&gt;Si Docker Desktop dice que no puede conectarse al daemon de Docker, reinicia Docker Desktop. Si eso no funciona, reinicia tu computadora. Docker Desktop tiene sus peculiaridades.&lt;/p&gt;
&lt;p&gt;El nivel gratuito de Fly.io te da 256MB de RAM. Si tu app necesita mas, ejecuta &lt;code class=&quot;language-text&quot;&gt;flyctl scale memory 512&lt;/code&gt;. O optimiza tu app; probablemente no necesitas cargar todo en memoria de una vez.&lt;/p&gt;
&lt;p&gt;Cuando los cambios no aparecen localmente, revisa ese mount de volumen en docker-compose.yml. En produccion, necesitas reconstruir y desplegar con &lt;code class=&quot;language-text&quot;&gt;flyctl deploy&lt;/code&gt;. Docker no detecta automaticamente cambios de codigo en produccion.&lt;/p&gt;
&lt;h2 id=&quot;consejos-que-ahorran-tiempo&quot;&gt;Consejos Que Ahorran Tiempo&lt;/h2&gt;
&lt;p&gt;Las imagenes Docker pueden volverse enormes. Usa imagenes base slim y agrega un archivo .dockerignore:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;__pycache__
*.pyc
.git
.env
venv/
node_modules/
*.db
.DS_Store&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Agrega logging apropiado a tu app. Cuando algo se rompe en produccion, los logs son tu unica ventana a lo que paso:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; logging
logging&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;basicConfig&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;level&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;logging&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;INFO&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;info&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;App starting up&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;La configuracion de Docker que acabas de crear es la misma que muchas empresas usan en produccion. Esta no es una configuracion de juguete; es despliegue de grado profesional que resulta ser gratis.&lt;/p&gt;
&lt;h2 id=&quot;lo-lograste&quot;&gt;Lo Lograste&lt;/h2&gt;
&lt;p&gt;Has containerizado exitosamente una aplicacion Flask con una base de datos de produccion, hot reloading local y despliegue de un comando. Tu entorno de desarrollo ahora coincide con produccion exactamente, eliminando una clase entera de bugs de despliegue.&lt;/p&gt;
&lt;p&gt;Este es el mismo flujo de trabajo que usan los equipos profesionales. El mismo Docker, el mismo proceso de despliegue, el mismo todo. La brecha entre proyectos hobby y aplicaciones de produccion es mas pequena de lo que la mayoria piensa. Es principalmente solo conocer las herramientas correctas.&lt;/p&gt;
&lt;h2 id=&quot;construye-tu-aplicacion-flask-primero&quot;&gt;Construye Tu Aplicacion Flask Primero&lt;/h2&gt;
&lt;p&gt;No tienes un blog Flask para dockerizar aun? Empieza aqui:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Construye un Blog con Flask&lt;/a&gt;&lt;/strong&gt; - Crea un blog Flask completo desde cero con PostgreSQL y autenticacion&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Construye un Portafolio con Flask&lt;/a&gt;&lt;/strong&gt; - Aprende fundamentos de Flask con un sitio de portafolio profesional&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Construye E-Commerce con Flask&lt;/a&gt;&lt;/strong&gt; - Domina Flask con un carrito de compras completo e integracion de pagos&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cada tutorial incluye prompts de IA paso a paso para guiarte en la construccion de aplicaciones Flask listas para produccion. Una vez que hayas construido tu app, regresa a esta guia para dockerizarla y desplegarla.&lt;/p&gt;
&lt;p&gt;Ahora ve a construir algo genial.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Dockeriser votre blog Flask : Guide complet + deploiement Fly.io]]></title><description><![CDATA[Apprenez a containeriser une application de blog Flask avec Docker et a la deployer sur Fly.io. Couvre la creation de Dockerfile, Docker Compose pour le developpement local, l'integration PostgreSQL et le deploiement production. Fonctionne avec n'importe quelle app Flask.]]></description><link>https://vibecodingwithfred.com/fr/blog/dockerize-flask-blog/</link><guid isPermaLink="false">https://vibecodingwithfred.com/fr/blog/dockerize-flask-blog/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Mon, 20 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Derniere verification :&lt;/strong&gt; Octobre 2025 | &lt;strong&gt;Docker :&lt;/strong&gt; 24.x | &lt;strong&gt;Flask :&lt;/strong&gt; 3.0.0 | &lt;strong&gt;PostgreSQL :&lt;/strong&gt; 15 | &lt;strong&gt;Python :&lt;/strong&gt; 3.11&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Le deploiement est frustrant. Vous faites fonctionner parfaitement votre app Flask sur votre machine, puis passez des heures a vous battre avec la configuration du serveur, les versions de Python et les dependances manquantes quand vous essayez de la deployer. Docker resout ca en empaquetant tout ce dont votre app a besoin dans un conteneur qui fonctionne de la meme facon partout.&lt;/p&gt;
&lt;p&gt;Ce guide vous montre comment containeriser un blog Flask et le deployer sur Fly.io. Le processus entier prend environ 15 minutes une fois que vous savez ce que vous faites. Pas de configuration de serveur, pas d&apos;enfer des dependances, juste votre app qui tourne en production.&lt;/p&gt;
&lt;h2 id=&quot;a-qui-sadresse-ce-guide&quot;&gt;A qui s&apos;adresse ce guide&lt;/h2&gt;
&lt;p&gt;Si vous avez une app Flask qui fonctionne localement et que vous voulez la deployer sans les maux de tete habituels, c&apos;est pour vous. Peut-etre que vous en avez assez de deboguer pourquoi quelque chose fonctionne sur votre laptop mais casse en production. Peut-etre que vous voulez utiliser des pratiques de deploiement modernes sans passer des semaines a apprendre le DevOps.&lt;/p&gt;
&lt;p&gt;Vous aurez besoin de connaissances basiques en Python et Flask. Si vous avez deja construit une app Flask, vous etes pret. Vous devriez etre a l&apos;aise avec la ligne de commande, et vous aurez besoin de Docker Desktop installe. C&apos;est tout.&lt;/p&gt;
&lt;p&gt;A la fin, vous aurez un developpement local qui correspond exactement a la production, des deploiements qui prennent des minutes au lieu d&apos;heures, et plus de conflits de version Python.&lt;/p&gt;
&lt;h2 id=&quot;pourquoi-docker-aide&quot;&gt;Pourquoi Docker aide&lt;/h2&gt;
&lt;p&gt;Docker a mauvaise reputation pour etre complexe, mais l&apos;idee de base est simple : c&apos;est une boite pour votre code. Votre app va dans la boite avec tout ce dont elle a besoin pour fonctionner. Cette boite fonctionne de la meme facon sur votre laptop, sur les serveurs CI et en production.&lt;/p&gt;
&lt;p&gt;Cette coherence elimine des categories entieres de bugs. Plus de discussions &quot;mais ca marche sur ma machine&quot;. Plus de decouvrir que la production a Python 3.8 quand vous avez developpe sur 3.11. Plus de bibliotheques systeme manquantes que vous avez oublie de documenter.&lt;/p&gt;
&lt;p&gt;Le vrai gain c&apos;est la vitesse de deploiement. Une fois que vous avez une configuration Docker fonctionnelle, deployer devient trivial. Poussez votre code, construisez l&apos;image, deployez. Les rollbacks sont tout aussi faciles : redeployez l&apos;image precedente et vous etes de retour en quelques secondes.&lt;/p&gt;
&lt;h2 id=&quot;ce-que-nous-construisons&quot;&gt;Ce que nous construisons&lt;/h2&gt;
&lt;p&gt;Nous allons prendre votre blog Flask existant et le containeriser correctement. Vous aurez le developpement local avec rechargement a chaud pour voir les changements instantanement. Nous utiliserons PostgreSQL parce que SQLite n&apos;est pas fait pour la production, peu importe ce qu&apos;on vous dit. Puis nous deploierons le tout sur Fly.io parce qu&apos;ils ont un palier gratuit genereux et executent vos conteneurs Docker tels quels.&lt;/p&gt;
&lt;h2 id=&quot;preparer-votre-app-flask&quot;&gt;Preparer votre app Flask&lt;/h2&gt;
&lt;p&gt;D&apos;abord, corrigeons votre requirements.txt. Si le votre dit juste &quot;Flask&quot; sans numero de version, vous cherchez les ennuis. Voici ce dont vous avez besoin pour la production :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;txt&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-txt line-numbers&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;Flask==3.0.0
Flask-SQLAlchemy==3.1.1
Flask-Migrate==4.0.5
psycopg2-binary==2.9.9
python-dotenv==1.0.0
gunicorn==21.2.0&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Le serveur integre de Flask est uniquement pour le developpement. Gunicorn est un serveur WSGI pret pour la production qui peut gerer du vrai trafic. Le package psycopg2-binary vous permet de parler a PostgreSQL. Tout a des numeros de version parce que &quot;Flask&quot; sans version signifie que vous pourriez avoir differentes versions dans differents environnements, ce qui annule tout l&apos;interet.&lt;/p&gt;
&lt;p&gt;Creez un fichier wsgi.py comme point d&apos;entree de votre application :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; app &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; create_app
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os

app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; create_app&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; __name__ &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;run&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        port&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;PORT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ce host=&quot;0.0.0.0&quot; est important. Ca signifie &quot;ecouter sur toutes les interfaces reseau&quot;. Le 127.0.0.1 par defaut n&apos;ecoute que localement, ce qui ne fonctionne pas dans un conteneur. Ce petit detail a cause des heures de debogage pour beaucoup de developpeurs.&lt;/p&gt;
&lt;p&gt;Votre config.py devrait utiliser des variables d&apos;environnement pour tout ce qui est sensible :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; dotenv &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; load_dotenv

basedir &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;abspath&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dirname&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__file__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
load_dotenv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;basedir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.env&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    SECRET_KEY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;SECRET_KEY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dev-secret-key-change-in-production&apos;&lt;/span&gt;

    SQLALCHEMY_DATABASE_URI &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;DATABASE_URL&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; \
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;sqlite:///&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;basedir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;app.db&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;

    SQLALCHEMY_TRACK_MODIFICATIONS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Certains services utilisent postgres:// mais SQLAlchemy a besoin de postgresql://&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; SQLALCHEMY_DATABASE_URI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;startswith&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;postgres://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        SQLALCHEMY_DATABASE_URI &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; SQLALCHEMY_DATABASE_URI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;replace&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;postgres://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;postgresql://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ne jamais coder en dur les secrets. Utilisez les variables d&apos;environnement. Votre futur vous vous remerciera quand vous ne committerez pas accidentellement votre mot de passe de base de donnees production sur GitHub.&lt;/p&gt;
&lt;h2 id=&quot;ecrire-un-dockerfile-qui-fonctionne&quot;&gt;Ecrire un Dockerfile qui fonctionne&lt;/h2&gt;
&lt;p&gt;Voici un Dockerfile qui fonctionne en production :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;dockerfile&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-dockerfile line-numbers&quot;&gt;&lt;code class=&quot;language-dockerfile&quot;&gt;&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; python:3.11-slim &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; base&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Le buffering Python peut causer des problemes dans les conteneurs&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ENV&lt;/span&gt; PYTHONUNBUFFERED=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PYTHONDONTWRITEBYTECODE=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PIP_NO_CACHE_DIR=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PIP_DISABLE_PIP_VERSION_CHECK=1&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;WORKDIR&lt;/span&gt; /app&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Installer les dependances systeme&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; apt-get update &amp;amp;&amp;amp; apt-get install -y &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    gcc &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    postgresql-client &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Copier requirements d&apos;abord pour un meilleur caching&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; requirements.txt .&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; pip install --no-cache-dir -r requirements.txt&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; . .&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Creer un utilisateur non-root pour la securite&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; useradd -m -u 1000 flaskuser &amp;amp;&amp;amp; &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    chown -R flaskuser:flaskuser /app&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;USER&lt;/span&gt; flaskuser&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;EXPOSE&lt;/span&gt; 8080&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;CMD&lt;/span&gt; [&lt;span class=&quot;token string&quot;&gt;&quot;gunicorn&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;--bind&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0:8080&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;--workers&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;2&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;wsgi:app&quot;&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;L&apos;ordre compte ici. Copier requirements.txt avant de copier votre code signifie que Docker peut mettre en cache la couche pip install. Quand vous changez votre code mais pas vos dependances, Docker reutilise la couche mise en cache avec tous vos packages deja installes. Ca transforme un rebuild de 5 minutes en un de 10 secondes.&lt;/p&gt;
&lt;p&gt;Executer en tant qu&apos;utilisateur non-root est une bonne pratique de securite. Si quelqu&apos;un compromet votre app, il n&apos;aura pas l&apos;acces root au conteneur.&lt;/p&gt;
&lt;h2 id=&quot;docker-compose-pour-le-developpement-local&quot;&gt;Docker Compose pour le developpement local&lt;/h2&gt;
&lt;p&gt;Docker Compose vous permet d&apos;executer plusieurs conteneurs ensemble. Voici un docker-compose.yml qui configure votre app Flask avec PostgreSQL :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;3.8&apos;&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;web&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; .
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;8080:8080&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; DATABASE_URL=postgresql&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//postgres&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;postgres@db&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;5432/flask_blog
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; SECRET_KEY=dev&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;secret&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;key
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; FLASK_ENV=development
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; .&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/app  &lt;span class=&quot;token comment&quot;&gt;# Montez votre code pour le rechargement a chaud&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; db
    &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; flask run &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;host=0.0.0.0 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;port=8080 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;reload

  &lt;span class=&quot;token key atrule&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; postgres&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;15&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;alpine
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_USER=postgres
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_PASSWORD=postgres
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_DB=flask_blog
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;5432:5432&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; postgres_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/var/lib/postgresql/data

&lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  postgres_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Le montage de volume (&lt;code class=&quot;language-text&quot;&gt;.:/app&lt;/code&gt;) signifie que les changements a votre code sont refletes immediatement sans reconstruire le conteneur. Le volume postgres_data garantit que votre base de donnees persiste meme quand vous arretez les conteneurs.&lt;/p&gt;
&lt;h2 id=&quot;tout-executer&quot;&gt;Tout executer&lt;/h2&gt;
&lt;p&gt;Construisez d&apos;abord votre image :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; build&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;La premiere construction prend du temps car elle telecharge les images de base et installe les packages. Les constructions suivantes sont beaucoup plus rapides grace au caching de couches de Docker.&lt;/p&gt;
&lt;p&gt;Demarrez la base de donnees :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; up &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; db&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Initialisez vos migrations de base de donnees si vous ne l&apos;avez pas deja fait :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db init
&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db migrate &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial migration&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db upgrade&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Maintenant demarrez tout :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; up&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Visitez localhost:8080 et votre blog devrait tourner. Si quelque chose ne va pas, les logs vous diront exactement quoi. Docker vous montre tout, ce qui est bien mieux que des echecs de production mysterieux sans messages d&apos;erreur.&lt;/p&gt;
&lt;h2 id=&quot;deployer-sur-flyio&quot;&gt;Deployer sur Fly.io&lt;/h2&gt;
&lt;p&gt;Fly.io execute votre veritable conteneur Docker, pas une version interpretee. Ils ont un palier gratuit qui ne necessite pas de carte de credit, ce qui est rafraichissant en 2025.&lt;/p&gt;
&lt;p&gt;Installez d&apos;abord leur CLI.&lt;/p&gt;
&lt;p&gt;Sur Mac :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flyctl&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sur Windows, telechargez l&apos;installateur depuis leur site ou utilisez PowerShell :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;powershell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-powershell line-numbers&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;pwsh &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;Command &lt;span class=&quot;token string&quot;&gt;&quot;iwr https://fly.io/install.ps1 -useb | iex&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sur Linux :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Lancez votre app avec &lt;code class=&quot;language-text&quot;&gt;flyctl launch&lt;/code&gt;. Quand on vous demande, donnez un nom a votre app (ou laissez-le generer un), choisissez une region proche de vous ou de vos utilisateurs, dites oui a PostgreSQL (choisissez development pour le palier gratuit), et dites non au deploiement immediatement parce que nous devons d&apos;abord definir les secrets.&lt;/p&gt;
&lt;p&gt;Definissez votre cle secrete :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl secrets &lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;SECRET_KEY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;openssl rand &lt;span class=&quot;token parameter variable&quot;&gt;-hex&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Deployez votre app :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Cela construit votre image Docker et la deploie. Prend environ 2 minutes. Quand c&apos;est fait, executez vos migrations de base de donnees :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl &lt;span class=&quot;token function&quot;&gt;ssh&lt;/span&gt; console &lt;span class=&quot;token parameter variable&quot;&gt;-C&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;flask db upgrade&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ouvrez votre app deployee avec &lt;code class=&quot;language-text&quot;&gt;flyctl open&lt;/code&gt;. Vous avez maintenant une app Flask de production avec HTTPS, redemarrages automatiques et sauvegardes de base de donnees. Pas de configuration de serveur necessaire.&lt;/p&gt;
&lt;h2 id=&quot;construisez-dabord-votre-application-flask&quot;&gt;Construisez d&apos;abord votre application Flask&lt;/h2&gt;
&lt;p&gt;Vous n&apos;avez pas encore de blog Flask a dockeriser ? Commencez ici :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Construire un blog avec Flask&lt;/a&gt;&lt;/strong&gt; - Creez un blog Flask complet a partir de zero avec PostgreSQL et authentification&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Construire un portfolio avec Flask&lt;/a&gt;&lt;/strong&gt; - Apprenez les fondamentaux Flask avec un site portfolio professionnel&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Construire un e-commerce avec Flask&lt;/a&gt;&lt;/strong&gt; - Maitrisez Flask avec un panier d&apos;achat complet et l&apos;integration de paiement&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Chaque tutoriel inclut des prompts IA etape par etape pour vous guider dans la construction d&apos;applications Flask prates pour la production. Une fois que vous avez construit votre app, revenez a ce guide pour la dockeriser et la deployer.&lt;/p&gt;
&lt;p&gt;Maintenant allez construire quelque chose de cool.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Flaskブログのコンテナ化完全ガイド + Fly.ioデプロイメント]]></title><description><![CDATA[DockerでFlaskブログアプリケーションをコンテナ化し、Fly.ioにデプロイする方法を学びます。Dockerfile作成、ローカル開発用Docker Compose、PostgreSQL統合、本番デプロイメントをカバー。どんなFlaskアプリにも対応。]]></description><link>https://vibecodingwithfred.com/ja/blog/dockerize-flask-blog/</link><guid isPermaLink="false">https://vibecodingwithfred.com/ja/blog/dockerize-flask-blog/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Mon, 20 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;最終確認:&lt;/strong&gt; 2025年10月 | &lt;strong&gt;Docker:&lt;/strong&gt; 24.x | &lt;strong&gt;Flask:&lt;/strong&gt; 3.0.0 | &lt;strong&gt;PostgreSQL:&lt;/strong&gt; 15 | &lt;strong&gt;Python:&lt;/strong&gt; 3.11&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;デプロイメントはフラストレーションがたまります。自分のマシンでFlaskアプリが完璧に動作するようにしても、デプロイしようとするとサーバー設定、Pythonバージョン、不足している依存関係と何時間も格闘することになります。Dockerは、アプリが必要とするすべてをコンテナにパッケージ化することでこれを解決します。コンテナはどこでも同じように動作します。&lt;/p&gt;
&lt;p&gt;このガイドでは、Flaskブログをコンテナ化してFly.ioにデプロイする方法を示します。やり方を知っていれば、全プロセスは約15分かかります。サーバー設定なし、依存関係地獄なし、ただ本番で動作するアプリだけ。&lt;/p&gt;
&lt;h2 id=&quot;このガイドの対象者&quot;&gt;このガイドの対象者&lt;/h2&gt;
&lt;p&gt;ローカルで動作するFlaskアプリがあり、通常の頭痛なしにデプロイしたい場合、これはあなた向けです。なぜラップトップでは動くのに本番では壊れるのかデバッグするのに疲れているかもしれません。何週間もDevOpsを学ぶことなく、モダンなデプロイメントプラクティスを使いたいかもしれません。&lt;/p&gt;
&lt;p&gt;基本的なPythonとFlaskの知識が必要です。以前にFlaskアプリを構築したことがあれば、準備はできています。コマンドラインに慣れている必要があり、Docker Desktopがインストールされている必要があります。それだけです。&lt;/p&gt;
&lt;p&gt;最後には、本番と正確に一致するローカル開発環境、数時間ではなく数分のデプロイメント、Pythonバージョンの競合がなくなります。&lt;/p&gt;
&lt;h2 id=&quot;なぜdockerが役立つか&quot;&gt;なぜDockerが役立つか&lt;/h2&gt;
&lt;p&gt;Dockerは複雑だという悪評がありますが、コアのアイデアはシンプルです：コードのための箱です。アプリは実行に必要なすべてと一緒に箱に入ります。その箱はラップトップ、CIサーバー、本番で同じように動作します。&lt;/p&gt;
&lt;p&gt;この一貫性はカテゴリ全体のバグを排除します。「でも私のマシンでは動く」という議論はもうありません。開発を3.11で行ったのに本番がPython 3.8だったことを発見することもありません。ドキュメント化し忘れたシステムライブラリが足りないこともありません。&lt;/p&gt;
&lt;p&gt;本当の勝利はデプロイメント速度です。動作するDockerセットアップがあれば、デプロイは些細なものになります。コードをプッシュし、イメージをビルドし、デプロイ。ロールバックも同様に簡単です：以前のイメージを再デプロイすれば、数秒でビジネスに戻れます。&lt;/p&gt;
&lt;h2 id=&quot;何を構築するか&quot;&gt;何を構築するか&lt;/h2&gt;
&lt;p&gt;既存のFlaskブログを適切にコンテナ化します。変更を即座に確認できるホットリロード付きのローカル開発を取得します。SQLiteは本番向けではないので、PostgreSQLを使用します。誰が何と言っても。そして、寛大な無料ティアがあり、Dockerコンテナをそのまま実行するFly.ioに全体をデプロイします。&lt;/p&gt;
&lt;h2 id=&quot;flaskアプリの準備&quot;&gt;Flaskアプリの準備&lt;/h2&gt;
&lt;p&gt;まず、requirements.txtを修正しましょう。バージョン番号なしで「Flask」とだけ書いてあると、問題を求めています。本番に必要なものはこちら：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;txt&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-txt line-numbers&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;Flask==3.0.0
Flask-SQLAlchemy==3.1.1
Flask-Migrate==4.0.5
psycopg2-binary==2.9.9
python-dotenv==1.0.0
gunicorn==21.2.0&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Flaskの組み込みサーバーは開発専用です。Gunicornは実際のトラフィックを処理できる本番対応のWSGIサーバーです。psycopg2-binaryパッケージでPostgreSQLと通信できます。すべてにバージョン番号があります。なぜなら、バージョンなしの「Flask」は、異なる環境で異なるバージョンを取得する可能性があり、それは全体のポイントを台無しにします。&lt;/p&gt;
&lt;p&gt;アプリケーションエントリポイントとしてwsgi.pyファイルを作成します：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; app &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; create_app
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os

app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; create_app&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; __name__ &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;run&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        port&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;PORT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;そのhost=&quot;0.0.0.0&quot;は重要です。「すべてのネットワークインターフェースでリッスンする」という意味です。デフォルトの127.0.0.1はローカルでのみリッスンし、コンテナ内では機能しません。この小さな詳細が多くの開発者にとって何時間ものデバッグの原因となっています。&lt;/p&gt;
&lt;p&gt;config.pyは機密性の高いものに環境変数を使用する必要があります：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; dotenv &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; load_dotenv

basedir &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;abspath&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dirname&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__file__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
load_dotenv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;basedir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.env&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    SECRET_KEY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;SECRET_KEY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dev-secret-key-change-in-production&apos;&lt;/span&gt;

    SQLALCHEMY_DATABASE_URI &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;DATABASE_URL&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; \
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;sqlite:///&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;basedir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;app.db&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;

    SQLALCHEMY_TRACK_MODIFICATIONS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Some services use postgres:// but SQLAlchemy needs postgresql://&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; SQLALCHEMY_DATABASE_URI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;startswith&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;postgres://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        SQLALCHEMY_DATABASE_URI &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; SQLALCHEMY_DATABASE_URI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;replace&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;postgres://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;postgresql://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;シークレットをハードコードしないでください。環境変数を使用してください。誤って本番データベースのパスワードをGitHubにコミットしなくて済むとき、将来のあなたが感謝するでしょう。&lt;/p&gt;
&lt;h2 id=&quot;動作するdockerfileを書く&quot;&gt;動作するDockerfileを書く&lt;/h2&gt;
&lt;p&gt;本番で動作するDockerfileはこちら：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;dockerfile&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-dockerfile line-numbers&quot;&gt;&lt;code class=&quot;language-dockerfile&quot;&gt;&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; python:3.11-slim &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; base&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Python buffering can cause issues in containers&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ENV&lt;/span&gt; PYTHONUNBUFFERED=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PYTHONDONTWRITEBYTECODE=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PIP_NO_CACHE_DIR=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PIP_DISABLE_PIP_VERSION_CHECK=1&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;WORKDIR&lt;/span&gt; /app&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Install system dependencies&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; apt-get update &amp;amp;&amp;amp; apt-get install -y &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    gcc &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    postgresql-client &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Copy requirements first for better caching&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; requirements.txt .&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; pip install --no-cache-dir -r requirements.txt&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; . .&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Create non-root user for security&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; useradd -m -u 1000 flaskuser &amp;amp;&amp;amp; &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    chown -R flaskuser:flaskuser /app&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;USER&lt;/span&gt; flaskuser&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;EXPOSE&lt;/span&gt; 8080&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;CMD&lt;/span&gt; [&lt;span class=&quot;token string&quot;&gt;&quot;gunicorn&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;--bind&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0:8080&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;--workers&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;2&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;wsgi:app&quot;&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;順序が重要です。コードをコピーする前にrequirements.txtをコピーすることで、Dockerがpip installレイヤーをキャッシュできます。依存関係ではなくコードを変更すると、Dockerはすべてのパッケージがすでにインストールされたキャッシュレイヤーを再利用します。これにより5分のリビルドが10秒に変わります。&lt;/p&gt;
&lt;p&gt;非rootユーザーとして実行することはセキュリティのベストプラクティスです。誰かがアプリを侵害しても、コンテナへのroot権限は持っていません。&lt;/p&gt;
&lt;h2 id=&quot;ローカル開発用docker-compose&quot;&gt;ローカル開発用Docker Compose&lt;/h2&gt;
&lt;p&gt;Docker Composeを使用すると、複数のコンテナを一緒に実行できます。FlaskアプリをPostgreSQLとセットアップするdocker-compose.ymlはこちら：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;3.8&apos;&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;web&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; .
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;8080:8080&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; DATABASE_URL=postgresql&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//postgres&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;postgres@db&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;5432/flask_blog
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; SECRET_KEY=dev&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;secret&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;key
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; FLASK_ENV=development
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; .&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/app  &lt;span class=&quot;token comment&quot;&gt;# Mount your code for hot reloading&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; db
    &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; flask run &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;host=0.0.0.0 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;port=8080 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;reload

  &lt;span class=&quot;token key atrule&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; postgres&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;15&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;alpine
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_USER=postgres
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_PASSWORD=postgres
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_DB=flask_blog
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;5432:5432&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; postgres_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/var/lib/postgresql/data

&lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  postgres_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ボリュームマウント（&lt;code class=&quot;language-text&quot;&gt;.:/app&lt;/code&gt;）は、コンテナを再ビルドせずにコードへの変更が即座に反映されることを意味します。postgres_dataボリュームは、コンテナを停止してもデータベースが永続化されることを保証します。&lt;/p&gt;
&lt;p&gt;そのdepends_onは起動順序を制御するだけです。PostgreSQLが準備できるまで待ちません。そのため、最初の起動時にFlaskアプリがクラッシュするかもしれません。再起動してください。これは正常で、一度だけ起こります。&lt;/p&gt;
&lt;h2 id=&quot;すべてを実行する&quot;&gt;すべてを実行する&lt;/h2&gt;
&lt;p&gt;最初にイメージをビルドします：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; build&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;最初のビルドは、ベースイメージをダウンロードしてパッケージをインストールするため時間がかかります。後続のビルドはDockerのレイヤーキャッシングのおかげでずっと速くなります。&lt;/p&gt;
&lt;p&gt;データベースを開始します：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; up &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; db&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;まだであればデータベースマイグレーションを初期化します：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db init
&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db migrate &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial migration&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db upgrade&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;次にすべてを開始します：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; up&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;localhost:8080にアクセスすると、ブログが動作しているはずです。何か問題があれば、ログが正確に何がおかしいか教えてくれます。Dockerはすべてを表示します。これはエラーメッセージのない謎めいた本番障害よりずっと良いです。&lt;/p&gt;
&lt;p&gt;PostgreSQLのノイズなしでアプリのログだけを見るには、&lt;code class=&quot;language-text&quot;&gt;docker-compose logs -f web&lt;/code&gt;を使用します。&lt;/p&gt;
&lt;h2 id=&quot;flyioへのデプロイ&quot;&gt;Fly.ioへのデプロイ&lt;/h2&gt;
&lt;p&gt;Fly.ioは実際のDockerコンテナを実行します。解釈されたバージョンではありません。クレジットカード不要の無料ティアがあり、2025年には新鮮です。**&lt;a href=&quot;/blog/flyio-free-tier-guide/&quot;&gt;Fly.ioの無料ティアの機能と制限&lt;/a&gt;**についてのより詳細な説明（パフォーマンス比較とスケーリング戦略を含む）は、完全ガイドをご覧ください。&lt;/p&gt;
&lt;p&gt;最初にCLIをインストールします。&lt;/p&gt;
&lt;p&gt;Macでは：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flyctl&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Windowsでは、ウェブサイトからインストーラーをダウンロードするか、PowerShellを使用します：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;powershell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-powershell line-numbers&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;pwsh &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;Command &lt;span class=&quot;token string&quot;&gt;&quot;iwr https://fly.io/install.ps1 -useb | iex&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Linuxでは：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;flyctlをPATHに追加する必要があるかもしれません。インストーラーはこれが必要かどうかを教え、実行する正確なコマンドを表示します。&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;flyctl launch&lt;/code&gt;でアプリを起動します。尋ねられたら、アプリに名前を付けるか（または生成させる）、あなたまたはユーザーの近くのリージョンを選び、PostgreSQLにyesと言い（無料ティアにはdevelopmentを選択）、最初にシークレットを設定する必要があるのですぐにデプロイするにはnoと言います。&lt;/p&gt;
&lt;p&gt;これはデプロイメントを設定するfly.tomlファイルを作成します：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token key property&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;your-app-name&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;primary_region&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iad&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;8080&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;http_service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;internal_port&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;force_https&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;auto_stop_machines&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;auto_start_machines&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;min_machines_running&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;cpu_kind&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;shared&quot;&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;cpus&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;memory_mb&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;auto_stop_machines設定は、誰も使用していないときにアプリを停止し、無料ティアの制限内に収まるのに役立ちます。誰かが訪問すると自動的に再起動します。&lt;/p&gt;
&lt;p&gt;シークレットキーを設定します：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl secrets &lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;SECRET_KEY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;openssl rand &lt;span class=&quot;token parameter variable&quot;&gt;-hex&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;アプリをデプロイします：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これはDockerイメージをビルドしてデプロイします。約2分かかります。完了したら、データベースマイグレーションを実行します：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl &lt;span class=&quot;token function&quot;&gt;ssh&lt;/span&gt; console &lt;span class=&quot;token parameter variable&quot;&gt;-C&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;flask db upgrade&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;flyctl open&lt;/code&gt;でデプロイされたアプリを開きます。HTTPS、自動再起動、データベースバックアップ付きの本番Flaskアプリができました。サーバー設定は不要でした。&lt;/p&gt;
&lt;h2 id=&quot;一般的な問題と解決策&quot;&gt;一般的な問題と解決策&lt;/h2&gt;
&lt;p&gt;「ポートは既に使用中」と表示されたら、おそらく別のコンテナが実行中です。&lt;code class=&quot;language-text&quot;&gt;docker-compose down&lt;/code&gt;ですべてを停止するか、ポートを変更してください。Docker Desktopが混乱することがあり、再起動で修正されることがあります。&lt;/p&gt;
&lt;p&gt;起動時のデータベース接続エラーは、通常FlaskがPostgreSQLの準備ができる前に接続しようとしていることを意味します。Flaskコンテナを再起動してください。データベース接続コードにリトライロジックを追加できますが、ローカル開発では単純な再起動で十分です。&lt;/p&gt;
&lt;p&gt;Docker DesktopがDockerデーモンに接続できないと言ったら、Docker Desktopを再起動してください。それでも動かなければ、コンピュータを再起動してください。Docker Desktopには癖があります。&lt;/p&gt;
&lt;p&gt;Fly.ioの無料ティアは256MBのRAMを提供します。アプリがもっと必要なら、&lt;code class=&quot;language-text&quot;&gt;flyctl scale memory 512&lt;/code&gt;を実行してください。または、アプリを最適化してください。おそらくすべてを一度にメモリにロードする必要はありません。&lt;/p&gt;
&lt;p&gt;ローカルで変更が表示されない場合は、docker-compose.ymlのボリュームマウントを確認してください。本番では、&lt;code class=&quot;language-text&quot;&gt;flyctl deploy&lt;/code&gt;で再ビルドしてデプロイする必要があります。Dockerは本番ではコードの変更を自動的に検出しません。&lt;/p&gt;
&lt;h2 id=&quot;時間を節約するヒント&quot;&gt;時間を節約するヒント&lt;/h2&gt;
&lt;p&gt;Dockerイメージは巨大になる可能性があります。スリムなベースイメージを使用し、.dockerignoreファイルを追加してください：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;__pycache__
*.pyc
.git
.env
venv/
node_modules/
*.db
.DS_Store&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;アプリに適切なログを追加してください。本番で何かが壊れたとき、ログは何が起こったかへの唯一の窓です：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; logging
logging&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;basicConfig&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;level&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;logging&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;INFO&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;info&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;App starting up&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;今作成したDockerセットアップは、多くの企業が本番で使用しているものと同じです。これはおもちゃのセットアップではありません。たまたま無料のプロフェッショナルグレードのデプロイメントです。&lt;/p&gt;
&lt;h2 id=&quot;やりました&quot;&gt;やりました&lt;/h2&gt;
&lt;p&gt;Flask アプリケーションを本番データベース、ローカルホットリロード、ワンコマンドデプロイメントでコンテナ化することに成功しました。開発環境は今や本番と正確に一致し、デプロイメントバグのクラス全体を排除しました。&lt;/p&gt;
&lt;p&gt;これはプロフェッショナルチームが使用するのと同じワークフローです。同じDocker、同じデプロイメントプロセス、すべて同じです。趣味のプロジェクトと本番アプリケーションの間のギャップは、ほとんどの人が思っているより小さいです。それは主に正しいツールを知っているだけです。&lt;/p&gt;
&lt;h2 id=&quot;まずflaskアプリケーションを構築する&quot;&gt;まずFlaskアプリケーションを構築する&lt;/h2&gt;
&lt;p&gt;コンテナ化するFlaskブログがまだありませんか？ここから始めてください：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;FlaskでブログをЛuild&lt;/a&gt;&lt;/strong&gt; - PostgreSQLと認証機能を備えた完全なFlaskブログをゼロから作成&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Flaskでポートフォリオを構築&lt;/a&gt;&lt;/strong&gt; - プロフェッショナルなポートフォリオサイトでFlaskの基本を学ぶ&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;FlaskでEコマースを構築&lt;/a&gt;&lt;/strong&gt; - ショッピングカートと決済統合のフル機能でFlaskをマスター&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;各チュートリアルには、本番対応のFlaskアプリケーションを構築するためのステップバイステップのAIプロンプトが含まれています。アプリを構築したら、このガイドに戻ってコンテナ化してデプロイしてください。&lt;/p&gt;
&lt;p&gt;さあ、何か素晴らしいものを構築しましょう。&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Zdockeryzuj swojego bloga Flask: Kompletny przewodnik + wdrozenie na Fly.io]]></title><description><![CDATA[Naucz sie konteneryzowac aplikacje blogowa Flask z Docker i wdrazac na Fly.io. Obejmuje tworzenie Dockerfile, Docker Compose do lokalnego rozwoju, integracje PostgreSQL i wdrozenie produkcyjne. Dziala z kazda aplikacja Flask.]]></description><link>https://vibecodingwithfred.com/pl/blog/dockerize-flask-blog/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pl/blog/dockerize-flask-blog/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Mon, 20 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Ostatnio weryfikowane:&lt;/strong&gt; Pazdziernik 2025 | &lt;strong&gt;Docker:&lt;/strong&gt; 24.x | &lt;strong&gt;Flask:&lt;/strong&gt; 3.0.0 | &lt;strong&gt;PostgreSQL:&lt;/strong&gt; 15 | &lt;strong&gt;Python:&lt;/strong&gt; 3.11&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Wdrazanie jest frustrujace. Dostajesz aplikacje Flask dzialajaca idealnie na swoim komputerze, potem spedzasz godziny walczac z konfiguracja serwera, wersjami Pythona i brakujacymi zaleznosciami gdy probusjesz ja wdrozyc. Docker naprawia to przez pakowanie wszystkiego czego potrzebuje twoja aplikacja do kontenera ktory dziala tak samo wszedzie.&lt;/p&gt;
&lt;p&gt;Ten przewodnik pokazuje jak skonteneryzowac bloga Flask i wdrozyc go na Fly.io. Caly proces zajmuje okolo 15 minut gdy wiesz co robisz. Bez konfiguracji serwera, bez piekla zaleznosci, tylko twoja aplikacja dzialajaca w produkcji.&lt;/p&gt;
&lt;h2 id=&quot;dla-kogo-jest-ten-przewodnik&quot;&gt;Dla kogo jest ten przewodnik&lt;/h2&gt;
&lt;p&gt;Jesli masz aplikacje Flask ktora dziala lokalnie i chcesz ja wdrozyc bez zwyklych bolaczek, to jest dla ciebie. Moze jestes zmeczony debugowaniem dlaczego cos dziala na twoim laptopie ale psuje sie w produkcji. Moze chcesz uzywac nowoczesnych praktyk wdrazania bez spedzania tygodni na nauce DevOps.&lt;/p&gt;
&lt;p&gt;Bedziesz potrzebowal podstawowej znajomosci Pythona i Flask. Jesli zbudowales wczesniej aplikacje Flask, jestes gotowy. Powinienes byc komfortowy z linia polecen i bedziesz potrzebowal zainstalowanego Docker Desktop. To wszystko.&lt;/p&gt;
&lt;p&gt;Pod koniec bedziesz mial lokalne srodowisko developerskie ktore dokladnie odpowiada produkcji, wdrozenia ktore zajmuja minuty zamiast godzin, i zadnych wiecej konfliktow wersji Pythona.&lt;/p&gt;
&lt;h2 id=&quot;dlaczego-docker-pomaga&quot;&gt;Dlaczego Docker pomaga&lt;/h2&gt;
&lt;p&gt;Docker ma zla opinie za bycie zlozonym, ale glowna idea jest prosta: to pudelko dla twojego kodu. Twoja aplikacja idzie do pudelka ze wszystkim czego potrzebuje do dzialania. To pudelko dziala tak samo na twoim laptopie, na serwerach CI i w produkcji.&lt;/p&gt;
&lt;p&gt;Ta spojnosc eliminuje cale kategorie bledow. Koniec z dyskusjami &quot;ale na moim komputerze dziala&quot;. Koniec z odkrywaniem ze produkcja ma Pythona 3.8 gdy rozwijales na 3.11. Koniec z brakujacymi bibliotekami systemowymi ktore zapomniales udokumentowac.&lt;/p&gt;
&lt;p&gt;Prawdziwa wygrana to szybkosc wdrazania. Gdy masz dzialajaca konfiguracje Docker, wdrazanie staje sie trywialne. Wypchnij kod, zbuduj obraz, wdroz. Rollbacki sa rownie latwe: wdroz ponownie poprzedni obraz i wracasz do pracy w sekundy.&lt;/p&gt;
&lt;h2 id=&quot;co-budujemy&quot;&gt;Co budujemy&lt;/h2&gt;
&lt;p&gt;Wezmiemy twojego istniejacego bloga Flask i prawidlowo go skonteneryzujemy. Dostaniesz lokalne srodowisko developerskie z hot reloadingiem zeby widziec zmiany natychmiast. Uzyjemy PostgreSQL bo SQLite nie jest przeznaczony do produkcji, bez wzgledu na to co ktokolwiek ci mowi. Potem wdrozymy calosc na Fly.io bo maja hojny darmowy tier i uruchamiaja twoje kontenery Docker bez zmian.&lt;/p&gt;
&lt;h2 id=&quot;przygotowanie-aplikacji-flask&quot;&gt;Przygotowanie aplikacji Flask&lt;/h2&gt;
&lt;p&gt;Najpierw naprawmy twoj requirements.txt. Jesli twoj mowi tylko &quot;Flask&quot; bez numeru wersji, prosisz sie o klopotow. Oto czego potrzebujesz do produkcji:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;txt&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-txt line-numbers&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;Flask==3.0.0
Flask-SQLAlchemy==3.1.1
Flask-Migrate==4.0.5
psycopg2-binary==2.9.9
python-dotenv==1.0.0
gunicorn==21.2.0&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Wbudowany serwer Flask jest tylko do developmentu. Gunicorn to gotowy do produkcji serwer WSGI ktory moze obslugiwac prawdziwy ruch. Pakiet psycopg2-binary pozwala komunikowac sie z PostgreSQL. Wszystko ma numery wersji bo &quot;Flask&quot; bez wersji oznacza ze mozesz dostac rozne wersje w roznych srodowiskach, co niweczy caly sens.&lt;/p&gt;
&lt;p&gt;Utworz plik wsgi.py jako punkt wejscia aplikacji:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; app &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; create_app
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os

app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; create_app&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; __name__ &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;run&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        port&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;PORT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To host=&quot;0.0.0.0&quot; jest wazne. Oznacza &quot;nasluchuj na wszystkich interfejsach sieciowych&quot;. Domyslne 127.0.0.1 nasluchuje tylko lokalnie, co nie dziala wewnatrz kontenera. Ten drobny szczegol spowodowal godziny debugowania dla wielu programistow.&lt;/p&gt;
&lt;p&gt;Twoj config.py powinien uzywac zmiennych srodowiskowych dla wszystkiego wrazliwego:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; dotenv &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; load_dotenv

basedir &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;abspath&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dirname&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__file__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
load_dotenv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;basedir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.env&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    SECRET_KEY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;SECRET_KEY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dev-secret-key-change-in-production&apos;&lt;/span&gt;

    SQLALCHEMY_DATABASE_URI &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;DATABASE_URL&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; \
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;sqlite:///&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;basedir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;app.db&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;

    SQLALCHEMY_TRACK_MODIFICATIONS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Niektore uslugi uzywaja postgres:// ale SQLAlchemy potrzebuje postgresql://&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; SQLALCHEMY_DATABASE_URI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;startswith&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;postgres://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        SQLALCHEMY_DATABASE_URI &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; SQLALCHEMY_DATABASE_URI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;replace&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;postgres://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;postgresql://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Nigdy nie koduj na twardo sekretow. Uzyj zmiennych srodowiskowych. Twoje przyszle ja bedziesz ci wdzieczne gdy przypadkiem nie zacommiujesz hasla do produkcyjnej bazy danych na GitHub.&lt;/p&gt;
&lt;h2 id=&quot;pisanie-dockerfile-ktory-dziala&quot;&gt;Pisanie Dockerfile ktory dziala&lt;/h2&gt;
&lt;p&gt;Oto Dockerfile ktory dziala w produkcji:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;dockerfile&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-dockerfile line-numbers&quot;&gt;&lt;code class=&quot;language-dockerfile&quot;&gt;&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; python:3.11-slim &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; base&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Buforowanie Pythona moze powodowac problemy w kontenerach&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ENV&lt;/span&gt; PYTHONUNBUFFERED=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PYTHONDONTWRITEBYTECODE=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PIP_NO_CACHE_DIR=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PIP_DISABLE_PIP_VERSION_CHECK=1&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;WORKDIR&lt;/span&gt; /app&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Zainstaluj zaleznosci systemowe&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; apt-get update &amp;amp;&amp;amp; apt-get install -y &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    gcc &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    postgresql-client &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Skopiuj requirements najpierw dla lepszego cache&apos;owania&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; requirements.txt .&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; pip install --no-cache-dir -r requirements.txt&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; . .&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Utworz uzytkownika bez roota dla bezpieczenstwa&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; useradd -m -u 1000 flaskuser &amp;amp;&amp;amp; &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    chown -R flaskuser:flaskuser /app&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;USER&lt;/span&gt; flaskuser&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;EXPOSE&lt;/span&gt; 8080&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;CMD&lt;/span&gt; [&lt;span class=&quot;token string&quot;&gt;&quot;gunicorn&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;--bind&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0:8080&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;--workers&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;2&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;wsgi:app&quot;&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Kolejnosc ma tu znaczenie. Kopiowanie requirements.txt przed kopiowaniem kodu oznacza ze Docker moze cache&apos;owac warstwe pip install. Gdy zmienisz kod ale nie zaleznosci, Docker ponownie uzywa zcache&apos;owanej warstwy ze wszystkimi pakietami juz zainstalowanymi. To zamienia 5-minutowa przebudowe w 10-sekundowa.&lt;/p&gt;
&lt;p&gt;Uruchamianie jako uzytkownik bez roota to najlepsza praktyka bezpieczenstwa. Jesli ktos skompromituje twoja aplikacje, nie bedzie mial dostepu root do kontenera.&lt;/p&gt;
&lt;h2 id=&quot;docker-compose-do-lokalnego-developmentu&quot;&gt;Docker Compose do lokalnego developmentu&lt;/h2&gt;
&lt;p&gt;Docker Compose pozwala uruchamiac wiele kontenerow razem. Oto docker-compose.yml ktory konfiguruje twoja aplikacje Flask z PostgreSQL:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;3.8&apos;&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;web&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; .
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;8080:8080&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; DATABASE_URL=postgresql&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//postgres&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;postgres@db&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;5432/flask_blog
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; SECRET_KEY=dev&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;secret&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;key
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; FLASK_ENV=development
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; .&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/app  &lt;span class=&quot;token comment&quot;&gt;# Zamontuj kod dla hot reloading&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; db
    &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; flask run &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;host=0.0.0.0 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;port=8080 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;reload

  &lt;span class=&quot;token key atrule&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; postgres&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;15&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;alpine
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_USER=postgres
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_PASSWORD=postgres
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_DB=flask_blog
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;5432:5432&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; postgres_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/var/lib/postgresql/data

&lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  postgres_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Montowanie volumenu (&lt;code class=&quot;language-text&quot;&gt;.:/app&lt;/code&gt;) oznacza ze zmiany w kodzie sa odzwierciedlane natychmiast bez przebudowywania kontenera. Volumen postgres_data zapewnia ze twoja baza danych przetrwa nawet gdy zatrzymasz kontenery.&lt;/p&gt;
&lt;p&gt;Ten depends_on tylko kontroluje kolejnosc startu. Nie czeka az PostgreSQL bedzie gotowy, wiec twoja aplikacja Flask moze sie wysypac przy pierwszym starcie. Po prostu zrestartuj; to normalne i zdarza sie tylko raz.&lt;/p&gt;
&lt;h2 id=&quot;uruchamianie-wszystkiego&quot;&gt;Uruchamianie wszystkiego&lt;/h2&gt;
&lt;p&gt;Najpierw zbuduj obraz:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; build&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Pierwsza budowa trwa chwile gdy pobiera obrazy bazowe i instaluje pakiety. Kolejne budowy sa znacznie szybsze dzieki cache&apos;owaniu warstw Docker.&lt;/p&gt;
&lt;p&gt;Uruchom baze danych:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; up &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; db&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Zainicjalizuj migracje bazy danych jesli jeszcze tego nie zrobiles:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db init
&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db migrate &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial migration&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db upgrade&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Teraz uruchom wszystko:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; up&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Wejdz na localhost:8080 i twoj blog powinien dzialac. Jesli cos jest nie tak, logi powiedzac ci dokladnie co. Docker pokazuje wszystko, co jest znacznie lepsze niz tajemnicze awarie produkcyjne bez komunikatow o bledach.&lt;/p&gt;
&lt;p&gt;Zeby widziec tylko logi aplikacji bez szumu PostgreSQL, uzyj &lt;code class=&quot;language-text&quot;&gt;docker-compose logs -f web&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;wdrazanie-na-flyio&quot;&gt;Wdrazanie na Fly.io&lt;/h2&gt;
&lt;p&gt;Fly.io uruchamia twoj rzeczywisty kontener Docker, nie jakas zinterpretowana jego wersje. Maja darmowy tier ktory nie wymaga karty kredytowej, co jest odswiezajace w 2025 roku. Dla glebszego wgladu w &lt;strong&gt;&lt;a href=&quot;/blog/flyio-free-tier-guide/&quot;&gt;mozliwosci i ograniczenia darmowego tieru Fly.io&lt;/a&gt;&lt;/strong&gt;, wlaczajac porownania wydajnosci i strategie skalowania, sprawdz nasz kompletny przewodnik.&lt;/p&gt;
&lt;p&gt;Najpierw zainstaluj ich CLI.&lt;/p&gt;
&lt;p&gt;Na Mac:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flyctl&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Na Windows, pobierz instalator z ich strony lub uzyj PowerShell:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;powershell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-powershell line-numbers&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;pwsh &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;Command &lt;span class=&quot;token string&quot;&gt;&quot;iwr https://fly.io/install.ps1 -useb | iex&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Na Linux:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Moze byc konieczne dodanie flyctl do PATH. Instalator powie ci jesli to konieczne i pokaze dokladna komende do uruchomienia.&lt;/p&gt;
&lt;p&gt;Uruchom aplikacje z &lt;code class=&quot;language-text&quot;&gt;flyctl launch&lt;/code&gt;. Gdy zapyta, daj aplikacji nazwe (lub pozwol wygenerowac jedna), wybierz region blisko ciebie lub twoich uzytkownikow, powiedz tak na PostgreSQL (wybierz development dla darmowego tieru) i powiedz nie na natychmiastowe wdrazanie bo najpierw musimy ustawic sekrety.&lt;/p&gt;
&lt;p&gt;To tworzy plik fly.toml ktory konfiguruje twoje wdrozenie:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token key property&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;your-app-name&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;primary_region&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iad&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;8080&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;http_service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;internal_port&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;force_https&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;auto_stop_machines&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;auto_start_machines&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;min_machines_running&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;cpu_kind&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;shared&quot;&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;cpus&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;memory_mb&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ustawienie auto_stop_machines zatrzymuje twoja aplikacje gdy nikt jej nie uzywa, co pomaga pozostac w limitach darmowego tieru. Uruchamia sie ponownie automatycznie gdy ktos odwiedza.&lt;/p&gt;
&lt;p&gt;Ustaw klucz sekretny:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl secrets &lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;SECRET_KEY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;openssl rand &lt;span class=&quot;token parameter variable&quot;&gt;-hex&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Wdroz aplikacje:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To buduje twoj obraz Docker i wdraza go. Zajmuje okolo 2 minut. Gdy skonczy, uruchom migracje bazy danych:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl &lt;span class=&quot;token function&quot;&gt;ssh&lt;/span&gt; console &lt;span class=&quot;token parameter variable&quot;&gt;-C&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;flask db upgrade&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Otworz wdrozona aplikacje z &lt;code class=&quot;language-text&quot;&gt;flyctl open&lt;/code&gt;. Masz teraz produkcyjna aplikacje Flask z HTTPS, automatycznymi restartami i kopiami zapasowymi bazy danych. Bez konfiguracji serwera.&lt;/p&gt;
&lt;h2 id=&quot;typowe-problemy-i-rozwiazania&quot;&gt;Typowe problemy i rozwiazania&lt;/h2&gt;
&lt;p&gt;Gdy widzisz &quot;Port already in use&quot;, prawdopodobnie masz inny kontener dzialajacy. Uruchom &lt;code class=&quot;language-text&quot;&gt;docker-compose down&lt;/code&gt; zeby zatrzymac wszystko, lub po prostu zmien port. Czasami Docker Desktop sie gubi i restart to naprawia.&lt;/p&gt;
&lt;p&gt;Bledy polaczenia z baza danych przy starcie zwykle oznaczaja ze Flask probuje sie polaczyc zanim PostgreSQL jest gotowy. Po prostu zrestartuj kontener Flask. Moglbys dodac logike ponowien do kodu polaczenia z baza, ale do lokalnego developmentu prosty restart dziala dobrze.&lt;/p&gt;
&lt;p&gt;Jesli Docker Desktop mowi ze nie moze polaczyc sie z daemonem Docker, zrestartuj Docker Desktop. Jesli to nie pomoze, zrestartuj komputer. Docker Desktop ma swoje dziwastwa.&lt;/p&gt;
&lt;p&gt;Darmowy tier Fly.io daje ci 256MB RAM. Jesli twoja aplikacja potrzebuje wiecej, uruchom &lt;code class=&quot;language-text&quot;&gt;flyctl scale memory 512&lt;/code&gt;. Albo zoptymalizuj aplikacje; prawdopodobnie nie musisz ladowac wszystkiego do pamieci naraz.&lt;/p&gt;
&lt;p&gt;Gdy zmiany sie nie pojawiaja lokalnie, sprawdz montowanie volumenu w docker-compose.yml. W produkcji musisz przebudowac i wdrozyc z &lt;code class=&quot;language-text&quot;&gt;flyctl deploy&lt;/code&gt;. Docker nie wykrywa automatycznie zmian kodu w produkcji.&lt;/p&gt;
&lt;h2 id=&quot;wskazowki-ktore-oszczedzaja-czas&quot;&gt;Wskazowki ktore oszczedzaja czas&lt;/h2&gt;
&lt;p&gt;Obrazy Docker moga byc ogromne. Uzyj slim obrazow bazowych i dodaj plik .dockerignore:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;__pycache__
*.pyc
.git
.env
venv/
node_modules/
*.db
.DS_Store&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Dodaj prawidlowe logowanie do aplikacji. Gdy cos sie zepsuje w produkcji, logi sa twoim jedynym oknem na to co sie stalo:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; logging
logging&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;basicConfig&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;level&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;logging&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;INFO&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;info&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;App starting up&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Konfiguracja Docker ktora wlasnie utworzyles jest ta sama ktorej wiele firm uzywa w produkcji. To nie jest konfiguracja zabawkowa; to wdrazanie klasy profesjonalnej ktore akurat jest darmowe.&lt;/p&gt;
&lt;h2 id=&quot;udalo-ci-sie&quot;&gt;Udalo ci sie&lt;/h2&gt;
&lt;p&gt;Wlasnie skonteneryzowales aplikacje Flask z produkcyjna baza danych, lokalnym hot reloadingiem i wdrazaniem jednym poleceniem. Twoje srodowisko developerskie teraz dokladnie odpowiada produkcji, eliminujac cala klase bledow wdrazania.&lt;/p&gt;
&lt;p&gt;To jest ten sam workflow ktorego uzywaja profesjonalne zespoly. Ten sam Docker, ten sam proces wdrazania, to samo wszystko. Przepasc miedzy projektami hobbystycznymi a aplikacjami produkcyjnymi jest mniejsza niz wiekszsc ludzi mysli. To glownie kwestia znajomosci wlasciwych narzedzi.&lt;/p&gt;
&lt;h2 id=&quot;najpierw-zbuduj-aplikacje-flask&quot;&gt;Najpierw zbuduj aplikacje Flask&lt;/h2&gt;
&lt;p&gt;Nie masz jeszcze bloga Flask do zdockeryzowania? Zacznij tutaj:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Zbuduj bloga z Flask&lt;/a&gt;&lt;/strong&gt; - Utworz kompletnego bloga Flask od zera z PostgreSQL i uwierzytelnianiem&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Zbuduj portfolio z Flask&lt;/a&gt;&lt;/strong&gt; - Naucz sie podstaw Flask z profesjonalna strona portfolio&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Zbuduj e-commerce z Flask&lt;/a&gt;&lt;/strong&gt; - Opanuj Flask z pelnym koszykiem zakupowym i integracja platnosci&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Kazdy samouczek zawiera prompty AI krok po kroku ktore przeprowadza cie przez budowanie gotowych do produkcji aplikacji Flask. Gdy zbudujesz aplikacje, wroc do tego przewodnika zeby ja zdockeryzowac i wdrozyc.&lt;/p&gt;
&lt;p&gt;Teraz zbuduj cos fajnego.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Dockerize Seu Blog Flask: Guia Completo + Deploy no Fly.io]]></title><description><![CDATA[Aprenda a containerizar uma aplicacao de blog Flask com Docker e fazer deploy no Fly.io. Cobre criacao de Dockerfile, Docker Compose para desenvolvimento local, integracao com PostgreSQL e deploy em producao. Funciona com qualquer app Flask.]]></description><link>https://vibecodingwithfred.com/pt/blog/dockerize-flask-blog/</link><guid isPermaLink="false">https://vibecodingwithfred.com/pt/blog/dockerize-flask-blog/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Mon, 20 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Ultima verificacao:&lt;/strong&gt; Outubro 2025 | &lt;strong&gt;Docker:&lt;/strong&gt; 24.x | &lt;strong&gt;Flask:&lt;/strong&gt; 3.0.0 | &lt;strong&gt;PostgreSQL:&lt;/strong&gt; 15 | &lt;strong&gt;Python:&lt;/strong&gt; 3.11&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Deploy e frustrante. Voce consegue que seu app Flask funcione perfeitamente na sua maquina, depois passa horas lutando com configuracao de servidor, versoes de Python e dependencias faltando quando tenta fazer deploy. Docker resolve isso empacotando tudo que seu app precisa em um container que roda da mesma forma em todo lugar.&lt;/p&gt;
&lt;p&gt;Este guia mostra como containerizar um blog Flask e fazer deploy no Fly.io. Todo o processo leva cerca de 15 minutos quando voce sabe o que esta fazendo. Sem configuracao de servidor, sem inferno de dependencias, apenas seu app rodando em producao.&lt;/p&gt;
&lt;h2 id=&quot;para-quem-e-este-guia&quot;&gt;Para Quem e Este Guia&lt;/h2&gt;
&lt;p&gt;Se voce tem um app Flask que funciona localmente e quer fazer deploy sem as dores de cabeca usuais, isso e para voce. Talvez voce esteja cansado de debugar por que algo funciona no seu laptop mas quebra em producao. Talvez voce queira usar praticas modernas de deployment sem gastar semanas aprendendo DevOps.&lt;/p&gt;
&lt;p&gt;Voce vai precisar de conhecimento basico de Python e Flask. Se voce ja construiu um app Flask antes, esta pronto. Voce deve estar confortavel com a linha de comando, e vai precisar do Docker Desktop instalado. So isso.&lt;/p&gt;
&lt;p&gt;No final, voce tera desenvolvimento local que corresponde exatamente a producao, deploys que levam minutos em vez de horas, e sem mais conflitos de versao Python.&lt;/p&gt;
&lt;h2 id=&quot;por-que-docker-ajuda&quot;&gt;Por Que Docker Ajuda&lt;/h2&gt;
&lt;p&gt;Docker tem ma fama por ser complexo, mas a ideia central e simples: e uma caixa para seu codigo. Seu app vai na caixa com tudo que precisa para rodar. Essa caixa roda da mesma forma no seu laptop, em servidores de CI e em producao.&lt;/p&gt;
&lt;p&gt;Essa consistencia elimina categorias inteiras de bugs. Sem mais discussoes de &quot;mas funciona na minha maquina&quot;. Sem mais descobrir que producao tem Python 3.8 quando voce desenvolveu em 3.11. Sem mais bibliotecas de sistema faltando que voce esqueceu de documentar.&lt;/p&gt;
&lt;p&gt;A verdadeira vitoria e a velocidade de deploy. Uma vez que voce tem uma configuracao Docker funcionando, fazer deploy se torna trivial. Push do seu codigo, build da imagem, deploy. Rollbacks sao igualmente faceis: redeploy da imagem anterior e voce volta ao ar em segundos.&lt;/p&gt;
&lt;h2 id=&quot;o-que-estamos-construindo&quot;&gt;O Que Estamos Construindo&lt;/h2&gt;
&lt;p&gt;Vamos pegar seu blog Flask existente e containeriza-lo corretamente. Voce tera desenvolvimento local com hot reloading para ver mudancas instantaneamente. Usaremos PostgreSQL porque SQLite nao foi feito para producao, nao importa o que ninguem te diga. Depois faremos deploy de tudo no Fly.io porque eles tem um nivel gratuito generoso e rodam seus containers Docker como estao.&lt;/p&gt;
&lt;h2 id=&quot;preparando-seu-app-flask&quot;&gt;Preparando Seu App Flask&lt;/h2&gt;
&lt;p&gt;Primeiro, vamos arrumar seu requirements.txt. Se o seu apenas diz &quot;Flask&quot; sem numero de versao, voce esta pedindo por problemas. Aqui esta o que voce precisa para producao:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;txt&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-txt line-numbers&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;Flask==3.0.0
Flask-SQLAlchemy==3.1.1
Flask-Migrate==4.0.5
psycopg2-binary==2.9.9
python-dotenv==1.0.0
gunicorn==21.2.0&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;O servidor embutido do Flask e apenas para desenvolvimento. Gunicorn e um servidor WSGI pronto para producao que pode lidar com trafego real. O pacote psycopg2-binary permite comunicar com PostgreSQL. Tudo tem numeros de versao porque &quot;Flask&quot; sem versao significa que voce pode pegar versoes diferentes em ambientes diferentes, o que derrota todo o proposito.&lt;/p&gt;
&lt;p&gt;Crie um arquivo wsgi.py como ponto de entrada da sua aplicacao:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; app &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; create_app
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os

app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; create_app&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; __name__ &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;run&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        port&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;PORT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Aquele host=&quot;0.0.0.0&quot; e importante. Significa &quot;escutar em todas as interfaces de rede.&quot; O padrao 127.0.0.1 so escuta localmente, o que nao funciona dentro de um container. Esse detalhe minusculo causou horas de debugging para muitos desenvolvedores.&lt;/p&gt;
&lt;p&gt;Seu config.py deve usar variaveis de ambiente para qualquer coisa sensivel:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; dotenv &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; load_dotenv

basedir &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;abspath&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dirname&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__file__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
load_dotenv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;basedir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.env&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    SECRET_KEY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;SECRET_KEY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dev-secret-key-change-in-production&apos;&lt;/span&gt;

    SQLALCHEMY_DATABASE_URI &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;DATABASE_URL&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; \
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;sqlite:///&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;basedir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;app.db&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;

    SQLALCHEMY_TRACK_MODIFICATIONS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Alguns servicos usam postgres:// mas SQLAlchemy precisa postgresql://&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; SQLALCHEMY_DATABASE_URI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;startswith&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;postgres://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        SQLALCHEMY_DATABASE_URI &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; SQLALCHEMY_DATABASE_URI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;replace&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;postgres://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;postgresql://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Nunca hardcode secrets. Use variaveis de ambiente. Seu eu futuro vai agradecer quando voce nao commitar acidentalmente sua senha de banco de producao no GitHub.&lt;/p&gt;
&lt;h2 id=&quot;escrevendo-um-dockerfile-que-funciona&quot;&gt;Escrevendo um Dockerfile que Funciona&lt;/h2&gt;
&lt;p&gt;Aqui esta um Dockerfile que funciona em producao:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;dockerfile&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-dockerfile line-numbers&quot;&gt;&lt;code class=&quot;language-dockerfile&quot;&gt;&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; python:3.11-slim &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; base&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Buffer do Python pode causar problemas em containers&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ENV&lt;/span&gt; PYTHONUNBUFFERED=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PYTHONDONTWRITEBYTECODE=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PIP_NO_CACHE_DIR=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PIP_DISABLE_PIP_VERSION_CHECK=1&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;WORKDIR&lt;/span&gt; /app&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Instalar dependencias do sistema&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; apt-get update &amp;amp;&amp;amp; apt-get install -y &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    gcc &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    postgresql-client &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Copiar requirements primeiro para melhor cache&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; requirements.txt .&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; pip install --no-cache-dir -r requirements.txt&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; . .&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Criar usuario nao-root para seguranca&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; useradd -m -u 1000 flaskuser &amp;amp;&amp;amp; &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    chown -R flaskuser:flaskuser /app&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;USER&lt;/span&gt; flaskuser&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;EXPOSE&lt;/span&gt; 8080&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;CMD&lt;/span&gt; [&lt;span class=&quot;token string&quot;&gt;&quot;gunicorn&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;--bind&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0:8080&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;--workers&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;2&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;wsgi:app&quot;&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A ordem importa aqui. Copiar requirements.txt antes de copiar seu codigo significa que Docker pode cachear a camada de pip install. Quando voce muda seu codigo mas nao suas dependencias, Docker reutiliza a camada cacheada com todos seus pacotes ja instalados. Isso transforma um rebuild de 5 minutos em um de 10 segundos.&lt;/p&gt;
&lt;p&gt;Rodar como usuario nao-root e uma melhor pratica de seguranca. Se alguem comprometer seu app, nao tera acesso root ao container.&lt;/p&gt;
&lt;h2 id=&quot;docker-compose-para-desenvolvimento-local&quot;&gt;Docker Compose para Desenvolvimento Local&lt;/h2&gt;
&lt;p&gt;Docker Compose permite rodar multiplos containers juntos. Aqui esta um docker-compose.yml que configura seu app Flask com PostgreSQL:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;3.8&apos;&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;web&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; .
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;8080:8080&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; DATABASE_URL=postgresql&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//postgres&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;postgres@db&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;5432/flask_blog
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; SECRET_KEY=dev&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;secret&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;key
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; FLASK_ENV=development
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; .&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/app  &lt;span class=&quot;token comment&quot;&gt;# Monta seu codigo para hot reloading&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; db
    &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; flask run &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;host=0.0.0.0 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;port=8080 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;reload

  &lt;span class=&quot;token key atrule&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; postgres&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;15&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;alpine
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_USER=postgres
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_PASSWORD=postgres
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_DB=flask_blog
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;5432:5432&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; postgres_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/var/lib/postgresql/data

&lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  postgres_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A montagem de volume (&lt;code class=&quot;language-text&quot;&gt;.:/app&lt;/code&gt;) significa que mudancas no seu codigo sao refletidas imediatamente sem reconstruir o container. O volume postgres_data garante que seu banco persiste mesmo quando voce para os containers.&lt;/p&gt;
&lt;p&gt;Aquele depends_on apenas controla ordem de inicializacao. Ele nao espera PostgreSQL estar pronto, entao seu app Flask pode crashar na primeira inicializacao. Apenas reinicie; isso e normal e so acontece uma vez.&lt;/p&gt;
&lt;h2 id=&quot;rodando-tudo&quot;&gt;Rodando Tudo&lt;/h2&gt;
&lt;p&gt;Build sua imagem primeiro:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; build&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;O primeiro build demora um pouco pois baixa imagens base e instala pacotes. Builds subsequentes sao muito mais rapidos gracas ao cache de camadas do Docker.&lt;/p&gt;
&lt;p&gt;Inicie o banco de dados:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; up &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; db&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Inicialize suas migrations de banco se ainda nao fez:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db init
&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db migrate &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial migration&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db upgrade&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Agora inicie tudo:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; up&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Visite localhost:8080 e seu blog deve estar rodando. Se algo estiver errado, os logs vao te dizer exatamente o que. Docker mostra tudo, o que e muito melhor do que falhas misteriosas em producao sem mensagens de erro.&lt;/p&gt;
&lt;p&gt;Para ver apenas os logs do seu app sem o barulho do PostgreSQL, use &lt;code class=&quot;language-text&quot;&gt;docker-compose logs -f web&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;fazendo-deploy-no-flyio&quot;&gt;Fazendo Deploy no Fly.io&lt;/h2&gt;
&lt;p&gt;Fly.io roda seu container Docker real, nao alguma versao interpretada dele. Eles tem um nivel gratuito que nao requer cartao de credito, o que e revigorante em 2025. Para uma analise mais profunda das &lt;strong&gt;&lt;a href=&quot;/blog/flyio-free-tier-guide/&quot;&gt;capacidades e limitacoes do nivel gratuito do Fly.io&lt;/a&gt;&lt;/strong&gt;, incluindo comparacoes de performance e estrategias de escala, confira nosso guia completo.&lt;/p&gt;
&lt;p&gt;Instale a CLI deles primeiro.&lt;/p&gt;
&lt;p&gt;No Mac:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flyctl&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;No Windows, baixe o instalador do site deles ou use PowerShell:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;powershell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-powershell line-numbers&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;pwsh &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;Command &lt;span class=&quot;token string&quot;&gt;&quot;iwr https://fly.io/install.ps1 -useb | iex&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;No Linux:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Voce pode precisar adicionar flyctl ao seu PATH. O instalador vai te dizer se isso for necessario e mostrar o comando exato para rodar.&lt;/p&gt;
&lt;p&gt;Lance seu app com &lt;code class=&quot;language-text&quot;&gt;flyctl launch&lt;/code&gt;. Quando perguntar, de um nome ao seu app (ou deixe gerar um), escolha uma regiao proxima de voce ou seus usuarios, diga sim ao PostgreSQL (escolha development para o nivel gratuito), e diga nao para fazer deploy imediatamente porque precisamos configurar secrets primeiro.&lt;/p&gt;
&lt;p&gt;Isso cria um arquivo fly.toml que configura seu deployment:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token key property&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;your-app-name&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;primary_region&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iad&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;8080&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;http_service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;internal_port&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;force_https&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;auto_stop_machines&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;auto_start_machines&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;min_machines_running&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;cpu_kind&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;shared&quot;&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;cpus&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;memory_mb&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A configuracao auto_stop_machines para seu app quando ninguem esta usando, o que ajuda voce a ficar dentro dos limites do nivel gratuito. Ele inicia novamente automaticamente quando alguem visita.&lt;/p&gt;
&lt;p&gt;Configure sua secret key:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl secrets &lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;SECRET_KEY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;openssl rand &lt;span class=&quot;token parameter variable&quot;&gt;-hex&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Faca deploy do seu app:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Isso build sua imagem Docker e faz deploy. Leva cerca de 2 minutos. Quando terminar, rode suas migrations de banco:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl &lt;span class=&quot;token function&quot;&gt;ssh&lt;/span&gt; console &lt;span class=&quot;token parameter variable&quot;&gt;-C&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;flask db upgrade&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Abra seu app deployado com &lt;code class=&quot;language-text&quot;&gt;flyctl open&lt;/code&gt;. Voce agora tem um app Flask em producao com HTTPS, restarts automaticos e backups de banco de dados. Nenhuma configuracao de servidor necessaria.&lt;/p&gt;
&lt;h2 id=&quot;problemas-comuns-e-solucoes&quot;&gt;Problemas Comuns e Solucoes&lt;/h2&gt;
&lt;p&gt;Quando voce ve &quot;Port already in use&quot;, provavelmente tem outro container rodando. Rode &lt;code class=&quot;language-text&quot;&gt;docker-compose down&lt;/code&gt; para parar tudo, ou apenas mude a porta. As vezes Docker Desktop fica confuso e um restart resolve.&lt;/p&gt;
&lt;p&gt;Erros de conexao de banco na inicializacao geralmente significam que Flask esta tentando conectar antes do PostgreSQL estar pronto. Apenas reinicie o container Flask. Voce poderia adicionar logica de retry ao seu codigo de conexao de banco, mas para desenvolvimento local, um simples restart funciona bem.&lt;/p&gt;
&lt;p&gt;Se Docker Desktop diz que nao consegue conectar ao daemon Docker, reinicie Docker Desktop. Se isso nao funcionar, reinicie seu computador. Docker Desktop tem seus quirks.&lt;/p&gt;
&lt;p&gt;O nivel gratuito do Fly.io da 256MB de RAM. Se seu app precisar de mais, rode &lt;code class=&quot;language-text&quot;&gt;flyctl scale memory 512&lt;/code&gt;. Ou otimize seu app; voce provavelmente nao precisa carregar tudo na memoria de uma vez.&lt;/p&gt;
&lt;p&gt;Quando mudancas nao estao aparecendo localmente, verifique aquela montagem de volume no docker-compose.yml. Em producao, voce precisa rebuildar e fazer deploy com &lt;code class=&quot;language-text&quot;&gt;flyctl deploy&lt;/code&gt;. Docker nao detecta automaticamente mudancas de codigo em producao.&lt;/p&gt;
&lt;h2 id=&quot;dicas-que-economizam-tempo&quot;&gt;Dicas que Economizam Tempo&lt;/h2&gt;
&lt;p&gt;Imagens Docker podem ficar enormes. Use imagens base slim e adicione um arquivo .dockerignore:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;__pycache__
*.pyc
.git
.env
venv/
node_modules/
*.db
.DS_Store&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Adicione logging adequado ao seu app. Quando algo quebra em producao, logs sao sua unica janela para o que aconteceu:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; logging
logging&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;basicConfig&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;level&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;logging&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;INFO&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;info&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;App starting up&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A configuracao Docker que voce acabou de criar e a mesma que muitas empresas usam em producao. Isso nao e uma configuracao de brinquedo; e deployment de nivel profissional que por acaso e gratis.&lt;/p&gt;
&lt;h2 id=&quot;voce-conseguiu&quot;&gt;Voce Conseguiu&lt;/h2&gt;
&lt;p&gt;Voce containerizou com sucesso uma aplicacao Flask com um banco de dados de producao, hot reloading local e deploy com um comando. Seu ambiente de desenvolvimento agora corresponde a producao exatamente, eliminando uma classe inteira de bugs de deployment.&lt;/p&gt;
&lt;p&gt;Esse e o mesmo fluxo de trabalho que equipes profissionais usam. O mesmo Docker, o mesmo processo de deployment, o mesmo tudo. A lacuna entre projetos hobby e aplicacoes de producao e menor do que a maioria das pessoas pensa. E principalmente apenas saber as ferramentas certas.&lt;/p&gt;
&lt;h2 id=&quot;construa-sua-aplicacao-flask-primeiro&quot;&gt;Construa Sua Aplicacao Flask Primeiro&lt;/h2&gt;
&lt;p&gt;Ainda nao tem um blog Flask para dockerizar? Comece aqui:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;Construa um Blog com Flask&lt;/a&gt;&lt;/strong&gt; - Crie um blog Flask completo do zero com PostgreSQL e autenticacao&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;Construa um Portfolio com Flask&lt;/a&gt;&lt;/strong&gt; - Aprenda fundamentos do Flask com um site de portfolio profissional&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;Construa E-Commerce com Flask&lt;/a&gt;&lt;/strong&gt; - Domine Flask com um carrinho de compras completo e integracao de pagamento&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cada tutorial inclui prompts de IA passo a passo para guia-lo na construcao de aplicacoes Flask prontas para producao. Depois de construir seu app, volte a este guia para dockerizar e fazer deploy.&lt;/p&gt;
&lt;p&gt;Agora va construir algo legal.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Docker 化你的 Flask 博客：完整指南 + Fly.io 部署]]></title><description><![CDATA[学习使用 Docker 容器化 Flask 博客应用程序并部署到 Fly.io。涵盖 Dockerfile 创建、用于本地开发的 Docker Compose、PostgreSQL 集成和生产部署。适用于任何 Flask 应用。]]></description><link>https://vibecodingwithfred.com/zh/blog/dockerize-flask-blog/</link><guid isPermaLink="false">https://vibecodingwithfred.com/zh/blog/dockerize-flask-blog/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Mon, 20 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;**最后验证：**2025 年 10 月 | **Docker：**24.x | **Flask：**3.0.0 | **PostgreSQL：**15 | **Python：**3.11&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;部署是令人沮丧的。你在本地机器上让 Flask 应用完美运行，然后在尝试部署时花费数小时与服务器配置、Python 版本和缺失的依赖项作斗争。Docker 通过将应用所需的一切打包到一个容器中来解决这个问题，该容器在任何地方都以相同的方式运行。&lt;/p&gt;
&lt;p&gt;本指南向你展示如何容器化 Flask 博客并将其部署到 Fly.io。一旦你知道该怎么做，整个过程大约需要 15 分钟。无需服务器配置，无需依赖地狱，只是你的应用在生产环境中运行。&lt;/p&gt;
&lt;h2 id=&quot;本指南适合谁&quot;&gt;本指南适合谁&lt;/h2&gt;
&lt;p&gt;如果你有一个在本地运行的 Flask 应用，并且想要在没有通常麻烦的情况下部署它，这就是为你准备的。也许你厌倦了调试为什么某些东西在你的笔记本电脑上工作但在生产环境中崩溃。也许你想使用现代部署实践而不需要花费数周学习 DevOps。&lt;/p&gt;
&lt;p&gt;你需要基本的 Python 和 Flask 知识。如果你以前构建过 Flask 应用，你就准备好了。你应该熟悉命令行，并且需要安装 Docker Desktop。就这些。&lt;/p&gt;
&lt;p&gt;到最后，你将拥有与生产环境完全匹配的本地开发环境，部署只需几分钟而不是几小时，不再有 Python 版本冲突。&lt;/p&gt;
&lt;h2 id=&quot;为什么-docker-有帮助&quot;&gt;为什么 Docker 有帮助&lt;/h2&gt;
&lt;p&gt;Docker 因复杂而声名狼藉，但核心想法很简单：它是代码的盒子。你的应用与运行所需的一切一起放入盒子中。该盒子在你的笔记本电脑、CI 服务器和生产环境中以相同的方式运行。&lt;/p&gt;
&lt;p&gt;这种一致性消除了整个类别的 bug。不再有&quot;但它在我的机器上可以工作&quot;的讨论。不再发现生产环境有 Python 3.8 而你在 3.11 上开发。不再有你忘记记录的缺失系统库。&lt;/p&gt;
&lt;p&gt;真正的胜利是部署速度。一旦你有了可工作的 Docker 设置，部署变得微不足道。推送你的代码，构建镜像，部署。回滚同样简单：重新部署之前的镜像，几秒钟内你就恢复了业务。&lt;/p&gt;
&lt;h2 id=&quot;我们正在构建什么&quot;&gt;我们正在构建什么&lt;/h2&gt;
&lt;p&gt;我们将采用你现有的 Flask 博客并正确地容器化它。你将获得具有热重载的本地开发环境，以便你可以立即看到更改。我们将使用 PostgreSQL，因为 SQLite 不适合生产环境，无论任何人怎么说。然后我们将整个东西部署到 Fly.io，因为他们有慷慨的免费层级，并按原样运行你的 Docker 容器。&lt;/p&gt;
&lt;h2 id=&quot;准备你的-flask-应用&quot;&gt;准备你的 Flask 应用&lt;/h2&gt;
&lt;p&gt;首先，让我们修复你的 requirements.txt。如果你的文件只写&quot;Flask&quot;而没有版本号，你是在自找麻烦。以下是生产环境所需的内容：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;txt&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-txt line-numbers&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;Flask==3.0.0
Flask-SQLAlchemy==3.1.1
Flask-Migrate==4.0.5
psycopg2-binary==2.9.9
python-dotenv==1.0.0
gunicorn==21.2.0&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Flask 的内置服务器仅用于开发。Gunicorn 是一个可以处理真实流量的生产就绪 WSGI 服务器。psycopg2-binary 包让你与 PostgreSQL 通信。所有东西都有版本号，因为没有版本的&quot;Flask&quot;意味着你可能在不同环境中获得不同的版本，这违背了整个目的。&lt;/p&gt;
&lt;p&gt;创建一个 wsgi.py 文件作为应用入口点：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; app &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; create_app
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os

app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; create_app&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; __name__ &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;run&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        port&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;PORT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;那个 host=&quot;0.0.0.0&quot; 很重要。它意味着&quot;监听所有网络接口&quot;。默认的 127.0.0.1 只在本地监听，这在容器内不起作用。这个小细节让许多开发者花费数小时调试。&lt;/p&gt;
&lt;p&gt;你的 config.py 应该为任何敏感内容使用环境变量：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; dotenv &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; load_dotenv

basedir &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;abspath&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dirname&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__file__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
load_dotenv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;basedir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.env&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    SECRET_KEY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;SECRET_KEY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dev-secret-key-change-in-production&apos;&lt;/span&gt;

    SQLALCHEMY_DATABASE_URI &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;DATABASE_URL&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; \
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;sqlite:///&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;basedir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;app.db&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;

    SQLALCHEMY_TRACK_MODIFICATIONS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# 一些服务使用 postgres:// 但 SQLAlchemy 需要 postgresql://&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; SQLALCHEMY_DATABASE_URI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;startswith&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;postgres://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        SQLALCHEMY_DATABASE_URI &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; SQLALCHEMY_DATABASE_URI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;replace&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;postgres://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;postgresql://&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;永远不要硬编码密钥。使用环境变量。当你不小心将生产数据库密码提交到 GitHub 时，未来的你会感谢自己。&lt;/p&gt;
&lt;h2 id=&quot;编写一个有效的-dockerfile&quot;&gt;编写一个有效的 Dockerfile&lt;/h2&gt;
&lt;p&gt;这是一个在生产环境中有效的 Dockerfile：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;dockerfile&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-dockerfile line-numbers&quot;&gt;&lt;code class=&quot;language-dockerfile&quot;&gt;&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; python:3.11-slim &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; base&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Python 缓冲可能在容器中导致问题&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ENV&lt;/span&gt; PYTHONUNBUFFERED=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PYTHONDONTWRITEBYTECODE=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PIP_NO_CACHE_DIR=1 &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    PIP_DISABLE_PIP_VERSION_CHECK=1&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;WORKDIR&lt;/span&gt; /app&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 安装系统依赖&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; apt-get update &amp;amp;&amp;amp; apt-get install -y &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    gcc &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    postgresql-client &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 首先复制 requirements 以获得更好的缓存&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; requirements.txt .&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; pip install --no-cache-dir -r requirements.txt&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; . .&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 为安全创建非 root 用户&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; useradd -m -u 1000 flaskuser &amp;amp;&amp;amp; &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    chown -R flaskuser:flaskuser /app&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;USER&lt;/span&gt; flaskuser&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;EXPOSE&lt;/span&gt; 8080&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;CMD&lt;/span&gt; [&lt;span class=&quot;token string&quot;&gt;&quot;gunicorn&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;--bind&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0:8080&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;--workers&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;2&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;wsgi:app&quot;&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;顺序在这里很重要。在复制代码之前复制 requirements.txt 意味着 Docker 可以缓存 pip install 层。当你更改代码但不更改依赖项时，Docker 重用已安装所有包的缓存层。这将 5 分钟的重建变成 10 秒。&lt;/p&gt;
&lt;p&gt;以非 root 用户运行是安全最佳实践。如果有人攻破你的应用，他们将无法获得容器的 root 访问权限。&lt;/p&gt;
&lt;h2 id=&quot;用于本地开发的-docker-compose&quot;&gt;用于本地开发的 Docker Compose&lt;/h2&gt;
&lt;p&gt;Docker Compose 让你一起运行多个容器。这是一个设置 Flask 应用与 PostgreSQL 的 docker-compose.yml：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;3.8&apos;&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;web&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; .
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;8080:8080&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; DATABASE_URL=postgresql&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//postgres&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;postgres@db&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;5432/flask_blog
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; SECRET_KEY=dev&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;secret&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;key
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; FLASK_ENV=development
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; .&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/app  &lt;span class=&quot;token comment&quot;&gt;# 挂载你的代码以进行热重载&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; db
    &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; flask run &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;host=0.0.0.0 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;port=8080 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;reload

  &lt;span class=&quot;token key atrule&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; postgres&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;15&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;alpine
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_USER=postgres
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_PASSWORD=postgres
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; POSTGRES_DB=flask_blog
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;5432:5432&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; postgres_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/var/lib/postgresql/data

&lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  postgres_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;卷挂载 (&lt;code class=&quot;language-text&quot;&gt;.:/app&lt;/code&gt;) 意味着对代码的更改会立即反映而无需重建容器。postgres_data 卷确保即使在停止容器时数据库也会持久保存。&lt;/p&gt;
&lt;p&gt;那个 depends_on 只是控制启动顺序。它不会等待 PostgreSQL 准备好，所以你的 Flask 应用可能在首次启动时崩溃。只需重启它；这是正常的，只发生一次。&lt;/p&gt;
&lt;h2 id=&quot;运行一切&quot;&gt;运行一切&lt;/h2&gt;
&lt;p&gt;首先构建你的镜像：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; build&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;第一次构建需要一段时间，因为它下载基础镜像并安装包。由于 Docker 的层缓存，后续构建会快得多。&lt;/p&gt;
&lt;p&gt;启动数据库：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; up &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; db&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果尚未初始化数据库迁移：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db init
&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db migrate &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Initial migration&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; web flask db upgrade&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;现在启动一切：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; up&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;访问 localhost:8080，你的博客应该正在运行。如果出了问题，日志会准确告诉你是什么。Docker 向你显示一切，这比没有错误消息的神秘生产故障要好得多。&lt;/p&gt;
&lt;p&gt;要只查看你的应用日志而不包含 PostgreSQL 噪音，使用 &lt;code class=&quot;language-text&quot;&gt;docker-compose logs -f web&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&quot;部署到-flyio&quot;&gt;部署到 Fly.io&lt;/h2&gt;
&lt;p&gt;Fly.io 运行你的实际 Docker 容器，而不是某个解释版本。他们有一个不需要信用卡的免费层级，这在 2025 年是令人耳目一新的。有关 &lt;strong&gt;&lt;a href=&quot;/blog/flyio-free-tier-guide/&quot;&gt;Fly.io 免费层级功能和限制&lt;/a&gt;&lt;/strong&gt; 的更深入了解，包括性能比较和扩展策略，请查看我们的完整指南。&lt;/p&gt;
&lt;p&gt;首先安装他们的 CLI。&lt;/p&gt;
&lt;p&gt;在 Mac 上：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flyctl&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在 Windows 上，从他们的网站下载安装程序或使用 PowerShell：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;powershell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-powershell line-numbers&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;pwsh &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;Command &lt;span class=&quot;token string&quot;&gt;&quot;iwr https://fly.io/install.ps1 -useb | iex&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在 Linux 上：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://fly.io/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;你可能需要将 flyctl 添加到你的 PATH。如果需要，安装程序会告诉你并显示要运行的确切命令。&lt;/p&gt;
&lt;p&gt;使用 &lt;code class=&quot;language-text&quot;&gt;flyctl launch&lt;/code&gt; 启动你的应用。当它询问时，给你的应用一个名称（或让它生成一个），选择一个靠近你或你的用户的区域，对 PostgreSQL 说是（选择 development 以获得免费层级），并对立即部署说否，因为我们需要先设置密钥。&lt;/p&gt;
&lt;p&gt;这会创建一个配置你部署的 fly.toml 文件：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token key property&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;your-app-name&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;primary_region&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iad&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;8080&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;http_service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;internal_port&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;force_https&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;auto_stop_machines&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;auto_start_machines&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;min_machines_running&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;cpu_kind&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;shared&quot;&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;cpus&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;memory_mb&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;auto_stop_machines 设置会在没人使用时停止你的应用，这有助于你保持在免费层级限制内。当有人访问时它会自动重新启动。&lt;/p&gt;
&lt;p&gt;设置你的密钥：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl secrets &lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;SECRET_KEY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;openssl rand &lt;span class=&quot;token parameter variable&quot;&gt;-hex&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;部署你的应用：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这会构建你的 Docker 镜像并部署它。大约需要 2 分钟。完成后，运行数据库迁移：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl &lt;span class=&quot;token function&quot;&gt;ssh&lt;/span&gt; console &lt;span class=&quot;token parameter variable&quot;&gt;-C&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;flask db upgrade&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;使用 &lt;code class=&quot;language-text&quot;&gt;flyctl open&lt;/code&gt; 打开你部署的应用。你现在有一个具有 HTTPS、自动重启和数据库备份的生产 Flask 应用。无需服务器配置。&lt;/p&gt;
&lt;h2 id=&quot;常见问题和解决方案&quot;&gt;常见问题和解决方案&lt;/h2&gt;
&lt;p&gt;当你看到&quot;端口已在使用中&quot;时，你可能有另一个容器正在运行。运行 &lt;code class=&quot;language-text&quot;&gt;docker-compose down&lt;/code&gt; 停止一切，或者只是更改端口。有时 Docker Desktop 会混乱，重启可以修复它。&lt;/p&gt;
&lt;p&gt;启动时的数据库连接错误通常意味着 Flask 在 PostgreSQL 准备好之前就尝试连接。只需重启 Flask 容器。你可以为数据库连接代码添加重试逻辑，但对于本地开发，简单的重启就可以了。&lt;/p&gt;
&lt;p&gt;如果 Docker Desktop 说它无法连接到 Docker 守护进程，重启 Docker Desktop。如果那不起作用，重启你的计算机。Docker Desktop 有怪癖。&lt;/p&gt;
&lt;p&gt;Fly.io 免费层级给你 256MB 的 RAM。如果你的应用需要更多，运行 &lt;code class=&quot;language-text&quot;&gt;flyctl scale memory 512&lt;/code&gt;。或者优化你的应用；你可能不需要一次将所有内容加载到内存中。&lt;/p&gt;
&lt;p&gt;当本地更改没有显示时，检查 docker-compose.yml 中的卷挂载。在生产环境中，你需要使用 &lt;code class=&quot;language-text&quot;&gt;flyctl deploy&lt;/code&gt; 重建和部署。Docker 不会在生产环境中自动检测代码更改。&lt;/p&gt;
&lt;h2 id=&quot;节省时间的技巧&quot;&gt;节省时间的技巧&lt;/h2&gt;
&lt;p&gt;Docker 镜像可能变得很大。使用精简基础镜像并添加 .dockerignore 文件：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;__pycache__
*.pyc
.git
.env
venv/
node_modules/
*.db
.DS_Store&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;为你的应用添加适当的日志记录。当生产环境中出问题时，日志是你了解发生了什么的唯一窗口：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-python line-numbers&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; logging
logging&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;basicConfig&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;level&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;logging&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;INFO&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;info&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;App starting up&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;你刚创建的 Docker 设置与许多公司在生产环境中使用的相同。这不是玩具设置；这是恰好免费的专业级部署。&lt;/p&gt;
&lt;h2 id=&quot;你做到了&quot;&gt;你做到了&lt;/h2&gt;
&lt;p&gt;你已经成功地容器化了一个具有生产数据库、本地热重载和一键部署的 Flask 应用程序。你的开发环境现在与生产环境完全匹配，消除了整个类别的部署 bug。&lt;/p&gt;
&lt;p&gt;这是专业团队使用的相同工作流程。相同的 Docker，相同的部署过程，相同的一切。业余项目和生产应用程序之间的差距比大多数人想象的要小。主要是知道正确的工具。&lt;/p&gt;
&lt;h2 id=&quot;先构建你的-flask-应用程序&quot;&gt;先构建你的 Flask 应用程序&lt;/h2&gt;
&lt;p&gt;还没有要 Docker 化的 Flask 博客？从这里开始：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/blog-flask/&quot;&gt;使用 Flask 构建博客&lt;/a&gt;&lt;/strong&gt; - 从头开始创建一个完整的 Flask 博客，包括 PostgreSQL 和认证&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/portfolio-flask/&quot;&gt;使用 Flask 构建作品集&lt;/a&gt;&lt;/strong&gt; - 通过专业的作品集网站学习 Flask 基础知识&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/tutorials/shopping-flask/&quot;&gt;使用 Flask 构建电子商务&lt;/a&gt;&lt;/strong&gt; - 通过完整的购物车和支付集成掌握 Flask&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;每个教程都包含逐步的 AI 提示，指导你构建生产就绪的 Flask 应用程序。构建完应用后，回到本指南进行 Docker 化和部署。&lt;/p&gt;
&lt;p&gt;现在去构建一些很酷的东西吧。&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How to Deploy Your Static Site to Cloudflare Workers in 2025]]></title><description><![CDATA[Cloudflare Pages is deprecated. Here's the complete guide to deploying your static site using Cloudflare Workers and Wrangler CLI—no more Git-based deployments, just pure control.]]></description><link>https://vibecodingwithfred.com/blog/cloudflare-workers-deployment/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/cloudflare-workers-deployment/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sun, 19 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Last tested:&lt;/strong&gt; October 2025 | &lt;strong&gt;Wrangler:&lt;/strong&gt; 3.x | &lt;strong&gt;Node.js:&lt;/strong&gt; 20+ | &lt;strong&gt;Platform:&lt;/strong&gt; macOS/Linux/Windows&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you&apos;ve been deploying to Cloudflare Pages via their Git integration, you might have noticed a new deprecation message: &lt;strong&gt;Cloudflare deprecated Pages in April 2025.&lt;/strong&gt; They&apos;re pushing everyone to Cloudflare Workers instead.&lt;/p&gt;
&lt;p&gt;At first, this sounds annoying. Pages was dead simple—connect your repo, set a build command, done. Workers? That sounds like you need to write serverless functions and understand edge computing and... yeah, it can be intimidating if you don&apos;t know where to start.&lt;/p&gt;
&lt;p&gt;Here&apos;s the good news: &lt;strong&gt;deploying a static site to Workers is straightforward once you understand the workflow.&lt;/strong&gt; And you get more control over your deployments in the process.&lt;/p&gt;
&lt;p&gt;I just migrated my Gatsby blog from the old Pages flow to Workers. Here&apos;s everything I learned.&lt;/p&gt;
&lt;h2 id=&quot;a-complete-migration-path&quot;&gt;A Complete Migration Path&lt;/h2&gt;
&lt;p&gt;This guide gives you the exact steps to migrate your static site to Workers, with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Working code examples&lt;/strong&gt; tested on real production sites&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Common gotchas&lt;/strong&gt; and how to avoid them&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Performance comparisons&lt;/strong&gt; showing Workers is faster&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cost analysis&lt;/strong&gt; (spoiler: still free for most sites)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;why-cloudflare-killed-pages&quot;&gt;Why Cloudflare Killed Pages&lt;/h2&gt;
&lt;p&gt;Cloudflare&apos;s reasoning is pretty clear: Workers is their unified platform for edge computing. Instead of maintaining two separate systems (Pages for static sites, Workers for functions), they&apos;re consolidating everything into Workers.
And although it may take a couple years for Cloudflare to completely retire the Pages deployment, Workers will get all the new features and be actively supported; Pages won&apos;t.&lt;/p&gt;
&lt;p&gt;If you&apos;re starting a new project or migrating an existing one, Workers is the only path forward. Just for emphasis: I do not recommend deploying any new projects to Cloudflare Pages.&lt;/p&gt;
&lt;h2 id=&quot;what-you-need&quot;&gt;What You Need&lt;/h2&gt;
&lt;p&gt;Before we start, make sure you have:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;A static site&lt;/strong&gt; (Gatsby, Next.js static export, React build, Hugo, Astro)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Node.js 20+&lt;/strong&gt; installed&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A Cloudflare account&lt;/strong&gt; (free tier is fine)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wrangler CLI&lt;/strong&gt; (we&apos;ll install this)&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;step-1-install-wrangler&quot;&gt;Step 1: Install Wrangler&lt;/h2&gt;
&lt;p&gt;Wrangler is Cloudflare&apos;s command-line tool for deploying to Workers. Add it to your project:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-D&lt;/span&gt; wrangler&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or install it globally if you prefer:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; wrangler&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I recommend installing it as a dev dependency in your project so your team uses the same version.&lt;/p&gt;
&lt;h2 id=&quot;step-2-authenticate-wrangler&quot;&gt;Step 2: Authenticate Wrangler&lt;/h2&gt;
&lt;p&gt;Before you can deploy, you need to connect Wrangler to your Cloudflare account:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;npx wrangler login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This opens your browser and asks you to authorize Wrangler. Click &quot;Allow&quot; and you&apos;re set.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For CI/CD&lt;/strong&gt;, you&apos;ll need an API token instead (we&apos;ll cover that later).&lt;/p&gt;
&lt;h2 id=&quot;step-3-create-wranglertoml&quot;&gt;Step 3: Create wrangler.toml&lt;/h2&gt;
&lt;p&gt;Wrangler needs a configuration file at the root of your project. Create &lt;code class=&quot;language-text&quot;&gt;wrangler.toml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token key property&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;your-project-name&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;compatibility_date&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2025-10-19&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# This tells Wrangler where your static files are&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;pages_build_output_dir&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;public&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;bucket&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;./public&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Key fields:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;name&lt;/code&gt;: Your project name (becomes part of your Workers URL)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;compatibility_date&lt;/code&gt;: Locks your Workers runtime version&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;pages_build_output_dir&lt;/code&gt;: Where your static files live after building&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;bucket&lt;/code&gt;: Same thing, different syntax (both work)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For a Gatsby site, the output directory is &lt;code class=&quot;language-text&quot;&gt;public&lt;/code&gt;. For Next.js, it&apos;s &lt;code class=&quot;language-text&quot;&gt;out&lt;/code&gt;. For Create React App, it&apos;s &lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;step-4-build-your-site&quot;&gt;Step 4: Build Your Site&lt;/h2&gt;
&lt;p&gt;Nothing changes here. Run your normal build command:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Gatsby&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build

&lt;span class=&quot;token comment&quot;&gt;# Next.js (static export)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run &lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Create React App&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This generates your static files in your output directory.&lt;/p&gt;
&lt;h2 id=&quot;step-5-deploy-to-workers&quot;&gt;Step 5: Deploy to Workers&lt;/h2&gt;
&lt;p&gt;Here&apos;s the magic command:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;npx wrangler pages deploy public&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Replace &lt;code class=&quot;language-text&quot;&gt;public&lt;/code&gt; with whatever your output directory is.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;First deploy?&lt;/strong&gt; Wrangler will ask:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;✔ Enter the name of your new project: … your-site-name
✔ Enter the production branch name: … main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After that, Wrangler builds and deploys your site. You&apos;ll get a URL like:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;https://your-site-name.pages.dev&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Yes, it still uses the &lt;code class=&quot;language-text&quot;&gt;.pages.dev&lt;/code&gt; domain even though it&apos;s deployed via Workers. Cloudflare kept that naming for static sites.&lt;/p&gt;
&lt;h2 id=&quot;step-6-add-deploy-scripts-to-packagejson&quot;&gt;Step 6: Add Deploy Scripts to package.json&lt;/h2&gt;
&lt;p&gt;Typing &lt;code class=&quot;language-text&quot;&gt;npx wrangler pages deploy public&lt;/code&gt; every time is tedious. Add scripts to your &lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-json line-numbers&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;build&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;gatsby build&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;deploy&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;npm run build &amp;amp;&amp;amp; wrangler pages deploy public&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;deploy:prod&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;npm run build &amp;amp;&amp;amp; wrangler pages deploy public --branch=main&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now deploying is just:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;step-7-custom-domain-setup&quot;&gt;Step 7: Custom Domain Setup&lt;/h2&gt;
&lt;p&gt;Your &lt;code class=&quot;language-text&quot;&gt;.pages.dev&lt;/code&gt; URL works, but you probably want your own domain.&lt;/p&gt;
&lt;h3 id=&quot;option-1-through-cloudflare-dashboard-easiest&quot;&gt;Option 1: Through Cloudflare Dashboard (Easiest)&lt;/h3&gt;
&lt;p&gt;Once your first deployment succeeds, add your custom domain:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Log into your Cloudflare Dashboard at &lt;code class=&quot;language-text&quot;&gt;https://dash.cloudflare.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;In the left sidebar, click &lt;strong&gt;Workers &amp;#x26; Pages&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Find your project (e.g., &lt;code class=&quot;language-text&quot;&gt;vibe-coding-redo&lt;/code&gt;) and click on it&lt;/li&gt;
&lt;li&gt;Click the &lt;strong&gt;Custom domains&lt;/strong&gt; tab at the top&lt;/li&gt;
&lt;li&gt;Click the &lt;strong&gt;Set up a custom domain&lt;/strong&gt; button&lt;/li&gt;
&lt;li&gt;Enter your domain (e.g., &lt;code class=&quot;language-text&quot;&gt;vibecodingwithfred.com&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Continue&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Add another domain for &lt;code class=&quot;language-text&quot;&gt;www&lt;/code&gt; subdomain if needed (e.g., &lt;code class=&quot;language-text&quot;&gt;www.vibecodingwithfred.com&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Activate domain&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Important notes:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Your domain must already be on Cloudflare DNS (if it&apos;s not, add it to Cloudflare first)&lt;/li&gt;
&lt;li&gt;SSL certificates are automatically provisioned (usually takes 1-2 minutes)&lt;/li&gt;
&lt;li&gt;DNS records are automatically created&lt;/li&gt;
&lt;li&gt;If the domain was previously used on another Pages/Workers project, Cloudflare will automatically move it&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;option-2-via-wrangler&quot;&gt;Option 2: Via Wrangler&lt;/h3&gt;
&lt;p&gt;You can also configure domains in &lt;code class=&quot;language-text&quot;&gt;wrangler.toml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token key property&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;your-project-name&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;compatibility_date&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2025-10-19&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;routes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;pattern&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;yourdomain.com&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;zone_name&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;yourdomain.com&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;routes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;pattern&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;www.yourdomain.com&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;zone_name&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;yourdomain.com&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then run:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;npx wrangler pages deploy public&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Wrangler picks up the domain config and applies it.&lt;/p&gt;
&lt;h2 id=&quot;step-8-automatic-deployments-with-github-actions&quot;&gt;Step 8: Automatic Deployments with GitHub Actions&lt;/h2&gt;
&lt;p&gt;The old Pages flow auto-deployed when you pushed to &lt;code class=&quot;language-text&quot;&gt;main&lt;/code&gt;. We can recreate that with GitHub Actions.&lt;/p&gt;
&lt;p&gt;Create &lt;code class=&quot;language-text&quot;&gt;.github/workflows/deploy.yml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deploy to Cloudflare Workers

&lt;span class=&quot;token key atrule&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;branches&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; main

&lt;span class=&quot;token key atrule&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;deploy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ubuntu&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;latest
    &lt;span class=&quot;token key atrule&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Checkout
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/checkout@v4

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Setup Node
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/setup&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;node@v4
        &lt;span class=&quot;token key atrule&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;node-version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;20&apos;&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;npm&apos;&lt;/span&gt;

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Install dependencies
        &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm ci

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Build site
        &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm run build

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deploy to Cloudflare Workers
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cloudflare/wrangler&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;action@v3
        &lt;span class=&quot;token key atrule&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;apiToken&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; secrets.CLOUDFLARE_API_TOKEN &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;accountId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; secrets.CLOUDFLARE_ACCOUNT_ID &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pages deploy public &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;project&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;name=your&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;project&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;name&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;get-your-cloudflare-credentials&quot;&gt;Get Your Cloudflare Credentials&lt;/h3&gt;
&lt;p&gt;You need two things:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Account ID:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go to Cloudflare Dashboard&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Workers &amp;#x26; Pages&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Your Account ID is in the right sidebar&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;2. API Token:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go to &lt;strong&gt;My Profile&lt;/strong&gt; → &lt;strong&gt;API Tokens&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create Token&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Use the &lt;strong&gt;&quot;Edit Cloudflare Workers&quot;&lt;/strong&gt; template&lt;/li&gt;
&lt;li&gt;Copy the token (you only see it once!)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;add-secrets-to-github&quot;&gt;Add Secrets to GitHub&lt;/h3&gt;
&lt;p&gt;Go to your repo → &lt;strong&gt;Settings&lt;/strong&gt; → &lt;strong&gt;Secrets and variables&lt;/strong&gt; → &lt;strong&gt;Actions&lt;/strong&gt; → &lt;strong&gt;New repository secret&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Add:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;CLOUDFLARE_API_TOKEN&lt;/code&gt;: Your API token&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;CLOUDFLARE_ACCOUNT_ID&lt;/code&gt;: Your account ID&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now every push to &lt;code class=&quot;language-text&quot;&gt;main&lt;/code&gt; triggers a deployment automatically.&lt;/p&gt;
&lt;h2 id=&quot;handling-environment-variables&quot;&gt;Handling Environment Variables&lt;/h2&gt;
&lt;p&gt;If your build needs environment variables (like API keys), there are two approaches:&lt;/p&gt;
&lt;h3 id=&quot;option-1-build-time-variables-github-actions&quot;&gt;Option 1: Build-time Variables (GitHub Actions)&lt;/h3&gt;
&lt;p&gt;Add them to your workflow:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Build site
  &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm run build
  &lt;span class=&quot;token key atrule&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;SUPABASE_URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; secrets.SUPABASE_URL &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;SUPABASE_ANON_KEY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; secrets.SUPABASE_ANON_KEY &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;option-2-runtime-variables-workers&quot;&gt;Option 2: Runtime Variables (Workers)&lt;/h3&gt;
&lt;p&gt;For runtime secrets (like serverless function keys), use Wrangler:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;npx wrangler secret put MY_SECRET&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or in &lt;code class=&quot;language-text&quot;&gt;wrangler.toml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;PUBLIC_API_URL&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://api.example.com&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note: Don&apos;t put actual secrets in &lt;code class=&quot;language-text&quot;&gt;wrangler.toml&lt;/code&gt;—use &lt;code class=&quot;language-text&quot;&gt;wrangler secret&lt;/code&gt; for those.&lt;/p&gt;
&lt;h2 id=&quot;preview-deployments-branch-previews&quot;&gt;Preview Deployments (Branch Previews)&lt;/h2&gt;
&lt;p&gt;One of the best features of the old Pages was automatic preview deploys for every branch. You can replicate this:&lt;/p&gt;
&lt;p&gt;Update &lt;code class=&quot;language-text&quot;&gt;.github/workflows/deploy.yml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deploy to Cloudflare Workers

&lt;span class=&quot;token key atrule&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;branches&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; main
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; develop
  &lt;span class=&quot;token key atrule&quot;&gt;pull_request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;deploy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ubuntu&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;latest
    &lt;span class=&quot;token key atrule&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Checkout
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/checkout@v4

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Setup Node
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/setup&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;node@v4
        &lt;span class=&quot;token key atrule&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;node-version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;20&apos;&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;npm&apos;&lt;/span&gt;

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Install dependencies
        &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm ci

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Build site
        &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm run build

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deploy to Cloudflare Workers
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cloudflare/wrangler&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;action@v3
        &lt;span class=&quot;token key atrule&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;apiToken&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; secrets.CLOUDFLARE_API_TOKEN &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;accountId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; secrets.CLOUDFLARE_ACCOUNT_ID &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pages deploy public &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;project&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;name=your&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;project&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;name &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;branch=$&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; github.ref_name &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now every branch and PR gets its own preview URL:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;main&lt;/code&gt; → &lt;code class=&quot;language-text&quot;&gt;https://your-site.pages.dev&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;develop&lt;/code&gt; → &lt;code class=&quot;language-text&quot;&gt;https://develop.your-site.pages.dev&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;PR #42 → &lt;code class=&quot;language-text&quot;&gt;https://pr-42.your-site.pages.dev&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;common-issues-and-fixes&quot;&gt;Common Issues and Fixes&lt;/h2&gt;
&lt;h3 id=&quot;issue-1-dependency-conflicts&quot;&gt;Issue 1: Dependency Conflicts&lt;/h3&gt;
&lt;p&gt;If you&apos;re migrating from Pages and hit npm errors like:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;npm error ERESOLVE could not resolve&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Create &lt;code class=&quot;language-text&quot;&gt;.npmrc&lt;/code&gt; in your project root:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;legacy-peer-deps=true&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This tells npm to ignore peer dependency conflicts (common with older Gatsby plugins).&lt;/p&gt;
&lt;h3 id=&quot;issue-2-node-version-mismatch&quot;&gt;Issue 2: Node Version Mismatch&lt;/h3&gt;
&lt;p&gt;Workers uses Node 20+ by default. If your project needs a specific version, lock it:&lt;/p&gt;
&lt;p&gt;Create &lt;code class=&quot;language-text&quot;&gt;.nvmrc&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;20&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And &lt;code class=&quot;language-text&quot;&gt;.node-version&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;20&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Update &lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-json line-numbers&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;engines&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;node&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&gt;=18.0.0 &amp;lt;=20.x&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;issue-3-build-output-directory-wrong&quot;&gt;Issue 3: Build Output Directory Wrong&lt;/h3&gt;
&lt;p&gt;If Wrangler can&apos;t find your files:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;✖ No such directory &apos;public&apos;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Check your &lt;code class=&quot;language-text&quot;&gt;wrangler.toml&lt;/code&gt; and make sure &lt;code class=&quot;language-text&quot;&gt;pages_build_output_dir&lt;/code&gt; matches your actual build output.&lt;/p&gt;
&lt;h3 id=&quot;issue-4-authentication-fails-in-cicd&quot;&gt;Issue 4: Authentication Fails in CI/CD&lt;/h3&gt;
&lt;p&gt;If GitHub Actions fails with authentication errors, double-check:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Your API token has &lt;strong&gt;Edit Cloudflare Workers&lt;/strong&gt; permissions&lt;/li&gt;
&lt;li&gt;You added both &lt;code class=&quot;language-text&quot;&gt;CLOUDFLARE_API_TOKEN&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;CLOUDFLARE_ACCOUNT_ID&lt;/code&gt; as secrets&lt;/li&gt;
&lt;li&gt;The token hasn&apos;t expired&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;zero-downtime-migration-from-old-pages&quot;&gt;Zero-Downtime Migration from Old Pages&lt;/h2&gt;
&lt;p&gt;If you&apos;re migrating from the old Pages setup:&lt;/p&gt;
&lt;h3 id=&quot;strategy-1-deploy-to-a-new-workers-project&quot;&gt;Strategy 1: Deploy to a New Workers Project&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Set up Workers deployment with a different project name&lt;/li&gt;
&lt;li&gt;Test on the &lt;code class=&quot;language-text&quot;&gt;.pages.dev&lt;/code&gt; preview URL&lt;/li&gt;
&lt;li&gt;When ready, add your custom domain to the new project&lt;/li&gt;
&lt;li&gt;Cloudflare automatically moves the domain from old to new (instant switchover)&lt;/li&gt;
&lt;li&gt;Delete the old Pages project&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;strategy-2-gradual-rollover&quot;&gt;Strategy 2: Gradual Rollover&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Keep the old Pages deployment running&lt;/li&gt;
&lt;li&gt;Deploy to Workers with a staging domain&lt;/li&gt;
&lt;li&gt;Test thoroughly&lt;/li&gt;
&lt;li&gt;Update DNS to point to Workers&lt;/li&gt;
&lt;li&gt;Deprecate Pages after confirming everything works&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Recommended:&lt;/strong&gt; Strategy 1 is cleaner and has zero downtime.&lt;/p&gt;
&lt;h2 id=&quot;what-about-workers-functions&quot;&gt;What About Workers Functions?&lt;/h2&gt;
&lt;p&gt;This guide covered static site deployment, but Workers can do way more. If you need serverless functions (like API endpoints), you can add them. For media storage, check out our &lt;a href=&quot;/tutorials/r2-media-manager/&quot;&gt;R2 Media Manager tutorial&lt;/a&gt; to learn how to upload and serve files from Cloudflare R2.&lt;/p&gt;
&lt;p&gt;Create &lt;code class=&quot;language-text&quot;&gt;functions/api.js&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;onRequest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Hello from Workers!&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-property property&quot;&gt;&quot;Content-Type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;application/json&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Deploy with:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;npx wrangler pages deploy public&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Your API is now live at &lt;code class=&quot;language-text&quot;&gt;/api&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is beyond the scope of this guide, but it&apos;s one reason Cloudflare wants everyone on Workers—you get static sites AND serverless functions in one platform.&lt;/p&gt;
&lt;h2 id=&quot;deployment-checklist&quot;&gt;Deployment Checklist&lt;/h2&gt;
&lt;p&gt;Here&apos;s your complete setup checklist:&lt;/p&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Install Wrangler: &lt;code class=&quot;language-text&quot;&gt;npm install -D wrangler&lt;/code&gt;&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Create &lt;code class=&quot;language-text&quot;&gt;wrangler.toml&lt;/code&gt; with your config&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Authenticate: &lt;code class=&quot;language-text&quot;&gt;npx wrangler login&lt;/code&gt;&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Build your site: &lt;code class=&quot;language-text&quot;&gt;npm run build&lt;/code&gt;&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Test deploy: &lt;code class=&quot;language-text&quot;&gt;npx wrangler pages deploy public&lt;/code&gt;&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Add deploy scripts to &lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt;&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Set up GitHub Actions workflow&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Add &lt;code class=&quot;language-text&quot;&gt;CLOUDFLARE_API_TOKEN&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;CLOUDFLARE_ACCOUNT_ID&lt;/code&gt; secrets to GitHub&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Configure custom domain&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Test automatic deployments&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; (Optional) Set up preview deployments for branches/PRs&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-bottom-line&quot;&gt;The Bottom Line&lt;/h2&gt;
&lt;p&gt;Cloudflare killing Pages and forcing everyone to Workers feels like a step backward at first. The Git-based auto-deploy was &lt;em&gt;really&lt;/em&gt; convenient.&lt;/p&gt;
&lt;p&gt;But once you set up Wrangler and CI/CD, you get:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Full control&lt;/strong&gt; over when and how you deploy&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Faster deployments&lt;/strong&gt; (no waiting for Cloudflare&apos;s build queue)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Better debugging&lt;/strong&gt; (you can test builds locally before deploying)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Access to Workers features&lt;/strong&gt; (functions, KV storage, edge logic)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The initial setup takes 20 minutes. After that, it&apos;s just &lt;code class=&quot;language-text&quot;&gt;git push&lt;/code&gt; and GitHub Actions handles the rest—same experience as Pages, but with more power under the hood.&lt;/p&gt;
&lt;p&gt;And when you&apos;re ready to add serverless functions or edge logic to your static site, you&apos;re already on the right platform.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prefer a simpler deployment?&lt;/strong&gt; If you&apos;re primarily building Next.js sites and value zero-config deployments, &lt;strong&gt;&lt;a href=&quot;/blog/getting-started-vercel/&quot;&gt;Vercel offers an excellent alternative&lt;/a&gt;&lt;/strong&gt; with automatic Git integration and generous free tier limits.&lt;/p&gt;
&lt;h2 id=&quot;related-guides&quot;&gt;Related Guides&lt;/h2&gt;
&lt;p&gt;Before deploying to Workers, make sure your Cloudflare setup is complete:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/godaddy-to-cloudflare-dns/&quot;&gt;Move Your DNS from GoDaddy to Cloudflare&lt;/a&gt;&lt;/strong&gt; - Get your domain on Cloudflare first for the best performance and SSL support&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/cloudflare-dns-api/&quot;&gt;Manage DNS Records with the Cloudflare API&lt;/a&gt;&lt;/strong&gt; - Automate DNS management as part of your deployment pipeline&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/seo/seo-content-only-experiment/&quot;&gt;Content-Only SEO Experiment&lt;/a&gt;&lt;/strong&gt; - Testing whether a new site can rank with just content and no backlinks&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/workers/wrangler/&quot;&gt;Wrangler Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/workers/&quot;&gt;Cloudflare Workers Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/cloudflare/wrangler-action&quot;&gt;GitHub Actions for Wrangler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/pages/migrations/&quot;&gt;Migrating from Pages to Workers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Got questions about migrating to Workers? Hit me up in the comments or on Twitter. I just went through this migration myself, so the pain is fresh in my memory.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How to Move Your GoDaddy DNS to Cloudflare for Free SSL and DDoS Protection]]></title><description><![CDATA[Step-by-step guide to migrating your DNS from GoDaddy to Cloudflare to get free SSL certificates and DDoS protection without moving your domain registration.]]></description><link>https://vibecodingwithfred.com/blog/godaddy-to-cloudflare-dns/</link><guid isPermaLink="false">https://vibecodingwithfred.com/blog/godaddy-to-cloudflare-dns/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sun, 19 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;why-move-to-cloudflare-dns&quot;&gt;Why Move to Cloudflare DNS?&lt;/h2&gt;
&lt;p&gt;If you bought your domain through GoDaddy but want better performance and security features, switching to Cloudflare&apos;s DNS is a no-brainer. You get all of this for free:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Free SSL certificates&lt;/strong&gt; - Automatic HTTPS for your site&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DDoS protection&lt;/strong&gt; - Cloudflare shields your site from attacks&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Faster DNS resolution&lt;/strong&gt; - Cloudflare&apos;s global network is lightning fast&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Better analytics&lt;/strong&gt; - See traffic patterns and threats in real-time&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Free CDN&lt;/strong&gt; - Cache your static content globally&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The best part? You don&apos;t need to transfer your domain registration. Your domain stays with GoDaddy, you&apos;re just changing where the DNS is managed.&lt;/p&gt;
&lt;h2 id=&quot;what-youll-need&quot;&gt;What You&apos;ll Need&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Your domain registered at GoDaddy&lt;/li&gt;
&lt;li&gt;A free Cloudflare account (sign up at &lt;a href=&quot;https://cloudflare.com&quot;&gt;cloudflare.com&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;About 15-20 minutes&lt;/li&gt;
&lt;li&gt;Access to your GoDaddy account&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;understanding-the-process&quot;&gt;Understanding the Process&lt;/h2&gt;
&lt;p&gt;Here&apos;s what we&apos;re doing in plain English:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Export DNS records from GoDaddy&lt;/strong&gt; - We&apos;ll grab your existing DNS settings&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Add your domain to Cloudflare&lt;/strong&gt; - Cloudflare will scan and import your DNS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Update nameservers at GoDaddy&lt;/strong&gt; - Point your domain to Cloudflare&apos;s nameservers&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Verify and activate&lt;/strong&gt; - Wait for DNS propagation (usually under an hour)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Your domain registration stays with GoDaddy. You&apos;re only changing who manages your DNS records.&lt;/p&gt;
&lt;h2 id=&quot;step-1-export-your-dns-records-from-godaddy&quot;&gt;Step 1: Export Your DNS Records from GoDaddy&lt;/h2&gt;
&lt;p&gt;Before we move anything, let&apos;s see what DNS records you currently have. This is important so we don&apos;t break anything.&lt;/p&gt;
&lt;h3 id=&quot;view-your-current-dns-records&quot;&gt;View Your Current DNS Records&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Log into GoDaddy&lt;/strong&gt; at &lt;a href=&quot;https://godaddy.com&quot;&gt;godaddy.com&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Navigate to your domains:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Click on your profile icon (top right)&lt;/li&gt;
&lt;li&gt;Select &quot;My Products&quot;&lt;/li&gt;
&lt;li&gt;Find your domain in the list&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Open DNS Management:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Click the DNS button next to your domain&lt;/li&gt;
&lt;li&gt;Or click the three dots (...) and select &quot;Manage DNS&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Review your records:&lt;/strong&gt;
You&apos;ll see a table with entries like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A Records&lt;/strong&gt; - Point to IP addresses (like 192.168.1.1)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CNAME Records&lt;/strong&gt; - Aliases (like www pointing to your main domain)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MX Records&lt;/strong&gt; - Mail servers&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TXT Records&lt;/strong&gt; - Verification codes, SPF records&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NS Records&lt;/strong&gt; - Nameservers (we&apos;ll change these later)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;document-your-records-optional-but-recommended&quot;&gt;Document Your Records (Optional but Recommended)&lt;/h3&gt;
&lt;p&gt;Take a screenshot or write down your current DNS records. You&apos;ll need this information to verify everything transferred correctly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example of what you might see:&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;TTL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;192.0.2.1&lt;/td&gt;
&lt;td&gt;600&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CNAME&lt;/td&gt;
&lt;td&gt;www&lt;/td&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;1 Hour&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MX&lt;/td&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;mailhost.example.com&lt;/td&gt;
&lt;td&gt;1 Hour&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TXT&lt;/td&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;v=spf1 include:_spf.google.com ~all&lt;/td&gt;
&lt;td&gt;1 Hour&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Important records to note:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A record (@)&lt;/strong&gt; - Your main domain&apos;s IP address&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CNAME (www)&lt;/strong&gt; - Usually points to your root domain&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MX records&lt;/strong&gt; - If you use custom email (like Google Workspace or Microsoft 365)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TXT records&lt;/strong&gt; - Often used for email authentication (SPF, DKIM)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;step-2-add-your-domain-to-cloudflare&quot;&gt;Step 2: Add Your Domain to Cloudflare&lt;/h2&gt;
&lt;p&gt;Now let&apos;s get your domain set up on Cloudflare.&lt;/p&gt;
&lt;h3 id=&quot;create-a-cloudflare-account&quot;&gt;Create a Cloudflare Account&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Go to &lt;a href=&quot;https://cloudflare.com&quot;&gt;cloudflare.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sign up for a free account:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Click &quot;Sign Up&quot;&lt;/li&gt;
&lt;li&gt;Enter your email and create a password&lt;/li&gt;
&lt;li&gt;Verify your email address&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Add your domain:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;On the dashboard, click &quot;Add a Site&quot;&lt;/li&gt;
&lt;li&gt;Enter your domain name (example.com)&lt;/li&gt;
&lt;li&gt;Click &quot;Add Site&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;choose-the-free-plan&quot;&gt;Choose the Free Plan&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Cloudflare will show you plan options&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Select the Free plan&lt;/strong&gt; (it&apos;s more than enough for most sites)&lt;/li&gt;
&lt;li&gt;Click &quot;Continue&quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;review-scanned-dns-records&quot;&gt;Review Scanned DNS Records&lt;/h3&gt;
&lt;p&gt;Cloudflare automatically scans your existing DNS records from GoDaddy:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare will display all DNS records it found&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Review these carefully&lt;/li&gt;
&lt;li&gt;Compare with your GoDaddy records from Step 1&lt;/li&gt;
&lt;li&gt;Look for any missing records&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Verify critical records are present:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Your A record for the root domain (@)&lt;/li&gt;
&lt;li&gt;www CNAME record&lt;/li&gt;
&lt;li&gt;MX records (if you use email)&lt;/li&gt;
&lt;li&gt;Any custom subdomains you&apos;ve set up&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Add any missing records manually:&lt;/strong&gt;
If Cloudflare missed something, click &quot;Add Record&quot; and enter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;/strong&gt;: A, CNAME, MX, TXT, etc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Name&lt;/strong&gt;: @ for root, www for www subdomain, or custom subdomain&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Content&lt;/strong&gt;: IP address, domain name, or other value&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TTL&lt;/strong&gt;: Auto is fine&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Proxy status&lt;/strong&gt;: Orange cloud for web traffic, gray for DNS-only&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Click &quot;Continue&quot;&lt;/strong&gt; when everything looks correct&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;quick-reference-cloudflare-proxy-status&quot;&gt;Quick Reference: Cloudflare Proxy Status&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Orange Cloud (Proxied)&lt;/strong&gt;: Traffic goes through Cloudflare&apos;s CDN and DDoS protection. Use this for web servers (HTTP/HTTPS).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gray Cloud (DNS Only)&lt;/strong&gt;: Direct connection, bypasses Cloudflare. Use this for mail servers, FTP, SSH, game servers, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Default settings:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A records for web traffic: Orange cloud (proxied)&lt;/li&gt;
&lt;li&gt;MX records: Automatically gray (Cloudflare forces this)&lt;/li&gt;
&lt;li&gt;Mail-related records: Gray cloud (DNS only)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;step-3-update-nameservers-in-godaddy&quot;&gt;Step 3: Update Nameservers in GoDaddy&lt;/h2&gt;
&lt;p&gt;This is the critical step where we point your domain to Cloudflare.&lt;/p&gt;
&lt;h3 id=&quot;get-your-cloudflare-nameservers&quot;&gt;Get Your Cloudflare Nameservers&lt;/h3&gt;
&lt;p&gt;After adding DNS records, Cloudflare will show you two nameservers. They&apos;ll look like:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;aldo.ns.cloudflare.com
beatriz.ns.cloudflare.com&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Write these down or keep the browser tab open.&lt;/strong&gt; You&apos;ll need them in a moment.&lt;/p&gt;
&lt;h3 id=&quot;change-nameservers-in-godaddy&quot;&gt;Change Nameservers in GoDaddy&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Go back to GoDaddy&lt;/strong&gt; (keep the Cloudflare tab open)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Navigate to Domain Settings:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go to &quot;My Products&quot;&lt;/li&gt;
&lt;li&gt;Find your domain&lt;/li&gt;
&lt;li&gt;Click the three dots (...) next to your domain&lt;/li&gt;
&lt;li&gt;Select &quot;Manage DNS&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Scroll down to the Nameservers section:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You&apos;ll see &quot;Nameservers&quot; with current values (usually GoDaddy&apos;s nameservers)&lt;/li&gt;
&lt;li&gt;Click &quot;Change&quot; or &quot;Manage&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Select &quot;I&apos;ll use my own nameservers&quot;:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GoDaddy might show this as &quot;Custom&quot; or &quot;Enter my own nameservers&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enter Cloudflare&apos;s nameservers:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Replace the existing nameservers with the two from Cloudflare&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Example:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Nameserver 1: &lt;code class=&quot;language-text&quot;&gt;aldo.ns.cloudflare.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Nameserver 2: &lt;code class=&quot;language-text&quot;&gt;beatriz.ns.cloudflare.com&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Delete any additional nameservers (you only need 2)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Save changes:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Click &quot;Save&quot;&lt;/li&gt;
&lt;li&gt;GoDaddy may show a warning about losing DNS settings - that&apos;s expected&lt;/li&gt;
&lt;li&gt;Confirm the change&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;what-just-happened&quot;&gt;What Just Happened?&lt;/h3&gt;
&lt;p&gt;You just told the internet: &quot;When someone asks for example.com, go ask Cloudflare instead of GoDaddy for the DNS records.&quot;&lt;/p&gt;
&lt;p&gt;Your domain is still registered with GoDaddy. You&apos;re still paying GoDaddy for the domain registration. But now Cloudflare handles all the DNS lookups.&lt;/p&gt;
&lt;h2 id=&quot;step-4-verify-and-activate-in-cloudflare&quot;&gt;Step 4: Verify and Activate in Cloudflare&lt;/h2&gt;
&lt;p&gt;Now we wait for the internet to catch up.&lt;/p&gt;
&lt;h3 id=&quot;confirm-the-nameserver-change&quot;&gt;Confirm the Nameserver Change&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Go back to your Cloudflare tab&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Click &quot;Done, check nameservers&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Cloudflare will begin checking if the nameservers have been updated&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;wait-for-dns-propagation&quot;&gt;Wait for DNS Propagation&lt;/h3&gt;
&lt;p&gt;This is the boring part. DNS changes can take anywhere from &lt;strong&gt;a few minutes to 24 hours&lt;/strong&gt; to propagate worldwide. In practice, most changes happen within &lt;strong&gt;30 minutes to 2 hours&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What&apos;s happening:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DNS servers around the world are updating their cached information&lt;/li&gt;
&lt;li&gt;Some will pick up the change quickly, others take longer&lt;/li&gt;
&lt;li&gt;Your site might work for you but not for someone else temporarily&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;check-activation-status&quot;&gt;Check Activation Status&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare will send you an email&lt;/strong&gt; when your site is active (usually within an hour)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Check status in Cloudflare dashboard:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go to your Cloudflare dashboard&lt;/li&gt;
&lt;li&gt;Look for your domain&lt;/li&gt;
&lt;li&gt;Status will change from &quot;Pending&quot; to &quot;Active&quot; when complete&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Manual check (optional):&lt;/strong&gt;
You can verify nameservers yourself using a terminal:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Check nameservers (Mac/Linux/WSL)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; NS example.com +short

&lt;span class=&quot;token comment&quot;&gt;# Windows (PowerShell)&lt;/span&gt;
Resolve-DnsName example.com &lt;span class=&quot;token parameter variable&quot;&gt;-Type&lt;/span&gt; NS&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You should see Cloudflare&apos;s nameservers in the results.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;step-5-enable-ssltls-in-cloudflare&quot;&gt;Step 5: Enable SSL/TLS in Cloudflare&lt;/h2&gt;
&lt;p&gt;Once your domain is active, let&apos;s turn on that free SSL.&lt;/p&gt;
&lt;h3 id=&quot;configure-ssltls-settings&quot;&gt;Configure SSL/TLS Settings&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;In Cloudflare dashboard, select your domain&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Go to SSL/TLS section&lt;/strong&gt; (left sidebar)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Choose encryption mode:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Flexible&lt;/strong&gt;: Cloudflare to visitor is encrypted, Cloudflare to your server is not
&lt;ul&gt;
&lt;li&gt;Use this if your server doesn&apos;t have SSL&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Full&lt;/strong&gt;: Encrypts both connections but doesn&apos;t validate your server&apos;s certificate
&lt;ul&gt;
&lt;li&gt;Use this if your server has a self-signed certificate&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Full (Strict)&lt;/strong&gt;: Full encryption with certificate validation
&lt;ul&gt;
&lt;li&gt;Use this if your server already has a valid SSL certificate&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Recommendation:&lt;/strong&gt; Start with &quot;Flexible&quot; if you don&apos;t have SSL on your server yet. Upgrade to &quot;Full (Strict)&quot; once you install an SSL certificate on your hosting.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enable &quot;Always Use HTTPS&quot;:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go to SSL/TLS → Edge Certificates&lt;/li&gt;
&lt;li&gt;Toggle &quot;Always Use HTTPS&quot; to ON&lt;/li&gt;
&lt;li&gt;This automatically redirects http:// to https://&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;enable-other-security-features-optional&quot;&gt;Enable Other Security Features (Optional)&lt;/h3&gt;
&lt;p&gt;While you&apos;re in Cloudflare:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Automatic HTTPS Rewrites:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SSL/TLS → Edge Certificates&lt;/li&gt;
&lt;li&gt;Toggle &quot;Automatic HTTPS Rewrites&quot; ON&lt;/li&gt;
&lt;li&gt;Fixes mixed content warnings&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Minimum TLS Version:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Set to TLS 1.2 or higher&lt;/li&gt;
&lt;li&gt;Disables old, insecure protocols&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enable HSTS&lt;/strong&gt; (once you&apos;re confident everything works):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SSL/TLS → Edge Certificates → Enable HSTS&lt;/li&gt;
&lt;li&gt;Forces browsers to always use HTTPS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Warning:&lt;/strong&gt; Only enable this after testing thoroughly&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;verify-everything-works&quot;&gt;Verify Everything Works&lt;/h2&gt;
&lt;p&gt;Let&apos;s make sure we didn&apos;t break anything.&lt;/p&gt;
&lt;h3 id=&quot;test-your-website&quot;&gt;Test Your Website&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Visit your website&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;https://example.com&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Should load over HTTPS (look for the padlock icon)&lt;/li&gt;
&lt;li&gt;No certificate warnings&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Test www version&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;https://www.example.com&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Should also work with HTTPS&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Test HTTP redirect&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;http://example.com&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Should automatically redirect to HTTPS version&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;test-email-if-applicable&quot;&gt;Test Email (If Applicable)&lt;/h3&gt;
&lt;p&gt;If you use custom email with your domain:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Send a test email&lt;/strong&gt; from your domain&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Receive a test email&lt;/strong&gt; to your domain&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Check email doesn&apos;t go to spam&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If email breaks, verify your MX records in Cloudflare match what you had in GoDaddy.&lt;/p&gt;
&lt;h3 id=&quot;check-dns-resolution&quot;&gt;Check DNS Resolution&lt;/h3&gt;
&lt;p&gt;Use online tools to verify DNS is working:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;WhatsMyDNS&lt;/strong&gt;: &lt;a href=&quot;https://whatsmydns.net&quot;&gt;whatsmydns.net&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enter your domain&lt;/li&gt;
&lt;li&gt;Select &quot;A&quot; record type&lt;/li&gt;
&lt;li&gt;Check propagation worldwide&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;DNS Checker&lt;/strong&gt;: &lt;a href=&quot;https://dnschecker.org&quot;&gt;dnschecker.org&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enter your domain&lt;/li&gt;
&lt;li&gt;See global DNS propagation status&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;troubleshooting-common-issues&quot;&gt;Troubleshooting Common Issues&lt;/h2&gt;
&lt;h3 id=&quot;website-shows-error-522-or-error-521&quot;&gt;Website Shows &quot;Error 522&quot; or &quot;Error 521&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Cloudflare can&apos;t connect to your server.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solutions:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Verify your A record points to the correct IP address&lt;/li&gt;
&lt;li&gt;Check if your hosting firewall is blocking Cloudflare&lt;/li&gt;
&lt;li&gt;Whitelist Cloudflare&apos;s IP ranges in your server firewall&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;ssl-certificate-errors&quot;&gt;SSL Certificate Errors&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Browser shows &quot;Your connection is not private&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solutions:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Wait 30 minutes - Cloudflare is still generating your certificate&lt;/li&gt;
&lt;li&gt;Check SSL/TLS mode - try &quot;Flexible&quot; if &quot;Full&quot; doesn&apos;t work&lt;/li&gt;
&lt;li&gt;Clear your browser cache and try incognito/private mode&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;email-stopped-working&quot;&gt;Email Stopped Working&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Can&apos;t send or receive emails&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solutions:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Check MX records in Cloudflare match GoDaddy&apos;s original records&lt;/li&gt;
&lt;li&gt;Verify MX records are &lt;strong&gt;gray cloud (DNS only)&lt;/strong&gt;, not proxied&lt;/li&gt;
&lt;li&gt;Check SPF and DKIM TXT records were copied correctly&lt;/li&gt;
&lt;li&gt;Wait for full DNS propagation (up to 24 hours)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;website-loads-slowly-or-intermittently&quot;&gt;Website Loads Slowly or Intermittently&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Site performance is worse than before&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solutions:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Wait for DNS propagation to complete (24 hours)&lt;/li&gt;
&lt;li&gt;Clear Cloudflare&apos;s cache: Dashboard → Caching → Purge Everything&lt;/li&gt;
&lt;li&gt;Check if caching rules are configured properly&lt;/li&gt;
&lt;li&gt;Verify proxy status (orange cloud) is enabled for web traffic&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;nameservers-havent-changed-in-cloudflare&quot;&gt;&quot;Nameservers haven&apos;t changed&quot; in Cloudflare&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Cloudflare still shows &quot;Pending&quot; after updating GoDaddy&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solutions:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Wait longer - DNS changes can take up to 24 hours&lt;/li&gt;
&lt;li&gt;Verify you entered nameservers correctly in GoDaddy (no typos)&lt;/li&gt;
&lt;li&gt;Try removing and re-adding the nameservers in GoDaddy&lt;/li&gt;
&lt;li&gt;Clear your local DNS cache:
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Mac&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; dscacheutil -flushcache&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;killall&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-HUP&lt;/span&gt; mDNSResponder

&lt;span class=&quot;token comment&quot;&gt;# Windows (PowerShell as Admin)&lt;/span&gt;
ipconfig /flushdns

&lt;span class=&quot;token comment&quot;&gt;# Linux&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; systemd-resolve --flush-caches&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;what-about-moving-the-domain-itself&quot;&gt;What About Moving the Domain Itself?&lt;/h2&gt;
&lt;p&gt;Right now, your &lt;strong&gt;domain is still registered with GoDaddy&lt;/strong&gt;, and you&apos;re just using Cloudflare for DNS management. This is totally fine and works great.&lt;/p&gt;
&lt;p&gt;If you want to transfer your domain registration to Cloudflare (so everything is in one place), that option is available:&lt;/p&gt;
&lt;h3 id=&quot;domain-transfer-to-cloudflare-coming-soon&quot;&gt;Domain Transfer to Cloudflare (Coming Soon)&lt;/h3&gt;
&lt;p&gt;Cloudflare offers domain registration at wholesale prices (no markup). Benefits include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Lower prices&lt;/strong&gt; - Pay only what Cloudflare pays to the registry&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No upsells&lt;/strong&gt; - No renewal price increases or hidden fees&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Free WHOIS privacy&lt;/strong&gt; - Always included&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unified management&lt;/strong&gt; - Everything in one dashboard&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Transfer process:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Unlock your domain in GoDaddy&lt;/li&gt;
&lt;li&gt;Get the authorization code (EPP code) from GoDaddy&lt;/li&gt;
&lt;li&gt;Initiate transfer in Cloudflare&lt;/li&gt;
&lt;li&gt;Pay the transfer fee (includes 1-year renewal at wholesale price)&lt;/li&gt;
&lt;li&gt;Wait 5-7 days for transfer to complete&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Domain transfers extend your registration by 1 year, so you won&apos;t lose any time you&apos;ve already paid for.&lt;/p&gt;
&lt;p&gt;I&apos;ll be writing a detailed guide on domain transfers soon. For now, using Cloudflare just for DNS works well and gives you all the security benefits.&lt;/p&gt;
&lt;h2 id=&quot;best-practices-going-forward&quot;&gt;Best Practices Going Forward&lt;/h2&gt;
&lt;p&gt;Now that you&apos;re on Cloudflare, here are some tips:&lt;/p&gt;
&lt;h3 id=&quot;security-settings&quot;&gt;Security Settings&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enable WAF (Web Application Firewall):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Security → WAF&lt;/li&gt;
&lt;li&gt;Enable managed rulesets for your platform (WordPress, etc.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enable Bot Fight Mode:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Security → Bots&lt;/li&gt;
&lt;li&gt;Free bot mitigation for your site&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Set up Page Rules:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rules → Page Rules&lt;/li&gt;
&lt;li&gt;Create rules for caching static content, redirects, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;performance-optimization&quot;&gt;Performance Optimization&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enable Auto Minify:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Speed → Optimization&lt;/li&gt;
&lt;li&gt;Check JavaScript, CSS, and HTML&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enable Brotli Compression:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Speed → Optimization&lt;/li&gt;
&lt;li&gt;Smaller file sizes = faster loading&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Configure Browser Cache TTL:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Caching → Configuration&lt;/li&gt;
&lt;li&gt;Set &quot;Browser Cache TTL&quot; to 4 hours or more&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;monitoring&quot;&gt;Monitoring&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Check Analytics regularly:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cloudflare → Analytics &amp;#x26; Logs&lt;/li&gt;
&lt;li&gt;See traffic patterns and threats blocked&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Set up email notifications:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Notifications&lt;/li&gt;
&lt;li&gt;Get alerts for security events or system issues&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Review Security Events:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Security → Events&lt;/li&gt;
&lt;li&gt;See what Cloudflare is blocking&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;quick-reference-checklist&quot;&gt;Quick Reference Checklist&lt;/h2&gt;
&lt;p&gt;Use this checklist when migrating DNS:&lt;/p&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Document current DNS records in GoDaddy&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Create free Cloudflare account&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Add domain to Cloudflare&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Review and verify imported DNS records&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Note Cloudflare&apos;s nameservers&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Update nameservers in GoDaddy&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Wait for DNS propagation (check email for confirmation)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Configure SSL/TLS in Cloudflare&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Enable &quot;Always Use HTTPS&quot;&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Test website loads over HTTPS&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Test email functionality (if applicable)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Verify DNS propagation globally&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Enable additional security features&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Set up performance optimizations&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Moving your DNS from GoDaddy to Cloudflare is straightforward and gives you enterprise-grade security and performance features for free. Your domain stays registered with GoDaddy, so you can continue managing renewals there, but you get all the benefits of Cloudflare&apos;s global network.&lt;/p&gt;
&lt;p&gt;The entire process takes about 15-20 minutes of actual work, plus some waiting for DNS propagation. Once active, your site will be faster, more secure, and you&apos;ll have much better visibility into your traffic and security events.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key takeaways:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DNS migration is separate from domain registration&lt;/li&gt;
&lt;li&gt;Free SSL certificates and DDoS protection from Cloudflare&lt;/li&gt;
&lt;li&gt;No downtime if you plan carefully and verify DNS records&lt;/li&gt;
&lt;li&gt;Can revert by changing nameservers back to GoDaddy anytime&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you run into any issues during the migration, Cloudflare&apos;s support documentation is excellent, and their community forums are very active. Take your time, double-check the DNS records, and you&apos;ll be up and running on Cloudflare in no time.&lt;/p&gt;
&lt;h2 id=&quot;next-steps&quot;&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;Now that you have your DNS on Cloudflare, you might want to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/cloudflare-dns-api/&quot;&gt;Automate DNS management with the Cloudflare API&lt;/a&gt;&lt;/strong&gt; - Learn how to programmatically manage your DNS records instead of clicking through the dashboard&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/cloudflare-workers-deployment/&quot;&gt;Deploy your static site to Cloudflare Workers&lt;/a&gt;&lt;/strong&gt; - Host your website on Cloudflare&apos;s edge network for blazing fast performance worldwide&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[So deployen Sie Ihre statische Website auf Cloudflare Workers in 2025]]></title><description><![CDATA[Cloudflare Pages ist veraltet. Hier ist der komplette Guide zum Deployen Ihrer statischen Website mit Cloudflare Workers und Wrangler CLI - keine Git-basierten Deployments mehr, nur pure Kontrolle.]]></description><link>https://vibecodingwithfred.com/de/blog/cloudflare-workers-deployment/</link><guid isPermaLink="false">https://vibecodingwithfred.com/de/blog/cloudflare-workers-deployment/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sun, 19 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Zuletzt getestet:&lt;/strong&gt; Oktober 2025 | &lt;strong&gt;Wrangler:&lt;/strong&gt; 3.x | &lt;strong&gt;Node.js:&lt;/strong&gt; 20+ | &lt;strong&gt;Plattform:&lt;/strong&gt; macOS/Linux/Windows&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Wenn Sie auf Cloudflare Pages ueber deren Git-Integration deployed haben, ist Ihnen vielleicht eine neue Deprecation-Meldung aufgefallen: &lt;strong&gt;Cloudflare hat Pages im April 2025 deprecated.&lt;/strong&gt; Sie draengen alle zu Cloudflare Workers.&lt;/p&gt;
&lt;p&gt;Zunaechst klingt das nervig. Pages war kinderleicht - Repository verbinden, Build-Befehl setzen, fertig. Workers? Das klingt so, als muessten Sie Serverless Functions schreiben und Edge Computing verstehen und... ja, es kann einschuechternd sein, wenn man nicht weiss, wo man anfangen soll.&lt;/p&gt;
&lt;p&gt;Hier ist die gute Nachricht: &lt;strong&gt;Das Deployen einer statischen Website auf Workers ist unkompliziert, sobald Sie den Workflow verstehen.&lt;/strong&gt; Und Sie bekommen mehr Kontrolle ueber Ihre Deployments im Prozess.&lt;/p&gt;
&lt;p&gt;Ich habe gerade meinen Gatsby-Blog vom alten Pages-Flow auf Workers migriert. Hier ist alles, was ich gelernt habe.&lt;/p&gt;
&lt;h2 id=&quot;was-sie-benoetigen&quot;&gt;Was Sie benoetigen&lt;/h2&gt;
&lt;p&gt;Bevor wir anfangen, stellen Sie sicher, dass Sie haben:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Eine statische Website&lt;/strong&gt; (Gatsby, Next.js static export, React build, Hugo, Astro)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Node.js 20+&lt;/strong&gt; installiert&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ein Cloudflare-Konto&lt;/strong&gt; (Free Tier reicht aus)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wrangler CLI&lt;/strong&gt; (installieren wir jetzt)&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;schritt-1-wrangler-installieren&quot;&gt;Schritt 1: Wrangler installieren&lt;/h2&gt;
&lt;p&gt;Wrangler ist Cloudflares Kommandozeilen-Tool zum Deployen auf Workers. Fuegen Sie es Ihrem Projekt hinzu:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-D&lt;/span&gt; wrangler&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Oder installieren Sie es global, wenn Sie das bevorzugen:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; wrangler&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ich empfehle, es als Dev-Dependency in Ihrem Projekt zu installieren, damit Ihr Team dieselbe Version verwendet.&lt;/p&gt;
&lt;h2 id=&quot;schritt-2-wrangler-authentifizieren&quot;&gt;Schritt 2: Wrangler authentifizieren&lt;/h2&gt;
&lt;p&gt;Bevor Sie deployen koennen, muessen Sie Wrangler mit Ihrem Cloudflare-Konto verbinden:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;npx wrangler login&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Dies oeffnet Ihren Browser und bittet Sie, Wrangler zu autorisieren. Klicken Sie auf &quot;Allow&quot; und Sie sind bereit.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fuer CI/CD&lt;/strong&gt; benoetigen Sie stattdessen ein API-Token (dazu spaeter mehr).&lt;/p&gt;
&lt;h2 id=&quot;schritt-3-wranglertoml-erstellen&quot;&gt;Schritt 3: wrangler.toml erstellen&lt;/h2&gt;
&lt;p&gt;Wrangler benoetigt eine Konfigurationsdatei im Root Ihres Projekts. Erstellen Sie &lt;code class=&quot;language-text&quot;&gt;wrangler.toml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token key property&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ihr-projekt-name&quot;&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;compatibility_date&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2025-10-19&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Das sagt Wrangler, wo Ihre statischen Dateien sind&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;pages_build_output_dir&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;public&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;bucket&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;./public&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Wichtige Felder:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;name&lt;/code&gt;: Ihr Projektname (wird Teil Ihrer Workers-URL)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;compatibility_date&lt;/code&gt;: Sperrt Ihre Workers-Runtime-Version&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;pages_build_output_dir&lt;/code&gt;: Wo Ihre statischen Dateien nach dem Build liegen&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;bucket&lt;/code&gt;: Dasselbe, andere Syntax (beides funktioniert)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Fuer eine Gatsby-Site ist das Output-Verzeichnis &lt;code class=&quot;language-text&quot;&gt;public&lt;/code&gt;. Fuer Next.js ist es &lt;code class=&quot;language-text&quot;&gt;out&lt;/code&gt;. Fuer Create React App ist es &lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;schritt-4-ihre-website-bauen&quot;&gt;Schritt 4: Ihre Website bauen&lt;/h2&gt;
&lt;p&gt;Hier aendert sich nichts. Fuehren Sie Ihren normalen Build-Befehl aus:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Gatsby&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build

&lt;span class=&quot;token comment&quot;&gt;# Next.js (static export)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run &lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Create React App&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run build&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Dies generiert Ihre statischen Dateien in Ihrem Output-Verzeichnis.&lt;/p&gt;
&lt;h2 id=&quot;schritt-5-auf-workers-deployen&quot;&gt;Schritt 5: Auf Workers deployen&lt;/h2&gt;
&lt;p&gt;Hier ist der magische Befehl:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;npx wrangler pages deploy public&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ersetzen Sie &lt;code class=&quot;language-text&quot;&gt;public&lt;/code&gt; mit dem, was auch immer Ihr Output-Verzeichnis ist.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Erstes Deploy?&lt;/strong&gt; Wrangler fragt:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;✔ Geben Sie den Namen Ihres neuen Projekts ein: … ihr-site-name
✔ Geben Sie den Production-Branch-Namen ein: … main&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Danach baut und deployed Wrangler Ihre Site. Sie erhalten eine URL wie:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;https://ihr-site-name.pages.dev&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;schritt-6-deploy-scripts-zu-packagejson-hinzufuegen&quot;&gt;Schritt 6: Deploy-Scripts zu package.json hinzufuegen&lt;/h2&gt;
&lt;p&gt;Jedes Mal &lt;code class=&quot;language-text&quot;&gt;npx wrangler pages deploy public&lt;/code&gt; zu tippen ist muehsam. Fuegen Sie Scripts zu Ihrer &lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt; hinzu:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-json line-numbers&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;build&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;gatsby build&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;deploy&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;npm run build &amp;amp;&amp;amp; wrangler pages deploy public&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;deploy:prod&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;npm run build &amp;amp;&amp;amp; wrangler pages deploy public --branch=main&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Jetzt ist Deployen nur noch:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run deploy&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;schritt-7-custom-domain-einrichten&quot;&gt;Schritt 7: Custom Domain einrichten&lt;/h2&gt;
&lt;p&gt;Ihre &lt;code class=&quot;language-text&quot;&gt;.pages.dev&lt;/code&gt;-URL funktioniert, aber Sie wollen wahrscheinlich Ihre eigene Domain.&lt;/p&gt;
&lt;h3 id=&quot;option-1-ueber-das-cloudflare-dashboard-am-einfachsten&quot;&gt;Option 1: Ueber das Cloudflare-Dashboard (Am einfachsten)&lt;/h3&gt;
&lt;p&gt;Sobald Ihr erstes Deployment erfolgreich ist, fuegen Sie Ihre Custom Domain hinzu:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Melden Sie sich in Ihrem Cloudflare-Dashboard an unter &lt;code class=&quot;language-text&quot;&gt;https://dash.cloudflare.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Klicken Sie in der linken Seitenleiste auf &lt;strong&gt;Workers &amp;#x26; Pages&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Finden Sie Ihr Projekt und klicken Sie darauf&lt;/li&gt;
&lt;li&gt;Klicken Sie oben auf den &lt;strong&gt;Custom domains&lt;/strong&gt;-Tab&lt;/li&gt;
&lt;li&gt;Klicken Sie auf die Schaltflaeche &lt;strong&gt;Set up a custom domain&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Geben Sie Ihre Domain ein (z.B. &lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Klicken Sie auf &lt;strong&gt;Continue&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Fuegen Sie bei Bedarf eine weitere Domain fuer die &lt;code class=&quot;language-text&quot;&gt;www&lt;/code&gt;-Subdomain hinzu&lt;/li&gt;
&lt;li&gt;Klicken Sie auf &lt;strong&gt;Activate domain&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;schritt-8-automatische-deployments-mit-github-actions&quot;&gt;Schritt 8: Automatische Deployments mit GitHub Actions&lt;/h2&gt;
&lt;p&gt;Der alte Pages-Flow hat automatisch deployed, wenn Sie zu &lt;code class=&quot;language-text&quot;&gt;main&lt;/code&gt; gepusht haben. Wir koennen das mit GitHub Actions nachbauen.&lt;/p&gt;
&lt;p&gt;Erstellen Sie &lt;code class=&quot;language-text&quot;&gt;.github/workflows/deploy.yml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yaml line-numbers&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deploy to Cloudflare Workers

&lt;span class=&quot;token key atrule&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;branches&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; main

&lt;span class=&quot;token key atrule&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;deploy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ubuntu&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;latest
    &lt;span class=&quot;token key atrule&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Checkout
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/checkout@v4

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Setup Node
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/setup&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;node@v4
        &lt;span class=&quot;token key atrule&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;node-version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;20&apos;&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;npm&apos;&lt;/span&gt;

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Install dependencies
        &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm ci

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Build site
        &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npm run build

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deploy to Cloudflare Workers
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cloudflare/wrangler&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;action@v3
        &lt;span class=&quot;token key atrule&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;apiToken&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; secrets.CLOUDFLARE_API_TOKEN &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;accountId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; secrets.CLOUDFLARE_ACCOUNT_ID &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pages deploy public &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;project&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;name=ihr&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;projekt&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;name&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;das-fazit&quot;&gt;Das Fazit&lt;/h2&gt;
&lt;p&gt;Cloudflares Einstellung von Pages und das Zwingen aller zu Workers fuehlt sich zunaechst wie ein Rueckschritt an. Das Git-basierte Auto-Deploy war &lt;em&gt;wirklich&lt;/em&gt; praktisch.&lt;/p&gt;
&lt;p&gt;Aber sobald Sie Wrangler und CI/CD eingerichtet haben, bekommen Sie:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Volle Kontrolle&lt;/strong&gt; darueber, wann und wie Sie deployen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Schnellere Deployments&lt;/strong&gt; (kein Warten auf Cloudflares Build-Warteschlange)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Besseres Debugging&lt;/strong&gt; (Sie koennen Builds lokal testen vor dem Deployen)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zugang zu Workers-Features&lt;/strong&gt; (Functions, KV Storage, Edge Logic)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Das initiale Setup dauert 20 Minuten. Danach ist es nur noch &lt;code class=&quot;language-text&quot;&gt;git push&lt;/code&gt; und GitHub Actions erledigt den Rest - dieselbe Erfahrung wie Pages, aber mit mehr Power unter der Haube.&lt;/p&gt;
&lt;h2 id=&quot;verwandte-guides&quot;&gt;Verwandte Guides&lt;/h2&gt;
&lt;p&gt;Bevor Sie auf Workers deployen, stellen Sie sicher, dass Ihr Cloudflare-Setup vollstaendig ist:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/godaddy-to-cloudflare-dns/&quot;&gt;DNS von GoDaddy zu Cloudflare verschieben&lt;/a&gt;&lt;/strong&gt; - Bringen Sie zuerst Ihre Domain auf Cloudflare fuer beste Performance und SSL-Support&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/blog/cloudflare-dns-api/&quot;&gt;DNS-Eintraege mit der Cloudflare API verwalten&lt;/a&gt;&lt;/strong&gt; - DNS-Verwaltung als Teil Ihrer Deployment-Pipeline automatisieren&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[So verschieben Sie Ihre GoDaddy DNS zu Cloudflare fuer kostenloses SSL und DDoS-Schutz]]></title><description><![CDATA[Schritt-fuer-Schritt-Anleitung zur Migration Ihrer DNS von GoDaddy zu Cloudflare, um kostenlose SSL-Zertifikate und DDoS-Schutz zu erhalten, ohne Ihre Domain-Registrierung zu verschieben.]]></description><link>https://vibecodingwithfred.com/de/blog/godaddy-to-cloudflare-dns/</link><guid isPermaLink="false">https://vibecodingwithfred.com/de/blog/godaddy-to-cloudflare-dns/</guid><dc:creator><![CDATA[Fred]]></dc:creator><pubDate>Sun, 19 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;warum-zu-cloudflare-dns-wechseln&quot;&gt;Warum zu Cloudflare DNS wechseln?&lt;/h2&gt;
&lt;p&gt;Wenn Sie Ihre Domain ueber GoDaddy gekauft haben, aber bessere Leistungs- und Sicherheitsfunktionen wuenschen, ist der Wechsel zu Cloudflares DNS eine klare Sache. Sie erhalten all das kostenlos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Kostenlose SSL-Zertifikate&lt;/strong&gt; - Automatisches HTTPS fuer Ihre Website&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DDoS-Schutz&lt;/strong&gt; - Cloudflare schuetzt Ihre Website vor Angriffen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Schnellere DNS-Aufloesung&lt;/strong&gt; - Cloudflares globales Netzwerk ist blitzschnell&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bessere Analysen&lt;/strong&gt; - Sehen Sie Verkehrsmuster und Bedrohungen in Echtzeit&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kostenloses CDN&lt;/strong&gt; - Cachen Sie Ihre statischen Inhalte global&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Das Beste daran? Sie muessen Ihre Domain-Registrierung nicht uebertragen. Ihre Domain bleibt bei GoDaddy, Sie aendern nur, wo das DNS verwaltet wird.&lt;/p&gt;
&lt;h2 id=&quot;was-sie-benoetigen&quot;&gt;Was Sie benoetigen&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ihre bei GoDaddy registrierte Domain&lt;/li&gt;
&lt;li&gt;Ein kostenloses Cloudflare-Konto (registrieren Sie sich unter &lt;a href=&quot;https://cloudflare.com&quot;&gt;cloudflare.com&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Etwa 15-20 Minuten&lt;/li&gt;
&lt;li&gt;Zugang zu Ihrem GoDaddy-Konto&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;den-prozess-verstehen&quot;&gt;Den Prozess verstehen&lt;/h2&gt;
&lt;p&gt;Hier ist, was wir in einfachen Worten tun:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;DNS-Eintraege von GoDaddy exportieren&lt;/strong&gt; - Wir holen Ihre bestehenden DNS-Einstellungen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ihre Domain zu Cloudflare hinzufuegen&lt;/strong&gt; - Cloudflare scannt und importiert Ihre DNS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nameserver bei GoDaddy aktualisieren&lt;/strong&gt; - Zeigen Sie Ihre Domain auf Cloudflares Nameserver&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Verifizieren und aktivieren&lt;/strong&gt; - Warten Sie auf die DNS-Propagierung (normalerweise unter einer Stunde)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ihre Domain-Registrierung bleibt bei GoDaddy. Sie aendern nur, wer Ihre DNS-Eintraege verwaltet.&lt;/p&gt;
&lt;h2 id=&quot;schritt-1-exportieren-sie-ihre-dns-eintraege-von-godaddy&quot;&gt;Schritt 1: Exportieren Sie Ihre DNS-Eintraege von GoDaddy&lt;/h2&gt;
&lt;p&gt;Bevor wir etwas verschieben, schauen wir uns an, welche DNS-Eintraege Sie derzeit haben. Dies ist wichtig, damit wir nichts kaputt machen.&lt;/p&gt;
&lt;h3 id=&quot;aktuelle-dns-eintraege-anzeigen&quot;&gt;Aktuelle DNS-Eintraege anzeigen&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Melden Sie sich bei GoDaddy an&lt;/strong&gt; unter &lt;a href=&quot;https://godaddy.com&quot;&gt;godaddy.com&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Navigieren Sie zu Ihren Domains:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Klicken Sie auf Ihr Profilsymbol (oben rechts)&lt;/li&gt;
&lt;li&gt;Waehlen Sie &quot;Meine Produkte&quot;&lt;/li&gt;
&lt;li&gt;Finden Sie Ihre Domain in der Liste&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;DNS-Verwaltung oeffnen:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Klicken Sie auf die DNS-Schaltflaeche neben Ihrer Domain&lt;/li&gt;
&lt;li&gt;Oder klicken Sie auf die drei Punkte (...) und waehlen Sie &quot;DNS verwalten&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ueberpruefen Sie Ihre Eintraege:&lt;/strong&gt;
Sie werden eine Tabelle mit Eintraegen sehen wie:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A-Eintraege&lt;/strong&gt; - Zeigen auf IP-Adressen (wie 192.168.1.1)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CNAME-Eintraege&lt;/strong&gt; - Aliase (wie www zeigt auf Ihre Hauptdomain)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MX-Eintraege&lt;/strong&gt; - Mailserver&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TXT-Eintraege&lt;/strong&gt; - Verifizierungscodes, SPF-Eintraege&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NS-Eintraege&lt;/strong&gt; - Nameserver (diese aendern wir spaeter)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;dokumentieren-sie-ihre-eintraege-optional-aber-empfohlen&quot;&gt;Dokumentieren Sie Ihre Eintraege (Optional aber empfohlen)&lt;/h3&gt;
&lt;p&gt;Machen Sie einen Screenshot oder schreiben Sie Ihre aktuellen DNS-Eintraege auf. Sie benoetigen diese Informationen, um zu verifizieren, dass alles korrekt uebertragen wurde.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Beispiel, was Sie sehen koennten:&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Typ&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Wert&lt;/th&gt;
&lt;th&gt;TTL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;192.0.2.1&lt;/td&gt;
&lt;td&gt;600&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CNAME&lt;/td&gt;
&lt;td&gt;www&lt;/td&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;1 Stunde&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MX&lt;/td&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;mailhost.example.com&lt;/td&gt;
&lt;td&gt;1 Stunde&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TXT&lt;/td&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;v=spf1 include:_spf.google.com ~all&lt;/td&gt;
&lt;td&gt;1 Stunde&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Wichtige Eintraege zu notieren:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A-Eintrag (@)&lt;/strong&gt; - Die IP-Adresse Ihrer Hauptdomain&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CNAME (www)&lt;/strong&gt; - Zeigt normalerweise auf Ihre Root-Domain&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MX-Eintraege&lt;/strong&gt; - Wenn Sie benutzerdefinierte E-Mail verwenden (wie Google Workspace oder Microsoft 365)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TXT-Eintraege&lt;/strong&gt; - Oft fuer E-Mail-Authentifizierung verwendet (SPF, DKIM)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;schritt-2-fuegen-sie-ihre-domain-zu-cloudflare-hinzu&quot;&gt;Schritt 2: Fuegen Sie Ihre Domain zu Cloudflare hinzu&lt;/h2&gt;
&lt;p&gt;Jetzt richten wir Ihre Domain bei Cloudflare ein.&lt;/p&gt;
&lt;h3 id=&quot;erstellen-sie-ein-cloudflare-konto&quot;&gt;Erstellen Sie ein Cloudflare-Konto&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Gehen Sie zu &lt;a href=&quot;https://cloudflare.com&quot;&gt;cloudflare.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Registrieren Sie sich fuer ein kostenloses Konto:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Klicken Sie auf &quot;Registrieren&quot;&lt;/li&gt;
&lt;li&gt;Geben Sie Ihre E-Mail ein und erstellen Sie ein Passwort&lt;/li&gt;
&lt;li&gt;Verifizieren Sie Ihre E-Mail-Adresse&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Fuegen Sie Ihre Domain hinzu:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Klicken Sie im Dashboard auf &quot;Website hinzufuegen&quot;&lt;/li&gt;
&lt;li&gt;Geben Sie Ihren Domainnamen ein (example.com)&lt;/li&gt;
&lt;li&gt;Klicken Sie auf &quot;Website hinzufuegen&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;waehlen-sie-den-kostenlosen-plan&quot;&gt;Waehlen Sie den kostenlosen Plan&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Cloudflare zeigt Ihnen Planoptionen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Waehlen Sie den kostenlosen Plan&lt;/strong&gt; (er reicht fuer die meisten Websites voellig aus)&lt;/li&gt;
&lt;li&gt;Klicken Sie auf &quot;Weiter&quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;gescannte-dns-eintraege-ueberpruefen&quot;&gt;Gescannte DNS-Eintraege ueberpruefen&lt;/h3&gt;
&lt;p&gt;Cloudflare scannt automatisch Ihre bestehenden DNS-Eintraege von GoDaddy:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare zeigt alle gefundenen DNS-Eintraege an&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ueberpruefen Sie diese sorgfaeltig&lt;/li&gt;
&lt;li&gt;Vergleichen Sie mit Ihren GoDaddy-Eintraegen aus Schritt 1&lt;/li&gt;
&lt;li&gt;Suchen Sie nach fehlenden Eintraegen&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Verifizieren Sie, dass kritische Eintraege vorhanden sind:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ihr A-Eintrag fuer die Root-Domain (@)&lt;/li&gt;
&lt;li&gt;www CNAME-Eintrag&lt;/li&gt;
&lt;li&gt;MX-Eintraege (wenn Sie E-Mail verwenden)&lt;/li&gt;
&lt;li&gt;Alle benutzerdefinierten Subdomains, die Sie eingerichtet haben&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Fuegen Sie fehlende Eintraege manuell hinzu:&lt;/strong&gt;
Wenn Cloudflare etwas verpasst hat, klicken Sie auf &quot;Eintrag hinzufuegen&quot; und geben Sie ein:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Typ&lt;/strong&gt;: A, CNAME, MX, TXT, etc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Name&lt;/strong&gt;: @ fuer Root, www fuer www-Subdomain oder benutzerdefinierte Subdomain&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inhalt&lt;/strong&gt;: IP-Adresse, Domainname oder anderer Wert&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TTL&lt;/strong&gt;: Auto ist in Ordnung&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Proxy-Status&lt;/strong&gt;: Orange Wolke fuer Webverkehr, grau fuer nur DNS&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Klicken Sie auf &quot;Weiter&quot;&lt;/strong&gt; wenn alles korrekt aussieht&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;kurzreferenz-cloudflare-proxy-status&quot;&gt;Kurzreferenz: Cloudflare Proxy-Status&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Orange Wolke (Proxied)&lt;/strong&gt;: Verkehr geht durch Cloudflares CDN und DDoS-Schutz. Verwenden Sie dies fuer Webserver (HTTP/HTTPS).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Graue Wolke (Nur DNS)&lt;/strong&gt;: Direkte Verbindung, umgeht Cloudflare. Verwenden Sie dies fuer Mailserver, FTP, SSH, Spieleserver, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Standardeinstellungen:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A-Eintraege fuer Webverkehr: Orange Wolke (proxied)&lt;/li&gt;
&lt;li&gt;MX-Eintraege: Automatisch grau (Cloudflare erzwingt dies)&lt;/li&gt;
&lt;li&gt;Mail-bezogene Eintraege: Graue Wolke (nur DNS)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;schritt-3-aktualisieren-sie-die-nameserver-bei-godaddy&quot;&gt;Schritt 3: Aktualisieren Sie die Nameserver bei GoDaddy&lt;/h2&gt;
&lt;p&gt;Dies ist der kritische Schritt, bei dem wir Ihre Domain auf Cloudflare zeigen.&lt;/p&gt;
&lt;h3 id=&quot;holen-sie-sich-ihre-cloudflare-nameserver&quot;&gt;Holen Sie sich Ihre Cloudflare-Nameserver&lt;/h3&gt;
&lt;p&gt;Nach dem Hinzufuegen der DNS-Eintraege zeigt Ihnen Cloudflare zwei Nameserver. Sie sehen etwa so aus:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;aldo.ns.cloudflare.com
beatriz.ns.cloudflare.com&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Schreiben Sie diese auf oder lassen Sie den Browser-Tab geoeffnet.&lt;/strong&gt; Sie benoetigen sie gleich.&lt;/p&gt;
&lt;h3 id=&quot;aendern-sie-die-nameserver-bei-godaddy&quot;&gt;Aendern Sie die Nameserver bei GoDaddy&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Gehen Sie zurueck zu GoDaddy&lt;/strong&gt; (lassen Sie den Cloudflare-Tab geoeffnet)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Navigieren Sie zu den Domain-Einstellungen:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gehen Sie zu &quot;Meine Produkte&quot;&lt;/li&gt;
&lt;li&gt;Finden Sie Ihre Domain&lt;/li&gt;
&lt;li&gt;Klicken Sie auf die drei Punkte (...) neben Ihrer Domain&lt;/li&gt;
&lt;li&gt;Waehlen Sie &quot;DNS verwalten&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Scrollen Sie zum Nameserver-Bereich:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sie sehen &quot;Nameserver&quot; mit aktuellen Werten (normalerweise GoDaddys Nameserver)&lt;/li&gt;
&lt;li&gt;Klicken Sie auf &quot;Aendern&quot; oder &quot;Verwalten&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Waehlen Sie &quot;Ich verwende meine eigenen Nameserver&quot;:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GoDaddy zeigt dies moeglicherweise als &quot;Benutzerdefiniert&quot; oder &quot;Eigene Nameserver eingeben&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Geben Sie Cloudflares Nameserver ein:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ersetzen Sie die bestehenden Nameserver durch die beiden von Cloudflare&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Beispiel:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Nameserver 1: &lt;code class=&quot;language-text&quot;&gt;aldo.ns.cloudflare.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Nameserver 2: &lt;code class=&quot;language-text&quot;&gt;beatriz.ns.cloudflare.com&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Loeschen Sie zusaetzliche Nameserver (Sie benoetigen nur 2)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Aenderungen speichern:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Klicken Sie auf &quot;Speichern&quot;&lt;/li&gt;
&lt;li&gt;GoDaddy zeigt moeglicherweise eine Warnung ueber den Verlust von DNS-Einstellungen - das ist erwartet&lt;/li&gt;
&lt;li&gt;Bestaetigen Sie die Aenderung&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;was-ist-gerade-passiert&quot;&gt;Was ist gerade passiert?&lt;/h3&gt;
&lt;p&gt;Sie haben dem Internet gerade gesagt: &quot;Wenn jemand nach example.com fragt, frag Cloudflare statt GoDaddy nach den DNS-Eintraegen.&quot;&lt;/p&gt;
&lt;p&gt;Ihre Domain ist immer noch bei GoDaddy registriert. Sie bezahlen immer noch GoDaddy fuer die Domain-Registrierung. Aber jetzt verwaltet Cloudflare alle DNS-Abfragen.&lt;/p&gt;
&lt;h2 id=&quot;schritt-4-verifizieren-und-aktivieren-bei-cloudflare&quot;&gt;Schritt 4: Verifizieren und Aktivieren bei Cloudflare&lt;/h2&gt;
&lt;p&gt;Jetzt warten wir darauf, dass das Internet aufholt.&lt;/p&gt;
&lt;h3 id=&quot;bestaetigen-sie-die-nameserver-aenderung&quot;&gt;Bestaetigen Sie die Nameserver-Aenderung&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Gehen Sie zurueck zu Ihrem Cloudflare-Tab&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Klicken Sie auf &quot;Fertig, Nameserver ueberpruefen&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Cloudflare beginnt zu ueberpruefen, ob die Nameserver aktualisiert wurden&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;warten-sie-auf-die-dns-propagierung&quot;&gt;Warten Sie auf die DNS-Propagierung&lt;/h3&gt;
&lt;p&gt;Dies ist der langweilige Teil. DNS-Aenderungen koennen zwischen &lt;strong&gt;wenigen Minuten und 24 Stunden&lt;/strong&gt; dauern, um sich weltweit zu verbreiten. In der Praxis passieren die meisten Aenderungen innerhalb von &lt;strong&gt;30 Minuten bis 2 Stunden&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Was passiert:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DNS-Server auf der ganzen Welt aktualisieren ihre gecachten Informationen&lt;/li&gt;
&lt;li&gt;Einige nehmen die Aenderung schnell auf, andere brauchen laenger&lt;/li&gt;
&lt;li&gt;Ihre Website funktioniert moeglicherweise fuer Sie, aber voruebergehend nicht fuer jemand anderen&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;aktivierungsstatus-pruefen&quot;&gt;Aktivierungsstatus pruefen&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare sendet Ihnen eine E-Mail&lt;/strong&gt;, wenn Ihre Website aktiv ist (normalerweise innerhalb einer Stunde)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Status im Cloudflare-Dashboard pruefen:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gehen Sie zu Ihrem Cloudflare-Dashboard&lt;/li&gt;
&lt;li&gt;Suchen Sie Ihre Domain&lt;/li&gt;
&lt;li&gt;Der Status aendert sich von &quot;Ausstehend&quot; zu &quot;Aktiv&quot; wenn abgeschlossen&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Manuelle Pruefung (optional):&lt;/strong&gt;
Sie koennen die Nameserver selbst mit einem Terminal verifizieren:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Nameserver pruefen (Mac/Linux/WSL)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; NS example.com +short

&lt;span class=&quot;token comment&quot;&gt;# Windows (PowerShell)&lt;/span&gt;
Resolve-DnsName example.com &lt;span class=&quot;token parameter variable&quot;&gt;-Type&lt;/span&gt; NS&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sie sollten Cloudflares Nameserver in den Ergebnissen sehen.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;schritt-5-ssltls-bei-cloudflare-aktivieren&quot;&gt;Schritt 5: SSL/TLS bei Cloudflare aktivieren&lt;/h2&gt;
&lt;p&gt;Sobald Ihre Domain aktiv ist, schalten wir das kostenlose SSL ein.&lt;/p&gt;
&lt;h3 id=&quot;ssltls-einstellungen-konfigurieren&quot;&gt;SSL/TLS-Einstellungen konfigurieren&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Waehlen Sie im Cloudflare-Dashboard Ihre Domain&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Gehen Sie zum SSL/TLS-Bereich&lt;/strong&gt; (linke Seitenleiste)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Waehlen Sie den Verschluesselungsmodus:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Flexibel&lt;/strong&gt;: Cloudflare zum Besucher ist verschluesselt, Cloudflare zu Ihrem Server nicht
&lt;ul&gt;
&lt;li&gt;Verwenden Sie dies, wenn Ihr Server kein SSL hat&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vollstaendig&lt;/strong&gt;: Verschluesselt beide Verbindungen, validiert aber nicht das Zertifikat Ihres Servers
&lt;ul&gt;
&lt;li&gt;Verwenden Sie dies, wenn Ihr Server ein selbstsigniertes Zertifikat hat&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vollstaendig (Strikt)&lt;/strong&gt;: Volle Verschluesselung mit Zertifikatsvalidierung
&lt;ul&gt;
&lt;li&gt;Verwenden Sie dies, wenn Ihr Server bereits ein gueltiges SSL-Zertifikat hat&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Empfehlung:&lt;/strong&gt; Beginnen Sie mit &quot;Flexibel&quot;, wenn Sie noch kein SSL auf Ihrem Server haben. Upgraden Sie auf &quot;Vollstaendig (Strikt)&quot;, sobald Sie ein SSL-Zertifikat auf Ihrem Hosting installiert haben.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Aktivieren Sie &quot;Immer HTTPS verwenden&quot;:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gehen Sie zu SSL/TLS -&gt; Edge-Zertifikate&lt;/li&gt;
&lt;li&gt;Schalten Sie &quot;Immer HTTPS verwenden&quot; auf AN&lt;/li&gt;
&lt;li&gt;Dies leitet automatisch http:// zu https:// um&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;weitere-sicherheitsfunktionen-aktivieren-optional&quot;&gt;Weitere Sicherheitsfunktionen aktivieren (Optional)&lt;/h3&gt;
&lt;p&gt;Waehrend Sie bei Cloudflare sind:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Automatische HTTPS-Rewrites:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SSL/TLS -&gt; Edge-Zertifikate&lt;/li&gt;
&lt;li&gt;Schalten Sie &quot;Automatische HTTPS-Rewrites&quot; AN&lt;/li&gt;
&lt;li&gt;Behebt Mixed-Content-Warnungen&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Minimale TLS-Version:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Setzen Sie auf TLS 1.2 oder hoeher&lt;/li&gt;
&lt;li&gt;Deaktiviert alte, unsichere Protokolle&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;HSTS aktivieren&lt;/strong&gt; (sobald Sie sicher sind, dass alles funktioniert):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SSL/TLS -&gt; Edge-Zertifikate -&gt; HSTS aktivieren&lt;/li&gt;
&lt;li&gt;Zwingt Browser, immer HTTPS zu verwenden&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Warnung:&lt;/strong&gt; Aktivieren Sie dies erst nach gruendlichen Tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;alles-verifizieren&quot;&gt;Alles verifizieren&lt;/h2&gt;
&lt;p&gt;Stellen wir sicher, dass wir nichts kaputt gemacht haben.&lt;/p&gt;
&lt;h3 id=&quot;testen-sie-ihre-website&quot;&gt;Testen Sie Ihre Website&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Besuchen Sie Ihre Website&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;https://example.com&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sollte ueber HTTPS laden (achten Sie auf das Schlosssymbol)&lt;/li&gt;
&lt;li&gt;Keine Zertifikatswarnungen&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Testen Sie die www-Version&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;https://www.example.com&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sollte auch mit HTTPS funktionieren&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Testen Sie HTTP-Weiterleitung&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;http://example.com&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sollte automatisch zur HTTPS-Version weiterleiten&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;e-mail-testen-falls-zutreffend&quot;&gt;E-Mail testen (Falls zutreffend)&lt;/h3&gt;
&lt;p&gt;Wenn Sie benutzerdefinierte E-Mail mit Ihrer Domain verwenden:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Senden Sie eine Test-E-Mail&lt;/strong&gt; von Ihrer Domain&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Empfangen Sie eine Test-E-Mail&lt;/strong&gt; an Ihre Domain&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pruefen Sie, ob E-Mails nicht im Spam landen&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Wenn E-Mail nicht funktioniert, verifizieren Sie, dass Ihre MX-Eintraege in Cloudflare mit denen in GoDaddy uebereinstimmen.&lt;/p&gt;
&lt;h3 id=&quot;dns-aufloesung-pruefen&quot;&gt;DNS-Aufloesung pruefen&lt;/h3&gt;
&lt;p&gt;Verwenden Sie Online-Tools, um zu verifizieren, dass DNS funktioniert:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;WhatsMyDNS&lt;/strong&gt;: &lt;a href=&quot;https://whatsmydns.net&quot;&gt;whatsmydns.net&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Geben Sie Ihre Domain ein&lt;/li&gt;
&lt;li&gt;Waehlen Sie &quot;A&quot;-Eintragstyp&lt;/li&gt;
&lt;li&gt;Pruefen Sie die weltweite Propagierung&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;DNS Checker&lt;/strong&gt;: &lt;a href=&quot;https://dnschecker.org&quot;&gt;dnschecker.org&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Geben Sie Ihre Domain ein&lt;/li&gt;
&lt;li&gt;Sehen Sie den globalen DNS-Propagierungsstatus&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;haeufige-probleme-beheben&quot;&gt;Haeufige Probleme beheben&lt;/h2&gt;
&lt;h3 id=&quot;website-zeigt-fehler-522-oder-fehler-521&quot;&gt;Website zeigt &quot;Fehler 522&quot; oder &quot;Fehler 521&quot;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Cloudflare kann keine Verbindung zu Ihrem Server herstellen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Loesungen:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Verifizieren Sie, dass Ihr A-Eintrag auf die korrekte IP-Adresse zeigt&lt;/li&gt;
&lt;li&gt;Pruefen Sie, ob Ihre Hosting-Firewall Cloudflare blockiert&lt;/li&gt;
&lt;li&gt;Setzen Sie Cloudflares IP-Bereiche auf die Whitelist Ihrer Server-Firewall&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;ssl-zertifikatsfehler&quot;&gt;SSL-Zertifikatsfehler&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Browser zeigt &quot;Ihre Verbindung ist nicht privat&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Loesungen:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Warten Sie 30 Minuten - Cloudflare generiert noch Ihr Zertifikat&lt;/li&gt;
&lt;li&gt;Pruefen Sie den SSL/TLS-Modus - versuchen Sie &quot;Flexibel&quot;, wenn &quot;Vollstaendig&quot; nicht funktioniert&lt;/li&gt;
&lt;li&gt;Loeschen Sie Ihren Browser-Cache und versuchen Sie es im Inkognito-/Privatmodus&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;e-mail-funktioniert-nicht-mehr&quot;&gt;E-Mail funktioniert nicht mehr&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; E-Mails koennen nicht gesendet oder empfangen werden&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Loesungen:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Pruefen Sie, ob MX-Eintraege in Cloudflare mit GoDaddys urspruenglichen Eintraegen uebereinstimmen&lt;/li&gt;
&lt;li&gt;Verifizieren Sie, dass MX-Eintraege &lt;strong&gt;graue Wolke (nur DNS)&lt;/strong&gt; sind, nicht proxied&lt;/li&gt;
&lt;li&gt;Pruefen Sie, ob SPF- und DKIM-TXT-Eintraege korrekt kopiert wurden&lt;/li&gt;
&lt;li&gt;Warten Sie auf vollstaendige DNS-Propagierung (bis zu 24 Stunden)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;website-laedt-langsam-oder-intermittierend&quot;&gt;Website laedt langsam oder intermittierend&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Website-Leistung ist schlechter als vorher&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Loesungen:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Warten Sie auf Abschluss der DNS-Propagierung (24 Stunden)&lt;/li&gt;
&lt;li&gt;Leeren Sie Cloudflares Cache: Dashboard -&gt; Caching -&gt; Alles loeschen&lt;/li&gt;
&lt;li&gt;Pruefen Sie, ob Caching-Regeln richtig konfiguriert sind&lt;/li&gt;
&lt;li&gt;Verifizieren Sie, dass Proxy-Status (orange Wolke) fuer Webverkehr aktiviert ist&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;nameserver-haben-sich-nicht-geaendert-in-cloudflare&quot;&gt;&quot;Nameserver haben sich nicht geaendert&quot; in Cloudflare&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Cloudflare zeigt immer noch &quot;Ausstehend&quot; nach Aktualisierung bei GoDaddy&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Loesungen:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Warten Sie laenger - DNS-Aenderungen koennen bis zu 24 Stunden dauern&lt;/li&gt;
&lt;li&gt;Verifizieren Sie, dass Sie die Nameserver korrekt bei GoDaddy eingegeben haben (keine Tippfehler)&lt;/li&gt;
&lt;li&gt;Versuchen Sie, die Nameserver bei GoDaddy zu entfernen und erneut hinzuzufuegen&lt;/li&gt;
&lt;li&gt;Leeren Sie Ihren lokalen DNS-Cache:
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Mac&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; dscacheutil -flushcache&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;killall&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-HUP&lt;/span&gt; mDNSResponder

&lt;span class=&quot;token comment&quot;&gt;# Windows (PowerShell als Admin)&lt;/span&gt;
ipconfig /flushdns

&lt;span class=&quot;token comment&quot;&gt;# Linux&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; systemd-resolve --flush-caches&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;was-ist-mit-dem-verschieben-der-domain-selbst&quot;&gt;Was ist mit dem Verschieben der Domain selbst?&lt;/h2&gt;
&lt;p&gt;Im Moment ist Ihre &lt;strong&gt;Domain immer noch bei GoDaddy registriert&lt;/strong&gt;, und Sie verwenden Cloudflare nur fuer die DNS-Verwaltung. Das ist voellig in Ordnung und funktioniert hervorragend.&lt;/p&gt;
&lt;p&gt;Wenn Sie Ihre Domain-Registrierung zu Cloudflare uebertragen moechten (damit alles an einem Ort ist), ist diese Option verfuegbar:&lt;/p&gt;
&lt;h3 id=&quot;domain-transfer-zu-cloudflare-kommt-bald&quot;&gt;Domain-Transfer zu Cloudflare (Kommt bald)&lt;/h3&gt;
&lt;p&gt;Cloudflare bietet Domain-Registrierung zu Grosshandelspreisen (kein Aufschlag). Vorteile sind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Niedrigere Preise&lt;/strong&gt; - Zahlen Sie nur das, was Cloudflare an die Registry zahlt&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keine Zusatzverkaeufe&lt;/strong&gt; - Keine Verlaengerungspreiserhoehungen oder versteckten Gebuehren&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kostenloser WHOIS-Datenschutz&lt;/strong&gt; - Immer inklusive&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Einheitliche Verwaltung&lt;/strong&gt; - Alles in einem Dashboard&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Transferprozess:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Entsperren Sie Ihre Domain bei GoDaddy&lt;/li&gt;
&lt;li&gt;Holen Sie den Autorisierungscode (EPP-Code) von GoDaddy&lt;/li&gt;
&lt;li&gt;Initiieren Sie den Transfer bei Cloudflare&lt;/li&gt;
&lt;li&gt;Zahlen Sie die Transfergebuehr (beinhaltet 1-Jahr-Verlaengerung zum Grosshandelspreis)&lt;/li&gt;
&lt;li&gt;Warten Sie 5-7 Tage auf den Abschluss des Transfers&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Hinweis:&lt;/strong&gt; Domain-Transfers verlaengern Ihre Registrierung um 1 Jahr, Sie verlieren also keine Zeit, die Sie bereits bezahlt haben.&lt;/p&gt;
&lt;p&gt;Ich werde bald eine detaillierte Anleitung zu Domain-Transfers schreiben. Im Moment funktioniert die Verwendung von Cloudflare nur fuer DNS gut und bietet Ihnen alle Sicherheitsvorteile.&lt;/p&gt;
&lt;h2 id=&quot;best-practices-fuer-die-zukunft&quot;&gt;Best Practices fuer die Zukunft&lt;/h2&gt;
&lt;p&gt;Jetzt, wo Sie bei Cloudflare sind, hier sind einige Tipps:&lt;/p&gt;
&lt;h3 id=&quot;sicherheitseinstellungen&quot;&gt;Sicherheitseinstellungen&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;WAF (Web Application Firewall) aktivieren:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sicherheit -&gt; WAF&lt;/li&gt;
&lt;li&gt;Aktivieren Sie verwaltete Regelsaetze fuer Ihre Plattform (WordPress, etc.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Bot Fight Mode aktivieren:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sicherheit -&gt; Bots&lt;/li&gt;
&lt;li&gt;Kostenlose Bot-Abwehr fuer Ihre Website&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Page Rules einrichten:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Regeln -&gt; Page Rules&lt;/li&gt;
&lt;li&gt;Erstellen Sie Regeln fuer das Caching statischer Inhalte, Weiterleitungen, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;performance-optimierung&quot;&gt;Performance-Optimierung&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Auto Minify aktivieren:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Geschwindigkeit -&gt; Optimierung&lt;/li&gt;
&lt;li&gt;Aktivieren Sie JavaScript, CSS und HTML&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Brotli-Komprimierung aktivieren:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Geschwindigkeit -&gt; Optimierung&lt;/li&gt;
&lt;li&gt;Kleinere Dateigroessen = schnelleres Laden&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Browser-Cache-TTL konfigurieren:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Caching -&gt; Konfiguration&lt;/li&gt;
&lt;li&gt;Setzen Sie &quot;Browser-Cache-TTL&quot; auf 4 Stunden oder mehr&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;ueberwachung&quot;&gt;Ueberwachung&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Analysen regelmaessig pruefen:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cloudflare -&gt; Analysen &amp;#x26; Logs&lt;/li&gt;
&lt;li&gt;Sehen Sie Verkehrsmuster und blockierte Bedrohungen&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;E-Mail-Benachrichtigungen einrichten:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Benachrichtigungen&lt;/li&gt;
&lt;li&gt;Erhalten Sie Warnungen fuer Sicherheitsereignisse oder Systemprobleme&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sicherheitsereignisse ueberpruefen:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sicherheit -&gt; Ereignisse&lt;/li&gt;
&lt;li&gt;Sehen Sie, was Cloudflare blockiert&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;kurzreferenz-checkliste&quot;&gt;Kurzreferenz-Checkliste&lt;/h2&gt;
&lt;p&gt;Verwenden Sie diese Checkliste bei der Migration von DNS:&lt;/p&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Aktuelle DNS-Eintraege bei GoDaddy dokumentieren&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Kostenloses Cloudflare-Konto erstellen&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Domain zu Cloudflare hinzufuegen&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Importierte DNS-Eintraege ueberpruefen und verifizieren&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Cloudflares Nameserver notieren&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Nameserver bei GoDaddy aktualisieren&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Auf DNS-Propagierung warten (E-Mail zur Bestaetigung pruefen)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; SSL/TLS bei Cloudflare konfigurieren&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &quot;Immer HTTPS verwenden&quot; aktivieren&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Testen, ob Website ueber HTTPS laedt&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; E-Mail-Funktionalitaet testen (falls zutreffend)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; DNS-Propagierung global verifizieren&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Zusaetzliche Sicherheitsfunktionen aktivieren&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disab