Run Stream Daemon in a Docker container for easy deployment, scalability, and consistency across environments.
Quick Start • Prerequisites • Deployment • Configuration • Author • Support
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:latestOption 2: Use Docker Hub
docker pull chiefgyk3dx/stream-daemon:latest
docker run -d --name stream-daemon --env-file .env chiefgyk3dx/stream-daemon:latestOption 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:localOption 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 -dThat's it! Stream Daemon is now running in the background.
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.shThe wizard helps you set up credentials in Doppler, AWS Secrets Manager, HashiCorp Vault, or generate a
.envfile. See Secrets Wizard Guide for details.
- 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)
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:
-
Navigate to Docker directory:
cd Docker -
Copy example config:
cp docker-compose.example.yml docker-compose.yml
-
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
-
Start the container:
docker-compose up -d
Note: The container will be named
stream-daemonfor easy reference in all Docker commands. -
View logs:
docker-compose logs -f
Use pre-built images for quick deployment:
-
Pull the image:
docker pull ghcr.io/chiefgyk3d/stream-daemon:latest # Or: docker pull chiefgyk3dx/stream-daemon:latest -
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
-
View logs:
docker logs -f stream-daemon
For development, testing, or custom modifications:
-
Clone the repository (if not already cloned):
git clone https://github.com/ChiefGyk3D/Stream-Daemon.git cd Stream-Daemon -
Build the image:
docker build -f Docker/Dockerfile -t stream-daemon:local . -
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
-
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
Automatically inject secrets without storing sensitive data in docker-compose.yml:
doppler run -- docker-compose up -dDoppler CLI automatically provides all secrets to the container.
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.shSupports Doppler, AWS Secrets Manager, Vault, or
.envfile generation.
Documentation: Secrets Wizard Guide • Config vs Secrets Behavior
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'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'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 GPUsBenefits:
- ✅ 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_POST_INTERVAL: '60' # Minutes to wait when stream is live
SETTINGS_CHECK_INTERVAL: '5' # Minutes to wait when offlineYou can mount custom message files:
volumes:
- ./my_messages.txt:/app/messages.txt
- ./my_end_messages.txt:/app/end_messages.txtSee MESSAGES_FORMAT.md for file format details.
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
environment:
SECRET_MANAGER: doppler
DOPPLER_TOKEN: ${DOPPLER_TOKEN} # Set in .env fileSee DOPPLER_GUIDE.md for complete setup.
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 environmentenvironment:
SECRET_MANAGER: vault
SECRETS_VAULT_URL: https://vault.example.com
SECRETS_VAULT_TOKEN: ${VAULT_TOKEN}
SECRETS_VAULT_TWITCH_SECRET_PATH: secret/twitchdocker-compose logs -f
docker-compose logs -f --tail=100 # Last 100 linesdocker-compose restartdocker-compose downdocker-compose down
docker-compose build --no-cache
docker-compose up -ddocker-compose ps
docker stats stream-daemonStream Daemon includes a comprehensive pytest-based test suite. You can run tests either inside the container or on your host system.
# 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=htmlIf 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/ -vSee tests/README.md for:
- Complete test suite documentation
- Writing new tests
- CI/CD integration examples
- Troubleshooting test failures
✅ 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
-
Check logs:
docker-compose logs
-
Verify environment variables:
docker-compose config
-
Test build:
docker-compose build
Make sure all required credentials are set in docker-compose.yml. Check logs for specific platform errors.
The container includes all dependencies. If you see import errors, rebuild:
docker-compose build --no-cacheThe container runs as the default user. Ensure mounted volumes have appropriate permissions.
-
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
-
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
Add health check to docker-compose.yml:
services:
stream-daemon:
# ... config
healthcheck:
test: ["CMD", "pgrep", "-f", "stream-daemon"]
interval: 60s
timeout: 10s
retries: 3MIT License - See LICENSE.md
- 📖 Documentation: See main README.md
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
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_MINUTESPlease note, the config.ini should be modified to match your needs.
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.
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.
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.
- Dockerize the script for easy deployment and scaling.
- Add support for more streaming platforms.
Made with ❤️ by ChiefGyk3D
ChiefGyk3D is the author of Stream Daemon (formerly Twitch and Toot)
If you find Stream Daemon useful, consider supporting development:
Donate:
Made with ❤️ by ChiefGyk3D
| 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!