<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged self-hosting</title>
<link>https://coderlegion.com/tag/self-hosting</link>
<description>Powered by Question2Answer</description>
<item>
<title>Shared Hosting vs Managed Cloud Hosting: Which Is Right for Your Growing Blog?</title>
<link>https://coderlegion.com/29077/shared-hosting-vs-managed-cloud-hosting-which-is-right-for-your-growing-blog</link>
<description>&lt;p&gt;Choosing web hosting is one of the first technical decisions a blogger makes, but it becomes more consequential as a site grows. A new blog may operate comfortably on an inexpensive shared hosting plan. As readership increases, however, heavier traffic, larger media libraries, more plugins, more frequent publishing, and higher expectations for page speed can put greater demands on the hosting environment.&lt;/p&gt;
&lt;p&gt;The decision eventually becomes less about getting a website online and more about choosing an infrastructure that can support the website reliably.&lt;/p&gt;
&lt;p&gt;Two options commonly considered at this stage are shared hosting and managed cloud hosting. They can both support a blog, but they differ substantially in how computing resources are allocated, how infrastructure is maintained, how easily resources can be increased, and how much technical responsibility falls on the site owner.&lt;/p&gt;
&lt;p&gt;There is no universal hosting choice for every growing blog. The appropriate option depends on traffic patterns, technical requirements, budget, operational priorities, and how much server administration the publisher wants to handle.&lt;/p&gt;
&lt;p&gt;What Is Shared Hosting?&lt;br&gt;
Shared hosting places multiple websites on the same physical server and allows those websites to share resources such as CPU, RAM, storage, and other server infrastructure. Amazon Web Services describes shared hosting as a model in which customers share server resources, while noting that it is commonly suitable for personal websites, blogs, and small businesses.&lt;/p&gt;
&lt;p&gt;The main attraction is cost.&lt;/p&gt;
&lt;p&gt;Instead of paying for an entire server or a more sophisticated infrastructure, the customer pays for a portion of a shared environment. Hosting companies generally package server management, control panels, software installation, email services, backups, SSL options, and other functions into relatively simple plans.&lt;/p&gt;
&lt;p&gt;For a new blogger, this can be practical. A website with modest traffic and relatively straightforward requirements does not necessarily need an elaborate hosting architecture.&lt;/p&gt;
&lt;p&gt;Shared hosting also tends to require less technical knowledge. The provider manages the underlying server, allowing the blogger to concentrate on publishing rather than server administration.&lt;/p&gt;
&lt;p&gt;The limitation is resource competition. Because multiple websites use the same underlying server, the available resources are not dedicated exclusively to one blog. Google Cloud describes shared hosting as economical but notes that individual websites are limited by the resources of the server they share.&lt;/p&gt;
&lt;p&gt;That distinction becomes more important as traffic grows.&lt;/p&gt;
&lt;p&gt;What Is Managed Cloud Hosting?&lt;br&gt;
Cloud hosting uses a network of virtual or physical computing resources rather than relying exclusively on a single traditional server. Google Cloud describes cloud hosting as an environment that can add or remove resources as demand changes, while AWS describes cloud hosting as an approach that can use multiple servers and provide greater flexibility than traditional hosting.&lt;/p&gt;
&lt;p&gt;The word &quot;managed&quot; adds another layer.&lt;/p&gt;
&lt;p&gt;With managed hosting, the hosting provider takes responsibility for significant portions of infrastructure administration. Depending on the provider and plan, this can include server maintenance, security updates, backups, monitoring, software configuration, and technical support. Google Cloud identifies server maintenance, security, software and hardware upgrades, and backups among responsibilities that can be handled by a managed hosting provider.&lt;/p&gt;
&lt;p&gt;Managed cloud hosting therefore combines two concepts:&lt;/p&gt;
&lt;p&gt;Cloud infrastructure that can provide greater flexibility in resource allocation.&lt;br&gt;
Provider management that reduces the amount of server administration required from the customer.&lt;br&gt;
The exact services included vary considerably between hosting companies. A buyer should therefore examine the actual plan documentation rather than assuming that every product labeled &quot;managed cloud hosting&quot; provides identical resources or services.&lt;/p&gt;
&lt;p&gt;Performance: What Actually Matters?&lt;br&gt;
Hosting is only one part of website performance.&lt;/p&gt;
&lt;p&gt;WordPress identifies several factors that can affect performance, including the hosting environment, WordPress configuration, software versions, image sizes, caching, and the use of a CDN.&lt;/p&gt;
&lt;p&gt;That matters because upgrading from shared hosting to cloud hosting does not automatically make every page fast.&lt;/p&gt;
&lt;p&gt;A poorly optimized blog with oversized images, excessive plugins, inefficient database queries, and inadequate caching can remain slow after moving to more powerful infrastructure.&lt;/p&gt;
&lt;p&gt;Caching is particularly important. WordPress explains that caching allows previously generated results to be reused instead of requiring the server to perform the same processing for every request. Server-side caching, browser caching, object caching, and other caching layers can reduce processing requirements and improve response times.&lt;/p&gt;
&lt;p&gt;A CDN can provide another performance layer. WordPress explains that a CDN distributes static content through multiple endpoints, allowing visitors to receive files from infrastructure closer to their location.&lt;/p&gt;
&lt;p&gt;For a growing blog, therefore, the relevant question is not simply, &quot;Which hosting type is faster?&quot; It is, &quot;Which infrastructure provides the resources and optimization options my website actually requires?&quot;&lt;/p&gt;
&lt;p&gt;Scalability Is Where the Difference Becomes More Significant&lt;br&gt;
A small blog may have predictable traffic. A growing publication can have unpredictable traffic.&lt;/p&gt;
&lt;p&gt;A new article may suddenly receive attention from social media, search engines, newsletters, another publication, or a large online community. Traffic can rise rapidly without the publisher having planned for it.&lt;/p&gt;
&lt;p&gt;Traditional shared hosting generally operates within the limits of its server environment. If the blog outgrows the plan, the owner may need to upgrade to another hosting package or migrate to a different infrastructure.&lt;/p&gt;
&lt;p&gt;Cloud infrastructure is designed around greater resource flexibility. Google Cloud identifies scalability as a central characteristic of cloud hosting, while AWS describes cloud hosting as capable of scaling resources according to changing requirements.&lt;/p&gt;
&lt;p&gt;This does not mean every managed cloud package automatically scales without limits. Capacity, pricing, configuration, and provider policies still apply.&lt;/p&gt;
&lt;p&gt;It does mean that cloud hosting can provide a more flexible foundation when a blog's resource requirements are becoming less predictable.&lt;/p&gt;
&lt;p&gt;Reliability and Redundancy&lt;br&gt;
Reliability is another important consideration for a commercial blog.&lt;/p&gt;
&lt;p&gt;A website outage can prevent visitors from accessing articles, interfere with advertising or affiliate activity, and interrupt other online operations. The infrastructure behind the website therefore matters.&lt;/p&gt;
&lt;p&gt;Cloud hosting can distribute workloads across multiple resources rather than relying entirely on one physical server. Google Cloud explains that cloud environments can use multiple servers and that another server can continue providing service when one server fails. AWS similarly describes cloud hosting as using clusters of servers and emphasizes availability and redundancy as benefits of the model.&lt;/p&gt;
&lt;p&gt;The actual reliability of a particular hosting service still depends on its architecture and provider practices. &quot;Cloud&quot; alone is not a guarantee of uninterrupted availability.&lt;/p&gt;
&lt;p&gt;For that reason, bloggers should examine uptime commitments, backup policies, recovery procedures, monitoring, and support arrangements before purchasing a plan.&lt;/p&gt;
&lt;p&gt;Cost: Shared Hosting Usually Starts Lower&lt;br&gt;
Price is often the strongest argument for shared hosting.&lt;/p&gt;
&lt;p&gt;Because multiple customers share infrastructure, the cost can be distributed among them. AWS explicitly identifies low monthly fees as one of the benefits of shared hosting.&lt;/p&gt;
&lt;p&gt;That makes shared hosting attractive for bloggers who are still establishing their audience or generating little revenue.&lt;/p&gt;
&lt;p&gt;Managed cloud hosting generally costs more because the customer may be paying for additional infrastructure, resource flexibility, management, monitoring, support, or other services.&lt;/p&gt;
&lt;p&gt;The important question is not simply whether cloud hosting costs more. It is whether the additional cost corresponds to a genuine business requirement.&lt;/p&gt;
&lt;p&gt;If a blog has modest traffic, limited technical requirements, and no recurring resource problems, moving to a more expensive environment may provide little practical benefit.&lt;/p&gt;
&lt;p&gt;If the site is regularly approaching resource limits or experiencing traffic surges, paying for additional infrastructure may be easier to justify.&lt;/p&gt;
&lt;p&gt;Technical Management&lt;br&gt;
Shared hosting is generally attractive to publishers who want minimal involvement with server administration.&lt;/p&gt;
&lt;p&gt;The hosting company handles much of the underlying infrastructure, while the customer manages the website itself.&lt;/p&gt;
&lt;p&gt;Managed cloud hosting can reduce the technical burden further, depending on the provider. Managed services may cover tasks that would otherwise require technical expertise, including system maintenance, security updates, backups, and infrastructure management.&lt;/p&gt;
&lt;p&gt;This distinction is important for bloggers who are building businesses rather than technology projects.&lt;/p&gt;
&lt;p&gt;A publisher may be capable of configuring a server but decide that server administration is not the best use of their time. In that situation, managed infrastructure can have value beyond raw performance.&lt;/p&gt;
&lt;p&gt;When Shared Hosting Makes Sense&lt;br&gt;
Shared hosting can remain a sensible option when a blog has:&lt;/p&gt;
&lt;p&gt;Modest or relatively predictable traffic&lt;br&gt;
Limited server resource requirements&lt;br&gt;
A small media library&lt;br&gt;
A relatively simple WordPress installation&lt;br&gt;
No recurring resource-limit problems&lt;br&gt;
A strong need to control hosting expenses&lt;br&gt;
Little need for advanced server configuration&lt;br&gt;
A blog does not become technologically inadequate merely because it uses shared hosting.&lt;/p&gt;
&lt;p&gt;WordPress itself identifies shared hosting as the most common hosting type and notes that websites hosted in such environments share a server with other sites.&lt;/p&gt;
&lt;p&gt;For many smaller publishers, that remains sufficient.&lt;/p&gt;
&lt;p&gt;When Managed Cloud Hosting Becomes More Practical&lt;br&gt;
Managed cloud hosting becomes more relevant when a blog has requirements such as:&lt;/p&gt;
&lt;p&gt;Rapidly increasing traffic&lt;br&gt;
Significant traffic spikes&lt;br&gt;
More demanding WordPress configurations&lt;br&gt;
Resource-intensive plugins&lt;br&gt;
Large or expanding media libraries&lt;br&gt;
Greater dependence on website availability&lt;br&gt;
Requirements for additional server resources&lt;br&gt;
A preference for managed technical operations&lt;br&gt;
A business model where downtime carries meaningful financial consequences&lt;br&gt;
The key is to identify an actual operational requirement rather than upgrading simply because cloud hosting sounds more advanced.&lt;/p&gt;
&lt;p&gt;If the current hosting environment is stable, responsive, adequately resourced, and properly configured, there may be no urgent reason to migrate.&lt;/p&gt;
&lt;p&gt;Do Not Ignore Caching and CDN Configuration&lt;br&gt;
A hosting upgrade should not become an excuse to ignore basic optimization.&lt;/p&gt;
&lt;p&gt;WordPress recommends caching as an important performance measure because cached content can reduce repeated processing by the server. Its documentation also identifies persistent object caching and CDNs as useful components of performance optimization.&lt;/p&gt;
&lt;p&gt;A CDN can also reduce the amount of static content that must be delivered directly by the origin server. WordPress explains that CDNs can distribute images, JavaScript, CSS, and other static resources through geographically distributed servers.&lt;/p&gt;
&lt;p&gt;Before migrating, a blogger should therefore review:&lt;/p&gt;
&lt;p&gt;Page caching&lt;br&gt;
Browser caching&lt;br&gt;
Object caching&lt;br&gt;
Image optimization&lt;br&gt;
Plugin usage&lt;br&gt;
Database performance&lt;br&gt;
CDN configuration&lt;br&gt;
PHP and WordPress versions&lt;br&gt;
Server resource consumption&lt;br&gt;
These checks can reveal whether the actual problem is hosting capacity or website configuration.&lt;/p&gt;
&lt;p&gt;How to Decide&lt;br&gt;
The simplest way to approach the decision is to start with evidence from the existing website.&lt;/p&gt;
&lt;p&gt;Look at resource usage, traffic patterns, page performance, error logs, storage consumption, and any warnings from the current hosting provider.&lt;/p&gt;
&lt;p&gt;If the blog consistently operates within its current limits and performs adequately, shared hosting may remain appropriate.&lt;/p&gt;
&lt;p&gt;If the site regularly encounters resource constraints, experiences significant traffic fluctuations, or requires infrastructure capabilities that the existing environment cannot provide, managed cloud hosting deserves closer consideration.&lt;/p&gt;
&lt;p&gt;Cost should then be evaluated against the business value of improved infrastructure.&lt;/p&gt;
&lt;p&gt;A blog that earns meaningful revenue from advertising, affiliate marketing, digital products, memberships, sponsorships, or other channels may have different hosting requirements from a personal blog that receives a small number of visitors.&lt;/p&gt;
&lt;p&gt;The Bottom Line for a Growing Blog&lt;br&gt;
Shared hosting and managed cloud hosting serve different operational needs.&lt;/p&gt;
&lt;p&gt;Shared hosting offers simplicity and lower costs by placing multiple websites on shared server resources. It can be entirely adequate for new and smaller blogs with modest requirements.&lt;/p&gt;
&lt;p&gt;Managed cloud hosting provides a more flexible infrastructure model and can reduce the amount of technical administration required from the website owner. Cloud environments can also provide greater scalability and redundancy, although the exact capabilities depend on the hosting provider and plan.&lt;/p&gt;
&lt;p&gt;For a growing blog, the decision should therefore be based on measurable requirements rather than the prestige of a particular hosting category.&lt;/p&gt;
&lt;p&gt;Start with the site's current traffic, resource consumption, performance, reliability requirements, technical workload, and budget. If shared hosting continues to meet those requirements, there is little reason to upgrade solely for the sake of upgrading.&lt;/p&gt;
&lt;p&gt;If the blog is encountering resource limitations or requires greater scalability and managed infrastructure, cloud hosting may provide the additional capacity and operational support needed for the next stage of growth.&lt;/p&gt;
&lt;p&gt;The best hosting decision is ultimately the one that matches the website's actual workload today while providing a practical path for its expected development.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/29077/shared-hosting-vs-managed-cloud-hosting-which-is-right-for-your-growing-blog</guid>
<pubDate>Tue, 29 Sep 2026 13:22:40 +0000</pubDate>
</item>
<item>
<title>I Built a Bulletproof Personal Email and Identity System for the Price of a Coffee a Year.</title>
<link>https://coderlegion.com/27073/i-built-a-bulletproof-personal-email-and-identity-system-for-the-price-of-a-coffee-a-year</link>
<description>&lt;p&gt;I quit Gmail. Not dramatically — no manifesto, no LinkedIn post about &quot;digital sovereignty.&quot; I just got tired of being the product in a relationship I never signed up for, tired of knowing that somewhere in a Mountain View data center there's a shockingly accurate profile of me built from thirteen years of subject lines, and tired of the fact that my entire digital identity — every password reset, every &quot;verify it's you&quot; — routed through a single company that owes me nothing and could nuke my account for a TOS violation I'll never fully understand.&lt;/p&gt;
&lt;p&gt;So I rebuilt it. Properly, as an engineer, not as someone who read one privacy blog and panic-deleted their contacts. What follows is the actual architecture: the domain, the mail routing, the encrypted mailbox, the hardware keys, and the self-hosted photo/file layer that finally let me tell Google Photos to get lost too. I'm also going to correct a popular myth along the way, because half the &quot;de-googling&quot; guides floating around right now are recommending a setup that's been dead since 2023 and don't seem to have noticed.&lt;/p&gt;
&lt;p&gt;Let's build it properly.&lt;/p&gt;
&lt;h3 id=&quot;first-let-me-kill-a-myth-free-custom-domain-corporate-email-mostly-doesn-t-exist-anymore&quot;&gt;First, Let Me Kill a Myth: &quot;Free Custom-Domain Corporate Email&quot; Mostly Doesn't Exist Anymore&lt;/h3&gt;
&lt;p&gt;If you've read any de-googling guide from the last few years, you've seen some version of this recipe: buy a domain, bolt it onto a free-tier business email suite from whatever regional Google Workspace competitor was fashionable that year, get real custom-domain mailboxes at zero cost, done. It used to work, for a bunch of different providers, and half the tutorials still floating around online are reheating a version of that trick from an era that's already over.&lt;/p&gt;
&lt;p&gt;The honest 2026 landscape: Google Workspace killed its free custom-domain tier years ago and never brought it back. Microsoft 365 never had one. Most &quot;free business email&quot; providers that still advertise a genuinely free custom-domain tier cap you hard — a handful of users, a few gigabytes, webmail-only with no real IMAP/POP access, meaning no Outlook, no Apple Mail, no third-party client. Fine for a solo side project, not something you want to build your actual identity on. I'm mentioning this loudly because nothing kills your credibility as &quot;the security guy&quot; faster than shipping someone a setup guide built around a free tier that got quietly gutted three years ago.&lt;/p&gt;
&lt;p&gt;So here's the actual, currently-true architecture, and it's honestly better than any single free-tier suite anyway, because it doesn't depend on one company's continued generosity.&lt;/p&gt;
&lt;h3 id=&quot;the-architecture&quot;&gt;The Architecture&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;your-domain.com (registered, DNS on Cloudflare)
        │
        ▼
Cloudflare Email Routing  (free, forever, forwards mail — no mailbox of its own)
        │
        ▼
Proton Mail  (the real, encrypted mailbox — zero-access, custom domain optional)
        │
        ▼
YubiKey / FIDO2 hardware key  (guards the front door to everything above)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Three moving parts, one hardware key protecting all of them. Let's go through each layer, because the interesting engineering is in &lt;em&gt;why&lt;/em&gt; each piece sits where it does, not just in the click-here-click-there setup steps you can already find in eleven other tutorials.&lt;/p&gt;
&lt;h4 id=&quot;layer-1-the-domain-and-why-the-registrar-matters-more-than-you-think&quot;&gt;Layer 1: The Domain, and Why the Registrar Matters More Than You Think&lt;/h4&gt;
&lt;p&gt;Buy a domain. Doesn't matter much which TLD, but do yourself a favor and register it directly through &lt;strong&gt;Cloudflare Registrar&lt;/strong&gt;, which sells at wholesale/cost pricing with no markup, no upsell renewal traps, and it lands your DNS on Cloudflare's infrastructure by default — which you need anyway for Email Routing in the next step.&lt;/p&gt;
&lt;p&gt;Two settings people skip that you shouldn't:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;WHOIS privacy&lt;/strong&gt; — on by default with most modern registrars now, but verify it. Your name and home address do not need to be a &lt;code&gt;whois&lt;/code&gt; lookup away from anyone who's curious.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Registry lock / registrar transfer lock&lt;/strong&gt; — this stops someone from social-engineering their way into transferring your domain out from under you. Your entire identity system is built on top of a domain name. Whoever controls the domain controls the DNS. Whoever controls the DNS controls where your mail goes. This is your actual root of trust, and it deserves more paranoia than the mailbox does.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;layer-2-cloudflare-email-routing-the-free-plumbing&quot;&gt;Layer 2: Cloudflare Email Routing — The Free Plumbing&lt;/h4&gt;
&lt;p&gt;This is the part that's genuinely free, forever, no asterisk. It is &lt;strong&gt;not&lt;/strong&gt; a mailbox — I want to be precise here because a lot of tutorials get sloppy about this and it causes confusion. Email Routing receives mail addressed to anything at your domain and forwards it to a real, existing inbox you already control. There's no login, no storage, no IMAP server sitting on Cloudflare's side.&lt;/p&gt;
&lt;p&gt;Setup, for real this time:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. Add your domain to Cloudflare (nameservers must point to Cloudflare)
2. Dashboard → Email → Email Routing → Enable
3. Cloudflare auto-adds the MX and SPF TXT records for you
4. Add a &quot;Destination address&quot; — this is where mail actually lands
   (verify it: Cloudflare emails you a confirmation link)
5. Create routing rules:
     *Emails are not allowed*     → forward to → your Proton Mail address
     *@your-domain.com       → catch-all  → same destination (optional)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The free tier gives you &lt;strong&gt;200 routing rules per domain and 200 destination addresses per account&lt;/strong&gt;, with a 25 MiB inbound message cap — genuinely generous limits that most humans will never bump into. The one thing to understand clearly: this is &lt;strong&gt;receive-only&lt;/strong&gt;. Hit reply and your message goes out from whatever mailbox you're actually forwarding into, not from a magic Cloudflare SMTP server. That's fine, because the next layer is where sending actually happens.&lt;/p&gt;
&lt;h4 id=&quot;layer-3-proton-mail-your-actual-mailbox-not-just-a-backup-channel-&quot;&gt;Layer 3: Proton Mail — Your Actual Mailbox, Not Just a &quot;Backup Channel&quot;&lt;/h4&gt;
&lt;p&gt;Here's where I'm going to gently push back on the brief I was given, because architecturally it doesn't quite hold up: Proton Mail isn't really a &quot;backup secure channel&quot; sitting behind something else — it's the actual encrypted mailbox doing the real work. Cloudflare Email Routing has nowhere to forward mail &lt;em&gt;to&lt;/em&gt; unless something on the other end is actually storing and encrypting it. Proton is that something.&lt;/p&gt;
&lt;p&gt;Two ways to wire it up, depending on how much you want to spend:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;$0 path:&lt;/strong&gt; free Proton Mail account as the destination for Cloudflare's forwarding rules. You receive at &lt;code&gt;*Emails are not allowed*&lt;/code&gt;, it lands zero-access-encrypted in Proton, and you reply from your &lt;code&gt;@proton.me&lt;/code&gt; address (or configure Gmail/whatever client-side &quot;send as&quot; trickery you like — it's the same limitation Cloudflare has, just one layer removed).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;~$4–5/month path:&lt;/strong&gt; Proton Mail Plus (or Unlimited) supports &lt;strong&gt;native custom domains&lt;/strong&gt; — full two-way send-and-receive as &lt;code&gt;*Emails are not allowed*&lt;/code&gt;, no forwarding hop needed at all, Proton handles your domain's MX directly. This is the cleaner setup if you want your custom address to be indistinguishable from a &quot;real&quot; hosted mailbox, and it skips Cloudflare Email Routing for mail entirely (you'd still likely keep Cloudflare as your DNS host for everything else).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Zero-access encryption means Proton's own infrastructure can't read your mail content even if compelled to — this is architecturally different from Gmail, where Google absolutely can and does read metadata and content for ad targeting, ML training, and &quot;safety&quot; scanning, whatever their current PR phrasing for that is this quarter.&lt;/p&gt;
&lt;h3 id=&quot;layer-4-the-yubikey-and-what-fido2-webauthn-actually-is-under-the-hood&quot;&gt;Layer 4: The YubiKey, and What FIDO2/WebAuthn Actually Is Under the Hood&lt;/h3&gt;
&lt;p&gt;This is the part every de-googling guide name-drops and almost none actually explain, so let's fix that.&lt;/p&gt;
&lt;p&gt;A YubiKey isn't &quot;a password, but physical.&quot; It's a hardware implementation of &lt;strong&gt;public-key cryptography for authentication&lt;/strong&gt;. When you register the key with a service, the key generates a unique public/private keypair &lt;em&gt;for that specific domain&lt;/em&gt; — the private key never leaves the hardware, ever, under any circumstances, not even during authentication. The service stores the public key. To log in, the service sends a challenge, your key signs it with the private key, and the service verifies the signature. Nothing secret ever crosses the network. There is no password to phish, because there's no password in the exchange at all — just a domain-bound cryptographic signature that a phishing site literally cannot forge, because it can't reproduce your domain's cryptographic challenge context.&lt;/p&gt;
&lt;p&gt;That domain-binding is the entire point, and it's why WebAuthn/FIDO2 is considered close to phishing-proof in a way SMS codes and even TOTP apps aren't — a fake login page at &lt;code&gt;proton-login-secure.com&lt;/code&gt; can absolutely trick you into typing a TOTP code, and that stolen code works. It cannot trick your YubiKey, because the key checks the actual origin before it signs anything, and it will simply refuse to respond to a domain it wasn't registered against.&lt;/p&gt;
&lt;p&gt;Practical setup:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Buy two.&lt;/strong&gt; One you carry, one that lives somewhere safe (a drawer, a safe deposit box, not &quot;in a drawer next to the first one&quot;). Register both as separate security keys everywhere. Losing your only key locks you out of your own life; losing one of two is a Tuesday.&lt;/li&gt;
&lt;li&gt;Register it on &lt;strong&gt;Proton&lt;/strong&gt; (Account Settings → Security → Two-factor authentication → Security keys), on &lt;strong&gt;Cloudflare&lt;/strong&gt; (this protects your DNS — arguably your most important account of all, per the root-of-trust point above), on &lt;strong&gt;GitHub&lt;/strong&gt;, and on your password manager.&lt;/li&gt;
&lt;li&gt;One honest nuance worth knowing, because it'll make you sound sharp in a security discussion rather than someone who just read the marketing page: Proton's &quot;FIDO2&quot; support is, more precisely, &lt;strong&gt;U2F running under the FIDO2 umbrella&lt;/strong&gt; — you still authenticate with username and password &lt;em&gt;plus&lt;/em&gt; the key, not a full passwordless discoverable-credential flow the way Google or Microsoft now support natively. It's still genuinely phishing-resistant and worth using; it's just not the fully passwordless flavor some competitors ship. Small distinction, but the kind of thing that separates &quot;I read a blog post&quot; from &quot;I actually understand what I deployed.&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;the-password-manager-you-still-need&quot;&gt;The Password Manager You Still Need&lt;/h4&gt;
&lt;p&gt;A hardware key protects logins that support it. Everything else — every random SaaS tool, every forum, every one-off account — still needs a strong, unique password, and you still need somewhere to keep them. &lt;strong&gt;Bitwarden&lt;/strong&gt; (or its self-hostable fork, &lt;strong&gt;Vaultwarden&lt;/strong&gt;, which runs happily on a Raspberry Pi) supports FIDO2/WebAuthn as an unlock method itself, so your entire password vault ends up gated behind the same hardware key guarding your mail. One key, one consistent security model, instead of a different app-based 2FA scheme for every service you own.&lt;/p&gt;
&lt;h3 id=&quot;de-googling-the-rest-files-and-photos&quot;&gt;De-Googling the Rest: Files and Photos&lt;/h3&gt;
&lt;p&gt;Email was never the whole problem. Google Photos and Google Drive are the other two legs of the stool, and 2026 finally has a clean, boring, mature answer for both — you just need two different tools, because they solve two different problems and pretending one tool does both is how people end up disappointed.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Immich&lt;/strong&gt; replaces Google Photos specifically. It's the closest like-for-like clone that exists: native iOS and Android apps with automatic background backup, CLIP-based natural-language search (&quot;photos of a dog on a beach&quot; actually works), on-device-adjacent face recognition, timeline and map views. AGPL-3.0, open source, sitting north of &lt;strong&gt;100,000 GitHub stars&lt;/strong&gt; as of mid-2026. Budget real resources for it — figure roughly 1.5–2GB of idle RAM and more under load for the ML workers doing face/search indexing; this is not a Raspberry Pi project unless you're patient.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nextcloud&lt;/strong&gt; replaces Google Drive, Calendar, and Contacts — a general-purpose self-hosted platform rather than a photo-specific app. Its own Photos app exists but is, by every current comparison, the weakest part of the suite; if photos are your main goal, don't lead with Nextcloud for that job.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The honest, slightly annoying truth: run both, side by side, on the same box if it has the RAM. They don't conflict, they solve different problems, and &quot;one self-hosted app to rule them all&quot; is a myth in this ecosystem the same way &quot;one language to rule them all&quot; is in ours. Nextcloud handles your documents and calendar; Immich handles your camera roll. You now maintain two databases and two upgrade paths instead of one, and that is the actual, non-negotiable cost of self-hosting — nobody hands you Google's engineering team for free, you're trading their maintenance burden for your own.&lt;/p&gt;
&lt;h3 id=&quot;the-part-nobody-mentions-don-t-self-host-the-mail-server-itself&quot;&gt;The Part Nobody Mentions: Don't Self-Host the Mail &lt;em&gt;Server&lt;/em&gt; Itself&lt;/h3&gt;
&lt;p&gt;I want to head off the inevitable next question, because I can feel some of you already reaching for &lt;code&gt;postfix&lt;/code&gt; and a fresh VPS: &lt;strong&gt;do not run your own SMTP server for this.&lt;/strong&gt; I've written about self-hosting plenty of things on this blog, and mail is the one category where I will talk you out of it every single time. Port 25 is blocked outbound by default on most major cloud providers specifically because of spam abuse. A brand-new IP has zero sending reputation and lands in spam folders by default. Getting off the major blocklists once you're on them is a slow, humiliating, manual process involving web forms and goodwill. Proton and Cloudflare have already spent years building and defending the sending reputation you're borrowing — let them keep doing that job. Self-host your files, your photos, your git repos, your home automation. Don't self-host your mail's deliverability reputation; you will lose that fight against Gmail's spam filter and you won't even get a good war story out of it.&lt;/p&gt;
&lt;p&gt;What you &lt;em&gt;should&lt;/em&gt; configure yourself, regardless of which mail path you pick: &lt;strong&gt;SPF, DKIM, and DMARC&lt;/strong&gt; records on your domain. These are the DNS records that tell the rest of the internet &quot;only these servers are allowed to send mail as me,&quot; and without them your domain is a much easier target for someone to spoof &lt;code&gt;*Emails are not allowed*&lt;/code&gt; in a phishing email sent to your own contacts. Both Cloudflare Email Routing and Proton's custom domain setup walk you through adding these automatically — just don't skip the step because the wizard finished without complaining.&lt;/p&gt;
&lt;h3 id=&quot;what-this-actually-costs&quot;&gt;What This Actually Costs&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Domain: roughly $10–15/year, depending on TLD&lt;/li&gt;
&lt;li&gt;Cloudflare Email Routing: $0, forever&lt;/li&gt;
&lt;li&gt;Proton Mail: $0 (free tier, forwarding path) or ~$50–60/year (custom domain, native send-and-receive)&lt;/li&gt;
&lt;li&gt;Vaultwarden self-hosted, or Bitwarden free tier: $0&lt;/li&gt;
&lt;li&gt;Two YubiKeys: roughly $50–60 total, one-time, and they'll outlive several phones&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Total: somewhere between the price of a domain name alone and the price of a decent dinner out, once a year, for a mail and identity system where no single ad-funded company holds the keys to your entire digital life. Not bad for an afternoon of DNS records and one very satisfying moment of finally deleting the Gmail app off your phone.&lt;/p&gt;
</description>
<category>Discussions</category>
<guid isPermaLink="true">https://coderlegion.com/27073/i-built-a-bulletproof-personal-email-and-identity-system-for-the-price-of-a-coffee-a-year</guid>
<pubDate>Sun, 13 Sep 2026 18:14:52 +0000</pubDate>
</item>
<item>
<title>Gnat - Self-Hosted Analytics</title>
<link>https://coderlegion.com/24653/gnat-self-hosted-analytics</link>
<description>&lt;p&gt;A few months back I was crawling the web for a side project and came across an analytics platform's data that had exposed users' raw IPs. It wasn't malicious, just careless. But it stuck with me: most people using these tools have no idea their visitors' data is sitting around like that.&lt;/p&gt;
&lt;p&gt;That's the moment that pushed me to build &lt;strong&gt;Gnat&lt;/strong&gt;, a self-hosted analytics tool that doesn't cut corners on privacy, but also doesn't force you into a painful setup to get it.&lt;/p&gt;
&lt;h3 id=&quot;no-third-party-no-phoning-home&quot;&gt;No third party, no phoning home&lt;/h3&gt;
&lt;p&gt;Gnat runs entirely on infrastructure you control. No third party in the loop, no API calling home anywhere, no data leaving your server. Completely free and open source.&lt;/p&gt;
&lt;h3 id=&quot;one-binary-zero-bloat&quot;&gt;One binary, zero bloat&lt;/h3&gt;
&lt;p&gt;Most self-hosted analytics tools make you choose: something lightweight with barely any real analysis, or something with real depth that also means Docker, a multi-service stack, and its own ops burden.&lt;/p&gt;
&lt;p&gt;Gnat is a single Go binary. No CGO, no Docker, no multi-service stack. The dashboard is compiled straight into the executable.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;tar xzf gnat-vX.Y.Z-linux-amd64.tar.gz
cd gnat-vX.Y.Z-linux-amd64
./gnat
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That's the whole install.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://gnat-np2m.onrender.com/dashboard&quot;&gt;https://gnat-np2m.onrender.com/dashboard&lt;/a&gt; (password: &lt;code&gt;vJzTMw0bjTtWHyNpBCPGaZqE&lt;/code&gt;, feel free to poke around, it's a shared demo instance so please be gentle with it)&lt;/p&gt;
&lt;p&gt;Visit my portfolio here and see it appear on the analytics dashboard &lt;a rel=&quot;nofollow&quot; href=&quot;https://var-raphael.vercel.app&quot;&gt;https://var-raphael.vercel.app&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;real-analytical-depth&quot;&gt;Real analytical depth&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Pageviews and custom events via JSON POST, no per-language SDKs&lt;/li&gt;
&lt;li&gt;Funnels, cohorts, retention curves&lt;/li&gt;
&lt;li&gt;Auto-discovered path analysis&lt;/li&gt;
&lt;li&gt;SQLite by default, or Postgres/MySQL if that's how you already run infrastructure&lt;/li&gt;
&lt;li&gt;CSV, JSON, and raw SQL export, it's your data&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;built-for-the-agent-era&quot;&gt;Built for the agent era&lt;/h3&gt;
&lt;p&gt;Gnat ships with a native MCP server. Claude or any MCP-compatible agent can query your analytics directly, no separate API glue.&lt;/p&gt;
&lt;h3 id=&quot;where-it-s-at&quot;&gt;Where it's at&lt;/h3&gt;
&lt;p&gt;Early days, v0.1.0, and I'm actively building on it. Multi-site support, SSO/team access, and managed hosting are on the roadmap but not built yet.&lt;/p&gt;
&lt;p&gt;Licensed under AGPLv3, free to self-host and modify for any purpose, including commercially, but if you run a modified version as a service for others, the source has to stay open under the same terms.&lt;/p&gt;
&lt;p&gt;I'd love feedback, issues, and contributors, especially if you've felt the same Docker-and-multi-service fatigue trying to self-host analytics.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/var-raphael/Gnat&quot;&gt;https://github.com/var-raphael/Gnat&lt;/a&gt;&lt;/p&gt;
</description>
<category>Launches</category>
<guid isPermaLink="true">https://coderlegion.com/24653/gnat-self-hosted-analytics</guid>
<pubDate>Fri, 14 Aug 2026 19:45:17 +0000</pubDate>
</item>
<item>
<title>What Self-Hosting a Workflow Engine Actually Costs You</title>
<link>https://coderlegion.com/23476/what-self-hosting-a-workflow-engine-actually-costs-you</link>
<description>&lt;p&gt;Every automation conversation reaches the same fork: pay per execution on someone else's runtime, or run it yourself. The honest version of that decision is not about ideology, it is about which costs you are willing to see as a line item and which ones you would rather absorb as your own time. Here is what self-hosting a workflow engine actually costs, using the one we build and maintain as the worked example.&lt;/p&gt;
&lt;h3 id=&quot;one-php-application-and-one-sqlite-file&quot;&gt;One PHP Application and One SQLite File&lt;/h3&gt;
&lt;p&gt;Workflow Chain Engine is deliberately small. The whole system is one PHP application with a single SQLite file, no framework, no build step, and no dependency install, so it runs on a three dollar shared host as happily as on a VPS or in a container. The visual editor ships inside the project, so nothing loads from anyone else's servers while you work.&lt;/p&gt;
&lt;p&gt;That shape decides the operating cost. Backups are a folder copy. Moving hosts is a folder copy. There is no queue service to keep alive, no database server to tune, and no upgrade that needs a migration weekend. The code is MIT licensed and lives on GitHub, so the version you run is the version you can read.&lt;/p&gt;
&lt;h3 id=&quot;four-triggers-one-run-history&quot;&gt;Four Triggers, One Run History&lt;/h3&gt;
&lt;p&gt;A flow is only useful at the moment it starts, and there are four of those: a webhook another service calls, an authenticated run API for your own code, a schedule, and a button. All four fill the same workflow variables from whatever they carry, and all four land in the same run history.&lt;/p&gt;
&lt;p&gt;One webhook detail is worth stealing no matter what you run. The response carries the run's real result, meaning the resolved success or fail message with its variables filled in, the step count, the run ID and the duration. Services that display webhook responses then show something meaningful, and services that retry on failure can react to a genuine Fail instead of guessing from a status code.&lt;/p&gt;
&lt;h3 id=&quot;where-self-hosting-actually-bites&quot;&gt;Where Self-Hosting Actually Bites&lt;/h3&gt;
&lt;p&gt;The server is not the hard part. Observability is. A hosted product hands you run history, alerting and retries as table stakes, and the moment you self-host those become things you have to insist on. Every node in our engine logs after the placeholders resolve, so a run detail shows the real URL that was called, the real comparison that was made, and the value each variable ended on. That is the difference between a two minute fix and an afternoon spent reproducing a failure.&lt;/p&gt;
&lt;p&gt;The second real cost is credentials. They now live in your database, which is exactly why some teams self-host and exactly why others should not. If nobody owns rotating them, self-hosting moved a risk rather than removing one.&lt;/p&gt;
&lt;h3 id=&quot;who-should-not-bother&quot;&gt;Who Should Not Bother&lt;/h3&gt;
&lt;p&gt;If your workflows are mostly connectors between large SaaS products, the volume is modest, and nobody on the team wants to own an upgrade path, pay the per-run price and get on with your work. Self-hosting earns its keep when data cannot leave your environment, when execution volume makes per-run pricing look silly, or when you want the workflows themselves as artifacts you version alongside the rest of your infrastructure.&lt;/p&gt;
&lt;h3 id=&quot;what-to-take-away&quot;&gt;What To Take Away&lt;/h3&gt;
&lt;p&gt;Self hosting is not cheaper by default. It is cheaper when the things you need most are control over your data, predictable cost at volume, and a run log you can actually read. Judge any engine on that last one, ours included, by looking at what it tells you after a run fails rather than how the editor looks when everything works.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.aiappsapi.com/Workflow-Chain-Engine/&quot;&gt;Full documentation, the six node types, and the source.&lt;/a&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/23476/what-self-hosting-a-workflow-engine-actually-costs-you</guid>
<pubDate>Sun, 26 Jul 2026 14:30:00 +0000</pubDate>
</item>
<item>
<title>How Much Does WooCommerce Hosting Cost? (Pricing Guide for New Store Owners)</title>
<link>https://coderlegion.com/21959/how-much-does-woocommerce-hosting-cost-pricing-guide-for-new-store-owners</link>
<description>&lt;p&gt;Most new WooCommerce store owners either overpay for hosting features they don't need, or pick the cheapest shared plan and wonder why checkout feels slow.&lt;/p&gt;
&lt;p&gt;The real answer sits in the middle: WooCommerce-optimized shared or entry-level VPS hosting, usually $15–$40/month, is the right fit for a simple store just getting started. Dedicated servers and fully managed plans only start paying off once you have consistent daily traffic.&lt;/p&gt;
&lt;p&gt;The biggest cost drivers aren't traffic alone — it's the number of products/images, plugin load, and whether backups/SSL are bundled in or billed separately.&lt;/p&gt;
&lt;p&gt;I wrote a full pricing breakdown with real ranges here: &lt;a rel=&quot;nofollow&quot; href=&quot;https://amanurrahman.com/blog-post/woocommerce-hosting-cost&quot;&gt;https://amanurrahman.com/blog-post/woocommerce-hosting-cost&lt;/a&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/21959/how-much-does-woocommerce-hosting-cost-pricing-guide-for-new-store-owners</guid>
<pubDate>Sun, 05 Jul 2026 16:38:24 +0000</pubDate>
</item>
<item>
<title>A Simple Beginners Guide to Purchasing a VPS</title>
<link>https://coderlegion.com/21661/a-simple-beginners-guide-to-purchasing-a-vps</link>
<description>&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Continuing on our developer's  journey, we will manage our Directus backend, supported by a PostgreSQL database and a Redis cache.&lt;br&gt;
To pull this off, we will need a VPS.&lt;/p&gt;
&lt;p&gt;As I would have stated in my previous post, we have to manage our VPS ourselves. I hope that you are as excited as I am, because we get to dig under the hood instead of letting someone else do it.&lt;/p&gt;
&lt;p&gt;Our first task would be to purchase a VPS. &lt;/p&gt;
&lt;p&gt;Before I continue, I want to be clear about who can benefit from this. This post will not meet the needs of an enterprise-grade organization as they will have strict compliance and security regulations. They often have specialized contracts with major cloud providers like AWS and Microsoft Azure; you get the picture. You, as a developer, will not be in the office that makes the decision as to what hosting solution the company will provide. It will be a team that does that.&lt;/p&gt;
&lt;p&gt;If we consider a medium-sized business, this will most likely not be the choice of any one person either. Individual developers rarely have total freedom, but if they are senior within the organization, they may have influence.&lt;/p&gt;
&lt;p&gt;It's in the start-up to small business arena, where a developer wears multiple hats, that you get the real opportunity of choosing the hosting solution or if you're developing your own app. At this scale, cost is a real factor, and so you have to consider the budget allocated carefully. Here is where all the excitement is.&lt;/p&gt;
&lt;p&gt;Let’s get Started!&lt;/p&gt;
&lt;h3 id=&quot;purchasing-a-vps&quot;&gt;Purchasing a VPS&lt;/h3&gt;
&lt;p&gt;Purchasing a VPS can be a daunting task. When I started out, I decided to go on YouTube and search for the best hosting provider.&lt;/p&gt;
&lt;p&gt;I was bombarded by terms I did not understand, metrics that I could not confirm, and a list of hosting providers that seemed to all look the same. In time I got to understand a bit more, and so I started to make some sense out of the hype. Some videos were excellent; others were entertaining.&lt;/p&gt;
&lt;p&gt;I’m no expert, but I’ve simplified the process for myself, so I’m sharing it with you. There are six basic characteristics to consider:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; * How many CPU cores do I need
 * How much RAM do I need
 * What type of hard drive and what size.
 * How much bandwidth do I anticipate will be used.
 * What OS should I use
 * Cost
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;let-s-start-with-the-os&quot;&gt;Let’s start with the OS&lt;/h4&gt;
&lt;p&gt;I choose Ubuntu every time because of the community that supports it, low resource consumption, and great stability. You don’t have to select Ubuntu; you may like another flavor of Linux. What I would recommend is to stick to one that you feel comfortable with and learn it inside out; that way you can become more proficient at configuring your VPS. I like Ubuntu for the reasons I stated above.&lt;/p&gt;
&lt;h4 id=&quot;cpu-cores&quot;&gt;CPU Cores&lt;/h4&gt;
&lt;p&gt;Ubuntu Server does not consume plenty of resources, so I never go for the most robust plan. Developers that have the opportunity to select their own hosting solution may be doing so for a start-up or small business. With this in mind, I would easily select a 2CPU-4CPU  setup to start with.&lt;/p&gt;
&lt;p&gt;It will not break the bank, and it's a good place to start, especially if you don’t have solid performance figures to work with, like site utilization.&lt;/p&gt;
&lt;p&gt;As a developer creating an app, you want to launch your minimum viable product (MVP) because you need to get to market to understand your audience as soon as possible.&lt;/p&gt;
&lt;p&gt;A basic online presence for a start-up with the intention to scale.&lt;/p&gt;
&lt;p&gt;2CPU—4CPU cores will get you in the ring to pack a good punch.&lt;/p&gt;
&lt;h4 id=&quot;ram&quot;&gt;RAM&lt;/h4&gt;
&lt;p&gt;The recommendation for Coolify to run smoothly is 2 GB. Coolify mentions that it can run on servers with lower specs, but they will always recommend higher than the minimum.&lt;/p&gt;
&lt;p&gt;RAM consumption generally boils down to four main culprits. Server-side rendering (SSR), active user session, database caching, and the code build process. In my opinion, 4 GB—8 GB is a good place to start because it gives you a great entry point from which you can build. Again, it's not going to break the bank, and can get you started with pretty decent performance.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If your code is not efficient and your application is not optimized, that can really affect your performance.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;disk&quot;&gt;DISK&lt;/h4&gt;
&lt;p&gt;I will always recommend NVMe disk space. It has the best read/write performance compared to regular HDD disks. As for the disk size, I recommend anything between 20 GB and 50 GB to start with.&lt;/p&gt;
&lt;h4 id=&quot;bandwidth&quot;&gt;Bandwidth&lt;/h4&gt;
&lt;p&gt;Bandwidth for a beginner will be difficult to determine. Three specific elements that can cause unexpected bandwidth spikes are unoptimized images, self-hosted videos, and malicious bots, so watch out for these. I would recommend starting at 500 GB to 1 TB (some hosting providers offer 4 TB on basic plans and even unlimited).&lt;/p&gt;
&lt;h4 id=&quot;the-last-factor-to-consider-cost-&quot;&gt;The last factor to consider, cost.&lt;/h4&gt;
&lt;p&gt;As a developer looking for a hosting solution on a budget, I would not recommend going beyond USD50 dollars to start. My recommendation for this is because you may not have the experience to properly assess what your initial needs might be. You may not have access to the right tools to properly inform you as to the direction to go. It's better to spend a small amount upfront and then realize that you need to scale up than to throw a lot of cash up front to then scale down, realizing that you did not need it.&lt;/p&gt;
&lt;p&gt;Let’s do the math. If you buy coffee regularly, let’s say Starbucks or Dunkin', that's about 14 cups. You may drink that in 1 week. If you drink lattes, iced cold brews, or frappuccinos, that's about 8 to 9 cups.&lt;/p&gt;
&lt;p&gt;If we consider McDonald's, Wendy's, and Chick-fil-A, that could be roughly 4 combo meals.&lt;/p&gt;
&lt;p&gt;I hope you get the picture. USD50 dollars can usually be spent on things that we don’t need. So it should not break the bank (for some it may; I do understand that).&lt;/p&gt;
&lt;p&gt;I think USD50 dollars is a good limit to start with, no need to spend more. If you get a good deal, you could always spend less.&lt;/p&gt;
&lt;h4 id=&quot;the-trap&quot;&gt;The Trap&lt;/h4&gt;
&lt;p&gt;Some hosting providers may put up a very competitive price, like USD2.99 or USD4.99. You’re so excited that you did not notice a small text that reads, &lt;em&gt;renews at USD20.00&lt;/em&gt;. Please be aware.&lt;/p&gt;
&lt;h4 id=&quot;choosing-a-hosting-provider&quot;&gt;Choosing a hosting provider&lt;/h4&gt;
&lt;p&gt;I would rather not recommend a hosting provider. I think that is up to you. Furthermore, I have given you a guide as to what to look for, and I think you should be fine. What you should do, however, is research customer reviews carefully. There are many providers that have excellent hardware available, and they have proven to be reliable. Some people may swear by a particular provider; I won’t do that. I currently use two, and they meet my needs; that is most important.&lt;/p&gt;
&lt;p&gt;The thing that I think separates good hosting providers from bad ones is not so much the hardware they offer but the customer service.&lt;/p&gt;
&lt;p&gt;As Andrew Henderson, the Nomad Capitalist, often says, &lt;em&gt;Go where you’re treated best.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;My recommendation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; * 2CPU—4CPU Cores
 * 4 GB-8 GB RAM
 * 20 GB-50 GB NVMe Disk Space
 * 500 GB-1TB Bandwidth
 * Cost—USD$50 as the limit; you could always pay less. I don’t recommend starting over this.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I hope this helps. If you’re new to this, I tried 6 hosting providers, and now I’ve stuck with just 2.&lt;/p&gt;
&lt;p&gt;You don’t have to be intimidated by all the hype that is often thrown around. You need to be single-minded, not narrow-minded. Take your time; make sure you understand. Be focused, and I find prayer helps in everything, so I do pray to the Lord God of heaven and earth.&lt;/p&gt;
&lt;p&gt;Cheers, happy VPS hunting!&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/21661/a-simple-beginners-guide-to-purchasing-a-vps</guid>
<pubDate>Wed, 01 Jul 2026 04:56:44 +0000</pubDate>
</item>
<item>
<title>Why Self-Hosted AI Workflow Automation Matters?</title>
<link>https://coderlegion.com/21401/why-self-hosted-ai-workflow-automation-matters</link>
<description>&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://hexabot.ai&quot;&gt;AI workflow automation&lt;/a&gt; is quickly becoming one of the most important layers of modern business software.&lt;/p&gt;
&lt;p&gt;Teams no longer want simple scripts that move data from one app to another. They want AI systems that can understand context, trigger actions, use tools, search knowledge, route conversations, escalate to humans, and adapt to changing business processes.&lt;/p&gt;
&lt;p&gt;That shift is powerful. But it also creates a new question:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where should your AI automation actually run?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;For many organizations, the default answer has been cloud-based SaaS. It is easy to start, fast to test, and usually requires little infrastructure knowledge. But as AI workflows become more deeply connected to customer conversations, internal operations, private data, and business-critical processes, self-hosting becomes much more than a deployment preference.&lt;/p&gt;
&lt;p&gt;It becomes a strategic choice.&lt;/p&gt;
&lt;p&gt;Self-hosted AI workflow automation gives teams more control over data, security, compliance, customization, reliability, and long-term independence. For companies that want to use AI seriously in production, that control matters.&lt;/p&gt;
&lt;h3 id=&quot;what-is-self-hosted-ai-workflow-automation-&quot;&gt;What Is Self-Hosted AI Workflow Automation?&lt;/h3&gt;
&lt;p&gt;Self-hosted AI workflow automation means running your automation platform on infrastructure you control.&lt;/p&gt;
&lt;p&gt;That infrastructure can be a private cloud, a virtual server, an on-premise environment, or a managed environment operated by your technical team. The important point is that the automation engine, data flows, integrations, logs, and configuration are not locked inside a third-party SaaS platform.&lt;/p&gt;
&lt;p&gt;In the context of AI, this becomes especially important because workflows are no longer just moving records between tools. They may process support conversations, analyze internal documents, trigger operational tasks, connect to CRMs, call APIs, search knowledge bases, and use language models to make decisions.&lt;/p&gt;
&lt;p&gt;A traditional workflow might say:&lt;/p&gt;
&lt;p&gt;“When a form is submitted, send an email.”&lt;/p&gt;
&lt;p&gt;An AI workflow can say:&lt;/p&gt;
&lt;p&gt;“Read the customer request, identify the intent, check the customer profile, search the knowledge base, decide whether the issue can be solved automatically, generate a response, trigger an internal action if needed, and escalate to a human if confidence is low.”&lt;/p&gt;
&lt;p&gt;That is a very different level of responsibility.&lt;/p&gt;
&lt;p&gt;When workflows become intelligent, contextual, and action-oriented, the environment where they run becomes part of the trust model.&lt;/p&gt;
&lt;h3 id=&quot;ai-automation-is-moving-closer-to-core-business-operations&quot;&gt;AI Automation Is Moving Closer to Core Business Operations&lt;/h3&gt;
&lt;p&gt;In the early days of automation, most workflows were peripheral. They synchronized leads, copied files, sent notifications, or created tickets.&lt;/p&gt;
&lt;p&gt;Today, AI automation is moving closer to the center of business operations.&lt;/p&gt;
&lt;p&gt;Companies are using AI workflows for customer support, sales qualification, document processing, internal knowledge access, IT support, onboarding, compliance workflows, and operational decision support.&lt;/p&gt;
&lt;p&gt;This means AI systems may interact with sensitive business data, customer identities, contracts, invoices, support histories, internal procedures, and proprietary knowledge.&lt;/p&gt;
&lt;p&gt;The more valuable the workflow, the more sensitive the context usually becomes.&lt;/p&gt;
&lt;p&gt;That is why self-hosting matters. It gives organizations the ability to decide how data moves, where it is stored, which systems can access it, and how the automation layer fits into existing security and governance policies.&lt;/p&gt;
&lt;p&gt;AI workflow automation is not only about productivity. It is about operational control.&lt;/p&gt;
&lt;h3 id=&quot;data-control-is-the-first-reason-self-hosting-matters&quot;&gt;Data Control Is the First Reason Self-Hosting Matters&lt;/h3&gt;
&lt;p&gt;AI workflows often need context to be useful.&lt;/p&gt;
&lt;p&gt;They may need to read messages, retrieve user profiles, search documents, inspect previous interactions, or connect to business systems. Without context, AI automation becomes generic. With context, it becomes useful.&lt;/p&gt;
&lt;p&gt;But context is also where risk begins.&lt;/p&gt;
&lt;p&gt;A cloud automation platform may require data to pass through external infrastructure. That may be acceptable for some use cases, but not for all. Organizations working with regulated industries, enterprise clients, private customer data, or confidential internal knowledge often need stronger guarantees.&lt;/p&gt;
&lt;p&gt;Self-hosted automation allows teams to keep more control over:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;where workflow data is processed&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;where logs and execution history are stored&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;which databases are used&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;which APIs are allowed&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;which models are connected&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;which data leaves the environment&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This does not automatically solve every privacy or compliance challenge. But it gives technical and security teams the foundation they need to design the right architecture.&lt;/p&gt;
&lt;p&gt;For AI workflows, data control is not a nice-to-have. It is one of the conditions for trust.&lt;/p&gt;
&lt;h3 id=&quot;compliance-needs-more-than-a-checkbox&quot;&gt;Compliance Needs More Than a Checkbox&lt;/h3&gt;
&lt;p&gt;Many companies are under pressure to adopt AI while also respecting compliance requirements, privacy policies, customer contracts, and internal governance rules.&lt;/p&gt;
&lt;p&gt;This is especially true for teams serving enterprise customers or operating in sectors such as finance, healthcare, telecom, government, insurance, legal services, and education.&lt;/p&gt;
&lt;p&gt;A common mistake is to treat AI automation as a simple productivity tool. In reality, AI workflows can become part of the organization’s decision-making and communication infrastructure.&lt;/p&gt;
&lt;p&gt;That means companies need to answer practical questions:&lt;/p&gt;
&lt;p&gt;Where is customer data processed? Who can access workflow logs? Can we audit what happened? Can we explain why a workflow made a decision? Can we restrict certain tools or actions? Can we separate environments for development, testing, and production? Can we choose which AI providers or models are used?&lt;/p&gt;
&lt;p&gt;Self-hosted AI workflow automation makes these questions easier to address because the organization has more control over the system design.&lt;/p&gt;
&lt;p&gt;It does not replace legal, security, or compliance work. But it gives teams the technical flexibility to implement policies instead of being forced to adapt to the limitations of a closed platform.&lt;/p&gt;
&lt;h3 id=&quot;security-requires-control-over-the-automation-layer&quot;&gt;Security Requires Control Over the Automation Layer&lt;/h3&gt;
&lt;p&gt;AI workflows are powerful because they connect systems together.&lt;/p&gt;
&lt;p&gt;That is also why they must be secured carefully.&lt;/p&gt;
&lt;p&gt;A workflow automation platform may have access to APIs, databases, messaging channels, CRMs, ticketing systems, internal tools, and knowledge bases. If the platform becomes deeply integrated into operations, it becomes a critical part of the security perimeter.&lt;/p&gt;
&lt;p&gt;With a self-hosted platform, teams can align the automation layer with their own security practices.&lt;/p&gt;
&lt;p&gt;They can manage network access, apply internal authentication rules, control secrets, restrict outbound connections, configure database policies, monitor logs, and deploy inside trusted infrastructure.&lt;/p&gt;
&lt;p&gt;This level of control is difficult to achieve when the automation platform is entirely managed outside the organization.&lt;/p&gt;
&lt;p&gt;The goal is not to say that cloud platforms are always insecure. Many SaaS providers invest heavily in security. The point is that security requirements vary by organization, and some teams need direct control over deployment, access, storage, and integration boundaries.&lt;/p&gt;
&lt;p&gt;For business-critical AI automation, that control can be decisive.&lt;/p&gt;
&lt;h3 id=&quot;self-hosting-reduces-vendor-lock-in&quot;&gt;Self-Hosting Reduces Vendor Lock-In&lt;/h3&gt;
&lt;p&gt;AI automation platforms are becoming the new operational layer between people, software, and AI models.&lt;/p&gt;
&lt;p&gt;Once a company builds dozens of workflows on a platform, switching becomes difficult. The workflows contain business logic, integrations, prompts, conditions, routing rules, and operational knowledge.&lt;/p&gt;
&lt;p&gt;If that logic is locked inside a closed platform, the company may become dependent on one vendor’s pricing, roadmap, uptime, limitations, and export options.&lt;/p&gt;
&lt;p&gt;Self-hosting helps reduce that dependency.&lt;/p&gt;
&lt;p&gt;When teams can run the platform themselves, inspect how workflows are structured, control the runtime, and integrate it into their own stack, they gain more long-term independence.&lt;/p&gt;
&lt;p&gt;This matters even more in AI because the ecosystem changes quickly. New models appear. Regulations evolve. Infrastructure costs fluctuate. Business needs shift.&lt;/p&gt;
&lt;p&gt;A flexible, self-hosted automation layer allows companies to adapt without rebuilding everything from scratch.&lt;/p&gt;
&lt;h3 id=&quot;customization-is-essential-for-real-business-automation&quot;&gt;Customization Is Essential for Real Business Automation&lt;/h3&gt;
&lt;p&gt;No two businesses operate exactly the same way.&lt;/p&gt;
&lt;p&gt;A support workflow for a telecom company is different from a workflow for a SaaS company. A sales qualification process in B2B is different from a public-sector service request. A chatbot for customer support is different from an internal AI assistant connected to company knowledge.&lt;/p&gt;
&lt;p&gt;Generic automation tools are useful for common tasks. But real business automation often requires custom logic, custom integrations, custom channels, custom permissions, and custom deployment constraints.&lt;/p&gt;
&lt;p&gt;Self-hosted AI workflow automation gives technical teams the freedom to extend the platform around the business.&lt;/p&gt;
&lt;p&gt;That can include connecting private APIs, building plugins, integrating with internal systems, adding custom business rules, controlling the user interface, or adapting workflows to local operational needs.&lt;/p&gt;
&lt;p&gt;This is where platforms like Hexabot are especially relevant.&lt;/p&gt;
&lt;p&gt;Hexabot is designed for teams that want the flexibility of AI agents and workflow automation while keeping control over deployment, data, and extensibility. Business teams can design and improve workflows visually, while technical teams can extend the platform with plugins, integrations, channels, and business-specific logic.&lt;/p&gt;
&lt;p&gt;That balance matters because many organizations do not want a rigid no-code tool, but they also do not want to build an AI automation platform from scratch.&lt;/p&gt;
&lt;h3 id=&quot;ai-workflows-need-reliability-not-just-intelligence&quot;&gt;AI Workflows Need Reliability, Not Just Intelligence&lt;/h3&gt;
&lt;p&gt;The AI industry often focuses on model intelligence. But in production, intelligence is not enough.&lt;/p&gt;
&lt;p&gt;A business workflow must be reliable.&lt;/p&gt;
&lt;p&gt;It needs clear triggers, predictable execution, error handling, observability, human escalation, and guardrails. It should be possible to understand what happened when something goes wrong.&lt;/p&gt;
&lt;p&gt;This is especially important with AI agents.&lt;/p&gt;
&lt;p&gt;An AI agent may reason, call tools, retrieve knowledge, and decide what to do next. That makes it more flexible than a traditional automation. But it also means teams need more structure around how the agent operates.&lt;/p&gt;
&lt;p&gt;A self-hosted workflow automation platform can give teams the ability to design that structure.&lt;/p&gt;
&lt;p&gt;Instead of letting AI behave like a black box, teams can build workflows that combine AI reasoning with explicit steps, conditions, approvals, tool restrictions, and fallback paths.&lt;/p&gt;
&lt;p&gt;For example, a customer support workflow can allow AI to answer simple questions automatically, but require human handoff when confidence is low, when the request involves billing, or when the customer expresses frustration.&lt;/p&gt;
&lt;p&gt;That is the right way to think about production AI automation: autonomy where it helps, control where it matters.&lt;/p&gt;
&lt;h3 id=&quot;human-oversight-still-matters&quot;&gt;Human Oversight Still Matters&lt;/h3&gt;
&lt;p&gt;A common assumption is that the goal of AI automation is to remove humans completely.&lt;/p&gt;
&lt;p&gt;In reality, the best AI workflows often keep humans in the loop for important moments.&lt;/p&gt;
&lt;p&gt;Human oversight is useful when decisions are sensitive, data is incomplete, confidence is low, or the customer experience requires empathy and judgment.&lt;/p&gt;
&lt;p&gt;Self-hosted AI workflow automation makes it easier to design human oversight according to the company’s own rules.&lt;/p&gt;
&lt;p&gt;A team can decide when to escalate, who receives the task, what context is shown, how approvals work, and how the final decision is logged.&lt;/p&gt;
&lt;p&gt;This is especially important in customer-facing automation. A chatbot or AI agent should not be judged only by how many conversations it handles automatically. It should also be judged by how safely and smoothly it knows when not to automate.&lt;/p&gt;
&lt;p&gt;The best AI systems do not replace human judgment everywhere. They make human judgment more focused, timely, and effective.&lt;/p&gt;
&lt;h3 id=&quot;cost-predictability-becomes-important-at-scale&quot;&gt;Cost Predictability Becomes Important at Scale&lt;/h3&gt;
&lt;p&gt;Cloud automation platforms are attractive because they are easy to start with. But pricing can become harder to predict as usage grows.&lt;/p&gt;
&lt;p&gt;AI workflows may involve many executions, messages, API calls, model requests, document searches, and team members. As automation becomes more successful, usage increases.&lt;/p&gt;
&lt;p&gt;That is a good problem to have, but it can also create budget uncertainty.&lt;/p&gt;
&lt;p&gt;Self-hosting gives teams more control over infrastructure and scaling costs. Organizations can choose their hosting provider, optimize resources, separate environments, use preferred databases, and decide which AI models are worth using for each workflow.&lt;/p&gt;
&lt;p&gt;Some workflows may need advanced models. Others may work well with smaller models, local inference, rule-based steps, or retrieval-based responses.&lt;/p&gt;
&lt;p&gt;A self-hosted architecture gives teams more room to optimize these decisions.&lt;/p&gt;
&lt;p&gt;Cost control is not only about paying less. It is about understanding what you are paying for and being able to adapt the architecture as the system grows.&lt;/p&gt;
&lt;h3 id=&quot;self-hosted-does-not-mean-isolated&quot;&gt;Self-Hosted Does Not Mean Isolated&lt;/h3&gt;
&lt;p&gt;Self-hosted AI workflow automation does not mean disconnected from the modern AI ecosystem.&lt;/p&gt;
&lt;p&gt;A self-hosted platform can still connect to external APIs, cloud models, open-source models, internal databases, messaging channels, CRMs, and business applications.&lt;/p&gt;
&lt;p&gt;The difference is that the organization controls the orchestration layer.&lt;/p&gt;
&lt;p&gt;This means teams can decide which services to connect, which data to send, which workflows should use external models, and which workflows should stay fully private.&lt;/p&gt;
&lt;p&gt;That flexibility is important because most companies will not use one AI model, one tool, or one deployment pattern forever.&lt;/p&gt;
&lt;p&gt;Some use cases may require cloud LLMs. Others may require private models. Some workflows may run on internal infrastructure. Others may integrate with external services.&lt;/p&gt;
&lt;p&gt;Self-hosting gives companies the ability to choose the right architecture for each use case instead of forcing every workflow through the same SaaS model.&lt;/p&gt;
&lt;h3 id=&quot;why-this-matters-for-ai-agents&quot;&gt;Why This Matters for AI Agents&lt;/h3&gt;
&lt;p&gt;AI agents are becoming one of the most discussed areas of automation.&lt;/p&gt;
&lt;p&gt;An AI agent can plan, use tools, retrieve context, interact with users, and take actions across systems. But the more capable an agent becomes, the more important governance becomes.&lt;/p&gt;
&lt;p&gt;A self-hosted AI workflow automation platform can help teams build agents that are not just powerful, but manageable.&lt;/p&gt;
&lt;p&gt;Instead of giving an AI agent unlimited freedom, teams can define the workflow around it:&lt;/p&gt;
&lt;p&gt;What tools can it use? What data can it access? When should it ask for confirmation? When should it escalate? What should be logged? Which actions are allowed automatically? Which actions require approval?&lt;/p&gt;
&lt;p&gt;This is the difference between experimenting with AI agents and running AI agents in production.&lt;/p&gt;
&lt;p&gt;Businesses do not only need autonomous systems. They need controlled autonomy.&lt;/p&gt;
&lt;h3 id=&quot;the-future-of-ai-automation-is-controlled-extensible-and-self-hostable&quot;&gt;The Future of AI Automation Is Controlled, Extensible, and Self-Hostable&lt;/h3&gt;
&lt;p&gt;AI workflow automation will continue to evolve quickly.&lt;/p&gt;
&lt;p&gt;More workflows will include AI reasoning. More business systems will expose APIs. More teams will expect automation to understand context and take action. More organizations will demand privacy, explainability, and control.&lt;/p&gt;
&lt;p&gt;This creates a clear direction for the next generation of automation platforms.&lt;/p&gt;
&lt;p&gt;They need to be visual enough for business teams, extensible enough for developers, reliable enough for production, and controllable enough for organizations that take data seriously.&lt;/p&gt;
&lt;p&gt;Self-hosting is a key part of that future.&lt;/p&gt;
&lt;p&gt;It gives teams the freedom to build AI workflows around their own infrastructure, security model, business logic, and operational needs.&lt;/p&gt;
&lt;p&gt;For small teams, it means independence and flexibility. For enterprises, it means governance and control. For developers, it means extensibility. For business teams, it means automation that can actually match how the organization works.&lt;/p&gt;
&lt;h3 id=&quot;how-hexabot-approaches-self-hosted-ai-workflow-automation&quot;&gt;How Hexabot Approaches Self-Hosted AI Workflow Automation&lt;/h3&gt;
&lt;p&gt;Hexabot is built for teams that want to create AI agents, conversational automation, and business workflows while keeping control over their platform.&lt;/p&gt;
&lt;p&gt;It combines visual workflow design with developer extensibility, allowing business and technical teams to collaborate on automation without being locked into a rigid black box.&lt;/p&gt;
&lt;p&gt;With Hexabot, teams can build workflows for customer support, internal operations, multichannel conversations, knowledge-based assistance, tool usage, and human handoff.&lt;/p&gt;
&lt;p&gt;The goal is not only to automate tasks. The goal is to help organizations build reliable AI systems that can run in real business environments.&lt;/p&gt;
&lt;p&gt;Self-hosted AI workflow automation matters because AI is becoming part of the operational core of companies.&lt;/p&gt;
&lt;p&gt;And when AI becomes operational, control matters.&lt;/p&gt;
&lt;h3 id=&quot;conclusion-1&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;AI workflow automation is no longer just about saving time.&lt;/p&gt;
&lt;p&gt;It is about how companies connect people, data, software, and intelligent systems.&lt;/p&gt;
&lt;p&gt;As AI workflows become more powerful, organizations need to think carefully about where those workflows run, who controls them, how data is handled, and how decisions are governed.&lt;/p&gt;
&lt;p&gt;Cloud tools will continue to be useful for many use cases. But for teams that care about data control, customization, compliance, security, and long-term independence, self-hosted AI workflow automation offers a stronger foundation.&lt;/p&gt;
&lt;p&gt;The future of AI automation will not be defined only by smarter models.&lt;/p&gt;
&lt;p&gt;It will be defined by the platforms that help teams use AI safely, reliably, and under their control.&lt;/p&gt;
&lt;p&gt;That is why self-hosted AI workflow automation matters.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/21401/why-self-hosted-ai-workflow-automation-matters</guid>
<pubDate>Fri, 26 Jun 2026 09:27:47 +0000</pubDate>
</item>
<item>
<title>Back-End Web Development — VPS vs Vercel vs Netlify</title>
<link>https://coderlegion.com/20868/back-end-web-development-vps-vs-vercel-vs-netlify</link>
<description>&lt;h2 id=&quot;introduction-1&quot;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Every great web application with millions of users has an even greater back end — and it has to be. Accessing your app over a prolonged period of time will test the integrity, availability, and speed of your back end. Backend technology can be inexpensive, or it can cost you thousands of dollars. So what's the deal here?   &lt;/p&gt;
&lt;p&gt;Let me warn you that this post is highly opinionated. I am sharing the tools that I use and how I use them.&lt;/p&gt;
&lt;p&gt;For my back end that powers my web apps, I use Directus for my headless CMS, supported by a PostgreSQL and Redis database, hosted on a VPS, and managed by Coolify. Wow, that is a mouthful — and on my channel I explore how they all work together.&lt;/p&gt;
&lt;p&gt;So let's tackle each technology one at a time, starting with the VPS.&lt;/p&gt;
&lt;h2 id=&quot;what-is-a-vps-&quot;&gt;What is a VPS?&lt;/h2&gt;
&lt;p&gt;A Virtual Private Server, known as a VPS, is a virtual environment created on a physical server. Think of it like an apartment building — everyone shares the same physical structure, but each unit has its own private space, utilities, and security. While multiple VPS instances share a physical server, be careful not to confuse this with shared hosting.&lt;/p&gt;
&lt;p&gt; Each VPS is allocated its own dedicated resources, which are restricted to that VPS for as long as it is active. Therefore, the performance of a VPS is not directly affected by the usage of other VPS instances, but rather by the underlying performance of the physical server itself.&lt;/p&gt;
&lt;h2 id=&quot;what-are-the-benefits-of-a-vps-&quot;&gt;What are the benefits of a VPS?&lt;/h2&gt;
&lt;p&gt;There are several benefits to consider when deciding on virtual private server hosting:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Greater control&lt;/strong&gt; — Compared to shared hosting, you have root access and can fully customize your server environment.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dedicated resources&lt;/strong&gt; — Allocated CPU, memory, and storage help ensure consistent performance.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability&lt;/strong&gt; — You can easily scale resources up or down to accommodate changing traffic and application demands.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cost-effectiveness&lt;/strong&gt; — A VPS typically offers a balance between the affordability of shared hosting and the power of a dedicated server.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Improved security&lt;/strong&gt; — Isolation from other users on the same physical server enhances security.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Choice of operating system&lt;/strong&gt; — You can choose the operating system that best suits your needs, such as Linux or Windows.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;how-does-it-stack-up-against-vercel-or-netlify-&quot;&gt;How does it stack up against Vercel or Netlify?&lt;/h2&gt;
&lt;p&gt;Vercel offers minimal setup with Git integration and fast deployment right out of the box. It has a free Hobby plan, but it is strictly for personal, non-commercial use. Once your app grows and needs to scale, you will need to move to a paid plan. &lt;/p&gt;
&lt;p&gt;The Pro plan starts at $20 per user per month, and also covers serverless functions. Despite the name, serverless code still runs on a physical server — however, the infrastructure management, such as scaling, security patching, and provisioning, is handled entirely by the cloud provider. The main factor to watch carefully is cost. &lt;/p&gt;
&lt;p&gt;Vercel uses usage-based billing, and costs can escalate quickly — especially since Turbo build machines became the default for new Pro projects in February 2026, at 0.126USD  per build minute. A moderate team workflow can generate over $400 per month in build costs alone, before bandwidth and compute charges. I have seen some alarming Vercel bills shared online by customers, which means you need to fully understand the pricing model before you commit.&lt;/p&gt;
&lt;p&gt;Netlify has historically been more suited to static sites and composable web applications. Composable applications are software systems built from independent, interchangeable modules rather than a single rigid code base. Netlify also has Git integration, customizable build plugins, and serverless functions. Netlify moved to a credit-based pricing model in September 2025, which is &lt;br&gt;
designed to simplify metered billing. &lt;/p&gt;
&lt;p&gt;As of April 2026, the Pro plan costs 20USD per month and now includes unlimited team member seats, which is an improvement over the previous per-seat model. However, teams working on active projects with real traffic can burn through their credit allocation quickly, and credit pack add-ons at 10USD per 1,500 credits mean teams can regularly spend 40USD to 80USD or more per month beyond the base subscription. Your overall control is also more limited compared to a VPS, and you will still face a monthly cost as your app grows.&lt;/p&gt;
&lt;h2 id=&quot;now-the-vps-&quot;&gt;Now the VPS.&lt;/h2&gt;
&lt;p&gt;VPS prices can grow as your app grows, but in my experience at a slower and more predictable rate — with no surprise charges. However, if you manage a VPS yourself, it requires understanding web servers, firewalls, operating systems, caching, and more. It can get complex very quickly and may cause you to spend more time managing the server than building and scaling your app.&lt;/p&gt;
&lt;p&gt;That is why some developers and business owners hire a team to handle it. Small teams may not have the budget for a dedicated infrastructure team, so they often opt for a more convenient managed solution.&lt;/p&gt;
&lt;p&gt;There is one tool, however, that I think is worth mentioning and is a genuine game changer — and that is Coolify. In a later post I will go into more detail about what Coolify is and what it does. Coolify is a self-hostable platform that makes managing your VPS significantly easier. It offers Git integration, runs apps in Dockerized containers, handles HTTPS automatically, and includes a built-in web server that works out of the box with no manual configuration required. This makes the VPS a very real and competitive option worth considering.&lt;/p&gt;
&lt;p&gt;If you choose a solid hosting provider and pair it with the right tools, you can make this an absolute dream to work with.&lt;/p&gt;
&lt;p&gt;Now don’t get me wrong, even with Coolify there are some configurations that you will have to make, but I do believe a VPS is a great solution for a start up, mid-size or enterprise scaled app, with the right tools.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;• https://cloud.google.com/learn/what-is-a-virtual-private-server 
• https://aws.amazon.com/what-is/vps/ 
• https://www.ibm.com/think/topics/vps 
• https://www.scalahosting.com/blog/what-is-a-vps-technical-explanation/ 
• https://www.dreamhost.com/blog/beginners-guide-vps/ 
• https://vercel.com/pricing 
• https://www.netlify.com/pricing/ 
• https://bejamas.com/blog/self-hosting-vs-vercel-and-netlify-which-solution-is-right
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/20868/back-end-web-development-vps-vs-vercel-vs-netlify</guid>
<pubDate>Thu, 18 Jun 2026 03:34:03 +0000</pubDate>
</item>
<item>
<title>Orbnetes — Release Orchestration</title>
<link>https://coderlegion.com/16228/orbnetes-release-orchestration</link>
<description>&lt;p&gt;I kept running into the same problem. CI tools are great at building code, but not at releasing it. Approvals feel bolted on, rollback is improvised, and when something breaks, nobody can answer who deployed what or when.&lt;/p&gt;
&lt;p&gt;So I built &lt;strong&gt;Orbnetes&lt;/strong&gt; — a self-hosted release orchestration layer that sits on top of your existing CI and handles everything after the build finishes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How it works&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You connect it to GitHub, GitLab, or your own storage. It picks up the artifact, validates it, and manages the release from there — approvals, environment promotion, rollback, full audit record.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=908888245211829804&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Deployments run through lightweight cross-platform agents (~2MB) inside your own infrastructure. Deployment logic lives in YAML blueprints with a syntax close to GitHub Actions — familiar but scoped purely to release control.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=1762107946470585175&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Every release gets a structured record. If something fails, rollback executes against the already-validated artifact not a pipeline re-run.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=4557192326772151328&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=8750719592175599704&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key features&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cross-platform agents for Linux, macOS, Windows&lt;/li&gt;
&lt;li&gt;YAML blueprints with approval gates and rollback policies&lt;/li&gt;
&lt;li&gt;Full audit trail independent of your CI platform&lt;/li&gt;
&lt;li&gt;Self-hosted, free, no Kubernetes required&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://orbnetes.cloud/&quot;&gt;Orbnetes&lt;/a&gt; is free to try. Would love to hear your feedback!&lt;/p&gt;
</description>
<category>Launches</category>
<guid isPermaLink="true">https://coderlegion.com/16228/orbnetes-release-orchestration</guid>
<pubDate>Thu, 30 Apr 2026 06:45:23 +0000</pubDate>
</item>
<item>
<title>CI and CD Are Not the Same Thing: How to Build a Resilient Release Process</title>
<link>https://coderlegion.com/15804/ci-and-cd-are-not-the-same-thing-how-to-build-a-resilient-release-process</link>
<description>&lt;p&gt;If you’re building a software product, your deployment process matters from day one. It’s not a “later” problem or just DevOps work in the background. It directly impacts how stable your product is, how fast you recover from issues, and how confident your team feels when shipping changes.&lt;/p&gt;
&lt;p&gt;Most teams know this. But in practice, their release process looks very different.&lt;/p&gt;
&lt;p&gt;Instead of a clear system, they end up with a patchwork of CI jobs — a deploy step here, a Slack alert there, a quick workaround that quietly becomes permanent.&lt;/p&gt;
&lt;p&gt;It works. Until it doesn’t.&lt;/p&gt;
&lt;p&gt;And when something breaks, the same question comes up: what just happened?&lt;/p&gt;
&lt;p&gt;If that sounds familiar, this article is for you.&lt;/p&gt;
&lt;h3 id=&quot;ci-and-cd-are-not-the-same-thing&quot;&gt;CI and CD are not the same thing&lt;/h3&gt;
&lt;p&gt;I’ve been building tech products for over ten years now, managing development teams through the full release cycle, from early-stage pipelines to production systems under real operational pressure. That experience made the gap between CI and CD for me impossible to ignore.&lt;/p&gt;
&lt;p&gt;Usually, teams treat CI platforms as the &lt;strong&gt;default place to do everything&lt;/strong&gt;: build, test, package, deploy, promote, and sometimes even roll back. At first it feels efficient. Your source code is already in GitHub or GitLab, your pipeline definitions live next to your code, your runners are already there. So why not push deployment and release orchestration into the same system too?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Because convenience at the beginning often becomes coupling at scale.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;CI and CD are related, but they are not the same responsibility. CI is about validating change – build the code, run the tests, produce an artifact, confirm the commit is healthy. It answers one question: &lt;strong&gt;&quot;Is this change valid?&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;CD is about controlled change propagation – selecting a release candidate, deciding where it goes, defining an approval flow, promoting through environments, enforcing role-based access, capturing audit history, handling rollback safely. It answers a completely different question: &lt;strong&gt;&quot;Who deployed which version, where, when, and what happened next?&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Those are different questions and they clearly deserve different systems.&lt;/p&gt;
&lt;h3 id=&quot;the-hidden-cost-of-using-ci-for-releases&quot;&gt;The hidden cost of using CI for releases&lt;/h3&gt;
&lt;p&gt;Using GitHub Actions or GitLab pipelines for deployments is not wrong. It is often the fastest way to get started. But once deployment logic lives inside CI, several problems pile up.&lt;/p&gt;
&lt;h3 id=&quot;1-your-release-process-becomes-coupled-to-your-source-platform&quot;&gt;1. Your release process becomes coupled to your source platform&lt;/h3&gt;
&lt;p&gt;If your CI platform is degraded, your release process is too. GitHub's incident history shows multiple events where Actions jobs failed or were delayed (sometimes in the same window that affected pull requests and API requests).&lt;/p&gt;
&lt;p&gt;When your builds, approvals, and production releases all depend on the same platform, one outage freezes both development and delivery simultaneously. If you need to ship a hotfix during that window, &quot;everything in one place&quot; stops looking like an advantage, it becomes a single operational dependency.&lt;/p&gt;
&lt;h3 id=&quot;2-ci-pipelines-are-great-at-execution-but-awkward-at-release-governance&quot;&gt;2. CI pipelines are great at execution but awkward at release governance&lt;/h3&gt;
&lt;p&gt;Pipelines are good at running jobs. They are less natural as systems of record for release intent. Yes, you can build approvals into workflows. Yes, you can model environment promotion in YAML. Yes, you can encode rollback logic in scripts. But over time teams start asking questions that CI was never built to answer cleanly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Which exact version was approved for staging?&lt;/li&gt;
&lt;li&gt;Who approved the promotion to production, and when?&lt;/li&gt;
&lt;li&gt;Was QA sign-off captured before the release went out?&lt;/li&gt;
&lt;li&gt;What was the previous successful version?&lt;/li&gt;
&lt;li&gt;Can we roll back automatically if a deployment health check fails?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At that point deployment stops being &quot;just another job&quot; and becomes an operational workflow, one the pipeline was never designed to own.&lt;/p&gt;
&lt;h3 id=&quot;3-release-logic-becomes-too-tightly-bound-to-repository-events&quot;&gt;3. Release logic becomes too tightly bound to repository events&lt;/h3&gt;
&lt;p&gt;Most CI-driven deployment patterns are built around repository triggers: push to branch, merge to main, create a tag. That works when your release process is simple. But at some point teams start wanting things pipelines were never designed for — build once, deploy many times; promote the same artifact from staging to production without rebuilding it; let operations trigger a deployment without touching the codebase; roll back without re-running anything. The pipeline starts fighting back. That friction is usually the first sign that deployment has outgrown CI.&lt;/p&gt;
&lt;h3 id=&quot;what-this-costs-at-2am&quot;&gt;What this costs at 2am&lt;/h3&gt;
&lt;p&gt;The real cost becomes visible during a production incident when every minute matters. These are the questions that come up in the first ten minutes:&lt;/p&gt;
&lt;p&gt;Who deployed the version currently running in production?&lt;br&gt;
Was QA sign-off captured before this version was promoted?&lt;br&gt;
What was the last known stable version before this deployment?&lt;br&gt;
Can we roll back in the next five minutes without re-running a build?&lt;br&gt;
When CI-driven deployments cannot answer these (because the information is scattered across pipeline logs, Slack threads, and individual memory) the incident takes longer to take care of.&lt;/p&gt;
&lt;p&gt;For teams building tech products, every minute of downtime has a direct user-facing impact. And there is a less visible cost too: the team gets slower without understanding why.&lt;/p&gt;
&lt;p&gt;Rollback deserves particular attention here. In many CI-driven setups, rollback isn’t a defined operation. It’s a scramble:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;find the old tag&lt;/li&gt;
&lt;li&gt;re-run a pipeline&lt;/li&gt;
&lt;li&gt;hope nothing has drifted&lt;/li&gt;
&lt;li&gt;reconstruct whatever parameters were used last time&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That’s improvisation under pressure. A release system should treat rollback as a first-class capability – &lt;strong&gt;tested, predictable, and fast.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Because at 2am, clarity matters more than anything else.&lt;/p&gt;
&lt;h3 id=&quot;keep-ci-and-cd-connected-not-fused&quot;&gt;Keep CI and CD connected, not fused&lt;/h3&gt;
&lt;p&gt;The fix is not to replace your CI setup. GitHub Actions is powerful, GitLab CI is well-designed, and Jenkins is still deeply useful in many organizations. This is an architectural argument, not a tooling one.&lt;/p&gt;
&lt;p&gt;Keep CI where it belongs – &lt;strong&gt;building, testing, packaging, publishing a versioned artifact.&lt;/strong&gt; Let it answer &lt;strong&gt;&quot;is this change ready?&quot;&lt;/strong&gt; and stop there. Then hand off to a separate, independent release layer that owns everything that happens next: which version ships, to which environment, with whose approval, under which rollback policy, with a full audit record that survives independently of your source platform.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=1754226023092024921&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;That separation gives you something most teams are missing: &lt;strong&gt;a controlled release process instead of an automated shell script with side effects.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The best release process is not the one with the fewest steps, it is the one that still makes sense at 2am during a production incident.&lt;/p&gt;
&lt;h3 id=&quot;how-to-actually-separate-ci-from-cd-and-what-to-use-&quot;&gt;How to actually separate CI from CD (and what to use)&lt;/h3&gt;
&lt;p&gt;If your infrastructure is already mature, there are several established paths.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Spinnaker&lt;/strong&gt; is a powerful open-source CD platform with strong support for multi-cloud deployments and promotion workflows but it comes with significant operational overhead.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Argo CD&lt;/strong&gt; is a solid choice for Kubernetes-native teams. It follows a GitOps model and has strong community support, but it is tightly coupled to Kubernetes environments.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Flux&lt;/strong&gt; takes a similar GitOps approach with a lighter footprint, though it shares the same Kubernetes focus.&lt;/p&gt;
&lt;p&gt;And tools like &lt;strong&gt;GitLab&lt;/strong&gt; can handle both CI and deployment in a single platform, something that works well for many teams, especially early on.&lt;/p&gt;
&lt;p&gt;But these tools solve different slices of the problem. They also assume a certain level of infrastructure maturity. For many teams, they introduce as much complexity as they remove.&lt;/p&gt;
&lt;p&gt;But the key idea is super simple: &lt;strong&gt;separate the system that builds artifacts from the one that promotes and deploys them.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;That became very obvious to me when I started testing deployment workflows outside of a single-machine setup – running services across isolated environments, with separate infrastructure components, and real failure conditions. The moment you leave the comfort of a local setup, hidden assumptions in pipeline-based deployments start to surface quickly.&lt;/p&gt;
&lt;p&gt;That’s the reason the idea of &lt;strong&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://orbnetes.cloud/&quot;&gt;Orbnetes&lt;/a&gt;&lt;/strong&gt; came into my mind. It’s a self-hosted release orchestration layer designed to sit on top of your existing CI, without requiring Kubernetes or heavy operational overhead.&lt;/p&gt;
&lt;p&gt;Instead of rebuilding per environment or encoding release logic in pipelines, the system focuses on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;promoting immutable artifacts&lt;/li&gt;
&lt;li&gt;defining explicit approval flows&lt;/li&gt;
&lt;li&gt;and keeping a release record independent of CI&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The goal isn’t to replace your CI, but to give deployments their own control plane – one that still makes sense when things go wrong.&lt;/p&gt;
&lt;h3 id=&quot;how-orbnetes-works-in-practice&quot;&gt;How Orbnetes works in practice&lt;/h3&gt;
&lt;p&gt;Your CI pipeline stays exactly as it is. It builds, tests, and produces an artifact.&lt;/p&gt;
&lt;p&gt;Orbnetes picks up from that point. It integrates with systems like GitHub and GitLab, as well as internal artifact storage or webhooks, and turns build outputs into versioned releases.&lt;/p&gt;
&lt;p&gt;Each artifact is validated (for example via checksum) and stored as a release candidate. From that point on, deployments use the same immutable artifact across environments – no rebuilding, no hidden differences between staging and production.&lt;/p&gt;
&lt;p&gt;That one decision alone removes an entire class of deployment inconsistencies.&lt;/p&gt;
&lt;p&gt;Deployments are executed through lightweight agents running inside your infrastructure. They are cross-platform, isolated, and centrally managed, so environments stay independent, but the release process stays consistent.&lt;/p&gt;
&lt;p&gt;Instead of embedding deployment logic in CI pipelines, it lives in blueprints – YAML definitions designed for release orchestration rather than build automation.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: production-release
inputs:
  target_env:
    type: string
    required: true

jobs:
  backup:
    tags: [linux]
    steps:
      - name: pre-deploy-backup
        run: echo &quot;Backup before deploy&quot;

  deploy:
    needs: [backup]
    tags: [linux]
    steps:
      - name: deploy-release
        run: echo &quot;Deploying artifact&quot;
  verify:
    needs: [deploy]
    tags: [linux]
    steps:
      - name: health-check
        run: echo &quot;Verifying deployment&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The syntax is intentionally familiar, but the responsibility is different: this is about releasing software, not building it.&lt;/p&gt;
&lt;p&gt;Blueprints are versioned, reusable, and visible to the whole team rather than hidden inside a pipeline file that only a few people understand.&lt;/p&gt;
&lt;p&gt;Before a release reaches a sensitive environment, it goes through explicit approval flows. Roles are separated: the people who build, approve, and deploy are not implicitly the same. Every action is recorded.&lt;/p&gt;
&lt;p&gt;If something fails, rollback is not a guess. The system restores the last known good version using the already validated artifact. It is defined upfront, not improvised during an incident.&lt;/p&gt;
&lt;p&gt;Every release becomes a tracked event:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;what version was deployed&lt;/li&gt;
&lt;li&gt;where it went&lt;/li&gt;
&lt;li&gt;who approved it&lt;/li&gt;
&lt;li&gt;what happened next&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And importantly, this record exists independently of your CI platform. If GitHub has an outage, your release history (and your ability to operate) does not disappear with it.&lt;/p&gt;
&lt;h3 id=&quot;don-t-wait-for-an-incident-to-fix-this&quot;&gt;Don't wait for an incident to fix this&lt;/h3&gt;
&lt;p&gt;CI tells you whether your software is ready. CD determines how it actually reaches production.&lt;/p&gt;
&lt;p&gt;Those are &lt;strong&gt;different responsibilities&lt;/strong&gt; and treating them as the same system is where teams start to lose control.&lt;/p&gt;
&lt;p&gt;At a small scale, pipeline-driven deployments feel efficient. Everything is in one place, automation is easy, and shipping is fast. But as systems grow, that convenience turns into coupling. And coupling turns into fragility (usually revealed at the worst possible moment).&lt;/p&gt;
&lt;p&gt;During an incident, the problem is never just the bug. It’s the lack of clarity:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What exactly is running in production?&lt;/li&gt;
&lt;li&gt;Who approved it?&lt;/li&gt;
&lt;li&gt;What changed?&lt;/li&gt;
&lt;li&gt;How fast can we safely roll back?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The goal is not to add more steps or slow teams down. It’s to make releases predictable, observable, and controlled even under pressure.&lt;/p&gt;
&lt;p&gt;That starts with a simple shift: &lt;strong&gt;build in CI, release through CD, keep them connected, but not fused.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If this resonates with how your team works, Orbnetes is free to try. The documentation covers full setup in under 30 minutes, and the &lt;a rel=&quot;nofollow&quot; href=&quot;https://orbnetes.cloud/blueprints&quot;&gt;blueprints&lt;/a&gt; library has ready-made examples for common deployment patterns across Linux, Docker, and multi-environment setups.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Remember that your deployment process is part of your product.&lt;/strong&gt; Treat it that way:)&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/15804/ci-and-cd-are-not-the-same-thing-how-to-build-a-resilient-release-process</guid>
<pubDate>Sat, 25 Apr 2026 11:37:27 +0000</pubDate>
</item>
<item>
<title>Building a Production-Ready NDVI Pipeline: Normalization Fixes, WAF Resilience, and System Stability</title>
<link>https://coderlegion.com/14008/building-production-ready-ndvi-pipeline-normalization-fixes-resilience-system-stability</link>
<description>&lt;hr&gt;
&lt;h2 id=&quot;from-it-works-to-production-fixing-ndvi-rendering-surviving-waf-blocks-and-stabilizing-a-failing-server&quot;&gt;From “It Works” to Production: Fixing NDVI Rendering, Surviving WAF Blocks, and Stabilizing a Failing Server&lt;/h2&gt;
&lt;p&gt;Most backend systems don’t fail because of obvious bugs.&lt;br&gt;
They fail quietly—through misleading data, unstable infrastructure, and assumptions that don’t hold under load.&lt;/p&gt;
&lt;p&gt;This week, I pushed an NDVI (Normalized Difference Vegetation Index) pipeline through a full transition:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;from &lt;em&gt;“it renders images”&lt;/em&gt; → to &lt;em&gt;a production-grade, resilient system&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This article breaks down what actually went wrong—and how each fix improved the system holistically.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;1-the-illusion-of-correctness-when-green-lies&quot;&gt;1. The Illusion of Correctness: When “Green” Lies&lt;/h3&gt;
&lt;p&gt;The first issue looked harmless:&lt;br&gt;
NDVI raster PNGs were rendering—but everything was green.&lt;/p&gt;
&lt;h4 id=&quot;root-cause&quot;&gt;Root Cause&lt;/h4&gt;
&lt;p&gt;The normalization formula:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;normalized = (ndvi + 1.0) / 2.0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This assumes NDVI values span &lt;strong&gt;[-1, 1]&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;But real-world farm data was tighter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;NDVI range: 0.42 → 0.63
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After normalization:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0.71 → 0.81 → Entirely “green zone”
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the system was technically correct—but &lt;strong&gt;visually misleading&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;2-the-fix-dual-normalization-strategy&quot;&gt;2. The Fix: Dual Normalization Strategy&lt;/h3&gt;
&lt;p&gt;Instead of replacing one approach with another, I introduced &lt;strong&gt;two modes&lt;/strong&gt;:&lt;/p&gt;
&lt;h4 id=&quot;histogram-based-normalization-default-&quot;&gt;Histogram-Based Normalization (Default)&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;normalized = (ndvi - ndvi_min) / (ndvi_max - ndvi_min)
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Expands contrast per image&lt;/li&gt;
&lt;li&gt;Reveals actual variation&lt;/li&gt;
&lt;li&gt;Best for analysis&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;fixed-normalization-legacy-&quot;&gt;Fixed Normalization (Legacy)&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;normalized = (ndvi + 1.0) / 2.0
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Keeps consistency across images&lt;/li&gt;
&lt;li&gt;Useful for comparisons&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;why-this-matters&quot;&gt;Why This Matters&lt;/h4&gt;
&lt;p&gt;This isn’t just a rendering fix—it’s a &lt;strong&gt;data integrity decision&lt;/strong&gt;:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Never force a single interpretation when the data has multiple valid contexts.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&quot;3-external-systems-don-t-like-you-stac-waf-blocks-&quot;&gt;3. External Systems Don’t Like You (STAC WAF Blocks)&lt;/h3&gt;
&lt;p&gt;The next issue wasn’t in my system—it was in how it behaved externally.&lt;/p&gt;
&lt;h4 id=&quot;symptom&quot;&gt;Symptom&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Requests to Copernicus STAC API started failing&lt;/li&gt;
&lt;li&gt;Response: empty HTML or “Request Rejected”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Classic &lt;strong&gt;WAF (Web Application Firewall)&lt;/strong&gt; behavior.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;root-cause-1&quot;&gt;Root Cause&lt;/h4&gt;
&lt;p&gt;The system behaved like a bot:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rapid consecutive requests&lt;/li&gt;
&lt;li&gt;Predictable timing patterns&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id=&quot;the-fix-controlled-request-behavior&quot;&gt;The Fix: Controlled Request Behavior&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;sleep(base_interval + random.uniform(jitter_min, jitter_max))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Implemented:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Minimum delay between requests&lt;/li&gt;
&lt;li&gt;Random jitter (1–5 seconds)&lt;/li&gt;
&lt;li&gt;Graceful handling of invalid responses&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id=&quot;result&quot;&gt;Result&lt;/h4&gt;
&lt;blockquote&gt;&lt;p&gt;The system stopped being “blocked” and started being &lt;strong&gt;tolerated&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is a key distributed systems lesson:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;You don’t just integrate with APIs—you adapt to their defensive behavior.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&quot;4-architecture-maturity-preparing-for-redis-streams&quot;&gt;4. Architecture Maturity: Preparing for Redis Streams&lt;/h3&gt;
&lt;p&gt;The NDVI pipeline originally used &lt;strong&gt;Celery&lt;/strong&gt; for async jobs.&lt;/p&gt;
&lt;p&gt;Instead of rewriting everything, I introduced a &lt;strong&gt;routing abstraction&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;if settings.NDVI_QUEUE_BACKEND == &quot;celery&quot;:
    dispatch_celery_job(...)
elif settings.NDVI_QUEUE_BACKEND == &quot;stream&quot;:
    raise NotImplementedError
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h4 id=&quot;why-this-is-important&quot;&gt;Why This Is Important&lt;/h4&gt;
&lt;p&gt;This small change enables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Seamless migration to Redis Streams&lt;/li&gt;
&lt;li&gt;Zero disruption to current workflows&lt;/li&gt;
&lt;li&gt;Incremental architecture evolution&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id=&quot;principle&quot;&gt;Principle&lt;/h4&gt;
&lt;blockquote&gt;&lt;p&gt;The best migrations don’t start with new systems—they start with &lt;strong&gt;abstractions&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&quot;5-the-real-problem-server-crashes-every-10-hours&quot;&gt;5. The Real Problem: Server Crashes Every 10 Hours&lt;/h3&gt;
&lt;p&gt;This was the most critical issue.&lt;/p&gt;
&lt;h4 id=&quot;symptoms&quot;&gt;Symptoms&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;System crashes after ~10 hours&lt;/li&gt;
&lt;li&gt;No single obvious failure point&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id=&quot;root-cause-2&quot;&gt;Root Cause&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Unbounded resource usage across multiple services:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MySQL buffer pool growing unchecked&lt;/li&gt;
&lt;li&gt;PHP-FPM workers accumulating memory&lt;/li&gt;
&lt;li&gt;Redis using unlimited memory&lt;/li&gt;
&lt;li&gt;Celery workers never restarting&lt;/li&gt;
&lt;li&gt;Monitoring stack filling disk&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;6-the-fix-system-wide-resource-governance&quot;&gt;6. The Fix: System-Wide Resource Governance&lt;/h3&gt;
&lt;p&gt;Instead of patching one component, I enforced limits everywhere:&lt;/p&gt;
&lt;h4 id=&quot;database&quot;&gt;Database&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-ini&quot;&gt;innodb_buffer_pool_size = 512M
max_connections = 50
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h4 id=&quot;php-fpm&quot;&gt;PHP-FPM&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-ini&quot;&gt;pm.max_children = 15
pm.max_requests = 500
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h4 id=&quot;redis&quot;&gt;Redis&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;mem_limit: 512mb
maxmemory-policy: allkeys-lru
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h4 id=&quot;celery&quot;&gt;Celery&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;worker_max_tasks_per_child = 100
worker_max_memory_per_child = 512000  # KB
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h4 id=&quot;observability-stack&quot;&gt;Observability Stack&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Prometheus: 7-day retention&lt;/li&gt;
&lt;li&gt;Loki: compaction + retention limits&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id=&quot;result-1&quot;&gt;Result&lt;/h4&gt;
&lt;blockquote&gt;&lt;p&gt;The system moved from &lt;strong&gt;eventual failure → controlled lifecycle stability&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&quot;7-observability-and-documentation-the-often-ignored-layer-&quot;&gt;7. Observability and Documentation (The Often Ignored Layer)&lt;/h3&gt;
&lt;p&gt;Alongside code changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Added alerts for system health&lt;/li&gt;
&lt;li&gt;Documented all NDVI configuration settings&lt;/li&gt;
&lt;li&gt;Created deployment + rollback guides&lt;/li&gt;
&lt;li&gt;Expanded test coverage&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id=&quot;why-this-matters-1&quot;&gt;Why This Matters&lt;/h4&gt;
&lt;p&gt;Without this layer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fixes don’t scale&lt;/li&gt;
&lt;li&gt;Bugs repeat&lt;/li&gt;
&lt;li&gt;Systems become tribal knowledge&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;8-security-mistake-worth-mentioning-&quot;&gt;8. Security Mistake (Worth Mentioning)&lt;/h3&gt;
&lt;p&gt;During the process, a sudo password was exposed in plain text.&lt;/p&gt;
&lt;p&gt;No system is “production-ready” if secrets are handled casually.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;immediate-takeaways&quot;&gt;Immediate Takeaways&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Never expose credentials in logs or chats&lt;/li&gt;
&lt;li&gt;Rotate immediately if leaked&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Move toward:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;environment-based configs&lt;/li&gt;
&lt;li&gt;secret management systems&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;final-thoughts&quot;&gt;Final Thoughts&lt;/h3&gt;
&lt;p&gt;This wasn’t about fixing a bug.&lt;/p&gt;
&lt;p&gt;It was about addressing three deeper problems:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Data correctness&lt;/strong&gt; (NDVI visualization)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;System behavior under external constraints&lt;/strong&gt; (WAF)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Infrastructure stability&lt;/strong&gt; (resource limits)&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h4 id=&quot;the-real-transformation&quot;&gt;The Real Transformation&lt;/h4&gt;
&lt;p&gt;Before:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;“The system works.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;“The system is predictable, resilient, and ready for scale.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&quot;key-lessons&quot;&gt;Key Lessons&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Correct output is not always &lt;strong&gt;truthful output&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;External APIs require &lt;strong&gt;behavioral adaptation&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Systems fail through &lt;strong&gt;unbounded growth&lt;/strong&gt;, not sudden errors&lt;/li&gt;
&lt;li&gt;Architecture evolves through &lt;strong&gt;abstraction, not rewrites&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Stability is a &lt;strong&gt;system-wide property&lt;/strong&gt;, not a single fix&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;If you’re building data pipelines or distributed systems, this pattern will repeat.&lt;/p&gt;
&lt;p&gt;The earlier you design for it—the less painful it becomes.&lt;/p&gt;
&lt;hr&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/14008/building-production-ready-ndvi-pipeline-normalization-fixes-resilience-system-stability</guid>
<pubDate>Sun, 05 Apr 2026 11:21:57 +0000</pubDate>
</item>
<item>
<title>Web Hosting Checker</title>
<link>https://coderlegion.com/13145/web-hosting-checker</link>
<description>&lt;p&gt;Wondering who hosts a website? Our &lt;a rel=&quot;nofollow&quot; href=&quot;https://beingoptimist.in/tools/hosting-tools/web-hosting-checker/&quot;&gt;Web Hosting Checker&lt;/a&gt; uses advanced ASN-based infrastructure analysis and real-time DNS lookup to identify the hosting provider, CDN, server location, and network organization behind any domain — accurately and for free.&lt;/p&gt;
</description>
<category>Launches</category>
<guid isPermaLink="true">https://coderlegion.com/13145/web-hosting-checker</guid>
<pubDate>Wed, 18 Mar 2026 15:48:27 +0000</pubDate>
</item>
<item>
<title>DevLog 20250520: Search Engine Architecture</title>
<link>https://coderlegion.com/3110/devlog-20250520-search-engine-architecture</link>
<description>&lt;h3 id=&quot;overview&quot;&gt;Overview&lt;/h3&gt;
&lt;p&gt;For an internal database, we needed to implement some sort of text-based search capabilities to help users locate documents. One goal was to be lightweight, hassle-free, easy to set up, expand, and maintain—and ideally, to set it up once and forget about it. It's okay if it costs a bit of computing power, but agility, quick iterations, usability, and robustness are of top concern.&lt;/p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;
&lt;p&gt;It's surprising how much we can do without a server. Most serverless or static webpage hosts are happy to serve anything from a few MB to a few GB for free, likely even distributed across the globe. For any particular individual, if the search experience is truly customized to their needs, then not much resource is needed to deliver a satisfying experience.&lt;/p&gt;
&lt;p&gt;Let's illustrate this with an example. Suppose that, for any webpage, the information we care about includes the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Title&lt;/li&gt;
&lt;li&gt;Abstract&lt;/li&gt;
&lt;li&gt;URL&lt;/li&gt;
&lt;li&gt;Keywords (weighted)&lt;/li&gt;
&lt;li&gt;Tags&lt;/li&gt;
&lt;li&gt;Last Modification Time&lt;/li&gt;
&lt;li&gt;Webpage Language&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If we assume the abstract is at most 200 words and the rest adds up to 50 bytes, then each website we index takes about 250 bytes to store. 1KB fits four entries, 1MB fits 4096 entries, and 3MB fits about 12K entries. If a blog updates daily, the most it can produce is 365 entries per year, so 3MB is enough to hold one year's worth of content for 40 blog-sized websites.&lt;/p&gt;
&lt;p&gt;If we go a bit crazy, it's reasonable to expect a few hundred megabytes of memory consumption. Let’s say the payload is 300MB—that’s 40 × 100 = 4,000 blog-sized websites for one year. This means that, without a server, and with everything distributed as static content, a user's browser client can happily serve indexed website data locally for 4,000 websites. Considering that most of the time we dwell on just a few dozen sites, and that time relevance usually plays a big role, this leaves plenty of room for imagination.&lt;/p&gt;
&lt;h3 id=&quot;the-indexing&quot;&gt;The Indexing&lt;/h3&gt;
&lt;p&gt;Call it an indexer or web crawler. In this step, we try to gather information about all available websites and process them into condensed formats like a database, CSV, or JSON.&lt;/p&gt;
&lt;p&gt;Conceptually, the job of a web crawler could be greatly simplified if every website simply reported what it had—that’s supposedly the purpose of a sitemap. But in practice, it's surprising how much effort people spend on so-called SEO optimization, simply because there's no straightforward way to submit such information. On the other hand, perhaps it’s a good thing—we don’t want website creators to fool the search engine by submitting dishonest summary information.&lt;/p&gt;
&lt;p&gt;One major challenge with web crawling, besides parsing and potential blocking by website hosts, is rendering JavaScript. Nowadays, lots of content is dynamic, meaning it’s not directly available in plain HTML—it may not require a server per se, but much of the visible content is rendered only during runtime. For instance, a dictionary app may only display content once a search keyword is entered.&lt;/p&gt;
&lt;h3 id=&quot;the-searching&quot;&gt;The Searching&lt;/h3&gt;
&lt;p&gt;Database search, plain/full-text search, fuzzy search, vector search, and advanced queries—there are so many possible ways to organize data and perform searches, and so many libraries to choose from, it’s surprising that some websites and software still have such poor built-in search functions.&lt;/p&gt;
&lt;p&gt;At the current stage, we don’t have absolute recommendations yet, but suffice it to say: advanced platforms like ElasticSearch or even a traditional database are completely unnecessary for the majority of applications. A plain full-text search is efficient enough, and lots of lightweight JavaScript or WASM libraries exist to speed up search—such as Fuse, Lunr.js, and FlexSearch. There are databases built specifically for search (not to mention the many vector databases now available for AI embedding workloads), such as Manticore Search.&lt;/p&gt;
&lt;h3 id=&quot;the-hosting&quot;&gt;The Hosting&lt;/h3&gt;
&lt;p&gt;As mentioned, the simplest search engine frontend is just a plain website that fetches index data during loading and performs search in-memory on the client side, without any server other than static file hosting. Again, it's worth stressing how powerful this can be—not only versatile and easily deployed, but also sufficient for most small to medium workloads. For typical payloads in the 3–5MB range and up to 300MB at most, this is more than enough. We can fit a lot within such constraints.&lt;/p&gt;
</description>
<category>Web Dev</category>
<guid isPermaLink="true">https://coderlegion.com/3110/devlog-20250520-search-engine-architecture</guid>
<pubDate>Wed, 21 May 2025 01:14:38 +0000</pubDate>
</item>
<item>
<title>A Love Story in Code: Building My Self-Hosted Photo Album</title>
<link>https://coderlegion.com/1619/a-love-story-in-code-building-my-self-hosted-photo-album</link>
<description>&lt;p&gt;I am almost one year into my current relationship. It is hard to believe how fast time flies, until I look into our photo archive. Being an enthusiastic photographer, my partner captured moments of us together. However, the increasing stack of photos is accelerating the imminent explosion of my cloud storage. That’s when I started to look for alternative options, then I realized my workstation is not doing much despite being always-on. That began my exploration into self-hosting, by releasing a barely functional application with &lt;a rel=&quot;nofollow&quot; href=&quot;https://cslai.coolsilon.com/2024/10/11/self-hosted-photo-album/&quot;&gt;a weekend worth of work in October last year&lt;/a&gt;. And now, I am back with another release (keep reading for example setup later in the article). Keeping the design goal of simplicity, &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/coolsilon/photos&quot;&gt;the photo album application&lt;/a&gt; can now do&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Easy to setup:&lt;/strong&gt; Answer prompts to initialize the application. No database setup is required, and all generated configuration is in simple text files.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Drag-and-drop photo management:&lt;/strong&gt; A folder containing photos is considered an album, just drop them into the application, and leave the rest to the indexer&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Intuitive album visibility:&lt;/strong&gt; Renaming album with specific suffixes changes the visibility&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Basic user privacy:&lt;/strong&gt; album visibility and accessibility is ensured with a simple login-based access control&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1024/1*Rccp0oWfRkASgKcdHelREA.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;The current state of the album&lt;/em&gt;&lt;/p&gt;
&lt;h4 id=&quot;why-self-hosting-a-journey-begins&quot;&gt;&lt;strong&gt;Why Self-Hosting? A Journey Begins&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;The project was initially created for own use, and it was published to GitHub without much thought. It was done just as I concluded my &lt;a rel=&quot;nofollow&quot; href=&quot;https://dev.to/jeffrey04/attending-an-open-government-workshop-i0p&quot;&gt;previous project on legislative data&lt;/a&gt; and &lt;a rel=&quot;nofollow&quot; href=&quot;https://dev.to/jeffrey04/beyond-the-code-a-lunar-new-year-reflection-on-career-recovery-and-new-beginnings-l77&quot;&gt;attended a meditation camp&lt;/a&gt;. I had also just returned from a trip to Thailand with my partner, bringing back a mountain of photos. The cloud storing was nearly full, so uploading them was not a viable option. On a more practical side, I just got out of a project and was still in search for opportunities (and still is), and thus budget was tight. Realizing the workstation remained idle most of the time, I figured it was a good opportunity to develop an application for the purpose.&lt;/p&gt;
&lt;p&gt;If you host your domains on Cloudflare, setting this up in a Linux workstation is easy, read on to find out.&lt;/p&gt;
&lt;p&gt;Aiming for simplicity, it was developed in a weekend, without a well-thought interface design (UX is still poor to this date). However, it was good enough to showcase collections of photos. While I need to re-run the indexer every time I drag folders of photos into the application, I find it acceptable for the scale of the project. If I were to deal with hundreds of gigabytes of photos, storing them to the cloud would be a more sensible choice.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1024/1*A8EmnVDHyMroQiBB3D2CCw.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;A photo I took in the Thailand trip&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;While the main users are just myself and my closer friends, some expressed interest in the project. If this were a product, this would be a perfect case of dogfooding my own product. This project is not meant to host thousands of photos, so it is an overkill to setup a database that is designed for scalability. Hence, the simplicity is perfect for people looking to try out self-hosting, with a spare machine lying around.&lt;/p&gt;
&lt;h4 id=&quot;implementing-user-management-and-visibility&quot;&gt;&lt;strong&gt;Implementing User Management and Visibility&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1024/1*iBo72VNI4yfe8XeRi2S1Yg.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;Difference in the list of albums before and after logging in&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The involuntary transition into a freelancer in the past year wasn’t just a change in career; it was a crash course in frontend development. I mostly worked as a backend developer in the past, with a limited frontend skill. Now, instead of worrying only on database and API design, I suddenly need to put half my attention and effort into frontend development. In addition to that, the increased expectations in tech job openings also means an applicant is expected to be sufficiently productive as a full-stack developer. That reflects in a lot of my past interview take-home assignments. The photo album application, in a way is a cultivation of all the learning experience.&lt;/p&gt;
&lt;p&gt;The projects and job applications led to new discoveries and relearning. In one of the job applications, I was given an opportunity to properly learn Ruby on Rails, and apply &lt;a rel=&quot;nofollow&quot; href=&quot;https://jwt.io/introduction&quot;&gt;JSON Web Token (JWT)&lt;/a&gt; into it. Spoiler, I didn’t get picked for the job, but it was a good introductory to both Rails and JWT. While I submitted my best work given the time constraint, but the implementation was at best theoretical.&lt;/p&gt;
&lt;p&gt;It was bad.&lt;/p&gt;
&lt;p&gt;The implementation follows only the spec of the protocol, i.e. how to sign and verify the token, but I didn’t know what payload should it carry. Though I was reassured that it didn’t matter due to my lack of experience with it, but I knew it could be done better. Months later, in my &lt;a rel=&quot;nofollow&quot; href=&quot;https://dev.to/jeffrey04/how-to-write-an-asyncio-telegram-bot-in-python-4hig&quot;&gt;current chatbot project&lt;/a&gt;, I get to properly revisit the topic.&lt;/p&gt;
&lt;p&gt;JWT is mostly used for authorization purpose. After spending some time going through some documentation and chatting with Gemini, I realized there is some best practice on how it should be applied. For instance, in the photo album, users authenticate themselves to get a JWT token in return, consisting a payload with identification data, alongside expiration details. This, in turn, allows albums to be set as hidden and private. Unlike my initial attempt, it shouldn’t be used for authentication, and should not contain sensitive data, even though it is signed with an unpublished secret key.&lt;/p&gt;
&lt;p&gt;I started the development to host photos taken by my partner and I. Then I figured why not just move more photos over from my cloud backup. As much as I like the accessibility, leaving everything publicly accessible is not exactly ideal. While it makes me smile whenever I browse the album featuring just us both, but I should probably keep silly photos of us making faces private.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1024/1*5gyf5LN4Rd1Z3FXPFHl3dA.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;Yeap, definitely keep this in private!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;With authorization in place, I start to look into visibility control without introducing much change to the code, both backend and frontend. Eventually, I settled with setting a naming convention to the albums, namely adding suffixes such as .hidden and .private. The backend returning the list of album now only selectively returns different lists of albums, depending on user login state, by checking the JWT token in the cookie. On the frontend part, I implemented an HTTP interceptor that redirects users to login page when they attempt to access private albums. I will probably write another post on the implementation in the future, on how to perform authorization with JWT referencing this web album application.&lt;/p&gt;
&lt;h4 id=&quot;setting-up-your-own-photo-album-a-step-by-step-guide&quot;&gt;&lt;strong&gt;Setting Up Your Own Photo Album: A Step-by-Step Guide&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;It is exciting applying new learned knowledge into something I build and use personally. Which is a satisfaction I long for in my daily work. The web album sets out to fix a very tangible problem, make photos accessible online. As phone cameras improve in quality, the need for greater storage space also increased. Higher quality equals higher storage cost, and more people are moving their backups to the cloud through subscriptions.&lt;/p&gt;
&lt;p&gt;On the other hand, as a software engineer, the quality of life in development also increases dramatically over the years. We used to require weeks of work to build an application like this web album. For example, I would have spent days figuring out how to arrange a grid of photo in masonry layout (in fact I attempted that in earlier iterations), but now all I needed is to import and use a React component to do the job.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1024/1*YrlqIBOn3zfxZGXSfXdfhA.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;A grid of photos in masonry layout, photos taken in EuroPython 2022&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;On deployment, tools like &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/astral-sh/uv&quot;&gt;uv&lt;/a&gt; is also useful, as it would help &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.astral.sh/uv/concepts/python-versions/#managed-python-distributions&quot;&gt;pulling the right CPython&lt;/a&gt; to run the application. Gone are the days, where pages of guide is needed to teach how to install the right version of python, and how to pull the dependencies.&lt;/p&gt;
&lt;p&gt;In my case, my photo album is made accessible online, through the use of Cloudflare tunnel. Setting it up is a breeze, here’s how to do it, and it is easily replicable if you run modern Linux distro.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install Cloudflare Tunnel by following the &lt;a rel=&quot;nofollow&quot; href=&quot;https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/local-management/create-local-tunnel/&quot;&gt;official installation and setup guide&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Authenticate your Cloudflare account using the command cloudflared login.&lt;/li&gt;
&lt;li&gt;Create a new tunnel using the command cloudflared tunnel create .&lt;/li&gt;
&lt;li&gt;Navigate to the &lt;a rel=&quot;nofollow&quot; href=&quot;https://one.dash.cloudflare.com&quot;&gt;Cloudflare Zero Trust dashboard&lt;/a&gt;, then go to &lt;strong&gt;Network&lt;/strong&gt; -&amp;gt;  &lt;strong&gt;Tunnels&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Locate the tunnel created in step 3, click the overflow menu (the three vertical dots), and select &lt;strong&gt;Configure&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Go to the &lt;strong&gt;Public Hostname&lt;/strong&gt;  tab.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Add a public hostname&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Fill in the form: for &lt;strong&gt;Hostname&lt;/strong&gt; , enter the desired subdomain (e.g., photos.yourdomain.com); for &lt;strong&gt;Service&lt;/strong&gt; , select HTTP; for URL, enter &lt;a rel=&quot;nofollow&quot; href=&quot;http://localhost:&amp;lt;YOUR\_PORT\_NUMBER&amp;gt;&quot;&gt;http://localhost:&amp;lt;YOUR\_PORT\_NUMBER&amp;gt;&lt;/a&gt; (replace &amp;lt;YOUR_PORT_NUMBER&amp;gt; with the port your web album is running on).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1024/1*oXBhONM7blf0u0vTtAKhqw.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;An example configuration&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This setup creates a secure, publicly accessible endpoint for your photo album, without exposing your server directly to the internet.&lt;/p&gt;
&lt;p&gt;Next, follow the instructions in the web album’s README file in the root directory to complete the setup. Albums suffixed with .hidden will not appear in the album listing, but can still be accessible with a direct link. On the other hand, albums suffixed with .private requires login before they can be accessed. The visibility setting allow sharing albums, but also offer some control such that semi-private photos are hidden.&lt;/p&gt;
&lt;p&gt;In order to register a user, run the following command.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;uv run python -m photos.main register $USERNAME
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Follow the prompt to set up your login password. Finally ensure to specify the same port number as defined earlier while running the fastapi command&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;uv run fastapi - port $PORT - host 0.0.0.0 src/photos/web.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you are new to self-hosting, and have problems following the guide, feel free to reach out in the comments for help. Learning to prepare instructions to people of various levels of tech skill level is also a humbling experience.&lt;/p&gt;
&lt;h4 id=&quot;sharing-my-story-sharing-the-love&quot;&gt;&lt;strong&gt;Sharing My Story, Sharing the Love&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1024/1*RKeC2Amh75M0i6v2EkgnIw.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;The result of a fortune-telling session. Photo taken in our Bangkok Trip last year.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Self-hosting your own data is becoming a trend these days, and it is really not hard to get started. There are even youtube creators that are creating content running self-host applications on used machines, for example &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.youtube.com/@HardwareHaven&quot;&gt;Hardware Haven&lt;/a&gt;. I personally find their content entertaining, especially when seeing them giving older or less capable hardware a new life.&lt;/p&gt;
&lt;p&gt;The project can be found at &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/coolsilon/photos&quot;&gt;GitHub&lt;/a&gt;, and is in a very early stage of development. I am currently the only person using the script. The simplicity in design, is also intended as I wanted it to be easily adopted. Feel free to check out and clone the repository, give it a try by following the setup instructions. While I may not promise active development, I do appreciate feedbacks, both technical and non-technical ones.&lt;/p&gt;
&lt;p&gt;I am excited with the achievements in this release, and hopefully I get to put in more time into the project. It is a rare but fun experience building an application that is actually useful (still giving me smiles going through the photos taken by my partner). The project began with a love story, and hopefuly by sharing it to the world, it radiates.&lt;/p&gt;
&lt;p&gt;This article was produced with the assistance of an AI editorial assistant to ensure clarity, reading flow, and language correctness. All opinions and experiences expressed are my own. If you’re interested in collaborating on a project or exploring job opportunities, please feel free to reach out to me here on Medium or connect with me on LinkedIn.&lt;/p&gt;
</description>
<category>Building Open Source Projects</category>
<guid isPermaLink="true">https://coderlegion.com/1619/a-love-story-in-code-building-my-self-hosted-photo-album</guid>
<pubDate>Thu, 20 Mar 2025 19:23:02 +0000</pubDate>
</item>
</channel>
</rss>