Self-Hosted Deploy Tools Felt Too Busy, So I Built ox
I could pay a lot to keep deploys simple, or pay less and fight a busy screen. I wanted neither, so I built a calm deploy tool for my own server.
Hi, I’m a self-taught backend developer with 3+ years of experience, currently working at a tech startup based in The Bahamas. I mostly work with Python and Django, building APIs, designing database models, and improving performance when needed. I enjoy learning new tools and technologies as projects require.
I built ox because putting my apps online was always the hard part, and no tool felt right to me. The easy hosted tools cost a lot. The tools you run on your own server were good, but their screens had too much on them. So I made a small tool that puts a repo on your own server, and I kept every screen as calm as I could.
Writing the app was the fun part
I taught myself to code on freeCodeCamp. Then I spent about five years building the server side of web apps for clients. Writing the app was always the fun part for me. Getting it online was not.
Each time, I had to set up a server again. The web server. The database. The jobs that run on a timer. I wrote long guides about it on this blog, like the one for Django with Gunicorn, Nginx and PostgreSQL. Each guide had many steps.
Two roads, and I did not like either
First I tried the easy tools, like Vercel. You push your code, and it goes live. It is a lovely feeling. But that nice feel costs a lot of money.
Then I tried tools you run on your own server. They are wonderful tools, and many people love them. I mean that. But their screens had too much on them for me. I could not enjoy using them.
So I could pay a lot to keep things simple. Or I could pay less and fight a busy screen. I did not want either one.
So I built my own
I called it ox. It puts your app on a server you rent, called a VPS. You push your code to GitHub. ox builds it and puts it live on your server. It does not use Docker. It uses the plain parts that come with Linux. Each app runs as a systemd service, and Caddy sits in front of it with HTTPS.
I set one rule for the screens. Show what you need right now, and hide the rest. A project's main page shows if your app is up, its web address and the last deploy. Everything else sits behind Settings. A new app needs no setup at all, because ox picks good settings for you.
Most of what ox does comes from pain I felt over the years. Here are the small things I cared about most.
Logs that show what led to an error
When something breaks, I filter the logs to show only errors. That helps. But a filter also hides the lines just before the error, and those lines often say why it happened.
So in ox, when a filter is on, each matching line gets two buttons. One brings back the 10 lines just above it. The other brings back the 10 lines just below it. Press again to go 10 lines further. You see what led up to the error, not only the error.
You can filter from a terminal too:
ox logs shop --severity error
ox logs shop --process web --grep "timeout"
Your AI writes the setup file
Most apps need no setup file. When yours does, it is one small file called ox.toml. You do not have to write it by hand. You copy our guide into your coding AI. It reads your code and writes the file for you.
Here is the part I care about. The AI only writes the file. When you deploy, ox just reads it. So the same file gives the same result every time. Here is one for a Django app with a worker:
domains = ["myapp.com"]
[app]
health = "/healthz"
[workers]
worker = "celery -A app worker"
[services]
postgres = {}
redis = {}
A check before every deploy
ox checks the file before it changes anything. A mistake, or a secret you forgot to set, stops the update before your live site is touched. You can run the same check in your repo:
ox check
It prints the plan and the variables you still need. When all is well, it ends with "Ready to deploy."
A failed update leaves your site up
This one matters most to me. If a step fails, your live app keeps running. The new version starts next to the old one. Traffic moves only after the new one passes its health check. If a step fails, your visitors stay on the old version. ox tells you which step failed, why, and how to fix it.
Commands for you and your AI
Most things on the dashboard are also a command. Each command can print its answer as data with --json, so an AI agent can use it too:
ox deploy myapp --wait --json
Where it stands today
ox is in beta, and my own apps run on it. One of them is Lazy Planner, a small app that helps you plan your days. ox works with JavaScript and TypeScript, Python, Go, Rust, PHP and plain websites.
It is not for everyone yet, and I want to be clear about that. One project runs on one server. Servers run the latest Ubuntu LTS. An account is for one person for now.
I think software should be as simple as it can be, while still doing all the things you need. ox is my try at that, for putting apps online.
Try it
ox is free while it is in beta. You can sign up with your GitHub account at deploywithox.com. The quickstart takes you from a fresh server to a live app. To see the log buttons I talked about, read the logs page.
![]()
Tired of doing all this by hand? ox deploys your repo to your own server for you. No Docker, no config maze. Try deploywithox.com



