briqbriq
Guides

Run your own app

Your code as a running service, with a URL, in one call and no image to build.

Recipes: Python app, Node.js app, Bun app, Go app, Ruby app, Rust app, PHP app, Static site

An agent writes a small app (an API, a dashboard, a webhook receiver) and wants it running where someone can open it. A language recipe takes the code as files and runs it: no Dockerfile, no registry, no build to wait for on your side.

Your code is in a repo?

On GitHub, GitLab or another git host: see Run a GitHub repo. The briq downloads the code itself.

Pick your language

RecipeImageInstalls at each startStarts with
pythonpython:<version>-slimrequirements.txtpython app.py
nodenode:<version>-slimpackage.jsonnode server.js
bunoven/bun:1-slimpackage.jsonbun run server.ts
gogolang:<version>-alpinebuilds the modulethe binary
rustrust:1-slimbuilds a releasecargo run --release
rubyruby:<version>-slimGemfileruby app.rb
phpphp:<version>-clinothingPHP's built-in server
staticnginxnothingnginx, serving your files

Each takes version, files (your code), start, install and build to change the defaults, env, port (8080) and size. Python, node, bun and ruby also take packages, for dependencies without a manifest. static takes only files and size, and serves port 80. Without files, each runs a hello-world app, a quick way to see the shape of it.

One call

briq_run({
  recipe: "python",
  params: {
    files: {
      "app.py": "…a Flask app listening on :: and $PORT…",
      "requirements.txt": "flask"
    }
  },
  expose: "private"
})
→ bq_9a2… app (python:3.12-slim) running · …internal · url: https://app-m4qa.briq.run/?briq_token=… · cost so far … · sleeps at 18:42 UTC unless used
  outputs:
    APP_URL=http://…internal:8080
    URL=https://app-m4qa.briq.run/?briq_token=…

What happens:

  1. The files are written into the briq under /app before anything starts.
  2. requirements.txt is installed, then python app.py starts with PORT=8080.
  3. briq waits until something answers on that port, then the call returns. A first install or build can outlast the call's two minutes: the briq then shows creating, and briq_status tells you when it runs.
  4. The URL was published as the briq was created: nothing restarts to publish it, and with wait: false you get it at once.

With a database

Run the database first, in the same stack, and hand its connection string to the app:

briq_run({ recipe: "postgres", stack: "portfolio" })
→ outputs: DATABASE_URL=postgres://postgres:…@….internal:5432/app

briq_run({
  recipe: "python",
  stack: "portfolio",
  params: {
    files: { "app.py": "…reads os.environ['DATABASE_URL']…", "requirements.txt": "flask\npsycopg[binary]" },
    env: { DATABASE_URL: { secret: "DATABASE_URL", value: "postgres://postgres:…@….internal:5432/app" } }
  },
  expose: "private"
})

Briqs in one stack reach each other on the private network; only the app gets a URL. The connection string holds a password, so it goes in as a secret: stored encrypted, shown as { secret: "DATABASE_URL" } in status and the dashboard, and kept out of the audit log.

Changing the code

The files you pass are the briq's boot files: written again whenever the process starts over (a restart, a cold start), so they match what you ran. A resume from a memory snapshot carries on as it was. To ship a new version, run a new briq with the new files and briq_destroy the old one. briq_files_put edits a file in place, until the process starts over. Anything else written on the briq's disk, installed packages included, survives restarts.

When it does not start

If the app exits before it answers (a typo, a missing package, the wrong port), the run fails: the briq is in error, and its error says how the process exited. briq_logs shows the traceback. briq_destroy it, fix the files, and run again (the name is free once it is destroyed).

If it exits later, the briq stops with stoppedReason: "exited" and the code in lastExit. briq_start runs the same files again; to change them, run a new briq.

Good to know

  • Listen on ::, not localhost: the private network is IPv6, and :: takes IPv4 too.
  • 256 KB of files in all. A bigger app runs from its repo.
  • Data you cannot lose goes in a database briq, or on a volume.
  • You already have an image? Run it with image instead of a recipe; files (absolute paths, like /app/server.py), ports and expose (with a single port) work the same.

On this page

Free to try

Let your agent try it, on us.

Every new account starts with €10 of credits. No card.

Connect your agent

How can we help?

Message to the briq team
hello@briq.cloud