oxid/ docs

// for developers

Someone gave you a token. Now what?

You do not run the Oxid server — someone on your team does. This page is the whole of what you need: connect once, push a branch, get a URL, read the logs when it misbehaves. Nothing here requires access to the server itself.

# once, on your machine:
oxid login http://oxid.tu-empresa.local:8080
→ paste your token when prompted

# then, from any checkout, forever:
oxid up mi-rama
oxid logs mi-rama

Connecting

oxid login saves the server and your token, checks both against the daemon, and makes it active. From then on no command needs --api or --token.

$ oxid login http://oxid.tu-empresa.local:8080
Access token (paste and press enter): ••••
[+] Logged in to http://oxid.tu-empresa.local:8080 as `juan` (developer)
[~] Projects: 1 — every other project answers 404
[~] Access expires: 2026-11-29 15:36:04
[~] You can: view environments and logs · deploy, pause, wake, destroy

The token is read from stdin rather than an argument, so it never lands in your shell history or in the process list where anyone on a shared machine could read it with ps. Pass --token instead when you are scripting.

CommandWhat it does
oxid login <url>Save a server and log in. --as-name staging if you use more than one.
oxid loginLog back in to the last server — the address is still saved, so you never re-type it.
oxid logoutClear the token, keep the server. What you want on a shared machine.
oxid logout --forgetRemove the server entry too.
oxid serverList saved servers; the active one is marked, tokens masked.
oxid connect stagingSwitch to another saved server.
oxid whoamiWho you are here, and what you may do.

Everything lives in ~/.config/oxid/config.toml, written 0600. oxid context is the same thing with more knobs, if you prefer it.

What am I allowed to do?

Ask, instead of finding out from a 403 halfway through something:

$ oxid whoami
[+] juan on http://oxid.tu-empresa.local:8080 (developer)
[~] Projects: 1 — every other project answers 404
[~] Access expires: 2026-11-29 15:36:04
[~] You can: view environments and logs · deploy, pause, wake, destroy
Your roleYou canYou cannot
viewerSee environments, logs and history.Change anything.
developerEverything above, plus deploy, roll back, pause, wake and destroy environments.Read or write secrets; change project settings.
maintainerEverything above, plus your projects' secrets, settings and branch rules.Anything about the server itself.
adminThe server too, and giving other people access.—

Two answers mean different things, and it is worth knowing which you got. A 403 tells you exactly what is wrong — your role is too low, your access expired, it was suspended — and is something an operator can fix for you. A 404 on a project means it is not in your scope; from where you stand it does not exist.

Getting a branch running

Usually you do not: someone wires a webhook once, and every push deploys its branch by itself. oxid up is for the times you want it now, or the branch is not one the webhook rules cover.

$ cd ~/code/tienda && git checkout -b feature-carrito
$ oxid up feature-carrito
[>] Building image for feature-carrito...
[+] Image built (cache hit: 100%, 832ms)
[+] Environment live at: http://feature-carrito.tienda.local.dev/

The daemon clones the repository itself, from your checkout's origin. It never reads your working tree — uncommitted work is not deployed, which is usually what you want and always worth knowing.

Asking explicitly always wins. If your team restricted which branches deploy on push, oxid up <branch> still deploys the branch you name. The filter is about what a push does, not about what you may ask for.

Reading logs, and working out what happened

$ oxid logs feature-carrito           # what the container printed
$ oxid logs feature-carrito --follow  # and keep printing
$ oxid logs feature-carrito --tail 200

Where to look, by what you are actually asking:

The questionThe command
Is my branch up, and on what URL?oxid status
What is my app printing?oxid logs <branch>
Why did my deploy fail?oxid logs <branch> — a failed build leaves a build_failed environment whose logs are the build output.
Who deployed this, and when?oxid audit --branch <branch>
Is it just waiting for capacity?oxid queue
Is it me, or the server?oxid doctor

States you will see

StateMeans
buildingThe image is being built. First build of a branch is the slow one; after that the cache does most of the work.
runningLive and serving.
pausedNobody used it for a while, so it was stopped and its memory given back. The next request wakes it — you do not have to do anything. oxid wake <branch> if you want it warm first.
build_failedYour build or first start broke. The previous working environment, if any, is still serving — a broken push does not take the branch down.
destroyedGone: the branch was deleted, its lifetime ran out, or someone tore it down.

A paused environment answering slowly on the first request is normal, not a bug: it is the container starting. That is the whole point of scale-to-zero — your idle branches are not holding the server's RAM.

The rest of the day-to-day

$ oxid status                    # your branches, states and URLs
$ oxid ps                        # projects you can see
$ oxid pause feature-carrito     # give the RAM back now
$ oxid wake feature-carrito      # warm it before a demo
$ oxid down feature-carrito      # destroy it for good
$ oxid rollback feature-carrito --commit a1b2c3d
$ oxid audit --branch feature-carrito

Every command takes --json and exits with a distinct code per failure kind, so any of this drops into CI without parsing text.

Prefer a browser? The same server serves a dashboard at its root. Paste your token into the box in the top bar and you get the same view, plus live logs. It installs as an app and opens offline — see Web dashboard.

Changing how your branch is built

Most repositories need nothing: if yours has a Dockerfile it is used, and if it does not, Oxid reads your package.json, go.mod, pyproject.toml or Cargo.toml and generates one — see Stacks & builds.

When you do need to say something, it goes in oxid.toml at the root of your repository, and it is read from the commit being deployed. So you can change it on your branch and see the effect on your branch alone:

[build]
dockerfile = "docker/Dockerfile.dev"
context    = "."
on_start   = ["./seed.sh"]   # runs inside the container once it is up

[routing]
port = 3000                # the port your app listens on

The base domain and the idle/lifetime policy are not yours to change from a branch — otherwise one branch could rewrite another's URL. Those belong to whoever runs the server.

When something is off

What you seeWhat it is
403 … needs the `maintainer` roleYour role is below the action. Ask an operator; nothing is broken.
403 … this access expiredYour token ran out. An operator issues a new one.
403 … has been suspendedYour access was switched off. It can be switched back on with the same token.
404 project …Not in your scope. From where you stand it does not exist.
401 missing or invalid bearer tokenNot logged in, or an OXID_TOKEN in your shell is overriding the saved one. oxid whoami says which server you are on.
cannot reach daemonWrong address, or the server is down. oxid server shows what you are pointed at; oxid doctor checks the rest.
Your branch deployed nothing on pushYour team may have restricted which branches deploy. oxid up <branch> still works, and oxid audit shows what happened.
The URL is slow the first timeThe environment was paused and is waking. Normal.