fix: Update Docker configuration and documentation for improved deployment process

This commit is contained in:
2025-11-13 21:10:10 +01:00
parent 6ed77b120f
commit 17021b00d6
6 changed files with 323 additions and 185 deletions

View File

@@ -56,8 +56,9 @@ setup/
docker/
.dockerignore
# Scripts (organized in scripts/ folder - not needed in Docker)
scripts/
# Scripts installer (not needed in Docker, but keep docker/ folder)
scripts/installer/
scripts/README.md
# Asset files (not needed for runtime)
assets/

View File

@@ -221,13 +221,16 @@ For containerized deployment with built-in scheduling:
```bash
# Ensure accounts.jsonc and config.jsonc exist in src/
docker compose up -d
npm run docker:compose
# Or use docker compose directly
docker compose -f docker/compose.yaml up -d
# View logs
docker logs -f microsoft-rewards-script
docker logs -f microsoft-rewards-bot
# Check status
docker compose ps
docker compose -f docker/compose.yaml ps
```
Container includes:
@@ -236,7 +239,7 @@ Container includes:
- ✅ Random execution delays (anti-detection)
- ✅ Health checks
**📖 [Full Docker Guide](docs/docker.md)**
**📖 [Complete Docker Guide](docs/docker-deployment.md)**
---

View File

@@ -1,6 +1,8 @@
services:
microsoft-rewards-script:
build: .
build:
context: ..
dockerfile: docker/Dockerfile
container_name: microsoft-rewards-bot
restart: unless-stopped
@@ -20,23 +22,22 @@ services:
#MIN_SLEEP_MINUTES: "5"
#MAX_SLEEP_MINUTES: "50"
SKIP_RANDOM_SLEEP: "false"
# Optionally set how long to wait before killing a stuck script run (prevents blocking future runs, default: 8 hours)
#STUCK_PROCESS_TIMEOUT_HOURS: "8"
# Optional resource limits for the container
# Optional resource limits for the container
mem_limit: 4g
cpus: 2
# Health check - monitors if cron daemon is running to ensure scheduled jobs can execute
# Container marked unhealthy if cron process dies
healthcheck:
test: ["CMD", "sh", "-c", "pgrep cron > /dev/null || exit 1"]
test: [ "CMD", "sh", "-c", "pgrep cron > /dev/null || exit 1" ]
interval: 60s
timeout: 10s
retries: 3
start_period: 30s
# Security hardening
security_opt:
- no-new-privileges:true

View File

@@ -1,19 +1,47 @@
# Docker Deployment Guide
## 🐳 Quick Start
Complete guide for containerized deployment with built-in scheduling.
### 1. Build the Image
```bash
cd docker
docker build -t microsoft-rewards-bot -f Dockerfile ..
## 📂 Docker File Structure
```
Microsoft-Rewards-Bot/
├── docker/ # All Docker-related files
│ ├── Dockerfile # Multi-stage build configuration
│ ├── compose.yaml # Service definition
│ ├── entrypoint.sh # Container initialization
│ ├── run_daily.sh # Daily execution wrapper + locking
│ └── crontab.template # Cron job template
├── src/
│ ├── accounts.jsonc # Your accounts (volume mount)
│ └── config.jsonc # Bot configuration (volume mount)
└── package.json # Build scripts
```
Or use the npm script:
**Important:** All Docker files are in the `docker/` folder, but the build context is the **project root** (to access `src/`, `package.json`, etc.)
---
## 🚀 Quick Start
### 1. Build the Image
**Option A: Using npm script (recommended)**
```bash
# From project root
npm run docker:build
```
**Option B: Direct Docker command**
```bash
# From project root
docker build -f docker/Dockerfile -t microsoft-rewards-bot .
```
**Why from root?** The Dockerfile needs access to `src/`, `package.json`, `tsconfig.json`. Docker can't copy files outside the build context.
### 2. Configure Environment
Edit `docker/compose.yaml`:
```yaml
environment:
@@ -23,27 +51,96 @@ environment:
```
### 3. Start the Container
**Option A: Using npm script**
```bash
cd docker
docker compose up -d
npm run docker:compose
```
**Option B: Direct docker compose command**
```bash
docker compose -f docker/compose.yaml up -d
```
**Note:** Volumes in `compose.yaml` use relative paths from `docker/`:
- `./src/``docker/../src/` (goes to project root)
- `./sessions/``docker/sessions/` (local to docker folder)
## 📋 Configuration Files
The container needs access to your configuration files via volume mounts:
```yaml
volumes:
- ../src/accounts.jsonc:/usr/src/microsoft-rewards-bot/dist/accounts.jsonc:ro
- ../src/config.jsonc:/usr/src/microsoft-rewards-bot/dist/config.jsonc:ro
# Read-only mounts for configuration (prevents accidental container edits)
- ./src/accounts.jsonc:/usr/src/microsoft-rewards-bot/dist/accounts.jsonc:ro
- ./src/config.jsonc:/usr/src/microsoft-rewards-bot/dist/config.jsonc:ro
# Read-write mount for persistent login sessions
- ./sessions:/usr/src/microsoft-rewards-bot/dist/browser/sessions
```
**Paths explained:**
- `./src/accounts.jsonc` = `docker/../src/accounts.jsonc` (relative from compose.yaml location)
- `./sessions` = `docker/sessions/` (local to docker folder)
**Before starting:**
1. Create `src/accounts.jsonc` (copy from `src/accounts.example.jsonc`)
2. Edit `src/config.jsonc` with your settings
3. (Optional) Create `docker/sessions/` directory for persistent login
---
## 🏗️ Architecture & Build Process
### Two-Stage Docker Build
**Stage 1: Builder**
```dockerfile
FROM node:22-slim AS builder
# 1. Install dependencies + dev dependencies
# 2. Compile TypeScript → JavaScript (dist/)
# 3. Install Playwright Chromium
# 4. Remove dev dependencies (keep only production)
```
**Stage 2: Runtime**
```dockerfile
FROM node:22-slim AS runtime
# 1. Install minimal system libraries for Chromium
# 2. Copy compiled code + dependencies from builder
# 3. Copy runtime scripts (entrypoint.sh, run_daily.sh)
# 4. Configure cron daemon
```
**Why two stages?**
- Smaller final image (~800 MB vs 1.5 GB)
- No build tools in production
- Security: no dev dependencies
### Build Context Explained
```bash
# ❌ WRONG: Building from docker/ folder
cd docker
docker build -t bot .
# Error: Cannot find package.json, src/, etc.
# ✅ CORRECT: Build from root, specify Dockerfile location
cd /path/to/Microsoft-Rewards-Bot
docker build -f docker/Dockerfile -t bot .
# Success: Access to all project files
```
**The Dockerfile copies files relative to project root:**
```dockerfile
COPY package.json tsconfig.json ./ # From project root
COPY src/ ./src/ # From project root
COPY docker/run_daily.sh ./docker/ # Subfolder
```
---
## 🔧 Environment Variables
| Variable | Required | Default | Description |
@@ -113,21 +210,50 @@ docker exec microsoft-rewards-bot ps aux
## 🛠️ Troubleshooting
### "Chromium not installed" After First Run
### ❌ Build Error: "Cannot find module 'package.json'"
**Cause:** Wrong build context - building from `docker/` instead of project root.
**Solution:**
```bash
# ❌ WRONG
cd docker
docker build -t bot .
# ✅ CORRECT (from project root)
docker build -f docker/Dockerfile -t bot .
# Or use npm script
npm run docker:build
```
### ❌ Build Error: "COPY failed: file not found: docker/run_daily.sh"
**Cause:** `.dockerignore` file excludes `docker/` folder.
**Solution:** Check `.dockerignore` - it should NOT contain `docker/`:
```ignore
# ❌ BAD
docker/
# ✅ GOOD (current config)
scripts/installer/
```
### ❌ "Chromium not installed" After First Run
**Symptoms:**
- Bot works on first run
- Fails on subsequent scheduled runs with "Chromium not installed"
**Root Cause:**
Fixed in latest version! Chromium browser files are now copied correctly from builder stage.
Fixed in v2.56.7+! Chromium browser files are now copied correctly from builder stage.
**Solution:**
```bash
# Rebuild with latest Dockerfile (includes fix)
docker build --no-cache -t microsoft-rewards-bot -f docker/Dockerfile ..
docker compose down
docker compose up -d
npm run docker:build
docker compose -f docker/compose.yaml down
docker compose -f docker/compose.yaml up -d
```
**Verification:**
@@ -138,7 +264,7 @@ docker exec microsoft-rewards-bot ls -la /usr/src/microsoft-rewards-bot/node_mod
You should see `browser-chromium/` directory.
### Container Exits Immediately
### Container Exits Immediately
**Check logs:**
```bash
@@ -147,183 +273,202 @@ docker logs microsoft-rewards-bot
**Common causes:**
1. **Missing CRON_SCHEDULE:** Set environment variable in compose.yaml
```yaml
environment:
CRON_SCHEDULE: "0 9 * * *" # Required!
```
2. **Invalid cron expression:** Validate at https://crontab.guru
3. **Permission issues:** Ensure config files are readable
3. **Script not executable:** Dockerfile should handle this automatically
```dockerfile
COPY --chmod=755 docker/entrypoint.sh /usr/local/bin/entrypoint.sh
```
**Fix:**
```bash
# Update compose.yaml with correct CRON_SCHEDULE
docker compose down
docker compose up -d
docker compose -f docker/compose.yaml down
docker compose -f docker/compose.yaml up -d
```
### Random Delays Not Working
### ❌ "Permission denied: entrypoint.sh"
**Check environment variables:**
```bash
docker exec microsoft-rewards-bot env | grep SLEEP
**Cause:** Script not executable or Windows CRLF line endings.
**Solution:** The Dockerfile handles both automatically:
```dockerfile
COPY --chmod=755 docker/entrypoint.sh /usr/local/bin/entrypoint.sh
RUN sed -i 's/\r$//' /usr/local/bin/entrypoint.sh # Convert CRLF → LF
```
**Verify run_daily.sh receives variables:**
```bash
docker exec microsoft-rewards-bot cat docker/run_daily.sh
```
**Test manually:**
```bash
docker exec microsoft-rewards-bot docker/run_daily.sh
```
### Timezone Incorrect
**Check container timezone:**
```bash
docker exec microsoft-rewards-bot date
```
**Fix:**
1. Update `TZ` in compose.yaml
2. Restart container:
```bash
docker compose restart
```
**Verify:**
```bash
docker exec microsoft-rewards-bot date
docker logs microsoft-rewards-bot | grep "Timezone:"
```
### Health Check Failing
**Check cron daemon:**
```bash
docker exec microsoft-rewards-bot ps aux | grep cron
```
**Expected output:**
```
root 1 0.0 0.0 2576 1024 ? Ss 12:00 0:00 cron -f
```
**Restart container if missing:**
```bash
docker compose restart
```
### Sessions Not Persisting
**Check volume mount:**
```bash
docker inspect microsoft-rewards-bot | grep sessions
```
**Verify local directory exists:**
```bash
ls -la docker/sessions/
```
**Fix permissions:**
If still failing, manually fix line endings:
```bash
# Linux/Mac
chmod -R 755 docker/sessions/
dos2unix docker/entrypoint.sh docker/run_daily.sh
# Windows
# No action needed (NTFS handles permissions)
# Or with sed
sed -i 's/\r$//' docker/entrypoint.sh
sed -i 's/\r$//' docker/run_daily.sh
```
### Out of Memory Errors
### ❌ Volumes Not Mounting
**Increase memory limit in compose.yaml:**
```yaml
mem_limit: 6g # Increase from 4g
```
### ❌ Volumes Not Mounting
**Restart:**
**Check if files exist:**
```bash
docker compose down
docker compose up -d
# From docker/ folder
ls -la ../src/accounts.jsonc ../src/config.jsonc
# Or from project root
ls -la src/accounts.jsonc src/config.jsonc
```
**Monitor memory usage:**
**Verify volume paths in running container:**
```bash
docker stats microsoft-rewards-bot
docker inspect microsoft-rewards-bot | grep -A 10 Mounts
```
## 🔄 Updates
**Fix paths in compose.yaml:**
```yaml
# Paths are relative to compose.yaml location (docker/)
volumes:
- ./src/accounts.jsonc:/usr/src/microsoft-rewards-bot/dist/accounts.jsonc:ro
# This resolves to: docker/../src/accounts.jsonc (project root)
```
### Update to Latest Version
---
**Method 1: Rebuild (Recommended)**
## 📚 Complete File Reference
### `docker/Dockerfile`
Multi-stage build configuration:
- **Builder stage:** Compiles TypeScript, installs Playwright
- **Runtime stage:** Minimal image with only production dependencies
### `docker/compose.yaml`
Service definition with:
- Build context (points to project root)
- Volume mounts (configuration files)
- Environment variables (scheduling, timezone)
- Resource limits (CPU, memory)
- Health checks (cron daemon monitoring)
### `docker/entrypoint.sh`
Container initialization script:
1. Configures timezone from `TZ` env var
2. Validates `CRON_SCHEDULE` is set
3. Optionally runs bot immediately (`RUN_ON_START=true`)
4. Templates cron job with environment variables
5. Starts cron daemon in foreground
### `docker/run_daily.sh`
Daily execution wrapper:
- File-based locking (prevents concurrent runs)
- Self-healing lockfile validation
- Random sleep delay (anti-detection)
- Stuck process killer (timeout after N hours)
- Executes `npm start`
### `docker/crontab.template`
Cron job template with variable interpolation:
```bash
# Pull latest code
git pull origin main
# Rebuild image
docker build --no-cache -t microsoft-rewards-bot -f docker/Dockerfile ..
# Restart container
docker compose down
docker compose up -d
${CRON_SCHEDULE} TZ=${TZ} /bin/bash /usr/src/microsoft-rewards-bot/docker/run_daily.sh >> /proc/1/fd/1 2>&1
```
**Method 2: Auto-Update (If Enabled in config.jsonc)**
The bot can auto-update itself if `update.enabled: true` in config.jsonc.
After auto-update, container will restart automatically (Docker restarts on exit).
Expanded by `entrypoint.sh` using `envsubst`.
### Backup Before Update
---
## 🎯 Build & Deployment Checklist
### Pre-Build Checklist
- [ ] Files exist: `src/accounts.jsonc`, `src/config.jsonc`
- [ ] Docker installed and running
- [ ] At project root (not in `docker/` folder)
- [ ] `.dockerignore` does NOT exclude `docker/` folder
### Build Steps
```bash
# Backup sessions
cp -r docker/sessions/ docker/sessions.backup/
# 1. Clean previous builds (optional)
docker rmi microsoft-rewards-bot
# Backup config
cp src/config.jsonc src/config.jsonc.backup
cp src/accounts.jsonc src/accounts.jsonc.backup
# 2. Build image
npm run docker:build
# Or: docker build -f docker/Dockerfile -t microsoft-rewards-bot .
# 3. Verify image created
docker images | grep microsoft-rewards-bot
```
## 📊 Resource Usage
### Deployment Steps
```bash
# 1. Configure compose.yaml
# - Set CRON_SCHEDULE (required)
# - Set TZ (optional, default UTC)
# - Set RUN_ON_START (optional, default false)
**Typical resource consumption:**
- **CPU:** 50-80% during active runs, <1% idle
- **RAM:** 1-3 GB during active runs, <100 MB idle
- **Disk:** ~500 MB (base image + browsers)
- **Network:** Minimal (<10 MB per run)
# 2. Start container
npm run docker:compose
# Or: docker compose -f docker/compose.yaml up -d
**Recommended limits:**
```yaml
mem_limit: 4g
cpus: 2
# 3. Verify running
docker ps | grep microsoft-rewards-bot
# 4. Check logs
docker logs -f microsoft-rewards-bot
# 5. Verify health
docker inspect microsoft-rewards-bot --format='{{.State.Health.Status}}'
```
## 🔐 Security Hardening
---
The default compose.yaml includes:
```yaml
security_opt:
- no-new-privileges:true # Prevent privilege escalation
## 🔍 Debugging Commands
### Check Build Context
```bash
# List files Docker can see during build
docker build -f docker/Dockerfile -t test . --progress=plain 2>&1 | grep "COPY"
```
**Additional hardening (optional):**
```yaml
security_opt:
- no-new-privileges:true
- seccomp:unconfined # Only if Chromium fails to start
read_only: false # Must be false (Chromium needs write access)
tmpfs:
- /tmp
- /root/.cache
### Inspect Running Container
```bash
# Shell access
docker exec -it microsoft-rewards-bot bash
# Check environment variables
docker exec microsoft-rewards-bot env
# Check cron jobs
docker exec microsoft-rewards-bot crontab -l
# Check timezone
docker exec microsoft-rewards-bot date
# Check Playwright browsers
docker exec microsoft-rewards-bot ls -la node_modules/@playwright/
# Check running processes
docker exec microsoft-rewards-bot ps aux
```
## 🆘 Getting Help
### Test Scripts Manually
```bash
# Test entrypoint
docker exec microsoft-rewards-bot /usr/local/bin/entrypoint.sh
If issues persist:
1. **Check logs:** `docker logs -f microsoft-rewards-bot`
2. **Rebuild with no cache:** `docker build --no-cache ...`
3. **Verify Chromium:** `docker exec microsoft-rewards-bot ls -la node_modules/@playwright/`
4. **Discord Support:** https://discord.gg/k5uHkx9mne
5. **GitHub Issues:** https://github.com/Obsidian-wtf/Microsoft-Rewards-Bot/issues
# Test run_daily (bypass lock)
docker exec microsoft-rewards-bot bash -c "rm -f /tmp/run_daily.lock && docker/run_daily.sh"
## 📚 Related Documentation
# Test bot directly
docker exec microsoft-rewards-bot npm start
```
---
## 📖 Additional Resources
- **Build System:** [docs/build-system.md](build-system.md)
- **Scheduling:** [src/scheduler/README.md](../src/scheduler/README.md)

View File

@@ -64,33 +64,20 @@ Explore advanced features and customization options:| **[NTFY Alerts](ntfy.md)**
| **[Proxy Setup](proxy.md)** | IP rotation (optional) |
### Core Features| **[Docker](docker.md)** | Container deployment |
| Guide | Description |---
### Core Features
| Guide | Description |
|-------|-------------|
| **[🔔 Notifications](notifications.md)** | Discord webhooks and mobile push alerts |## 🆘 Troubleshooting
| **[🔔 Notifications](notifications.md)** | Discord webhooks and mobile push alerts |
| **[📊 Dashboard](../src/dashboard/README.md)** | Web interface for monitoring and control |
| **[🌐 Proxy Setup](proxy.md)** | Configure proxies for privacy |
| **[🤖 Humanization](humanization.md)** | Anti-detection and natural behavior patterns |
| **[🌐 Proxy Setup](proxy.md)** | Configure proxies for privacy || Issue | Solution |
### Deployment
| **[🤖 Humanization](humanization.md)** | Anti-detection and natural behavior patterns ||-------|----------|
| **Bot not working?** | [Troubleshooting Guide](diagnostics.md) |
### Deployment| **Login failed?** | [Accounts & 2FA](accounts.md#troubleshooting) |
| **Account banned?** | [Security Guide](security.md) |
| Guide | Description || **Git conflicts?** | [Conflict Resolution](git-conflict-resolution.md) |
|-------|-------------|| **General questions?** | [FAQ](FAQ.md) |
| **[🐳 Docker](docker.md)** | Containerized deployment with Docker Compose |
| Guide | Description |
|-------|-------------|
| **[🐳 Docker](docker-deployment.md)** | Containerized deployment with Docker Compose |
| **[☁️ Cloud Deployment](cloud-deployment.md)** | Deploy to VPS, Raspberry Pi, or cloud services |**Need help?** → [Discord Community](https://discord.gg/k5uHkx9mne)
@@ -186,7 +173,7 @@ Technical references and detailed information:
### For Docker Users
1. [Docker Guide](docker.md) — Setup Docker Compose
1. [Docker Guide](docker-deployment.md) — Setup Docker Compose
2. [Environment Variables](environment-variables.md) — Configure via env vars
3. [Notifications](notifications.md) — Monitor container runs

View File

@@ -31,8 +31,9 @@
"lint": "eslint \"src/**/*.{ts,tsx}\"",
"setup": "node ./scripts/installer/setup.mjs",
"kill-chrome": "node -e \"const { execSync } = require('child_process'); const isWin = process.platform === 'win32'; try { execSync(isWin ? 'taskkill /F /IM chrome.exe 2>nul || exit 0' : 'pkill -f chrome || true', {stdio: 'inherit'}); } catch(e) {}\"",
"docker:build": "docker build -t microsoft-rewards-bot .",
"docker:run": "docker run -d --name ms-rewards microsoft-rewards-bot"
"docker:build": "docker build -f docker/Dockerfile -t microsoft-rewards-bot .",
"docker:run": "docker run -d --name ms-rewards microsoft-rewards-bot",
"docker:compose": "docker compose -f docker/compose.yaml up -d"
},
"keywords": [
"Bing Rewards",