Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions docs/blog/posts/2026-08-17-one-command-self-hosting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
title: Fluxify now starts from a single docker run
date: 2026-08-17
author: Prajwal Aradhya
tags:
- release
- self-hosting
- engineering
---

# Fluxify now starts from a single docker run

Trying Fluxify used to mean copying an environment file, filling in a database URL, a cache host, and an event bus token, then bringing up four containers with `docker compose` before you'd seen a single screen of the product. That's a reasonable price to pay for a production deployment, but it's the wrong first five minutes for someone who just wants to see what Fluxify does.

The trial image now ships everything it needs. One command:

```bash
docker run -d --name fluxify \
-p 8080:8080 \
-v fluxify_data:/data \
-e SEED_USER_EMAIL=admin@example.com \
-e SEED_USER_PASSWORD=ChangeThisPassword123! \
fluxify-kit
```

and you have a complete stack: the dashboard, the API, the database, the cache, and the event bus, all up and healthy behind port `8080`.

## Still the same image, still your choice

Nothing was removed. Bringing your own database, cache, and event bus with `docker compose` is still fully supported, for anyone who wants their data in infrastructure they already manage. The image just decides for itself which mode to run in: if you hand it a database connection string, it uses yours, and if you don't, it starts its own inside the container. Same image, same compose file, no separate build to maintain.

## What actually changed underneath

Getting a single container to boot a full stack reliably surfaced a handful of problems that only show up once everything genuinely has to start together and stay up:

- **A dead service used to leave the container "running."** If one internal piece crashed, the container kept reporting healthy while quietly serving nothing. Now the whole container exits the moment anything inside it dies, so your restart policy actually gets a chance to fix it, instead of a demo that looks fine and answers nothing.
- **The health check was pointed at a URL that didn't exist**, so a perfectly healthy instance could never report itself as ready.
- **A missing admin email or password used to fail late and vaguely.** A fresh instance now refuses to start at all without both, rather than coming up with no way to log in.
- **The dashboard is a static bundle now**, served directly rather than run as its own Node process. One less moving part inside the container, and the whole thing comes in under 340MB.

None of this changes how you run Fluxify in production, that path is untouched and still the recommended one for anything beyond a trial. It changes how long it takes to find out whether Fluxify is worth running in production at all.

## A UI to actually test what you build

The other big piece this week: `apps/portal`, the current dashboard, had no way to create or run test suites at all. The backend for sandboxed test execution had been built out over a run of earlier issues, but every screen for it lived only in the legacy dashboard, so once that gets retired a user could build routes and blocks but never write a single test for them. [Issue #227](https://github.com/Fluxify-rest/Fluxify/issues/227) tracked closing that gap, and [PR #253](https://github.com/Fluxify-rest/Fluxify/pull/253) shipped it.

The new UI covers the full loop: create and edit a suite for a route, define assertions against the status code, body, headers, timing, or a custom JS check, override app config and integrations so a test run doesn't touch production data, then run one suite or every suite for a route and watch results fill in as they finish rather than waiting on a single spinner. A run that times out or errors says so plainly instead of showing an empty result.

![Test suite UI showing run results for a route](/test-suites/demo-blog.png)

## Try it

Full walkthrough, including how to point it at your own database instead of the bundled one, is in the [Kit deployment guide](/deployments/kit).
Binary file modified docs/public/assets/favicon.ico
Binary file not shown.
Binary file modified docs/public/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 29 additions & 1 deletion docs/public/assets/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/public/assets/logo.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/public/assets/logo_source.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[["Layer",{"applyMatrix":true,"children":[["Group",{"applyMatrix":true,"children":[["Group",{"applyMatrix":true,"children":[["Group",{"applyMatrix":true,"children":[["Path",{"applyMatrix":true,"segments":[[-160.29422,500.39835],[-308.95755,414.79918],[-308.95755,585.99753],[-160.29422,671.5967]],"closed":true,"fillColor":[0.70196,0.90196,0],"strokeColor":[0.70196,0.90196,0],"strokeWidth":2,"strokeJoin":"round","miterLimit":4,"selectedColor":[0.18431,0.6902,0.62745,1]}],["Path",{"applyMatrix":true,"segments":[[-160.29422,500.39835],[-11.63088,414.79918],[-11.63088,585.99753],[-160.29422,671.5967]],"closed":true,"fillColor":[0.54902,0.74902,0],"strokeColor":[0.54902,0.74902,0],"strokeWidth":2,"strokeJoin":"round","miterLimit":4,"selectedColor":[0.18431,0.6902,0.62745,1]}],["Path",{"applyMatrix":true,"segments":[[-160.29422,500.39835],[-308.95755,414.79918],[-160.29422,329.20001],[-11.63088,414.79918]],"closed":true,"fillColor":[0.83137,1,0],"strokeColor":[0.83137,1,0],"strokeWidth":2,"strokeJoin":"round","miterLimit":4,"selectedColor":[0.18431,0.6902,0.62745,1]}],["Path",{"applyMatrix":true,"segments":[[434.35912,500.39835],[285.69578,414.79918],[285.69578,585.99753],[434.35912,671.5967]],"closed":true,"fillColor":[0.70196,0.90196,0],"strokeColor":[0.70196,0.90196,0],"strokeWidth":2,"strokeJoin":"round","miterLimit":4,"selectedColor":[0.18431,0.6902,0.62745,1]}],["Path",{"applyMatrix":true,"segments":[[434.35912,500.39835],[583.02245,414.79918],[583.02245,585.99753],[434.35912,671.5967]],"closed":true,"fillColor":[0.54902,0.74902,0],"strokeColor":[0.54902,0.74902,0],"strokeWidth":2,"strokeJoin":"round","miterLimit":4,"selectedColor":[0.18431,0.6902,0.62745,1]}],["Path",{"applyMatrix":true,"segments":[[434.35912,500.39835],[285.69578,414.79918],[434.35912,329.20001],[583.02245,414.79918]],"closed":true,"fillColor":[0.83137,1,0],"strokeColor":[0.83137,1,0],"strokeWidth":2,"strokeJoin":"round","miterLimit":4,"selectedColor":[0.18431,0.6902,0.62745,1]}],["Path",{"applyMatrix":true,"segments":[[137.03245,158.00167],[-11.63088,72.4025],[-11.63088,243.60084],[137.03245,329.20001]],"closed":true,"fillColor":[0.70196,0.90196,0],"strokeColor":[0.70196,0.90196,0],"strokeWidth":2,"strokeJoin":"round","miterLimit":4,"selectedColor":[0.18431,0.6902,0.62745,1]}],["Path",{"applyMatrix":true,"segments":[[137.03245,158.00167],[285.69578,72.4025],[285.69578,243.60084],[137.03245,329.20001]],"closed":true,"fillColor":[0.54902,0.74902,0],"strokeColor":[0.54902,0.74902,0],"strokeWidth":2,"strokeJoin":"round","miterLimit":4,"selectedColor":[0.18431,0.6902,0.62745,1]}],["Path",{"applyMatrix":true,"segments":[[137.03245,158.00167],[-11.63088,72.4025],[137.03245,-13.19667],[285.69578,72.4025]],"closed":true,"fillColor":[0.83137,1,0],"strokeColor":[0.83137,1,0],"strokeWidth":2,"strokeJoin":"round","miterLimit":4,"selectedColor":[0.18431,0.6902,0.62745,1]}]]}],["Path",{"applyMatrix":true,"segments":[[[62.70078,200.80126],[0,0],[-148.66333,0]],[[-160.29422,414.79918],[0,-142.66528],[0,0]]],"strokeColor":[0.50196,0.50196,0.50196],"strokeWidth":18,"strokeCap":"round","miterLimit":4,"selectedColor":[0.18431,0.6902,0.62745,1]}],["Path",{"applyMatrix":true,"segments":[[[211.36412,200.80126],[0,0],[148.66333,0]],[[434.35912,414.79918],[0,-142.66528],[0,0]]],"strokeColor":[0.50196,0.50196,0.50196],"strokeWidth":18,"strokeCap":"round","miterLimit":4,"selectedColor":[0.18431,0.6902,0.62745,1]}]]}],["PointText",{"applyMatrix":false,"matrix":[1,0,0,1,656.09036,404.37172],"data":{"textContent":"FLUXIFY","textWidth":845.94914,"textHeight":235.65658},"content":"FLUXIFY","fillColor":[0.54902,0.74902,0,1],"miterLimit":4,"selectedColor":[0,0,0,0],"fontFamily":"Inter Tight","fontWeight":"900","fontSize":200,"leading":240}]]}]]}]]
Binary file modified docs/public/assets/logo_title.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/public/assets/logo_title.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion docs/public/assets/provector-logo.json

This file was deleted.

Binary file added docs/public/test-suites/demo-blog.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading