Prerequisites
System Requirements
System Requirements
Cloud Server Options
Cloud Server Options
Any cloud provider works. Popular choices:
- AWS EC2: t3.medium or larger
- Google Cloud: e2-medium or larger
- Digital Ocean: Basic Droplet with 4GB RAM
- Hetzner: CX21 or larger
http://hummingbot-api:8000 on your private tailnet.Tailscale (recommended for production)
Tailscale (recommended for production)
Create a free account at tailscale.com, then:
- Generate a reusable auth key at Settings → Keys (starts with
tskey-auth-) - Enable MagicDNS so
hummingbot-apiresolves by name - Install Tailscale on any device that should reach the API (your laptop, Condor host, etc.) and sign in to the same account
y when asked to enable Tailscale.Do I Need Tailscale?
What binds where by default
Every port in the Hummingbot API stack is on loopback out of the box. The one port that is not is Condor’s own dashboard, and only in Telegram mode — which is the mode that authenticates.
EMQX’s other listeners —
8883, 8083, 8084, 8081, 61613 — are not
published at all, since nothing in this stack speaks them.
The Condor dashboard is the one thing that binds all interfaces by default, and
only in Telegram mode, which authenticates. Local mode has no login, so it
binds loopback and stays there unless you set WEB_HOST yourself; turning
Tailscale on binds loopback too, because tailscale serve is then what exposes
it — to your tailnet only.
None of this is a substitute for the credentials. A loopback bind protects the
port; it does nothing about anyone already on that machine.
If you’re just testing locally, skip ahead—the Quick Install below works without Tailscale. See Learning Path for more use-case-based routing.
Quick Install
- Quick Start
- Hummingbot API only
- Manual install
From an empty directory:
- How you will use Condor — Telegram or Local. See Choose your install below.
- Telegram Bot Token and Telegram User ID (Telegram mode only): create the bot via @BotFather, get your id via @userinfobot.
- Tailscale, yes or no — whether to secure the connection to Hummingbot API (and the dashboard) with Tailscale. Answer
yfor production or any remote setup. You paste thetskey-auth-...key later, at the point it is actually needed. - Public IP or hostname (Telegram mode without Tailscale only) — press Enter if Condor runs on your own machine, or give the server’s public address so the
/webdashboard link works from your phone. - AI model — the wizard offers to pick the model your Trading Agents think with, and installs its CLI bridge for you. It asks before it downloads anything and tells you the cost (~250MB on a first run, 1–3 minutes), so declining is instant. You can skip it and run
make pick-modellater. See Integrating your LLM. - Whether to configure and launch Hummingbot API with Docker — answer yes if you are deploying Condor and the API on the same machine. Have Docker installed and running first. If the API runs on another server, skip this and enter that API’s URL instead. If an API is already running on port 8000, the wizard offers to keep it and asks for its credentials rather than replacing it.
- Tailscale auth key (if you said yes at step 3) — paste your
tskey-auth-...key from the Tailscale admin console. When Condor is deploying Hummingbot API on this same machine, it also asks whether that API should get its own tailnet node. Answer no unless another device needs to reach the API directly — Condor itself reaches it overlocalhosteither way. - Hummingbot API credentials — an admin username, password, and a config password. These are required and have no defaults: whatever you enter is written to the API’s
.envand to Condor’sconfig.ymlso the two sides match. Passwords are not echoed as you type.
Choose your install
Three paths. All three run the same agents, bots, routines and web dashboard — what differs is who can reach them and where alerts go.Local
Your own machine, no Telegram account. Dashboard only, no login.
Local + Telegram alerts
Your own machine, plus a bot that pushes alerts and approvals to your phone.
Server
A VPS running 24/7. Reachable from anywhere over Tailscale.
Local
No bot, no token, no Telegram account. The dashboard runs on the machine you installed on and you are already logged in when you open it:ADMIN_USER_ID — the same id your servers, chat defaults, preferences and agent memory are already keyed to. An existing Telegram install that switches to local keeps all of it.
Local + Telegram alerts
The same install, with a bot attached. You control Condor with commands (/portfolio, /trade, /agent), agents push alerts and approval requests to your phone, and /web hands you a time-limited link to the browser dashboard.
This is the difference that matters: an agent asking permission to place a trade reaches you when you are not at the machine. In Local mode that request waits until you next open the dashboard.
Needs a bot token from @BotFather and your numeric Telegram user id from @userinfobot — both covered in Create a Telegram Bot below.
Server
Condor and Hummingbot API on a VPS, running whether or not your laptop is on. Everything from the path above, plus:- Tailscale is not optional here. Hummingbot API binds
127.0.0.1by default, so on a VPS your laptop cannot reach it at all — and the alternative, wideningAPI_BINDto a public interface, is the thing you do not want: Docker’s published ports are not blocked byufw, whose rules are evaluated after Docker’s own. Tailscale gives your devices a private path without opening anything. See Do I Need Tailscale? for why. - The dashboard binds
127.0.0.1and is published to your tailnet throughtailscale serve— see The dashboard under Tailscale. - Either mode works. Telegram is the usual choice, since it reaches you off the tailnet; Local mode on a server is only reachable through the tailnet.
- Run
make doctoron the VPS after setup. It is the fastest way to catch a public bind before it matters.
The Telegram/Local distinction is recorded as
CONDOR_MODE in .env (telegram or local) and is never inferred from whether a token happens to be present. To switch later, re-run make setup and pick the other mode — your TELEGRAM_TOKEN is left in place, so switching back costs nothing. “Server” is not a mode; it is where you run one of the two. For the usual sequence — Local first, Telegram later, a server after that — see Start local, grow later.Start local, grow later
The three paths are not a one-time choice. The common route is to start with Local, attach Telegram once you want alerts reaching your phone, and involve a server once real capital is on the line. Each hop keeps what you have built — here is what each one takes.Add Telegram to a Local install
- Create a bot and get your numeric user id — Create a Telegram Bot and Get Your User ID below.
- Run
make setup. It shows the current mode and asks Keep local mode? — answernand pick Telegram, then enter the token and your id. Everything else is remembered. make restart. Send/startto your bot.
A Local install that never had Telegram runs as user id 1. Adding a bot switches your login to your Telegram id: the API servers you configured are shared and carry over, but dashboard preferences and agent conversations are keyed per user and stay behind under id 1. Make this hop early, before there is much history to leave. (The reverse switch, Telegram → Local, keeps your id — and with it everything.)
Keep Condor local, put the API on a server
You do not have to move Condor to get 24/7 execution. Bots and executors run on the Hummingbot API server — a laptop Condor driving a VPS API keeps strategies running while the laptop sleeps. Only agents, routines and alerts live in Condor itself.- On the VPS, run the Hummingbot API only installer and answer
yto Tailscale — see On the API server. - On your machine, install Tailscale and sign in to the same tailnet.
- Add the server — Settings → Servers in the dashboard (Local mode) or
/serversin Telegram: hosthummingbot-api, port8000, the credentials you set on the VPS. make doctor— the new server should report reachable, authenticated.
Move Condor itself to the server
When you want agents and routines running around the clock too:-
Install Condor on the VPS (Quick Install), in the same mode you ran locally, and answer
yto Tailscale — on a VPS it is not optional. -
Stop the new install (
make stop) and copy your state over. From the old Condor directory:Custom agents inagents/and routines inroutines/are plain files — copy those too if you wrote any. -
On the VPS:
make doctor, thenmake run. If the API now lives on this same VPS, point the server entry atlocalhostin Settings → Servers (or/servers). -
Retire the old install (
make stopon the laptop) so two Condors are not driving the same accounts.
Create a Telegram Bot
Telegram mode only—skip this and the next section if you chose Local mode.
- Open @BotFather in Telegram
- Send
/newbotand follow the prompts to name your bot - Copy the bot token (format:
123456789:ABCdefGHIjklMNOpqrsTUVwxyz)
Get Your User ID
- Open @userinfobot in Telegram
- Send
/startto receive your user ID
Secure Remote Access with Tailscale
Use Tailscale when Condor and Hummingbot API run on different machines—for example Condor on your laptop and the API on a cloud VPS.On the API server
- Run the Hummingbot API only installer (or Quick Start with API enabled)
- When asked Use Tailscale for secure private networking?, answer
y - Paste your auth key and deploy:
On the Condor machine
- Install Tailscale and sign in to the same account
- In Telegram, open
/servers— or in Local mode, Settings → Servers in the dashboard — and add the API with:- Host:
hummingbot-api(MagicDNS name, not a public IP) - Port:
8000 - Username / Password: same as the API
.env
- Host:
The dashboard under Tailscale
Turning Tailscale on changes where the web dashboard listens. WithUSE_TAILSCALE=true in .env, Condor binds the dashboard to 127.0.0.1 and publishes it to your tailnet through tailscale serve, rather than binding 0.0.0.0 and trusting the network. The port is never on a public interface, and only devices signed in to your tailnet can reach it.
If the tailscale serve proxy cannot be confirmed, Condor logs an error and leaves the dashboard on loopback. It does not fall back to a public bind — a silent fallback is how a trading dashboard ends up on the open internet. So a dashboard you cannot reach from another device means the proxy is not up, not that the bind is wrong:
Verify Installation
Runmake doctor first—it reports dependencies, config, the AI model, the dashboard binding, Tailscale, and Hummingbot API connectivity in one pass, and exits non-zero if anything is actually broken.
Telegram mode
- Open your Telegram bot and send
/start - You should see the main menu with commands like
/portfolio,/trade,/agent
- Open
http://localhost:8088in a browser on the machine running Condor - You are logged in already—no token, no login screen
Note: After Condor starts successfully, admins should receive a Telegram message: “Condor is online and ready.” If that does not appear within a minute or two, see Troubleshooting (for example attach to the condor tmux session after Quick Start).
Access Points
Managing Services
How you manage Condor depends on how you installed it. After Quick Start (deploy installer): Condor runs in a tmux session namedcondor.
condor folder, you can also upgrade with:
make run also starts Condor in a tmux session named condor, and the Makefile wraps the same operations:
hummingbot-api directory (sibling of condor when installed by the deploy script):
Keeping Condor updated
Updating is admin-only and available from both surfaces, over one shared engine:/update in Telegram and Settings → Updates in the dashboard. They
are two views of the same run, so an update started in Telegram can be watched
to completion in the browser and vice versa — starting a second one hands you
back the one already in flight rather than queueing it.
This is what makes a Local mode install self-sufficient: the dashboard
panel is the surface it has, so an install with no Telegram bot does not need
one to update.
What can be updated
Two components, versioned by what actually governs them:
Whether the API is rebuilt from source or pulled as a published image is not a
setting —
docker compose config already knows, from whether the service has a
build: key.
Preflight: what is in the way
Before anything runs you get the blockers, the warnings, and the ordered plan. Blockers stop the update and say why in terms you can act on — the checkout is not a git repo, it has commits the remote does not (so it cannot be fast-forwarded), local changes would be overwritten, or the registry could not be reached. Where a blocker has a safe way out it offers one: a dirty checkout can be resolved with discard or stash without leaving the panel. Warnings never refuse — they tell you a consequence worth knowing: restarting the API container stops its executors, and Condor keeps running the code it booted with until you relaunch it.The relaunch step
An update deliberately stops one step short of running the new code. It lands the code, syncs dependencies, rebuilds the dashboard, records that a relaunch is owed, and asks you to do it. That is not an omission. Condor is almost never the top of its own process tree — started throughmake run, a shell wrapper, or a supervisor — so re-execing
itself races the parent into bringing a second Condor up on the same port,
against the same config and the same Telegram token.
data/update_run.json
at every step, so the panel picks the result back up across the restart and the
next boot tells you whether the update worked.
Update notifications
Condor checks in the background and tells the admin when a component falls behind — once per update, not once per check, so deferring one does not bury the rest of your notifications. Each surface gets a next step it can actually take: a Telegram message, and a bell entry that opens the update panel for a browser-only admin. Tune it withUPDATE_CHECK_INTERVAL in .env — seconds, default 3600, and
0 disables the checks. The first runs 30 seconds after startup.
Both paths are git-based, so they work on a git checkout — which is what
the Quick Start and manual installs both produce. An install unpacked some
other way is reported as a blocker rather than silently skipped, and updates
by whatever means it was installed.
Privacy: telemetry and sharing
Two separate things, with separate switches. Neither sends anything about your trading, your keys, or your balances.Telemetry — anonymous counts
An admin answers once, for the whole install. Three levels:
The identifier is a random UUID generated once — not derived from your hostname, username, MAC, or any token. Server names, URLs and keys are never sent; a routine you wrote yourself is reported as
custom rather than by name.
The consent prompt offers ping or usage and has no “off” button, so ignoring it is not read as a refusal. Turning it off is a deliberate act, in any of three places — highest precedence first:
.env—CONDOR_TELEMETRY=off. The full kill switch: it overrides everything and suppresses the prompt.- Settings → Privacy in the dashboard — readable by every seat, changeable only by the admin. This is also where an install running without Telegram is asked in the first place, since it has no bot to be asked through. Choosing
offhere is the durable form: it is stored, not read from one process’s environment. config.yml— thetelemetrysection directly:consent: granted|deniedpluslevel.
Downgrading from
usage to ping, or turning telemetry off, is a withdrawal, not a pause — the in-memory buffer and the outbox file are deleted, so nothing already recorded can be sent afterwards.Sharing — whole conversations
Separate from telemetry, and off until you turn it on. Telemetry is anonymous counts an admin consents to once; a share is a transcript, and only the person who held the conversation can hand it over. Secrets are redacted before a transcript is built, and again before it leaves. In Settings → Privacy:- Off — nothing is shared. The share button still works if you want it. This is where every install starts.
- Ask me — the button, one conversation at a time, with the redacted transcript in front of you before you confirm.
- Always — conversations are shared on their own, redacted the same way, without showing you first.
- Idle — only after 30 minutes of silence in that chat.
- Forward-only — only conversations started after you chose Always. Your archive is never swept, and turning it off and on again starts a fresh window rather than reaching back.
- Single-author only — a Telegram group is never taken automatically. You can consent for yourself, not for the other people in the room.
- Excluded chats, forever — every covered conversation carries an undismissable marker with one click to leave it out, and that exclusion is permanent.
- Rate limited — at most 3 conversations per 15-minute sweep.
CONDOR_SHARING=off reaches transcripts already queued and destroys them — but a queued unshare is still delivered, because a revocation is a deletion the install already promised.Troubleshooting
Hit a snag—Condor can’t reach the API, Telegram stays quiet, Tailscale won’t connect—or want to check whether your broker needs securing? See the dedicated Troubleshooting page, which also covers the message broker security fix.Next Step
Adding Credentials
Connect your exchange accounts

