Run Freqtrade on a DigitalOcean VPS: setup guide
Set up Freqtrade on a $12-18 DigitalOcean droplet with Docker: SSH keys, cloud firewall, dry-run config, FreqUI over an SSH tunnel and IP-locked exchange keys.
Key takeaways
- Freqtrade recommends at least 2 GB of RAM and 2 vCPUs. On DigitalOcean that is the $18 Basic droplet; the $12 plan (2 GB, 1 vCPU) works for one bot on a slow timeframe.
- Use Docker with Freqtrade's official docker-compose.yml. It binds FreqUI to 127.0.0.1:8080, so you reach it through an SSH tunnel instead of exposing it to the internet.
- A DigitalOcean Cloud Firewall that allows only SSH from your own IP is free and, unlike ufw, is not bypassed by Docker's port publishing.
- A droplet has a fixed public IP, so you can lock your exchange API key to that IP and disable withdrawals, the strongest setup for a bot key.
Contents 13 sections
- Which droplet should you pick?
- Step 1: Create an SSH key
- Step 2: Create the droplet
- Step 3: Add a Cloud Firewall
- Step 4: Create a user and install Docker
- Step 5: Install Freqtrade with Docker
- Step 6: Open FreqUI through an SSH tunnel
- Step 7: Backtest before you trust a strategy
- Step 8: Telegram alerts
- Step 9: Keep secrets out of config.json
- Step 10: Switching to live trading
- What it costs in practice
- Related reading
Running Freqtrade on a DigitalOcean droplet takes about 30 minutes: create an Ubuntu droplet with SSH-key login, put a Cloud Firewall in front of it, install Docker, generate a dry-run config with Freqtrade’s official compose file, and reach the FreqUI dashboard through an SSH tunnel. The payoff over a platform like Railway is a fixed IP address, so your exchange API key can be locked to your server.
Everything below follows Freqtrade’s Docker quickstart and DigitalOcean’s own docs, with the security steps those docs mention but don’t spell out.
Which droplet should you pick?
Freqtrade’s documentation recommends a Linux server with at least 2 GB of RAM, 2 vCPUs and 1 GB of disk. DigitalOcean’s Basic (shared CPU) droplets, as listed on the pricing page in September 2026:
| Plan | RAM | vCPU | SSD | Transfer | Price | Fit for Freqtrade |
|---|---|---|---|---|---|---|
| Basic | 1 GiB | 1 | 25 GB | 1,000 GB | $6/mo | Too tight, dry-run experiments only |
| Basic | 2 GiB | 1 | 50 GB | 2,000 GB | $12/mo | One bot, 5m+ timeframe |
| Basic | 2 GiB | 2 | 60 GB | 3,000 GB | $18/mo | Matches the recommended minimum |
| Basic | 4 GiB | 2 | 80 GB | 4,000 GB | $24/mo | Several bots or regular backtesting |
Droplets are billed per second with a monthly cap. Weekly backups add 20% of the droplet price ($3.60 a month on the $18 plan), which is cheap insurance for your trade database and strategies.
Pick a region close to you for comfortable SSH. More important: make sure your exchange serves the country the datacenter is in. Several exchanges block API traffic from certain jurisdictions, and a bot in a blocked region simply fails to connect.
New accounts that sign up to DigitalOcean with a referral link get the platform’s sign-up credit (the landing page shows the current amount and how long it lasts), which comfortably covers a few weeks of dry-run testing.
Step 1: Create an SSH key
Password logins on a public server get brute-forced constantly. Use a key. On your own computer:
ssh-keygen -t ed25519 -C "freqtrade-droplet"
cat ~/.ssh/id_ed25519.pub
Accept the default path and set a passphrase. Copy the output of the second command; that public key is what you give DigitalOcean. The private key (id_ed25519 without .pub) never leaves your machine.
Step 2: Create the droplet
In the DigitalOcean control panel, open Create, then Droplets:
- Region: see the note above.
- Image: Ubuntu 24.04 LTS (26.04 LTS also works; both are supported by Docker).
- Size: Basic, Regular CPU, 2 GiB.
- Authentication: choose SSH Key, click New SSH Key, paste your public key.
- Backups: optional but recommended.
- Hostname: something like
freqtrade-1.
Create it and note the public IPv4 address.
Step 3: Add a Cloud Firewall
DigitalOcean’s Cloud Firewalls are free and filter traffic before it reaches the droplet. Open Create, then Firewall:
- Inbound rules: keep only SSH (TCP 22), and change the source from “All IPv4/All IPv6” to your own IP address if it’s reasonably stable.
- Outbound rules: leave the default (all traffic allowed). The bot needs to reach the exchange, Telegram and package mirrors.
- Apply to Droplets: select your droplet.
Do not add a rule for port 8080. FreqUI will be reached through SSH instead.
Step 4: Create a user and install Docker
Log in as root once, create a regular user and copy your key over:
ssh root@YOUR_DROPLET_IP
adduser freqtrade
usermod -aG sudo freqtrade
rsync --archive --chown=freqtrade:freqtrade ~/.ssh /home/freqtrade
apt update && apt upgrade -y
exit
Log back in as the new user and install Docker from Docker’s own apt repository, as described in the Docker Engine install guide for Ubuntu:
ssh freqtrade@YOUR_DROPLET_IP
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Run docker without sudo (log out and back in afterwards)
sudo usermod -aG docker $USER
After logging back in, docker run hello-world should print a success message.
Step 5: Install Freqtrade with Docker
These are the official quickstart commands:
mkdir ft_userdata && cd ft_userdata
curl https://raw.githubusercontent.com/freqtrade/freqtrade/stable/docker-compose.yml -o docker-compose.yml
docker compose pull
docker compose run --rm freqtrade create-userdir --userdir user_data
docker compose run --rm freqtrade new-config --config user_data/config.json
The last command asks a series of questions. Sensible answers for a first run:
| Question | Answer |
|---|---|
| Enable Dry-run (simulated trades)? | Yes |
| Stake currency | USDT (or USD/USDC, whatever your exchange quotes in) |
| Stake amount | A fixed number such as 50, not “unlimited” |
| max_open_trades | 3 |
| Timeframe | 5m (or match your strategy) |
| Exchange | Yours |
| Perpetual futures? | No, start with spot |
| Enable Telegram? | Yes if you have a token (see below), otherwise No |
| Enable the Rest API (includes FreqUI)? | Yes |
| API server listen address | Keep the default 0.0.0.0 (correct inside Docker) |
| API username and password | A unique username and a long random password |
Because you chose dry-run, it won’t ask for exchange keys. The generated config gets a random JWT secret automatically.
Open user_data/config.json and check the pair whitelist before starting. Then launch:
docker compose up -d
docker compose ps # should show "freqtrade" as running
docker compose logs -f # Ctrl+C to stop following
The compose file sets restart: unless-stopped, so the bot comes back after a crash or a droplet reboot. Trades are stored in user_data/tradesv3.sqlite and logs in user_data/logs/freqtrade.log.
Step 6: Open FreqUI through an SSH tunnel
The official compose file publishes the API as 127.0.0.1:8080:8080, so it’s only reachable from the droplet itself. Freqtrade’s REST API docs are blunt about why: FreqUI has no HTTPS out of the box, and anyone who can reach it and guess the login can control the bot.
From your own computer:
ssh -N -L 8080:127.0.0.1:8080 freqtrade@YOUR_DROPLET_IP
Leave that running and open http://localhost:8080 in your browser. Log in with the API username and password from the config. Close the tunnel with Ctrl+C when you’re done.
Never change the port mapping to 8080:8080 to “make it work”. That exposes the bot to the whole internet.
Step 7: Backtest before you trust a strategy
The droplet is also a good place to backtest, since it runs 24/7 anyway. Download candles, then test:
docker compose run --rm freqtrade download-data --exchange binance --pairs BTC/USDT ETH/USDT --timeframes 5m --days 90
docker compose run --rm freqtrade backtesting --config user_data/config.json --strategy SampleStrategy --timerange 20260601-20260901 -i 5m
To use your own strategy, copy the file into user_data/strategies/ (for example with scp MyStrategy.py freqtrade@YOUR_DROPLET_IP:~/ft_userdata/user_data/strategies/) and change --strategy SampleStrategy in the command section of docker-compose.yml to your class name. Then docker compose up -d to restart with it.
Backtests are optimistic: they assume fills at candle prices and can’t model sudden liquidity gaps. Run the strategy in dry-run for at least a few weeks and compare the results.
Step 8: Telegram alerts
Freqtrade’s Telegram integration sends a message on every entry and exit and lets you run /status, /profit, /balance, /stopentry (stop opening new trades) and /forceexit from your phone.
- In Telegram, message @BotFather, send
/newbot, and copy the token. - Press Start in a chat with your new bot.
- Get your numeric ID from @userinfobot.
Rather than pasting the token into config.json, keep it in an environment file (next section).
Step 9: Keep secrets out of config.json
Freqtrade reads any setting from environment variables named FREQTRADE__SECTION__KEY, and they override the config file. That lets you keep config.json shareable and put secrets in a separate file only the bot user can read.
Create ~/ft_userdata/.env:
FREQTRADE__TELEGRAM__ENABLED=true
FREQTRADE__TELEGRAM__TOKEN=123456789:your-bot-token
FREQTRADE__TELEGRAM__CHAT_ID=your-numeric-id
FREQTRADE__API_SERVER__PASSWORD=your-long-random-password
# Only when going live:
# FREQTRADE__EXCHANGE__KEY=...
# FREQTRADE__EXCHANGE__SECRET=...
Lock it down and tell compose to load it by adding an env_file line under the freqtrade service:
chmod 600 ~/ft_userdata/.env
services:
freqtrade:
image: freqtradeorg/freqtrade:stable
restart: unless-stopped
env_file: .env
# ...rest of the official file unchanged
Run docker compose up -d to apply. If you keep ft_userdata in Git, add .env and user_data/tradesv3*.sqlite to .gitignore before the first commit.
Step 10: Switching to live trading
When dry-run results hold up:
- Create a restricted API key on the exchange. Enable reading balances and placing and cancelling orders. Leave withdrawals disabled.
- Lock the key to your droplet’s IP. Most major exchanges offer an IP allowlist for API keys. Enter the droplet’s public IPv4. A stolen key is then useless from anywhere else. This is the main security advantage of a VPS over platforms whose outbound IPs change.
- Add the key to
.env, not toconfig.json. - Use a fresh database. Freqtrade’s docs recommend it so dry-run trades don’t pollute live stats. Set
"dry_run": falsein the config, and point the--db-urlindocker-compose.ymlto a new file such assqlite:////freqtrade/user_data/tradesv3.live.sqlite. - Start small. Use a stake you’d be fine losing to a bug, and keep
max_open_tradeslow for the first weeks.
Keep the bot updated with docker compose pull && docker compose up -d, but read the Freqtrade changelog first; releases occasionally need config changes.
What it costs in practice
A worked example for one year on the recommended plan: $18 × 12 = $216 for the droplet, plus $43.20 for weekly backups, so about $259 before exchange fees. The $12 plan brings that to about $173. Freqtrade itself is free.
Compared with deploying on Railway, you pay a flat price and get root access, a fixed IP and room for several bots. You also take on server upkeep: security updates, disk space and monitoring. If you’d rather skip that, our Railway Freqtrade guide gets a dry-run bot live in about ten minutes.
Related reading
- If your trade ideas come from chart alerts, which TradingView plan you need explains which plans support webhook alerts that bots can consume.
- Self-hosted bots hold your exchange keys; Telegram bots often hold your wallet keys. Are Telegram trading bots safe explains the difference.
- Building your own tooling around onchain data rather than exchange APIs? Start with Alchemy vs QuickNode to pick an RPC provider.
Frequently asked questions
What size droplet do I need for Freqtrade?
Freqtrade's docs recommend a Linux server with at least 2 GB of RAM, 2 vCPUs and 1 GB of disk. The $18 Basic droplet matches that; heavy backtesting or FreqAI needs more.
How do I access FreqUI on a VPS securely?
Keep the default port mapping 127.0.0.1:8080:8080 and open an SSH tunnel with ssh -L 8080:127.0.0.1:8080 user@your-droplet-ip, then browse to http://localhost:8080 on your own computer.
Does ufw protect Docker containers?
Not reliably. Docker writes its own iptables rules, so ports published on 0.0.0.0 can bypass ufw. Bind ports to 127.0.0.1 and use DigitalOcean's Cloud Firewall, which filters traffic before it reaches the droplet.
Is Freqtrade free?
Yes. Freqtrade is open-source software under the GPL-3.0 licence. You only pay for the server and your exchange's trading fees.
