<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Foisal Islam]]></title><description><![CDATA[Foisal Islam]]></description><link>https://foisalislam.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sat, 07 Nov 2026 11:16:13 GMT</lastBuildDate><atom:link href="https://foisalislam.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[I wanted backups on a VPS I rent, not another Dropbox subscription]]></title><description><![CDATA[Most people need a backup. The usual choices feel bad: a monthly fee to keep files on someone else's computers, "pro" backup software with schedules that…]]></description><link>https://foisalislam.hashnode.dev/i-wanted-backups-on-a-vps-i-rent-not-another-dropbox-subscription</link><guid isPermaLink="true">https://foisalislam.hashnode.dev/i-wanted-backups-on-a-vps-i-rent-not-another-dropbox-subscription</guid><category><![CDATA[#selfhosted]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[Backup]]></category><dc:creator><![CDATA[Foisal Islam]]></dc:creator><pubDate>Fri, 06 Nov 2026 06:53:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6aeb9f36275626370aceee01/6d4f0c2e-771d-4b05-ad33-8c832f1afe4d.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Most people need a backup. The usual choices feel bad: a monthly fee to keep files on someone else's computers, "pro" backup software with schedules that are easy to set up wrong, or a USB drive you forget until the day you need it.</p>
<p>I wanted something in the middle — a small always-on computer I rent (a VPS), almost no setup, and defaults that back up the folders I'd miss. That's OpenBackup.</p>
<h2>What you get</h2>
<ul>
<li>Automatic backups of Documents, Pictures, Videos, Music, Desktop (and folders you add)</li>
<li>Only changed pieces of files are uploaded, so daily runs stay light</li>
<li>History — restore yesterday's version, or last week's</li>
<li>A dashboard in the browser to see devices and download a file or folder as a ZIP</li>
<li>An optional desktop app if you prefer buttons over a terminal</li>
<li>Optional encryption, so even the server can't read the files (you keep a recovery code)</li>
<li>Agents for Windows, macOS and Linux</li>
</ul>
<p>It does <strong>not</strong> try to clone your whole OS install. It backs up <em>your</em> files. System folders, trash, caches, <code>node_modules</code>, build output and huge VM images are skipped on purpose.</p>
<p>Android is not ready yet.</p>
<h2>Install in four steps</h2>
<p><strong>1. Put the server on a VPS</strong> (Ubuntu 22.04 or 24.04 is easiest):</p>
<pre><code class="language-bash">curl -fsSL https://raw.githubusercontent.com/foisalislambd/openbackup/main/scripts/install-server.sh | sudo sh
</code></pre>
<p>It prints a web address like <code>http://YOUR_IP:18200</code> plus a sign-in email and password. Open that, sign in, change the password. Prefer reading the script first if you don't like piping to <code>sh</code> — it's in the repo at <code>scripts/install-server.sh</code>.</p>
<p><strong>2. Create a connection code</strong> in the dashboard under Devices. It looks like <code>ABCD-EFGH-JKLM</code>, works once, expires in 24 hours.</p>
<p><strong>3. Connect each computer</strong></p>
<ul>
<li>Windows: download the desktop installer from <a href="https://github.com/foisalislambd/openbackup/releases">Releases</a></li>
<li>Mac / Linux:</li>
</ul>
<pre><code class="language-bash">curl -fsSL https://raw.githubusercontent.com/foisalislambd/openbackup/main/scripts/install-agent.sh | sh
openbackup connect --server http://YOUR_IP:18200 --code ABCD-EFGH-JKLM
</code></pre>
<p>Use HTTPS for real use — the install-server docs cover that.</p>
<p><strong>4. Check</strong></p>
<pre><code class="language-bash">openbackup status
openbackup doctor
</code></pre>
<p>Then restore <strong>one file</strong> while nothing is broken, so you know how when you need it.</p>
<h2>Everyday commands (optional)</h2>
<p>The background service keeps working without you. Handy when you want control:</p>
<pre><code class="language-bash">openbackup backup
openbackup folders
openbackup folders add ~/Projects
openbackup pause --for 2h
openbackup find "tax return"
openbackup restore --path Documents/report.docx --to .
</code></pre>
<h2>Encryption</h2>
<pre><code class="language-bash">openbackup encrypt
</code></pre>
<p>You'll get a recovery code. Write it down somewhere safe that is not only on that same computer. Lose the code and those encrypted backups can't be opened. There is no "reset password" on the server side — that's the point.</p>
<h2>Status and license</h2>
<p>Server, agent, dashboard and desktop app work end to end. Current release is <strong>v0.2.9</strong>. Until 1.0, treat minor versions as able to change the wire protocol — upgrade the server before the agents. MIT. Repo: <a href="https://github.com/foisalislambd/openbackup">github.com/foisalislambd/openbackup</a>.</p>
<p>Disk on the VPS matters more than CPU. The README's tip is that many people run this on a roughly €4–6/month plan. prices change; pick a plan with enough disk for your photos and video.</p>
<p>If you try it, I'd like to hear where the defaults were wrong for your machine, and whether the connection-code flow felt clear. Issues and discussions are open on GitHub.</p>
<p>— foisal</p>
]]></content:encoded></item><item><title><![CDATA[I got tired of pasting API keys into every coding agent, so I built a local router]]></title><description><![CDATA[You open Cursor and paste an OpenAI key. Then Claude Code wants Anthropic. OpenCode wants something else. Switch models for a week and you're editing three…]]></description><link>https://foisalislam.hashnode.dev/i-got-tired-of-pasting-api-keys-into-every-coding-agent-so-i-built-a-local-router</link><guid isPermaLink="true">https://foisalislam.hashnode.dev/i-got-tired-of-pasting-api-keys-into-every-coding-agent-so-i-built-a-local-router</guid><category><![CDATA[AI]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Foisal Islam]]></dc:creator><pubDate>Fri, 06 Nov 2026 06:52:28 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6aeb9f36275626370aceee01/6abacf12-7ed4-459c-8b98-b35c6b937d09.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You open Cursor and paste an OpenAI key. Then Claude Code wants Anthropic. OpenCode wants something else. Switch models for a week and you're editing three config files and hoping you didn't leave a key in a screenshot.</p>
<p>I wanted one address on my own machine that every OpenAI-compatible client could talk to, with the provider keys staying on disk. That's WowRouter.</p>
<h2>What it actually is</h2>
<p>WowRouter is a local AI router. It listens only on this computer:</p>
<table>
<thead>
<tr>
<th>What</th>
<th>Address</th>
</tr>
</thead>
<tbody><tr>
<td>Web panel</td>
<td><code>http://127.0.0.1:8787</code></td>
</tr>
<tr>
<td>OpenAI-compatible API</td>
<td><code>http://127.0.0.1:8787/v1</code></td>
</tr>
</tbody></table>
<p>You add provider keys in the panel, turn models on, create a router key (shown once, starts with <code>sk-airoute-</code>), and point Cursor or any OpenAI client at that base URL with the router key.</p>
<p>A public model id looks like <code>openai/gpt-4o-mini</code>. You can also set the model to <code>auto</code> (or <code>auto/cheap</code>, <code>auto/fast</code>, <code>auto/coding</code>) and let the router pick among the chat models you turned on. Named combos use ids like <code>fallback/daily</code> and fall through when a model fails.</p>
<p>Provider keys are encrypted with a local secret. Router keys are stored as hashes — the panel cannot show a router key again after you leave the create screen. The server rejects a listen address that isn't loopback (<code>127.0.0.1</code>, <code>localhost</code>, or <code>::1</code>).</p>
<h2>Install</h2>
<p>Node.js 20 or newer:</p>
<pre><code class="language-bash">npm install -g wowrouter
wowrouter
</code></pre>
<p><code>npm install -g airoute</code> is the same program. Desktop builds for Windows, macOS and Linux are attached to each <a href="https://github.com/foisalislambd/wowrouter/releases">GitHub release</a>. Docker works too, still bound to this computer:</p>
<pre><code class="language-bash">docker run -d --name wowrouter \
  -p 127.0.0.1:8787:8787 \
  -v wowrouter:/data \
  foisalislambd/wowrouter:latest
</code></pre>
<h2>First setup</h2>
<ol>
<li>Open the panel.</li>
<li><strong>Providers</strong> — save an API key (GitHub Enterprise Copilot uses Sign in with GitHub; Copilot Web asks for a bearer token). Rows marked Unsupported have no stable API.</li>
<li>Turn on the models you want. A model that is off is not offered to clients.</li>
<li><strong>API keys</strong> — create a router key.</li>
<li>In Cursor (or any OpenAI client): base URL <code>http://127.0.0.1:8787/v1</code>, API key = that router key.</li>
</ol>
<p>Chat calls need three things at once: a saved provider key, the model switched on, and a router key on the request. Password / OIDC on the panel are off by default. Leave them off on your own computer. Turn one on before you publish the port (for example from Docker on a VPS).</p>
<p>Some providers ship with an empty model list. <strong>Load models</strong> on that provider's page fills it from the provider.</p>
<h2>What's in the panel</h2>
<p>Overview, Providers, Routing (<code>auto</code> presets and named fallbacks), API keys, Playground, Activity (each gateway call with request/response), Clients (copy-paste setup plus a confirmed one-click writer for Claude Code, OpenCode and Codex), Usage (calls by model, 14-day chart, estimated cost), Memory (optional notes prepended to chat), and Settings.</p>
<p>Closing the browser tab does not stop the router.</p>
<h2>Stack and license</h2>
<p>Go server and SQLite, React panel, native desktop wrapper, npm CLI that launches the server. MIT. Current release is <strong>v1.5.5</strong>. Repo: <a href="https://github.com/foisalislambd/wowrouter">github.com/foisalislambd/wowrouter</a>.</p>
<h2>Honest limits</h2>
<ul>
<li>It's young. The repo started in October 2026. I'm one person.</li>
<li>Some providers are marked Unsupported. Decision models use <code>POST /v1/systemone</code>, not chat completions.</li>
<li>If you expose the port past loopback without a panel password or OIDC, that's on you — the README is clear about locking it first.</li>
<li>I have not counted how many providers the catalog currently lists; open the Providers page after install rather than trusting a number from a blog post.</li>
</ul>
<p>If you try it and something breaks, open an issue on the repo. If your setup is "three agents, five keys, one laptop", I'd like to know whether one local endpoint actually helped.</p>
<p>— foisal</p>
]]></content:encoded></item><item><title><![CDATA[I got tired of rebuilding the same admin panel for every framework]]></title><description><![CDATA[Every side project eventually needs an admin screen. Sidebar, login, a table of things, a settings page, dark mode. On Next.js there are plenty of starting…]]></description><link>https://foisalislam.hashnode.dev/i-got-tired-of-rebuilding-the-same-admin-panel-for-every-framework</link><guid isPermaLink="true">https://foisalislam.hashnode.dev/i-got-tired-of-rebuilding-the-same-admin-panel-for-every-framework</guid><category><![CDATA[webdev]]></category><category><![CDATA[Next.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Open Source]]></category><dc:creator><![CDATA[Foisal Islam]]></dc:creator><pubDate>Fri, 06 Nov 2026 06:51:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6aeb9f36275626370aceee01/4311159e-4e27-4dc8-8ef9-41cc0445f70e.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every side project eventually needs an admin screen. Sidebar, login, a table of things, a settings page, dark mode. On Next.js there are plenty of starting points. On Vue, Svelte, Astro or Angular I kept rebuilding the same chrome by hand — or giving up and shipping something ugly.</p>
<p>ZenPanel is my attempt to stop doing that.</p>
<h2>What it is</h2>
<p>ZenPanel is an open-source admin UI shell. One command scaffolds the same polished dashboard for several frameworks:</p>
<pre><code class="language-bash">npm create zenpanel@latest
</code></pre>
<p>You'll be asked for a project name and a framework. Or skip the prompts:</p>
<pre><code class="language-bash">npm create zenpanel@latest my-admin -- --framework nextjs
npm create zenpanel@latest my-admin -- --framework vue
npm create zenpanel@latest my-admin -- --framework svelte
# also: react, preact, solid, html, astro, angular
</code></pre>
<p>Then:</p>
<pre><code class="language-bash">cd my-admin
npm run dev
</code></pre>
<p>Login URLs differ by framework (Next on <code>:3000</code>, most Vite templates on <code>:5173</code>, Astro <code>:4321</code>, Angular <code>:4200</code>). Demo credentials for the preview UI are <code>admin</code> / <code>admin</code> — that is not real auth.</p>
<p>There's a live demo at <a href="https://zenpanel.foisal.org/">zenpanel.foisal.org</a>.</p>
<h2>What's included</h2>
<ul>
<li>Responsive shell: collapsible sidebar, header, breadcrumbs, user menu</li>
<li>Dashboard: welcome hero, stats cards, revenue chart, activity feed, quick actions</li>
<li>Resource pages with table layout and empty states ready for an API</li>
<li>Messages (two-pane inbox empty state) and Settings (account &amp; branding)</li>
<li>Login (split-screen preview auth)</li>
<li>Light and dark themes</li>
<li>Optional AI assistant panel (depth depends on the framework)</li>
</ul>
<p>Next.js is the visual source of truth. The React, Preact, Solid, Svelte, Vue, HTML, Astro and Angular templates are meant to match that UI. Remix is listed as coming soon.</p>
<h2>Customize, then connect an API</h2>
<p>Branding and nav live in one config file per template (<code>src/config/admin.config.ts</code> for most Vite/Next templates; Angular, HTML and Astro have their own paths — see the README). Change the name, tagline, logo letter, login copy and sidebar links there.</p>
<p>The sample metrics and tables are preview data. When you're ready, replace them with your own endpoints. The docs under <code>docs/connecting-api.md</code> walk through that. ZenPanel ships a shell, not a backend.</p>
<h2>Requirements and stack</h2>
<p>Node.js 20+ (Astro needs 22.12+). Templates use Tailwind CSS 4 and Lucide icons. Current release of the CLI is <strong><a href="mailto:create-zenpanel@2.1.3">create-zenpanel@2.1.3</a></strong>. MIT licensed.</p>
<p>Repo: <a href="https://github.com/foisalislambd/zenpanel">github.com/foisalislambd/zenpanel</a></p>
<h2>Honest limits</h2>
<ul>
<li>Preview login is not production auth. You still need real authentication before you put this on the internet.</li>
<li>There is no built-in data layer like react-admin or Refine. If you need that, those projects are better fits.</li>
<li>Remix isn't ready yet.</li>
<li>It's a young project (repo started June 2026) and mostly me.</li>
</ul>
<p>If you try a template and the UI drifts from Next, or a framework install breaks on your machine, please open an issue. The whole point is that the shell should feel the same wherever you land.</p>
<p>— foisal</p>
]]></content:encoded></item><item><title><![CDATA[Stop uploading your contracts to random websites. I wrote a PDF editor instead]]></title><description><![CDATA[You need to merge two pages of a contract and add your signature. Small job. On a Linux laptop, the fastest option is usually one of those free online PDF…]]></description><link>https://foisalislam.hashnode.dev/stop-uploading-your-contracts-to-random-websites-i-wrote-a-pdf-editor-instead</link><guid isPermaLink="true">https://foisalislam.hashnode.dev/stop-uploading-your-contracts-to-random-websites-i-wrote-a-pdf-editor-instead</guid><category><![CDATA[C++]]></category><category><![CDATA[Linux]]></category><category><![CDATA[open source]]></category><category><![CDATA[privacy]]></category><dc:creator><![CDATA[Foisal Islam]]></dc:creator><pubDate>Wed, 04 Nov 2026 21:52:36 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6aeb9f36275626370aceee01/1115401e-afaf-4124-9aaa-41f12129bf63.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You need to merge two pages of a contract and add your signature. Small job. On a Linux laptop, the fastest option is usually one of those free online PDF sites. Drag, drop, done.</p>
<p>Then think about what you just did. You uploaded a document with your name, your address, the other party's details and your signature to a server you know nothing about. To merge two pages.</p>
<p>That kept bothering me every time I thought about it. So I started building SweetPDF.</p>
<h2>The problem I kept running into</h2>
<p>On Windows the answer is usually "pay for Acrobat". A monthly subscription for something most of us open a few times a month to sign, fill a form, or black out an account number. On Linux the situation is different but not better. You end up with a reader for viewing, a separate tool for rearranging pages, a command-line OCR script, and maybe a proprietary editor for the rest.</p>
<p>All of those tools are fine. I just wanted one desktop app that did the boring everyday stuff, worked offline, and didn't want an account.</p>
<h2>What SweetPDF does today</h2>
<p>SweetPDF is a native desktop PDF editor written in C++20 with Qt 6 and MuPDF. It's AGPL-3.0 and it runs on Linux and Windows. Right now it can:</p>
<ul>
<li>Highlight, underline, strike out, draw, add notes, text boxes and shapes. These are real PDF annotations, so other viewers see them.</li>
<li>Reorder pages by dragging thumbnails, insert, delete, rotate, extract, merge and split.</li>
<li>Fill in forms, reset them, and flatten them so nobody can change the values.</li>
<li>Add a signature you draw, type, or import as an image.</li>
<li>Redact for real. The content underneath is removed from the file, not covered with a black box.</li>
<li>Encrypt with AES-128 or AES-256 and choose what's still allowed (printing, copying and so on).</li>
<li>Run OCR with Tesseract so a scanned document becomes searchable.</li>
<li>Export pages as images, text or HTML, add watermarks, and compress.</li>
</ul>
<p>Everything is on one undo stack, including page moves. Nothing touches the file on disk until you save. There's no telemetry and no auto-updater, which is a bit old-fashioned, but it means the app never talks to the internet unless you click a link.</p>
<h2>Some choices I made, and why</h2>
<p><strong>Qt Widgets, not QML.</strong> A ribbon, two side panels and a canvas with hundreds of items is a dense desktop UI. Widgets stay fast and look native, and QML would have added a runtime for very little gain.</p>
<p><strong>MuPDF for rendering and annotations.</strong> One C API covers rasterising, structured text, annotations and redaction, and it's quick. The catch is the license: MuPDF is AGPL, so SweetPDF is AGPL too. I'm fine with that. If you're building on top of it, you should know before you start.</p>
<p><strong>QPDF for structural work.</strong> Merge, split, encryption and repair happen at the object level, which is where MuPDF is weakest.</p>
<p><strong>Tesseract for OCR.</strong> It's the only serious open-source engine, and it gives per-word bounding boxes, which is what you need to lay an invisible text layer over a scan.</p>
<p>The redaction part was the most interesting to get right. Plenty of tools "redact" by drawing a rectangle on top. Copy the text out and it's all still there. SweetPDF uses MuPDF's redaction so the glyphs and image data under the mark are actually removed when you apply it.</p>
<h2>What it doesn't do yet</h2>
<p>I'd rather you hear this from me than find it after downloading.</p>
<ul>
<li><strong>Text editing is replacement, not reflow.</strong> You select words and replace them. The old glyphs are redacted away and your text is placed on top. It works for fixing a name or a date. It won't reflow a paragraph like a word processor. Proper reflow is the next big item on the roadmap.</li>
<li><strong>No cryptographic (PKCS#7) signatures yet.</strong> Visual signatures work. SweetPDF can check existing signed fields, but it can't create a certificate-based signature.</li>
<li><strong>No macOS build yet.</strong> The code builds on macOS with Homebrew, but I don't ship a binary. That's on the list.</li>
<li><strong>Not in Flathub, winget or Homebrew yet.</strong> Packaging is next.</li>
</ul>
<p>It's a young project. There are rough edges and I'm one person.</p>
<h2>Trying it</h2>
<p>Grab a build from the <a href="https://github.com/foisalislambd/SweetPDF/releases">releases page</a>:</p>
<ul>
<li>Ubuntu 26.04+ / Debian 14+: <code>sudo apt install ./sweetpdf_*.deb</code></li>
<li>Other Linux: unpack the tarball and run <code>bin/sweetpdf</code> (needs Qt 6.4+, MuPDF and Tesseract from your distro)</li>
<li>Windows 10/11: the setup <code>.exe</code>, or the portable <code>.zip</code> that writes nothing to the registry</li>
</ul>
<p>Every release has a <code>SHA256SUMS</code> file. If you'd rather build it yourself, the README has steps for Ubuntu, Fedora, MSYS2 and macOS.</p>
<p>The easiest way to get a feel for it: open a copy of some PDF and try every tool. Nothing is destructive until you press Ctrl+S.</p>
<h2>What would help</h2>
<p>If you try it, I'd really like to know what broke, what felt slow, and which missing feature stopped you from using it for real work. Issues are open on <a href="https://github.com/foisalislambd/SweetPDF">GitHub</a>. If you know Flatpak packaging or have a Mac and some patience, that help would go a long way too.</p>
<p>And if you just want a PDF editor that doesn't ask you to upload your contracts to a stranger's server, give it a try.</p>
<p>— foisal</p>
]]></content:encoded></item><item><title><![CDATA[I already had a VPS, so why was I paying a platform to deploy my apps?]]></title><description><![CDATA[I already had my own VPS. It sat there with plenty of RAM, mostly idle. And I was still paying a platform to deploy my apps onto someone else's servers…]]></description><link>https://foisalislam.hashnode.dev/i-already-had-a-vps-so-why-was-i-paying-a-platform-to-deploy-my-apps</link><guid isPermaLink="true">https://foisalislam.hashnode.dev/i-already-had-a-vps-so-why-was-i-paying-a-platform-to-deploy-my-apps</guid><category><![CDATA[Docker]]></category><category><![CDATA[self-hosted]]></category><category><![CDATA[open source]]></category><category><![CDATA[Devops]]></category><dc:creator><![CDATA[Foisal Islam]]></dc:creator><pubDate>Wed, 04 Nov 2026 21:13:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6aeb9f36275626370aceee01/d085b8bc-3d44-4c3c-ba8d-b5186de13006.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I already had my own VPS. It sat there with plenty of RAM, mostly idle. And I was <em>still</em> paying a platform to deploy my apps onto someone else's servers.</p>
<p>That felt silly. So I built Dockfin.</p>
<h2>The problem nobody puts on the pricing page</h2>
<p>Platforms like Heroku and Vercel are great at one thing: they make the first deploy feel like magic. You push, you get a URL, you feel like a genius.</p>
<p>The trouble starts later. A second app. A database. A preview environment for every pull request. A teammate who needs access. Each of these is reasonable on its own, and together they become a monthly number you try not to look at.</p>
<p>The alternative is doing it yourself. Docker, a reverse proxy, TLS, webhooks, backups, all wired up by hand. That's a weekend you never get back, and then you have to <em>maintain</em> it.</p>
<p>So the choice usually looks like this: pay for convenience, or pay with your time. I wanted a third option.</p>
<h2>What Dockfin is</h2>
<p>Dockfin is an MIT-licensed self-hosted PaaS. The whole thing (a Go API plus a React dashboard) ships as a single Docker image. You install it on an Ubuntu or Debian server with one command:</p>
<pre><code class="language-bash">curl -fsSL https://raw.githubusercontent.com/foisalislambd/dockfin/main/scripts/install.sh | sudo bash
</code></pre>
<p>The script installs Docker if it's missing, generates secrets, starts Postgres and Dockfin, and opens the dashboard on port 8000. Ports 80 and 443 stay free for the proxy. You register an admin account, the server adds itself, and you create your first project.</p>
<p>From there you can deploy:</p>
<ul>
<li><strong>Apps</strong> from a Dockerfile, a Compose file, a prebuilt image, Railpack, or a static build</li>
<li><strong>Databases</strong> like Postgres, MySQL, MongoDB, and Redis, with backups to S3</li>
<li><strong>One-click services</strong> from a library of hundreds of templates</li>
</ul>
<p>It talks to your servers over SSH, so one dashboard can manage several machines. State lives in your own Postgres, so nothing leaves your infrastructure.</p>
<h2>Three features I'd fight for</h2>
<p>Most PaaS feature lists look the same, so I'll skip the checklist and talk about the parts I care about most.</p>
<p><strong>1. Deploy freeze.</strong> You can freeze an environment with a reason, like "Launch day, no deploys until 6pm." New deploys stop. Git webhooks get <em>skipped</em> instead of failing, so your Git provider doesn't keep retrying and filling your logs with red. Restarts, stops, and rollbacks still work, because a freeze should stop surprises, not stop you from fixing things. If an owner really needs to ship a hotfix, there's an explicit override.</p>
<p>Anyone who has watched an auto-deploy land in the middle of a launch or an incident knows why this matters.</p>
<p><strong>2. Deploys you can watch, and undo.</strong> Every deploy streams its logs live and shows which step it's on. If it fails, you see why. If it succeeds and breaks something anyway, rollback is one click. From the terminal, <code>dfin logs &lt;id&gt; --follow</code> gives you the same stream.</p>
<p><strong>3. A CLI that isn't an afterthought.</strong> <code>dfin</code> can create, edit, and delete servers, projects, environments, apps, services, databases, env vars, and domains. Every command has a <code>--json</code> flag, so it works in scripts and CI:</p>
<pre><code class="language-bash">dfin --json projects list
dfin freeze &lt;project&gt; &lt;env&gt; --reason "maintenance"
dfin deploy &lt;app&gt; --override-freeze
</code></pre>
<h2>The boring parts that matter</h2>
<p>The stuff nobody tweets about is what lets you sleep. Dockfin has:</p>
<ul>
<li>per-IP rate limits, stricter on auth and webhooks</li>
<li>security headers and a Content-Security-Policy</li>
<li>TOTP 2FA and team roles</li>
<li>an audit log of who did what, kept for 90 days by default</li>
<li>a Prometheus <code>/metrics</code> endpoint, which you can lock behind a token</li>
<li>an OpenAPI 3.1 spec generated straight from the router, with a test that fails if the spec and the code drift apart</li>
</ul>
<p>It also handles Git webhooks for GitHub, GitLab, Gitea, and Bitbucket, PR preview environments that clean themselves up, Traefik or Caddy, Docker Swarm, and Cloudflare Tunnel.</p>
<h2>What it's <em>not</em></h2>
<p>I'd rather lose you now than disappoint you later:</p>
<ul>
<li>It <strong>won't run on cPanel or shared hosting.</strong> It needs Docker and root on a VPS or dedicated server.</li>
<li>It's <strong>young.</strong> The repo started in July 2026. It's at v2.0.0, but it's mostly built by one person, so it hasn't been battle-tested by thousands of users.</li>
<li>If you need Kubernetes-scale orchestration or a vendor SLA, use something else.</li>
</ul>
<p>And yes, Coolify is the obvious comparison. It's a great project, and if it already works for you, keep using it. Dockfin is my take on the same idea: a Go control plane, one image, and a strong focus on safe deploys (freeze, live progress, rollback) and a scriptable CLI. Try both and keep the one that fits how you work.</p>
<h2>What's next</h2>
<p>The next big thing I want is an <strong>app marketplace</strong>: a separate catalog service with its own API, which Dockfin reads so you can install apps like WordPress into a project in one click. The idea is that new apps can be added without shipping a new Dockfin release.</p>
<h2>Try it, and break it</h2>
<p>If you have a spare VPS (even a cheap one), I'd love for you to try Dockfin and tell me where it falls over. Issues, rough edges, confusing screens, anything:</p>
<p>👉 <a href="https://github.com/foisalislambd/dockfin"><strong>https://github.com/foisalislambd/dockfin</strong></a></p>
<p>Website and docs: <a href="https://dockfin.foisal.org">https://dockfin.foisal.org</a></p>
<p>A star helps other people find it. A bug report helps me more.</p>
<p>Thanks for reading. — Foisal</p>
]]></content:encoded></item></channel></rss>