[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"public-config":3,"i-flag:ph-4x3":14,"i-flag:us-4x3":19,"i-flag:de-4x3":21,"i-flag:hk-4x3":23,"i-tabler:lifebuoy":25,"i-tabler:timeline":28,"i-tabler:apps":30,"i-tabler:package":32,"i-tabler:circle-half-2":34,"i-tabler:sun":36,"i-tabler:moon":38,"i-tabler:menu-2":40,"i-tabler:user":42,"i-tabler:notebook":44,"i-simple-icons:forgejo":46,"i-tabler:shield-lock":48,"i-tabler:tools":50,"i-tabler:calendar":52,"i-tabler:x":54,"$fpim0brj42h8b":56,"i-tabler:arrow-left":73,"i-tabler:tag":75},{"matomo":4,"booking":7,"site":9,"blog":11,"newsletter":12},{"enabled":5,"siteId":6},true,"7",{"enabled":5,"url":8},"https:\u002F\u002Fcal.com\u002Fjdbungart",{"url":10},"https:\u002F\u002Fjdneer.com",{"enabled":5},{"enabled":13},false,{"left":15,"top":15,"width":16,"height":17,"rotate":15,"vFlip":13,"hFlip":13,"body":18},0,640,480,"\u003Cpath fill=\"#0038a8\" d=\"M0 0h640v240H0z\"\u002F>\u003Cpath fill=\"#ce1126\" d=\"M0 240h640v240H0z\"\u002F>\u003Cpath fill=\"#fff\" d=\"M415.7 240L0 480V0\"\u002F>\u003Cpath fill=\"#fcd116\" d=\"M26.7 42.4L41 55l16.6-9.2l-7.4 17.5l14 13l-19-1.6l-8.1 17.2l-4.3-18.5L14 71l16.3-10zm323.8 172.3l.4 19l18 6.3l-18 6.2l-.4 19l-11.5-15.1l-18.2 5.5l10.8-15.6l-10.8-15.6l18.2 5.5zM37.2 388.1l8 17.2l19-1.6l-13.9 13l7.4 17.5l-16.6-9.1l-14.4 12.4l3.6-18.7L14 409l18.9-2.4zm114.2-249l-6.2 6.2l3.1 47l-3 .3l-5.7-42.9l-5.1 5l7.6 38.4a48 48 0 0 0-17.2 7.1l-21.7-32.4H96l26.4 34.3l-2.4 2l-31.1-35.5h-8.8v8.8l35.4 31l-2 2.5l-34.3-26.3v7.1l32.5 21.7q-5.2 7.8-7.1 17.2L66.3 223l-5.1 5l42.9 5.7q-.3 1.6-.3 3.1l-47-3l-6.2 6.2l6.2 6.2l47-3.1l.3 3.1l-42.9 5.7l5 5l38.4-7.6a48 48 0 0 0 7.1 17.2l-32.5 21.7v7.2l34.3-26.3l2 2.4l-35.4 31v8.8H89l31-35.4l2.5 2L96 312.2h7.2l21.7-32.5q7.8 5.2 17.2 7.1l-7.6 38.4l5 5l5.7-42.9q1.5.3 3.1.3l-3 47l6.1 6.2l6.3-6.2l-3.1-47l3-.3l5.7 43l5.1-5.1l-7.6-38.4a48 48 0 0 0 17.2-7.1l21.7 32.5h7.2l-26.4-34.3l2.4-2l31.1 35.4h8.8v-8.8l-35.4-31l2-2.4l34.3 26.3v-7.2l-32.5-21.7q5.2-7.8 7.1-17.2l38.3 7.6l5.1-5l-42.9-5.7q.3-1.5.3-3.1l47 3l6.2-6.1l-6.2-6.2l-47 3l-.3-3l42.9-5.7l-5-5l-38.4 7.5a48 48 0 0 0-7.1-17.2l32.5-21.7v-7.1l-34.3 26.3l-2-2.4l35.4-31v-8.9H214l-31 35.5l-2.5-2l26.4-34.3h-7.2L178 200.2q-7.8-5.2-17.2-7.1l7.6-38.3l-5-5l-5.7 42.8l-3.1-.3l3-47z\"\u002F>",{"left":15,"top":15,"width":16,"height":17,"rotate":15,"vFlip":13,"hFlip":13,"body":20},"\u003Cpath fill=\"#bd3d44\" d=\"M0 0h640v480H0\"\u002F>\u003Cpath stroke=\"#fff\" stroke-width=\"37\" d=\"M0 55.3h640M0 129h640M0 203h640M0 277h640M0 351h640M0 425h640\"\u002F>\u003Cpath fill=\"#192f5d\" d=\"M0 0h364.8v258.5H0\"\u002F>\u003Cmarker id=\"SVGEq3dreKJ\" markerHeight=\"30\" markerWidth=\"30\">\u003Cpath fill=\"#fff\" d=\"m14 0l9 27L0 10h28L5 27z\"\u002F>\u003C\u002Fmarker>\u003Cpath fill=\"none\" marker-mid=\"url(#SVGEq3dreKJ)\" d=\"m0 0l16 11h61h61h61h61h60L47 37h61h61h60h61L16 63h61h61h61h61h60L47 89h61h61h60h61L16 115h61h61h61h61h60L47 141h61h61h60h61L16 166h61h61h61h61h60L47 192h61h61h60h61L16 218h61h61h61h61h60z\"\u002F>",{"left":15,"top":15,"width":16,"height":17,"rotate":15,"vFlip":13,"hFlip":13,"body":22},"\u003Cpath fill=\"#fc0\" d=\"M0 320h640v160H0z\"\u002F>\u003Cpath fill=\"#000001\" d=\"M0 0h640v160H0z\"\u002F>\u003Cpath fill=\"red\" d=\"M0 160h640v160H0z\"\u002F>",{"left":15,"top":15,"width":16,"height":17,"rotate":15,"vFlip":13,"hFlip":13,"body":24},"\u003Cpath fill=\"#ec1b2e\" d=\"M0 0h640v480H0\"\u002F>\u003Cpath id=\"SVG5tfvBPpj\" fill=\"#fff\" d=\"M346.3 103.1C267 98 230.6 201.9 305.6 240.3c-26-22.4-20.6-55.3-10.1-72.4l1.9 1.1c-13.8 23.5-11.2 52.7 11.1 71c-12.7-12.3-9.5-39 12.1-48.9s23.6-39.3 16.4-49.1q-14.7-25.6 9.3-38.9M307.9 164l-4.7 7.4l-1.8-8.6l-8.6-2.3l7.8-4.3l-.6-8.9l6.5 6.1l8.3-3.3l-3.7 8.1l5.6 6.8z\"\u002F>\u003Cuse href=\"#SVG5tfvBPpj\" transform=\"rotate(72 312.5 243.5)\"\u002F>\u003Cuse href=\"#SVG5tfvBPpj\" transform=\"rotate(144 312.5 243.5)\"\u002F>\u003Cuse href=\"#SVG5tfvBPpj\" transform=\"rotate(216 312.5 243.5)\"\u002F>\u003Cuse href=\"#SVG5tfvBPpj\" transform=\"rotate(288 312.5 243.5)\"\u002F>",{"left":15,"top":15,"width":26,"height":26,"rotate":15,"vFlip":13,"hFlip":13,"body":27},24,"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M8 12a4 4 0 1 0 8 0a4 4 0 1 0-8 0\"\u002F>\u003Cpath d=\"M3 12a9 9 0 1 0 18 0a9 9 0 1 0-18 0m12 3l3.35 3.35M9 15l-3.35 3.35m0-12.7L9 9m9.35-3.35L15 9\"\u002F>\u003C\u002Fg>",{"left":15,"top":15,"width":26,"height":26,"rotate":15,"vFlip":13,"hFlip":13,"body":29},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m4 16l6-7l5 5l5-6\"\u002F>\u003Cpath d=\"M14 14a1 1 0 1 0 2 0a1 1 0 1 0-2 0M9 9a1 1 0 1 0 2 0a1 1 0 1 0-2 0m-6 7a1 1 0 1 0 2 0a1 1 0 1 0-2 0m16-8a1 1 0 1 0 2 0a1 1 0 1 0-2 0\"\u002F>\u003C\u002Fg>",{"left":15,"top":15,"width":26,"height":26,"rotate":15,"vFlip":13,"hFlip":13,"body":31},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 5a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1zm0 10a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1zm10 0a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1zm0-8h6m-3-3v6\"\u002F>",{"left":15,"top":15,"width":26,"height":26,"rotate":15,"vFlip":13,"hFlip":13,"body":33},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m12 3l8 4.5v9L12 21l-8-4.5v-9zm0 9l8-4.5M12 12v9m0-9L4 7.5m12-2.25l-8 4.5\"\u002F>",{"left":15,"top":15,"width":26,"height":26,"rotate":15,"vFlip":13,"hFlip":13,"body":35},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M3 12a9 9 0 1 0 18 0a9 9 0 1 0-18 0m9-9v18m0-7l7-7m-7 12l8.5-8.5M12 9l4.5-4.5\"\u002F>",{"left":15,"top":15,"width":26,"height":26,"rotate":15,"vFlip":13,"hFlip":13,"body":37},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 12a4 4 0 1 0 8 0a4 4 0 1 0-8 0m-5 0h1m8-9v1m8 8h1m-9 8v1M5.6 5.6l.7.7m12.1-.7l-.7.7m0 11.4l.7.7m-12.1-.7l-.7.7\"\u002F>",{"left":15,"top":15,"width":26,"height":26,"rotate":15,"vFlip":13,"hFlip":13,"body":39},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 3h.393a7.5 7.5 0 0 0 7.92 12.446A9 9 0 1 1 12 2.992z\"\u002F>",{"left":15,"top":15,"width":26,"height":26,"rotate":15,"vFlip":13,"hFlip":13,"body":41},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 6h16M4 12h16M4 18h16\"\u002F>",{"left":15,"top":15,"width":26,"height":26,"rotate":15,"vFlip":13,"hFlip":13,"body":43},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 7a4 4 0 1 0 8 0a4 4 0 0 0-8 0M6 21v-2a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v2\"\u002F>",{"left":15,"top":15,"width":26,"height":26,"rotate":15,"vFlip":13,"hFlip":13,"body":45},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 4h11a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1m3 0v18m4-14h2m-2 4h2\"\u002F>",{"left":15,"top":15,"width":26,"height":26,"rotate":15,"vFlip":13,"hFlip":13,"body":47},"\u003Cpath fill=\"currentColor\" d=\"M16.777 0a2.9 2.9 0 1 1-2.529 4.322H12.91a4.266 4.266 0 0 0-4.265 4.195v2.118a7.08 7.08 0 0 1 4.147-1.42l.118-.002h1.338a2.9 2.9 0 0 1 5.43 1.422a2.9 2.9 0 0 1-5.43 1.422H12.91a4.266 4.266 0 0 0-4.265 4.195v2.319A2.9 2.9 0 0 1 7.222 24A2.9 2.9 0 0 1 5.8 18.57V8.589a7.11 7.11 0 0 1 6.991-7.108l.118-.001h1.338A2.9 2.9 0 0 1 16.778 0M7.223 19.905a1.194 1.194 0 1 0 0 2.389a1.194 1.194 0 0 0 0-2.389m9.554-10.464a1.194 1.194 0 1 0 0 2.389a1.194 1.194 0 0 0 0-2.39m0-7.735a1.194 1.194 0 1 0 0 2.389a1.194 1.194 0 0 0 0-2.389\"\u002F>",{"left":15,"top":15,"width":26,"height":26,"rotate":15,"vFlip":13,"hFlip":13,"body":49},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M12 3a12 12 0 0 0 8.5 3A12 12 0 0 1 12 21A12 12 0 0 1 3.5 6A12 12 0 0 0 12 3\"\u002F>\u003Cpath d=\"M11 11a1 1 0 1 0 2 0a1 1 0 1 0-2 0m1 1v2.5\"\u002F>\u003C\u002Fg>",{"left":15,"top":15,"width":26,"height":26,"rotate":15,"vFlip":13,"hFlip":13,"body":51},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M3 21h4L20 8a1.5 1.5 0 0 0-4-4L3 17zM14.5 5.5l4 4\"\u002F>\u003Cpath d=\"M12 8L7 3L3 7l5 5M7 8L5.5 9.5M16 12l5 5l-4 4l-5-5m4 1l-1.5 1.5\"\u002F>\u003C\u002Fg>",{"left":15,"top":15,"width":26,"height":26,"rotate":15,"vFlip":13,"hFlip":13,"body":53},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 7a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2zm12-4v4M8 3v4m-4 4h16m-9 4h1m0 0v3\"\u002F>",{"left":15,"top":15,"width":26,"height":26,"rotate":15,"vFlip":13,"hFlip":13,"body":55},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18 6L6 18M6 6l12 12\"\u002F>",{"slug":57,"title":58,"excerpt":59,"image":60,"publishedAt":61,"topics":62,"readMinutes":63,"html":64,"metaTitle":58,"metaDescription":65,"shareImage":66,"updatedAt":61,"author":70,"related":72},"rosbackup-ng-reimagined-from-backup-script-to-routeros-management-platform","rosbackup-ng Reimagined: From Backup Script to RouterOS Management Platform","What began as a simple RouterOS backup script has evolved into a self-hosted management platform. This post explores the major refactor behind rosbackup-ng, its new modular architecture, the optional web platform, and what's next before the 1.0 release.","\u002Fcontent\u002Fimages\u002F2026\u002F06\u002Fweb-dashboard.png","2026-06-30T08:30:42.000+08:00",[],5,"\u003Cp>Some projects have a habit of growing far beyond their original scope.\u003C\u002Fp>\u003Cp>When I first started \u003Cstrong>rosbackup-ng\u003C\u002Fstrong> over a decade ago, all I wanted was a reliable way to automate backups for MikroTik RouterOS devices. At the time, I wasn't trying to build a platform. I simply wanted something that produced binary and plaintext backups, could run against multiple routers in parallel.\u003C\u002Fp>\u003Cp>It scratched my own itch.\u003C\u002Fp>\u003Cp>As it turns out, it also solved a problem for a lot of other people.\u003C\u002Fp>\u003Cp>Over the last year and a half, the project has steadily grown. Every release added another feature, another quality-of-life improvement, another request from users, or another problem I'd encountered in production. Eventually I reached a point where I wasn't spending most of my time building new functionality anymore. I was spending it working around architectural decisions that had made perfect sense when the project consisted of a few Python files.\u003C\u002Fp>\u003Cp>That's usually a good sign that it's time to stop adding features and start improving the foundation.\u003C\u002Fp>\u003Cfigure class=\"kg-card kg-bookmark-card\">\u003Ca class=\"kg-bookmark-container\" href=\"https:\u002F\u002Fgit.jdneer.com\u002Fjd\u002Frosbackup-ng?ref=ghost.jdneer.com\">\u003Cdiv class=\"kg-bookmark-content\">\u003Cdiv class=\"kg-bookmark-title\">rosbackup-ng\u003C\u002Fdiv>\u003Cdiv class=\"kg-bookmark-description\">Automated, resilient backup utility for MikroTik RouterOS - parallel, encrypted binary &amp; plaintext backups with tmpfs staging and tag\u002Fgroup targeting, pluggable storage (local\u002FSFTP\u002FS3\u002FNextcloud) with retention &amp; mirroring, and an optional self-hosted web UI\u002FAPI for scheduling, monitoring, and pus…\u003C\u002Fdiv>\u003Cdiv class=\"kg-bookmark-metadata\">\u003Cimg class=\"kg-bookmark-icon\" src=\"\u002Fcontent\u002Fimages\u002Ficon\u002Ffavicon-4423048c-ded6-4202-8f9c-25ebaa207688.svg\" alt=\"\" \u002F>\u003Cspan class=\"kg-bookmark-author\">Forgejo: Beyond coding. We Forge.\u003C\u002Fspan>\u003Cspan class=\"kg-bookmark-publisher\">jd\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"kg-bookmark-thumbnail\">\u003Cimg src=\"\u002Fcontent\u002Fimages\u002Fthumbnail\u002Fsummary-card-dc0d55ff-3e4f-4d7e-9d7a-1b16d6789f09\" alt=\"\" \u002F>\u003C\u002Fdiv>\u003C\u002Fa>\u003C\u002Ffigure>\u003Ch2 id=\"more-than-a-refactor\">More Than a Refactor\u003C\u002Fh2>\u003Cp>Calling this latest work a \"refactor\" doesn't really do it justice.\u003C\u002Fp>\u003Cp>The goal wasn't simply to clean up some code or split a few files into packages. I wanted to rethink how rosbackup-ng was structured while preserving everything that already worked well.\u003C\u002Fp>\u003Cp>The original CLI remains, existing workflows continue to work, and the YAML configuration format is still familiar. Underneath, though, almost everything has been redesigned into a much more modular architecture that's significantly easier to maintain and extend.\u003C\u002Fp>\u003Cp>That work isn't particularly glamorous, but it's probably the most important change the project has seen since it started.\u003C\u002Fp>\u003Ch2 id=\"reliable-backups-were-always-the-goal\">Reliable Backups Were Always the Goal\u003C\u002Fh2>\u003Cp>At its core, rosbackup-ng is still a backup utility.\u003C\u002Fp>\u003Cp>It creates both binary (\u003Ccode>.backup\u003C\u002Fcode>) and plaintext (\u003Ccode>.rsc\u003C\u002Fcode>) backups, supports encryption, stages backups in tmpfs to reduce flash wear where supported, and was built to continue working even across unreliable overlay networks like ZeroTier.\u003C\u002Fp>\u003Cp>I've always cared more about reliability than flashy features.\u003C\u002Fp>\u003Cp>Networks aren't perfect. VPNs flap. SSH sessions drop. Remote sites lose connectivity.\u003C\u002Fp>\u003Cp>That's why a lot of time has gone into things users hopefully never have to think about: connection retry windows, TCP keepalives, operation-level reconnects, proper host key verification, secure defaults, encrypted backups, restrictive file permissions, and a healthy amount of automated testing.\u003Cbr \u002F>Those aren't the features that get screenshots on social media.\u003C\u002Fp>\u003Cp>They're the ones that make software dependable.\u003C\u002Fp>\u003Ch2 id=\"growing-beyond-backups\">Growing Beyond Backups\u003C\u002Fh2>\u003Cp>As the project evolved, I found myself wanting features that went beyond simply creating backup files.\u003C\u002Fp>\u003Cp>Managing hundreds of routers manually isn't much fun.\u003C\u002Fp>\u003Cp>So rosbackup-ng has gradually become much more fleet-aware.\u003C\u002Fp>\u003Cp>Devices can now be organized using tags and groups, making it easy to target entire customers, sites, or infrastructure classes. Backup storage has become completely pluggable, supporting local storage, SFTP, Nextcloud, S3-compatible object storage, and future backends through a clean plugin architecture. Each destination can have its own routing and retention policy, making off-site backup strategies much easier to implement.\u003C\u002Fp>\u003Cp>It's a completely different experience compared to where the project started.\u003C\u002Fp>\u003Cpre>\u003Ccode>[+] Backing up 5000 targets\n    ██████████░░░░░░░░░░░░░░░░░░░░ 1640\u002F5000  33%   ✔ 1628  ✘ 12  ⠹ 48 running   2m14s   eta 4m31s\n\nActive:\n    ⠹ router-1641             Backing Up          1.2s\n    ⠼ router-1642             Getting Info        0.4s\n    … and 46 more running\n\nRecent failures:\n    router-0044, router-0210\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"a-better-experience-for-large-deployments\">A Better Experience for Large Deployments\u003C\u002Fh2>\u003Cp>One feature I didn't expect to spend so much time on was terminal output.\u003C\u002Fp>\u003Cp>When you're backing up three routers, traditional logging works perfectly.\u003C\u002Fp>\u003Cp>When you're backing up three thousand, it's chaos.\u003C\u002Fp>\u003Cp>I wanted something that remained readable regardless of fleet size, so I built a compose-style interface that automatically adapts. Smaller environments get detailed per-device progress, while larger deployments switch to an aggregate dashboard showing throughput, ETA, active operations, and recent failures.\u003C\u002Fp>\u003Cp>It's one of my favorite parts of the project because it solves a surprisingly common problem that most command-line tools simply ignore.\u003C\u002Fp>\u003Ch2 id=\"introducing-rosbackup-web\">Introducing rosbackup-web\u003C\u002Fh2>\u003Cp>Probably the biggest addition during this refactor is the optional web platform.\u003C\u002Fp>\u003Cp>One thing I wanted to avoid was creating yet another cloud service. Infrastructure administrators should be able to run their own tools inside their own environments.\u003C\u002Fp>\u003Cfigure class=\"kg-card kg-image-card kg-width-wide\">\u003Cimg src=\"\u002Fcontent\u002Fimages\u002F2026\u002F06\u002Fweb-dashboard-1.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"2000\" height=\"1125\" srcset=\"\u002Fcontent\u002Fimages\u002Fsize\u002Fw600\u002F2026\u002F06\u002Fweb-dashboard-1.png 600w, \u002Fcontent\u002Fimages\u002Fsize\u002Fw1000\u002F2026\u002F06\u002Fweb-dashboard-1.png 1000w, \u002Fcontent\u002Fimages\u002Fsize\u002Fw1600\u002F2026\u002F06\u002Fweb-dashboard-1.png 1600w, \u002Fcontent\u002Fimages\u002F2026\u002F06\u002Fweb-dashboard-1.png 2000w\" sizes=\"(min-width: 1200px) 1200px\" \u002F>\u003C\u002Ffigure>\u003Cp>That's exactly what \u003Cstrong>rosbackup-web\u003C\u002Fstrong> does.\u003C\u002Fp>\u003Cp>It shares the same backup engine as the CLI but adds a self-hosted dashboard, inventory management, scheduling, backup browsing, firmware upgrades, latency monitoring, API tokens, audit logging, an encrypted Vault for credentials, and a REST API for automation. Everything stays under your control.\u003C\u002Fp>\u003Cp>One feature I'm particularly happy with is the guarded push-restore workflow.\u003C\u002Fp>\u003Cp>Restoring a RouterOS backup is inherently risky, so the application treats it accordingly. Before anything destructive happens, it creates a fresh backup, verifies integrity, requires explicit confirmation, prevents concurrent operations, and records everything in the audit log.\u003C\u002Fp>\u003Cp>Those extra safeguards don't exist because they're complicated.\u003C\u002Fp>\u003Cp>They exist because everyone eventually has a bad day.\u003C\u002Fp>\u003Ch2 id=\"getting-started\">Getting Started\u003C\u002Fh2>\u003Cp>If you'd like to try rosbackup-ng, the quickest way is with Docker.\u003C\u002Fp>\u003Cfigure class=\"kg-card kg-bookmark-card kg-card-hascaption\">\u003Ca class=\"kg-bookmark-container\" href=\"https:\u002F\u002Fgit.jdneer.com\u002Fjd\u002Frosbackup-ng\u002Fsrc\u002Fbranch\u002Fmain\u002Fdoc\u002FDEPLOY.md?ref=ghost.jdneer.com\">\u003Cdiv class=\"kg-bookmark-content\">\u003Cdiv class=\"kg-bookmark-title\">rosbackup-ng\u002Fdoc\u002FDEPLOY.md at main\u003C\u002Fdiv>\u003Cdiv class=\"kg-bookmark-description\">rosbackup-ng - Automated, resilient backup utility for MikroTik RouterOS - parallel, encrypted binary &amp; plaintext backups with tmpfs staging and tag\u002Fgroup targeting, pluggable storage (local\u002FSFTP\u002FS3\u002FNextcloud) with retention &amp; mirroring, and an optional self-hosted web UI\u002FAPI for scheduling, monitoring, and push-restore.\u003C\u002Fdiv>\u003Cdiv class=\"kg-bookmark-metadata\">\u003Cimg class=\"kg-bookmark-icon\" src=\"\u002Fcontent\u002Fimages\u002Ficon\u002Ffavicon-83b6a432-3d47-4399-95c4-c7cbe3291799.svg\" alt=\"\" \u002F>\u003Cspan class=\"kg-bookmark-author\">Forgejo: Beyond coding. We Forge.\u003C\u002Fspan>\u003Cspan class=\"kg-bookmark-publisher\">jd\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"kg-bookmark-thumbnail\">\u003Cimg src=\"\u002Fcontent\u002Fimages\u002Fthumbnail\u002Fsummary-card-f9778cd8-4798-4dde-a7f4-cbf82543ab41\" alt=\"\" \u002F>\u003C\u002Fdiv>\u003C\u002Fa>\u003Cfigcaption>\u003Cp>\u003Cspan>Getting started with the rosbackup-ng docker compose stack.\u003C\u002Fspan>\u003C\u002Fp>\u003C\u002Ffigcaption>\u003C\u002Ffigure>\u003Cp>The included deployment script sets everything up for you, including the optional web platform.\u003C\u002Fp>\u003Cp>After that you'll have access to the dashboard, scheduling, backup browser, inventory management, firmware workflows, and the REST API. If Docker isn't your thing, rosbackup-ng can also be installed via \u003Cstrong>pip\u003C\u002Fstrong>, as a standalone Python zipapp, or directly from source.\u003C\u002Fp>\u003Ch2 id=\"why-its-still-pre-10\">Why It's Still Pre-1.0\u003C\u002Fh2>\u003Cp>You might notice the project is still marked as pre-1.0.\u003C\u002Fp>\u003Cp>That's intentional.\u003C\u002Fp>\u003Cp>The software is \u003Cstrong>not yet\u003C\u002Fstrong> considered stable enough for production use and I want to give myself room to keep refining the architecture before committing to long-term API and configuration compatibility.\u003C\u002Fp>\u003Cp>I've learned over the years that it's much easier to get those decisions right now than to carry them forever.\u003C\u002Fp>\u003Ch2 id=\"looking-ahead\">Looking Ahead\u003C\u002Fh2>\u003Cp>Looking back, it's funny to think this all started as a backup script.\u003C\u002Fp>\u003Cp>Today it's evolved into something much larger: a self-hosted RouterOS management platform that's designed to scale from a handful of devices to thousands.\u003C\u002Fp>\u003Cp>There are still plenty of ideas on my list. Better reporting, richer inventory, additional automation workflows, and more operational tooling are all things I want to build.\u003C\u002Fp>\u003Cp>The difference now is that I finally have an architecture that makes those ideas exciting instead of intimidating.\u003C\u002Fp>\u003Cp>Sometimes the most valuable work you can do on a project isn't adding another feature.\u003C\u002Fp>\u003Cp>Sometimes it's taking the time to build a foundation that's ready for everything that comes next.\u003C\u002Fp>","What began as a simple RouterOS backup script has evolved into a self-hosted management platform. This post explores the major refactor behind...",{"src":60,"width":67,"height":68,"type":69},2000,1125,"image\u002Fpng",{"name":71,"url":10,"owner":5},"JD Bungart",[],{"left":15,"top":15,"width":26,"height":26,"rotate":15,"vFlip":13,"hFlip":13,"body":74},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 12h14M5 12l6 6m-6-6l6-6\"\u002F>",{"left":15,"top":15,"width":26,"height":26,"rotate":15,"vFlip":13,"hFlip":13,"body":76},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M6.5 7.5a1 1 0 1 0 2 0a1 1 0 1 0-2 0\"\u002F>\u003Cpath d=\"M3 6v5.172a2 2 0 0 0 .586 1.414l7.71 7.71a2.41 2.41 0 0 0 3.408 0l5.592-5.592a2.41 2.41 0 0 0 0-3.408l-7.71-7.71A2 2 0 0 0 11.172 3H6a3 3 0 0 0-3 3\"\u002F>\u003C\u002Fg>"]