<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Foisal Islam</title>
    <description>The latest articles on DEV Community by Foisal Islam (@foisal_islam_43df80b6d4e2).</description>
    <link>https://dev.to/foisal_islam_43df80b6d4e2</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4227181%2Fe99bc0b5-94a8-430d-ab10-502cd31f4d36.png</url>
      <title>DEV Community: Foisal Islam</title>
      <link>https://dev.to/foisal_islam_43df80b6d4e2</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/foisal_islam_43df80b6d4e2"/>
    <language>en</language>
    <item>
      <title>Stop uploading your contracts to random websites. I wrote a PDF editor instead</title>
      <dc:creator>Foisal Islam</dc:creator>
      <pubDate>Wed, 04 Nov 2026 21:49:31 +0000</pubDate>
      <link>https://dev.to/foisal_islam_43df80b6d4e2/stop-uploading-your-contracts-to-random-websites-i-wrote-a-pdf-editor-instead-5d0j</link>
      <guid>https://dev.to/foisal_islam_43df80b6d4e2/stop-uploading-your-contracts-to-random-websites-i-wrote-a-pdf-editor-instead-5d0j</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;That kept bothering me every time I thought about it. So I started building SweetPDF.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem I kept running into
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What SweetPDF does today
&lt;/h2&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Highlight, underline, strike out, draw, add notes, text boxes and shapes. These are real PDF annotations, so other viewers see them.&lt;/li&gt;
&lt;li&gt;Reorder pages by dragging thumbnails, insert, delete, rotate, extract, merge and split.&lt;/li&gt;
&lt;li&gt;Fill in forms, reset them, and flatten them so nobody can change the values.&lt;/li&gt;
&lt;li&gt;Add a signature you draw, type, or import as an image.&lt;/li&gt;
&lt;li&gt;Redact for real. The content underneath is removed from the file, not covered with a black box.&lt;/li&gt;
&lt;li&gt;Encrypt with AES-128 or AES-256 and choose what's still allowed (printing, copying and so on).&lt;/li&gt;
&lt;li&gt;Run OCR with Tesseract so a scanned document becomes searchable.&lt;/li&gt;
&lt;li&gt;Export pages as images, text or HTML, add watermarks, and compress.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some choices I made, and why
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Qt Widgets, not QML.&lt;/strong&gt; 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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MuPDF for rendering and annotations.&lt;/strong&gt; 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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;QPDF for structural work.&lt;/strong&gt; Merge, split, encryption and repair happen at the object level, which is where MuPDF is weakest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tesseract for OCR.&lt;/strong&gt; 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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it doesn't do yet
&lt;/h2&gt;

&lt;p&gt;I'd rather you hear this from me than find it after downloading.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Text editing is replacement, not reflow.&lt;/strong&gt; 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.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No cryptographic (PKCS#7) signatures yet.&lt;/strong&gt; Visual signatures work. SweetPDF can check existing signed fields, but it can't create a certificate-based signature.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No macOS build yet.&lt;/strong&gt; The code builds on macOS with Homebrew, but I don't ship a binary. That's on the list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not in Flathub, winget or Homebrew yet.&lt;/strong&gt; Packaging is next.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's a young project. There are rough edges and I'm one person.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trying it
&lt;/h2&gt;

&lt;p&gt;Grab a build from the &lt;a href="https://github.com/foisalislambd/SweetPDF/releases" rel="noopener noreferrer"&gt;releases page&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ubuntu 26.04+ / Debian 14+: &lt;code&gt;sudo apt install ./sweetpdf_*.deb&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Other Linux: unpack the tarball and run &lt;code&gt;bin/sweetpdf&lt;/code&gt; (needs Qt 6.4+, MuPDF and Tesseract from your distro)&lt;/li&gt;
&lt;li&gt;Windows 10/11: the setup &lt;code&gt;.exe&lt;/code&gt;, or the portable &lt;code&gt;.zip&lt;/code&gt; that writes nothing to the registry&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every release has a &lt;code&gt;SHA256SUMS&lt;/code&gt; file. If you'd rather build it yourself, the README has steps for Ubuntu, Fedora, MSYS2 and macOS.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What would help
&lt;/h2&gt;

&lt;p&gt;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 &lt;a href="https://github.com/foisalislambd/SweetPDF" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. If you know Flatpak packaging or have a Mac and some patience, that help would go a long way too.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;— foisal&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>linux</category>
      <category>privacy</category>
      <category>cpp</category>
    </item>
    <item>
      <title>I already had a VPS, so why was I paying a platform to deploy my apps?</title>
      <dc:creator>Foisal Islam</dc:creator>
      <pubDate>Wed, 04 Nov 2026 21:07:57 +0000</pubDate>
      <link>https://dev.to/foisal_islam_43df80b6d4e2/i-already-had-a-vps-so-why-was-i-paying-a-platform-to-deploy-my-apps-5blj</link>
      <guid>https://dev.to/foisal_islam_43df80b6d4e2/i-already-had-a-vps-so-why-was-i-paying-a-platform-to-deploy-my-apps-5blj</guid>
      <description>&lt;p&gt;I already had my own VPS. It sat there with plenty of RAM, mostly idle. And I was &lt;em&gt;still&lt;/em&gt; paying a platform to deploy my apps onto someone else's servers.&lt;/p&gt;

&lt;p&gt;That felt silly. So I built Dockfin.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem nobody puts on the pricing page
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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 &lt;em&gt;maintain&lt;/em&gt; it.&lt;/p&gt;

&lt;p&gt;So the choice usually looks like this: pay for convenience, or pay with your time. I wanted a third option.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Dockfin is
&lt;/h2&gt;

&lt;p&gt;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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/foisalislambd/dockfin/main/scripts/install.sh | &lt;span class="nb"&gt;sudo &lt;/span&gt;bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;From there you can deploy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Apps&lt;/strong&gt; from a Dockerfile, a Compose file, a prebuilt image, Railpack, or a static build&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Databases&lt;/strong&gt; like Postgres, MySQL, MongoDB, and Redis, with backups to S3&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One-click services&lt;/strong&gt; from a library of hundreds of templates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three features I'd fight for
&lt;/h2&gt;

&lt;p&gt;Most PaaS feature lists look the same, so I'll skip the checklist and talk about the parts I care about most.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Deploy freeze.&lt;/strong&gt; You can freeze an environment with a reason, like "Launch day, no deploys until 6pm." New deploys stop. Git webhooks get &lt;em&gt;skipped&lt;/em&gt; 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.&lt;/p&gt;

&lt;p&gt;Anyone who has watched an auto-deploy land in the middle of a launch or an incident knows why this matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Deploys you can watch, and undo.&lt;/strong&gt; 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, &lt;code&gt;dfin logs &amp;lt;id&amp;gt; --follow&lt;/code&gt; gives you the same stream.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. A CLI that isn't an afterthought.&lt;/strong&gt; &lt;code&gt;dfin&lt;/code&gt; can create, edit, and delete servers, projects, environments, apps, services, databases, env vars, and domains. Every command has a &lt;code&gt;--json&lt;/code&gt; flag, so it works in scripts and CI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dfin &lt;span class="nt"&gt;--json&lt;/span&gt; projects list
dfin freeze &amp;lt;project&amp;gt; &amp;lt;&lt;span class="nb"&gt;env&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;--reason&lt;/span&gt; &lt;span class="s2"&gt;"maintenance"&lt;/span&gt;
dfin deploy &amp;lt;app&amp;gt; &lt;span class="nt"&gt;--override-freeze&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The boring parts that matter
&lt;/h2&gt;

&lt;p&gt;The stuff nobody tweets about is what lets you sleep. Dockfin has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;per-IP rate limits, stricter on auth and webhooks&lt;/li&gt;
&lt;li&gt;security headers and a Content-Security-Policy&lt;/li&gt;
&lt;li&gt;TOTP 2FA and team roles&lt;/li&gt;
&lt;li&gt;an audit log of who did what, kept for 90 days by default&lt;/li&gt;
&lt;li&gt;a Prometheus &lt;code&gt;/metrics&lt;/code&gt; endpoint, which you can lock behind a token&lt;/li&gt;
&lt;li&gt;an OpenAPI 3.1 spec generated straight from the router, with a test that fails if the spec and the code drift apart&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it's &lt;em&gt;not&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;I'd rather lose you now than disappoint you later:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It &lt;strong&gt;won't run on cPanel or shared hosting.&lt;/strong&gt; It needs Docker and root on a VPS or dedicated server.&lt;/li&gt;
&lt;li&gt;It's &lt;strong&gt;young.&lt;/strong&gt; 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.&lt;/li&gt;
&lt;li&gt;If you need Kubernetes-scale orchestration or a vendor SLA, use something else.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;The next big thing I want is an &lt;strong&gt;app marketplace&lt;/strong&gt;: 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it, and break it
&lt;/h2&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com/foisalislambd/dockfin" rel="noopener noreferrer"&gt;https://github.com/foisalislambd/dockfin&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Website and docs: &lt;a href="https://dockfin.foisal.org" rel="noopener noreferrer"&gt;https://dockfin.foisal.org&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A star helps other people find it. A bug report helps me more.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;br&gt;
— Foisal&lt;/p&gt;

</description>
      <category>selfhosted</category>
      <category>opensource</category>
      <category>devops</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
