OOM watchdog: - vm-oom-watchdog.sh — scans journalctl -k since cursor for oom-kill, killed-process, and "out of memory ... killed" entries; maps cgroup hits back to container names via docker inspect; posts a single Telegram alert per scan window (no dedupe needed — cursor advances on every run). Cursor at /var/log/vm-oom-cursor, log at /var/log/vm-oom-watchdog.log. - Systemd: OnBootSec=10min, OnUnitActiveSec=1h, Persistent=true. Orphan containers (no compose file on disk): - trading-backend → docker update --memory=768m (high-I/O bot) - gitea-npm-registry → docker update --memory=512m - orphan-containers.md captures canonical configs for recovery (env, mounts, networks, restart policy, memory limits). Closes Phase 2.3 (post-monitoring) and Phase 3.3 (orphan limits). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2.8 KiB
Orphan Containers — Canonical Configuration
Two containers on this VM run without an on-disk compose file:
| Container | Image | Memory Limit | Restart Policy | Source |
|---|---|---|---|---|
trading-backend |
bytelyst-trading-bot-service-trading-backend |
768 MiB | always | compose file deleted; image present |
gitea-npm-registry |
gitea/gitea:1.22 |
512 MiB | unless-stopped | started via docker run |
Both have runtime memory limits applied via docker update. Limits persist across
restarts of the same container but are lost on docker rm. If recreated, use the
recovery procedures below.
trading-backend
Compose file referenced by container labels:
/opt/bytelyst/trading/bytelyst-trading-bot-service/docker-compose.yml — missing on disk.
Only the logs/ directory remains; the bind mount references it.
Recovery procedure
If the container is removed, recreate the compose file with:
services:
trading-backend:
image: bytelyst-trading-bot-service-trading-backend
container_name: trading-backend
user: node
working_dir: /app
entrypoint: ["docker-entrypoint.sh"]
command: ["node", "dist/index.js"]
env_file:
- .env # holds secrets — restore from backup
environment:
ENABLE_TRADING: "true"
PAPER_TRADING: "true"
EXECUTION_PROVIDER: alpaca
ALPACA_SUBTAG_ENV: paper
SYMBOLS: "BTC/USDT,ETH/USDT,SOL/USDT,DOGE/USDT,PEPE/USDT"
TOTAL_CAPITAL: "1000"
EXECUTION_TIMEFRAME: 15m
POLLING_INTERVAL: "60000"
volumes:
- /opt/bytelyst/trading/bytelyst-trading-bot-service/logs:/app/logs
networks:
- default
restart: always
deploy:
resources:
limits:
memory: 768m
networks:
default:
name: learning_ai_common_plat_default
external: true
Full env captured via docker inspect is needed for secrets; check .env backup
or recover from hermes drive backup.
gitea-npm-registry
Started via raw docker run rather than compose. The internal package registry
service used by ByteLyst monorepos for @bytelyst/* package distribution.
Recovery procedure
docker run -d \
--name gitea-npm-registry \
--restart unless-stopped \
--memory 512m --memory-swap 512m \
-p 3300:3000 \
-v gitea-data:/data \
-e GITEA__server__DOMAIN=gitea.bytelyst.com \
-e GITEA__server__SSH_DOMAIN=gitea.bytelyst.com \
-e GITEA__server__ROOT_URL=https://gitea.bytelyst.com/ \
-e GITEA__server__HTTP_PORT=3000 \
-e GITEA__packages__ENABLED=true \
-e GITEA__security__INSTALL_LOCK=true \
-e INSTALL_LOCK=true \
--network bridge \
gitea/gitea:1.22
docker network connect learning_ai_common_plat_default gitea-npm-registry
The gitea-data named volume contains all repository + package state; never
delete it without a backup.