diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..bef7bf6 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,46 @@ +# Git files +.git +.gitignore + +# Documentation +*.md +!README.md +PLAN.md +TODO.md + +# Build artifacts +bin/ +*.exe +*.dll +*.so +*.dylib + +# Test files +*_test.go + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# Data directories +sessions/ +data/ +*.db +*.db-shm +*.db-wal + +# Config files (will be mounted as volumes) +config.json +*.example.json +.whatshooked-cli.example.json + +# Assets +assets/ + +# Claude +.claude/ +CLAUDE.md +AI_USE.md diff --git a/DOCKER.md b/DOCKER.md new file mode 100644 index 0000000..631e05e --- /dev/null +++ b/DOCKER.md @@ -0,0 +1,326 @@ +# Docker Deployment Guide + +This guide explains how to run WhatsHooked using Docker and Docker Compose. + +## Prerequisites + +- Docker installed (version 20.10 or later) +- Docker Compose installed (version 1.29 or later) + +## Quick Start + +1. **Copy the example configuration file:** + ```bash + cp config.example.json config.json + ``` + +2. **Edit the configuration file:** + Open `config.json` and update: + - WhatsApp phone numbers + - Webhook URLs and authentication + - Server settings (port, authentication) + +3. **Create required directories:** + ```bash + mkdir -p sessions data/media + ``` + +4. **Build and start the server:** + ```bash + docker-compose up -d + ``` + +5. **View logs to scan QR code (first run):** + ```bash + docker-compose logs -f whatshooked + ``` + Scan the QR code with WhatsApp on your phone to authenticate. + +6. **Check server health:** + ```bash + curl http://localhost:8080/health + ``` + +## Docker Commands + +### Build the image +```bash +docker-compose build +``` + +### Start the service +```bash +docker-compose up -d +``` + +### Stop the service +```bash +docker-compose down +``` + +### View logs +```bash +docker-compose logs -f +``` + +### Restart the service +```bash +docker-compose restart +``` + +### Access the container shell +```bash +docker-compose exec whatshooked sh +``` + +## Volume Mounts + +The docker-compose.yml file mounts three important volumes: + +1. **config.json** - Server configuration (read-only) +2. **sessions/** - WhatsApp session data (persistent authentication) +3. **data/media/** - Downloaded media files + +These volumes ensure your data persists across container restarts. + +## Configuration + +### Port Mapping + +By default, the server runs on port 8080. To change the port: + +**Option 1: Update config.json** +```json +{ + "server": { + "port": 9090 + } +} +``` +Then update docker-compose.yml: +```yaml +ports: + - "9090:9090" +``` + +**Option 2: Map to different host port** +```yaml +ports: + - "3000:8080" # Access via localhost:3000, server still runs on 8080 internally +``` + +### Authentication + +Set authentication in config.json: + +**Option 1: API Key** +```json +{ + "server": { + "auth_key": "your-secure-api-key-here" + } +} +``` + +**Option 2: Username/Password** +```json +{ + "server": { + "username": "admin", + "password": "secure-password" + } +} +``` + +### Resource Limits + +Uncomment the deploy section in docker-compose.yml to set resource limits: + +```yaml +deploy: + resources: + limits: + cpus: '1.0' + memory: 512M + reservations: + cpus: '0.25' + memory: 128M +``` + +## QR Code Scanning + +When you first start the server, you'll need to scan a QR code to authenticate with WhatsApp. + +### View QR Code in Logs +```bash +docker-compose logs -f whatshooked +``` + +The QR code will be displayed in ASCII art in the terminal. Scan it with WhatsApp on your phone: +1. Open WhatsApp +2. Go to Settings > Linked Devices +3. Tap "Link a Device" +4. Scan the QR code from the terminal + +### Alternative: Use CLI Tool + +You can also use the CLI tool outside Docker to link accounts, then mount the session: +```bash +./bin/whatshook-cli accounts add +``` + +## Troubleshooting + +### Container won't start +Check logs for errors: +```bash +docker-compose logs +``` + +### Config file not found +Ensure config.json exists in the project root: +```bash +ls -la config.json +``` + +### Permission issues with volumes +Fix ownership of mounted directories: +```bash +sudo chown -R $(id -u):$(id -g) sessions data +``` + +### QR code not displaying +Ensure `show_qr: true` is set in config.json: +```json +{ + "whatsapp": [ + { + "show_qr": true + } + ] +} +``` + +### Cannot connect to server +Check if the container is running: +```bash +docker-compose ps +``` + +Check health status: +```bash +docker inspect whatshooked-server | grep -A 10 Health +``` + +## Production Deployment + +### Security Best Practices + +1. **Use secrets for sensitive data:** + - Don't commit config.json with real credentials + - Use Docker secrets or environment variables + - Enable authentication (auth_key or username/password) + +2. **Use HTTPS:** + - Put the server behind a reverse proxy (nginx, Traefik, Caddy) + - Enable SSL/TLS certificates + - Update webhook base_url to use https:// + +3. **Network isolation:** + - Use Docker networks to isolate the service + - Only expose necessary ports + - Consider using a VPN for webhook endpoints + +4. **Regular backups:** + - Backup the sessions/ directory regularly + - Backup config.json (securely) + - Backup media files if needed + +### Example with Reverse Proxy (nginx) + +Create a network: +```bash +docker network create whatshooked-net +``` + +Update docker-compose.yml: +```yaml +services: + whatshooked: + networks: + - whatshooked-net + # Don't expose ports to host, only to network + # ports: + # - "8080:8080" + +networks: + whatshooked-net: + external: true +``` + +Configure nginx to proxy to the container: +```nginx +server { + listen 443 ssl; + server_name whatshooked.yourdomain.com; + + ssl_certificate /path/to/cert.pem; + ssl_certificate_key /path/to/key.pem; + + location / { + proxy_pass http://whatshooked:8080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } +} +``` + +## Monitoring + +### Health Checks + +The compose file includes a health check that runs every 30 seconds: +```bash +docker inspect --format='{{.State.Health.Status}}' whatshooked-server +``` + +### Log Management + +Limit log size to prevent disk space issues: +```yaml +services: + whatshooked: + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" +``` + +## Updates + +To update to the latest version: + +1. Pull latest code: + ```bash + git pull + ``` + +2. Rebuild the image: + ```bash + docker-compose build --no-cache + ``` + +3. Restart the service: + ```bash + docker-compose down + docker-compose up -d + ``` + +## Multi-Platform Builds + +To build for different architectures (e.g., ARM for Raspberry Pi): + +```bash +docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t whatshooked:latest . +``` diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2d65663 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,39 @@ +# Build stage +FROM golang:1.23-alpine AS builder + +# Install build dependencies (SQLite requires CGO) +RUN apk add --no-cache gcc musl-dev sqlite-dev + +WORKDIR /build + +# Copy go mod files +COPY go.mod go.sum ./ +RUN go mod download + +# Copy source code +COPY . . + +# Build the server binary +# CGO is required for mattn/go-sqlite3 +RUN CGO_ENABLED=1 GOOS=linux go build -a -installsuffix cgo -o whatshooked-server ./cmd/server + +# Runtime stage +FROM alpine:latest + +# Install runtime dependencies +RUN apk add --no-cache ca-certificates sqlite-libs tzdata + +WORKDIR /app + +# Copy binary from builder +COPY --from=builder /build/whatshooked-server . + +# Create necessary directories +RUN mkdir -p /app/sessions /app/data/media + +# Expose the default server port +EXPOSE 8080 + +# Run the server +ENTRYPOINT ["/app/whatshooked-server"] +CMD ["-config", "/app/config.json"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..019a396 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,51 @@ +version: '3.8' + +services: + whatshooked: + build: + context: . + dockerfile: Dockerfile + container_name: whatshooked-server + ports: + - "8080:8080" + volumes: + # Mount config file + - ./config.json:/app/config.json:ro + + # Mount sessions directory for WhatsApp authentication persistence + - ./sessions:/app/sessions + + # Mount media directory for storing downloaded media files + - ./data/media:/app/data/media + + restart: unless-stopped + + # Health check + healthcheck: + test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8080/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + + # Environment variables (optional - can override config.json settings) + # environment: + # - LOG_LEVEL=info + + # Use host network mode if you need QR code scanning via terminal + # network_mode: "host" + + # Resource limits (optional) + # deploy: + # resources: + # limits: + # cpus: '1.0' + # memory: 512M + # reservations: + # cpus: '0.25' + # memory: 128M + +# Optional: Add networks for more complex setups +# networks: +# whatshooked-network: +# driver: bridge