Skip to content

Latest commit

 

History

History
793 lines (616 loc) · 24.2 KB

File metadata and controls

793 lines (616 loc) · 24.2 KB

Stream Daemon - Docker Deployment

Run Stream Daemon in a Docker container for easy deployment, scalability, and consistency across environments.

Quick StartPrerequisitesDeploymentConfigurationAuthorSupport


🐳 Quick Start

Option 1: Use Pre-Built Image from GitHub Container Registry (Recommended)

docker pull ghcr.io/chiefgyk3d/stream-daemon:latest
docker run -d \
  --name stream-daemon \
  --restart unless-stopped \
  --env-file .env \
  -v $(pwd)/messages.txt:/app/messages.txt \
  -v $(pwd)/end_messages.txt:/app/end_messages.txt \
  ghcr.io/chiefgyk3d/stream-daemon:latest

Option 2: Use Docker Hub

docker pull chiefgyk3dx/stream-daemon:latest
docker run -d --name stream-daemon --env-file .env chiefgyk3dx/stream-daemon:latest

Option 3: Build from Source

# Clone the repository (if not already cloned)
git clone https://github.com/ChiefGyk3D/Stream-Daemon.git
cd Stream-Daemon

# Build the Docker image
docker build -f Docker/Dockerfile -t stream-daemon:local .

# Run with environment file
docker run -d \
  --name stream-daemon \
  --restart unless-stopped \
  --env-file .env \
  -v $(pwd)/messages.txt:/app/messages.txt \
  -v $(pwd)/end_messages.txt:/app/end_messages.txt \
  stream-daemon:local

Option 4: Docker Compose

cd Docker
cp docker-compose.example.yml docker-compose.yml

# Edit docker-compose.yml:
# - To use pre-built: change `build: .` to `image: ghcr.io/chiefgyk3d/stream-daemon:latest`
# - To build from source: keep `build: .` (or change to proper build context)
nano docker-compose.yml

docker-compose up -d

That's it! Stream Daemon is now running in the background.

📦 Available Docker Images

Stream Daemon is published to two container registries:

  • GitHub Container Registry: ghcr.io/chiefgyk3d/stream-daemon:latest (Recommended)
  • Docker Hub: chiefgyk3dx/stream-daemon:latest (Alternative)

Both images are automatically built and published on every release with support for linux/amd64 and linux/arm64 platforms.

Why GHCR is recommended:

  • Integrated with GitHub repository
  • Automatic builds on every release
  • Better integration with GitHub Actions
  • Free for public repositories

💡 Tip: New to Stream Daemon? Use the secrets wizard to generate your configuration:

cd ..  # Return to root directory
./scripts/create-secrets.sh

The wizard helps you set up credentials in Doppler, AWS Secrets Manager, HashiCorp Vault, or generate a .env file. See Secrets Wizard Guide for details.

📋 Prerequisites

  • Docker installed (Get Docker)
  • Docker Compose installed (Get Docker Compose)
  • API credentials for at least one streaming platform (Twitch, YouTube, or Kick)
  • API credentials for at least one social platform (Mastodon, Bluesky, Discord, or Matrix)

🚀 Deployment Methods

Method 1: Docker Compose (Recommended)

Benefits:

  • ✅ Easy configuration with docker-compose.yml
  • ✅ Automatic restart on failure
  • ✅ Volume mounting for message files
  • ✅ Environment variable management
  • ✅ Consistent container name: stream-daemon

Steps:

  1. Navigate to Docker directory:

    cd Docker
  2. Copy example config:

    cp docker-compose.example.yml docker-compose.yml
  3. Edit docker-compose.yml with your credentials:

    Using pre-built image (recommended):

    version: '3.8'
    services:
      stream-daemon:
        image: ghcr.io/chiefgyk3d/stream-daemon:latest
        container_name: stream-daemon
        restart: unless-stopped
        environment:
          # Enable ONE streaming platform
          TWITCH_ENABLE: 'True'
          TWITCH_USERNAME: 'your_username'
          TWITCH_CLIENT_ID: 'your_client_id'
          TWITCH_CLIENT_SECRET: 'your_client_secret'
          
          # Enable ONE social platform
          MASTODON_ENABLE_POSTING: 'True'
          MASTODON_API_BASE_URL: 'https://mastodon.social'
          MASTODON_CLIENT_ID: 'your_client_id'
          MASTODON_CLIENT_SECRET: 'your_client_secret'
          MASTODON_ACCESS_TOKEN: 'your_access_token'

    Building from source:

    version: '3.8'
    services:
      stream-daemon:
        build:
          context: ..
          dockerfile: Docker/Dockerfile
        container_name: stream-daemon
        restart: unless-stopped
        environment:
          # ... same environment variables as above
  4. Start the container:

    docker-compose up -d

    Note: The container will be named stream-daemon for easy reference in all Docker commands.

  5. View logs:

    docker-compose logs -f

Method 2: Direct Docker Run (Pre-Built Image)

Use pre-built images for quick deployment:

  1. Pull the image:

    docker pull ghcr.io/chiefgyk3d/stream-daemon:latest
    # Or: docker pull chiefgyk3dx/stream-daemon:latest
  2. Run the container:

    docker run -d \
      --name stream-daemon \
      --restart unless-stopped \
      -e TWITCH_ENABLE=True \
      -e TWITCH_USERNAME=your_username \
      -e TWITCH_CLIENT_ID=your_client_id \
      -e TWITCH_CLIENT_SECRET=your_client_secret \
      -e MASTODON_ENABLE_POSTING=True \
      -e MASTODON_API_BASE_URL=https://mastodon.social \
      -e MASTODON_CLIENT_ID=your_client_id \
      -e MASTODON_CLIENT_SECRET=your_client_secret \
      -e MASTODON_ACCESS_TOKEN=your_access_token \
      ghcr.io/chiefgyk3d/stream-daemon:latest
  3. View logs:

    docker logs -f stream-daemon

Method 3: Build from Source

For development, testing, or custom modifications:

  1. Clone the repository (if not already cloned):

    git clone https://github.com/ChiefGyk3D/Stream-Daemon.git
    cd Stream-Daemon
  2. Build the image:

    docker build -f Docker/Dockerfile -t stream-daemon:local .
  3. Run the container:

    docker run -d \
      --name stream-daemon \
      --restart unless-stopped \
      -e TWITCH_ENABLE=True \
      -e TWITCH_USERNAME=your_username \
      -e TWITCH_CLIENT_ID=your_client_id \
      -e TWITCH_CLIENT_SECRET=your_client_secret \
      -e MASTODON_ENABLE_POSTING=True \
      -e MASTODON_API_BASE_URL=https://mastodon.social \
      -e MASTODON_CLIENT_ID=your_client_id \
      -e MASTODON_CLIENT_SECRET=your_client_secret \
      -e MASTODON_ACCESS_TOKEN=your_access_token \
      stream-daemon:local
  4. View logs:

    docker logs -f stream-daemon

Why build from source?

  • Testing local changes before submitting a PR
  • Custom modifications for your environment
  • Running unreleased features from development branches
  • Air-gapped or restricted network environments
  • Learning how the Docker image is constructed

Method 4: Docker with Doppler CLI

Automatically inject secrets without storing sensitive data in docker-compose.yml:

doppler run -- docker-compose up -d

Doppler CLI automatically provides all secrets to the container.

⚙️ Configuration

Environment Variables

Stream Daemon uses pure environment variables - no config files needed in Docker!

🪄 Quick Setup: Use the interactive wizard to generate your configuration:

cd .. && ./scripts/create-secrets.sh

Supports Doppler, AWS Secrets Manager, Vault, or .env file generation.
Documentation: Secrets Wizard GuideConfig vs Secrets Behavior

Streaming Platforms (Enable at least ONE)

Twitch:

TWITCH_ENABLE: 'True'
TWITCH_USERNAME: 'your_username'
TWITCH_CLIENT_ID: 'your_client_id'
TWITCH_CLIENT_SECRET: 'your_client_secret'

YouTube:

YOUTUBE_ENABLE: 'True'
YOUTUBE_CHANNEL_ID: 'your_channel_id'  # OR use username
YOUTUBE_API_KEY: 'your_api_key'

Kick:

KICK_ENABLE: 'True'
KICK_USERNAME: 'your_username'

Social Platforms (Enable at least ONE)

Mastodon:

MASTODON_ENABLE_POSTING: 'True'
MASTODON_API_BASE_URL: 'https://mastodon.social'
MASTODON_CLIENT_ID: 'your_client_id'
MASTODON_CLIENT_SECRET: 'your_client_secret'
MASTODON_ACCESS_TOKEN: 'your_access_token'

Bluesky:

BLUESKY_ENABLE_POSTING: 'True'
BLUESKY_HANDLE: 'yourname.bsky.social'
BLUESKY_APP_PASSWORD: 'your_app_password'

Discord:

DISCORD_ENABLE_POSTING: 'True'
DISCORD_WEBHOOK_URL: 'https://discord.com/api/webhooks/YOUR_WEBHOOK'

Matrix:

MATRIX_ENABLE_POSTING: 'True'
MATRIX_HOMESERVER: 'https://matrix.org'
MATRIX_USERNAME: '@bot:matrix.org'
MATRIX_PASSWORD: 'your_password'
MATRIX_ROOM_ID: '!roomid:matrix.org'

AI / LLM (Optional)

Option 1: Ollama (Local AI - Recommended)

LLM_ENABLE: 'True'
LLM_PROVIDER: 'ollama'
LLM_OLLAMA_HOST: 'http://192.168.1.100'  # Your Ollama server IP
LLM_OLLAMA_PORT: '11434'
LLM_MODEL: 'gemma3:4b'  # or gemma3:12b for 16GB GPUs

Benefits:

  • ✅ 100% privacy - data never leaves your network
  • ✅ Zero API costs
  • ✅ Works offline
  • ✅ No rate limits

Option 2: Google Gemini (Cloud API)

LLM_ENABLE: 'True'
LLM_PROVIDER: 'gemini'
GEMINI_API_KEY: 'your_api_key'
LLM_MODEL: 'gemini-2.0-flash-lite'

Benefits:

  • ✅ No local hardware needed
  • ✅ Quick setup
  • ✅ Low cost (~$0.0001 per message)

See AI Messages Guide for complete setup instructions.

Settings

SETTINGS_POST_INTERVAL: '60'    # Minutes to wait when stream is live
SETTINGS_CHECK_INTERVAL: '5'    # Minutes to wait when offline

Custom Message Files

You can mount custom message files:

volumes:
  - ./my_messages.txt:/app/messages.txt
  - ./my_end_messages.txt:/app/end_messages.txt

See MESSAGES_FORMAT.md for file format details.

🔐 Secrets Management

For production deployments, use a secrets manager instead of plaintext environment variables.

🪄 Quick Setup: Use the interactive wizard to configure secrets automatically:

cd .. && ./scripts/create-secrets.sh

📖 Secrets Wizard Guide - Interactive setup
📖 Secrets Management Guide - Manual configuration

Doppler (Recommended)

environment:
  SECRET_MANAGER: doppler
  DOPPLER_TOKEN: ${DOPPLER_TOKEN}  # Set in .env file

See DOPPLER_GUIDE.md for complete setup.

AWS Secrets Manager

environment:
  SECRET_MANAGER: aws
  SECRETS_AWS_TWITCH_SECRET_NAME: twitch-api-keys
  SECRETS_AWS_MASTODON_SECRET_NAME: mastodon-api-keys
  # AWS credentials via IAM role or environment

HashiCorp Vault

environment:
  SECRET_MANAGER: vault
  SECRETS_VAULT_URL: https://vault.example.com
  SECRETS_VAULT_TOKEN: ${VAULT_TOKEN}
  SECRETS_VAULT_TWITCH_SECRET_PATH: secret/twitch

📊 Container Management

View Logs

docker-compose logs -f
docker-compose logs -f --tail=100  # Last 100 lines

Restart Container

docker-compose restart

Stop Container

docker-compose down

Rebuild After Code Changes

docker-compose down
docker-compose build --no-cache
docker-compose up -d

Check Container Status

docker-compose ps
docker stats stream-daemon

🧪 Testing & Validation

Stream Daemon includes a comprehensive pytest-based test suite. You can run tests either inside the container or on your host system.

Run Tests in Container

# Enter the running container
docker exec -it stream-daemon bash

# Install pytest (if not in image)
pip install pytest pytest-asyncio pytest-cov

# Run tests
pytest tests/ -v

# Run tests by category
pytest tests/ -m streaming      # Twitch, YouTube, Kick
pytest tests/ -m social          # Mastodon, Bluesky, Discord, Matrix
pytest tests/ -m integration     # End-to-end workflows

# Run with coverage
pytest tests/ --cov=stream_daemon --cov-report=html

Run Tests on Host

If you have Python installed locally:

# Clone the repository
cd /path/to/Stream-Daemon

# Install dependencies
pip install -r requirements.txt

# Set up environment (use your .env or secrets manager)
export $(cat .env | xargs)

# Run tests
pytest tests/ -v

Test Documentation

See tests/README.md for:

  • Complete test suite documentation
  • Writing new tests
  • CI/CD integration examples
  • Troubleshooting test failures

What Tests Validate

Configuration Loading - Environment variables and secrets
API Authentication - Valid credentials for each platform
Stream Detection - Live status checking
Social Posting - Message formatting and platform features
Security - Secret masking and safe logging
Integration - Complete stream lifecycle workflows

🐛 Troubleshooting

Container Won't Start

  1. Check logs:

    docker-compose logs
  2. Verify environment variables:

    docker-compose config
  3. Test build:

    docker-compose build

Authentication Errors

Make sure all required credentials are set in docker-compose.yml. Check logs for specific platform errors.

Import Errors

The container includes all dependencies. If you see import errors, rebuild:

docker-compose build --no-cache

Permission Issues

The container runs as the default user. Ensure mounted volumes have appropriate permissions.

🚢 Production Deployment

Using Pre-Built Images

  1. Pull pre-built image from GHCR (recommended):

    services:
      stream-daemon:
        image: ghcr.io/chiefgyk3d/stream-daemon:latest
        container_name: stream-daemon
        restart: unless-stopped
        environment:
          # ... your config

    Or from Docker Hub:

    services:
      stream-daemon:
        image: chiefgyk3dx/stream-daemon:latest
        # ... rest of config
  2. Auto-updates with Watchtower:

    services:
      stream-daemon:
        image: ghcr.io/chiefgyk3d/stream-daemon:latest
        container_name: stream-daemon
        restart: unless-stopped
        # ... config
      
      watchtower:
        image: containrrr/watchtower
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
        command: --interval 86400  # Check daily

Health Checks

Add health check to docker-compose.yml:

services:
  stream-daemon:
    # ... config
    healthcheck:
      test: ["CMD", "pgrep", "-f", "stream-daemon"]
      interval: 60s
      timeout: 10s
      retries: 3

📝 License

MIT License - See LICENSE.md

🤝 Support

⚙️ Configuration

Environment Variables

Stream Daemon uses pure environment variables - no config files needed in Docker!

Here's an example structure for the config.ini file:

[Twitch]
client_id = YOUR_TWITCH_CLIENT_ID
client_secret = YOUR_TWITCH_CLIENT_SECRET
user_login = YOUR_TWITCH_USERNAME

[Mastodon]
app_name = YOUR_APP_NAME
api_base_url = YOUR_INSTANCE_URL
client_id = YOUR_CLIENT_ID
client_secret = YOUR_CLIENT_SECRET
access_token = YOUR_ACCESS_TOKEN
messages_file = MESSAGES_FILE_PATH
end_messages_file = END_MESSAGES_FILE_PATH
post_end_stream_message = BOOLEAN_VALUE

[Secrets]
secret_manager = YOUR_SECRET_MANAGER_TYPE 
aws_twitch_secret_name = YOUR_TWITCH_SECRET_NAME_IN_AWS_SECRETS_MANAGER
aws_mastodon_secret_name = YOUR_MASTODON_SECRET_NAME_IN_AWS_SECRETS_MANAGER
vault_url = YOUR_VAULT_URL
vault_token = YOUR_VAULT_TOKEN
vault_twitch_secret_path = YOUR_TWITCH_SECRET_PATH_IN_VAULT
vault_mastodon_secret_path = YOUR_MASTODON_SECRET_PATH_IN_VAULT

[Settings]
post_interval = YOUR_PREFERRED_POST_INTERVAL_IN_HOURS
check_interval = YOUR_PREFERRED_CHECK_INTERVAL_IN_MINUTES

Please note, the config.ini should be modified to match your needs.

Caution

While the above example demonstrates how to configure the bot with secrets directly placed into the config.ini file, this is not a recommended practice for production environments. It is highly suggested to use services like HashiCorp Vault or AWS Secrets Manager to handle secrets more securely.

If you still prefer to put your secrets into config.ini, ensure that this file is appropriately secured and never committed into a public repository.

The Twitch-Mastodon Bot supports the use of both AWS Secrets Manager and HashiCorp Vault. Please see the following sections for how to configure them.

AWS Secrets Manager Integration

The script supports optional integration with AWS Secrets Manager for secure storage and retrieval of Twitch and Mastodon API keys. To use this feature, store the credentials as secrets in AWS Secrets Manager and provide the secret names in the config.ini file.

Please note that this feature is still in testing and any issues should be reported.

HashiCorp Vault Integration

The script also supports optional integration with HashiCorp Vault for secure storage and retrieval of Twitch and Mastodon API keys. To use this feature, store the credentials in Vault and provide the necessary Vault information in the config.ini file.

Please note that this feature is still in testing and any issues should be reported.

Future plans

  • Dockerize the script for easy deployment and scaling.
  • Add support for more streaming platforms.

👤 Author & Socials

Made with ❤️ by ChiefGyk3D

Mastodon Bluesky Twitch YouTube Kick TikTok Discord Matrix
Mastodon Bluesky Twitch YouTube Kick TikTok Discord Matrix

ChiefGyk3D is the author of Stream Daemon (formerly Twitch and Toot)


💝 Donations and Tips

If you find Stream Daemon useful, consider supporting development:

Donate:

Patreon StreamElements
Patreon StreamElements

Cryptocurrency Tips

Bitcoin Bitcoin
bc1qztdzcy2wyavj2tsuandu4p0tcklzttvdnzalla
Monero Monero
84Y34QubRwQYK2HNviezeH9r6aRcPvgWmKtDkN3EwiuVbp6sNLhm9ffRgs6BA9X1n9jY7wEN16ZEpiEngZbecXseUrW8SeQ
Ethereum Ethereum
0x554f18cfB684889c3A60219BDBE7b050C39335ED

Made with ❤️ by ChiefGyk3D

Author & Socials

Mastodon Bluesky Twitch YouTube Kick TikTok Discord Matrix
Mastodon Bluesky Twitch YouTube Kick TikTok Discord Matrix

ChiefGyk3D is the author of Stream Daemon (formerly Twitch and Toot)

If Stream Daemon helps you, consider ⭐ starring the repo!