Docker Container Setup for Trading Bot
Trading bot run directly on VPS without isolation — dependencies problems, unpredictable restarts on crash and lack of reproducibility. Docker solves all this in couple hours of setup. Main tasks: environment isolation, automatic restart on failure, secure API key passing, logging, updates without downtime.
Dockerfile for Python Bot
FROM python:3.12-slim
# System dependencies (if need C-extensions like ta-lib)
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
# First dependencies (layer cache when only code changes)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
# Don't run as root
RUN adduser --disabled-password --gecos '' botuser
USER botuser
CMD ["python", "-u", "bot.py"]
Flag -u in Python disables stdout buffering — logs visible immediately, not after flush.
docker-compose with Secrets and Auto-restart
services:
trading-bot:
build: .
container_name: trading_bot
restart: unless-stopped # restart on failure, but not on manual stop
environment:
- PYTHONUNBUFFERED=1
- TZ=UTC
# Secrets via env_file, don't hardcode in compose
env_file:
- .env.secrets
volumes:
- ./data:/app/data # bot persistent data
- ./logs:/app/logs # logs outside container
# Resource limits
deploy:
resources:
limits:
memory: 512M
cpus: '0.5'
# Health check — Docker restart if bot hangs
healthcheck:
test: ["CMD", "python", "-c", "import os; os.path.exists('/app/data/heartbeat')"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "5"
.env.secrets (never commit to git):
BINANCE_API_KEY=your_key_here
BINANCE_SECRET=your_secret_here
TELEGRAM_BOT_TOKEN=notification_token
Add .env.secrets to .gitignore. Better approach — Docker Secrets or HashiCorp Vault, but for simple bot env_file enough if repo is private.
Health Check via Heartbeat File
Bot writes timestamp to file every N seconds. Docker checks file freshness:
# In bot — heartbeat every 10 sec
import threading
import time
import pathlib
def heartbeat_loop():
while True:
pathlib.Path('/app/data/heartbeat').touch()
time.sleep(10)
threading.Thread(target=heartbeat_loop, daemon=True).start()
# healthcheck command checks file modified < 60 sec ago
test: ["CMD", "bash", "-c", "[ $(($(date +%s) - $(date +%s -r /app/data/heartbeat))) -lt 60 ]"]
Update Without Full Downtime
# Rebuild and replace container
docker-compose build trading-bot
docker-compose up -d --no-deps trading-bot
--no-deps doesn't touch other services. Container stops, new one starts — downtime 5-10 seconds. For trading bot usually acceptable.
Useful Commands
# Run
docker-compose up -d
# Real-time logs
docker-compose logs -f trading-bot
# Status
docker-compose ps
# Debug inside container
docker-compose exec trading-bot bash
# Restart
docker-compose restart trading-bot







