Add Docker support with multi-arch builds
- Multi-stage Dockerfile (Alpine base, ~174MB) - All runtime dependencies: ffmpeg, ffprobe, ca-certificates, tzdata, wget - Camera database included in image (17MB) - Security: non-root user (strix:1000) - Healthcheck on /api/v1/health - docker-compose.yml for simple deployment - docker-compose.full.yml with go2rtc and Frigate integration - GitHub Actions workflow for automated multi-arch builds (amd64, arm64) - Auto-publish to Docker Hub (eduard256/strix) - DOCKER.md documentation
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
# Git
|
||||
.git
|
||||
.gitignore
|
||||
.github
|
||||
|
||||
# IDE
|
||||
.vscode
|
||||
.idea
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# Build artifacts
|
||||
bin/
|
||||
dist/
|
||||
*.exe
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test files
|
||||
*.test
|
||||
*_test.go
|
||||
coverage.*
|
||||
*.out
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
strix.log
|
||||
|
||||
# Config files (user-specific)
|
||||
strix.yaml
|
||||
test_*.yaml
|
||||
config.yaml
|
||||
|
||||
# Temporary files
|
||||
tmp/
|
||||
temp/
|
||||
*.dump
|
||||
*_output.txt
|
||||
|
||||
# Documentation (included in image metadata instead)
|
||||
*.md
|
||||
!README.md
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Development
|
||||
.env
|
||||
.env.local
|
||||
@@ -0,0 +1,77 @@
|
||||
name: Docker Build and Push
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
tags:
|
||||
- 'v*'
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
env:
|
||||
REGISTRY: docker.io
|
||||
IMAGE_NAME: eduard256/strix
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_TOKEN }}
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.IMAGE_NAME }}
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
build-args: |
|
||||
VERSION=${{ steps.meta.outputs.version }}
|
||||
|
||||
- name: Docker Hub Description
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: peter-evans/dockerhub-description@v4
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_TOKEN }}
|
||||
repository: ${{ env.IMAGE_NAME }}
|
||||
readme-filepath: ./README.md
|
||||
short-description: "Smart IP Camera Stream Discovery System"
|
||||
@@ -0,0 +1,164 @@
|
||||
# 🐳 Docker Setup for Strix
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Using Docker Compose (Recommended)
|
||||
|
||||
```bash
|
||||
# Start Strix
|
||||
docker-compose up -d
|
||||
|
||||
# View logs
|
||||
docker-compose logs -f strix
|
||||
|
||||
# Stop Strix
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
Access: http://localhost:4567
|
||||
|
||||
### Using Docker Run
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name strix \
|
||||
-p 4567:4567 \
|
||||
eduard256/strix:latest
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Using Environment Variables
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name strix \
|
||||
-p 8080:8080 \
|
||||
-e STRIX_API_LISTEN=:8080 \
|
||||
-e STRIX_LOG_LEVEL=debug \
|
||||
eduard256/strix:latest
|
||||
```
|
||||
|
||||
### Using Config File
|
||||
|
||||
```bash
|
||||
# Create strix.yaml
|
||||
cat > strix.yaml <<EOF
|
||||
api:
|
||||
listen: ":8080"
|
||||
EOF
|
||||
|
||||
# Run with mounted config
|
||||
docker run -d \
|
||||
--name strix \
|
||||
-p 8080:8080 \
|
||||
-v $(pwd)/strix.yaml:/app/strix.yaml:ro \
|
||||
eduard256/strix:latest
|
||||
```
|
||||
|
||||
## Full Stack (Strix + go2rtc + Frigate)
|
||||
|
||||
```bash
|
||||
docker-compose -f docker-compose.full.yml up -d
|
||||
```
|
||||
|
||||
Services:
|
||||
- Strix: http://localhost:4567
|
||||
- go2rtc: http://localhost:1984
|
||||
- Frigate: http://localhost:5000
|
||||
|
||||
## Building Locally
|
||||
|
||||
```bash
|
||||
# Build for your platform
|
||||
docker build -t strix:local .
|
||||
|
||||
# Build for multiple platforms
|
||||
docker buildx build --platform linux/amd64,linux/arm64 -t strix:multi .
|
||||
```
|
||||
|
||||
## Image Information
|
||||
|
||||
- **Image**: `eduard256/strix:latest`
|
||||
- **Platforms**: linux/amd64, linux/arm64
|
||||
- **Size**: ~80-90MB
|
||||
- **Base**: Alpine Linux
|
||||
- **User**: Non-root (strix:1000)
|
||||
|
||||
## Included Dependencies
|
||||
|
||||
- ffmpeg/ffprobe (stream validation)
|
||||
- ca-certificates (HTTPS support)
|
||||
- tzdata (timezone support)
|
||||
- wget (healthcheck)
|
||||
- Camera database (3600+ models)
|
||||
|
||||
## Health Check
|
||||
|
||||
```bash
|
||||
# Check container health
|
||||
docker inspect --format='{{.State.Health.Status}}' strix
|
||||
|
||||
# Manual health check
|
||||
docker exec strix wget -q -O- http://localhost:4567/api/v1/health
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### View logs
|
||||
```bash
|
||||
docker logs strix
|
||||
docker logs -f strix # Follow logs
|
||||
```
|
||||
|
||||
### Check if ffprobe works
|
||||
```bash
|
||||
docker exec strix ffprobe -version
|
||||
```
|
||||
|
||||
### Inspect container
|
||||
```bash
|
||||
docker exec -it strix sh
|
||||
```
|
||||
|
||||
### Restart container
|
||||
```bash
|
||||
docker restart strix
|
||||
```
|
||||
|
||||
## Security
|
||||
|
||||
- Runs as non-root user (UID 1000)
|
||||
- Minimal attack surface (Alpine base)
|
||||
- No unnecessary packages
|
||||
- Health checks enabled
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `STRIX_API_LISTEN` | `:4567` | Server listen address |
|
||||
| `STRIX_LOG_LEVEL` | `info` | Log level (debug, info, warn, error) |
|
||||
| `STRIX_LOG_FORMAT` | `json` | Log format (json, text) |
|
||||
| `STRIX_DATA_PATH` | `./data` | Camera database path |
|
||||
|
||||
## Volumes
|
||||
|
||||
```bash
|
||||
# Optional: Custom configuration
|
||||
-v ./strix.yaml:/app/strix.yaml:ro
|
||||
|
||||
# Optional: Custom camera database
|
||||
-v ./data:/app/data:ro
|
||||
```
|
||||
|
||||
## Docker Hub
|
||||
|
||||
Pre-built images available at: https://hub.docker.com/r/eduard256/strix
|
||||
|
||||
Tags:
|
||||
- `latest` - Latest stable release
|
||||
- `v0.1.0` - Specific version
|
||||
- `0.1` - Minor version
|
||||
- `0` - Major version
|
||||
- `main` - Development branch
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
# Strix - Smart IP Camera Stream Discovery System
|
||||
# Multi-stage Dockerfile for minimal image size
|
||||
|
||||
# Stage 1: Builder
|
||||
FROM golang:1.24-alpine AS builder
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
# Install build dependencies
|
||||
RUN apk add --no-cache git
|
||||
|
||||
# Copy go mod files
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build static binary
|
||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build \
|
||||
-ldflags="-s -w -X main.Version=docker" \
|
||||
-o strix \
|
||||
cmd/strix/main.go
|
||||
|
||||
# Stage 2: Runtime
|
||||
FROM alpine:latest
|
||||
|
||||
# Install runtime dependencies
|
||||
# - ffmpeg/ffprobe: Required for RTSP stream validation
|
||||
# - ca-certificates: Required for HTTPS requests to cameras
|
||||
# - tzdata: Required for correct timestamps
|
||||
# - wget: Required for healthcheck
|
||||
RUN apk add --no-cache \
|
||||
ffmpeg \
|
||||
ca-certificates \
|
||||
tzdata \
|
||||
wget \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy binary from builder
|
||||
COPY --from=builder /build/strix .
|
||||
|
||||
# Copy camera database (CRITICAL - app won't work without it)
|
||||
COPY --from=builder /build/data ./data
|
||||
|
||||
# Create directory for optional config
|
||||
RUN mkdir -p /app/config
|
||||
|
||||
# Create non-root user for security
|
||||
RUN addgroup -g 1000 strix && \
|
||||
adduser -D -u 1000 -G strix strix && \
|
||||
chown -R strix:strix /app
|
||||
|
||||
# Switch to non-root user
|
||||
USER strix
|
||||
|
||||
# Expose default port
|
||||
EXPOSE 4567
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:4567/api/v1/health || exit 1
|
||||
|
||||
# Start application
|
||||
CMD ["./strix"]
|
||||
@@ -0,0 +1,93 @@
|
||||
version: '3.8'
|
||||
|
||||
# Full home automation stack: Strix + go2rtc + Frigate
|
||||
# This configuration shows how to use Strix together with go2rtc and Frigate
|
||||
|
||||
services:
|
||||
# Strix - Camera Stream Discovery
|
||||
strix:
|
||||
image: eduard256/strix:latest
|
||||
container_name: strix
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "4567:4567"
|
||||
environment:
|
||||
- STRIX_LOG_LEVEL=info
|
||||
- STRIX_LOG_FORMAT=json
|
||||
networks:
|
||||
- cameras
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4567/api/v1/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
# go2rtc - Universal Stream Server
|
||||
go2rtc:
|
||||
image: alexxit/go2rtc:latest
|
||||
container_name: go2rtc
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "1984:1984" # Web UI
|
||||
- "8554:8554" # RTSP
|
||||
- "8555:8555" # WebRTC
|
||||
volumes:
|
||||
- ./go2rtc.yaml:/config/go2rtc.yaml:ro
|
||||
networks:
|
||||
- cameras
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:1984"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
# Frigate - NVR with Object Detection
|
||||
frigate:
|
||||
image: ghcr.io/blakeblackshear/frigate:stable
|
||||
container_name: frigate
|
||||
restart: unless-stopped
|
||||
privileged: true
|
||||
shm_size: "256mb"
|
||||
ports:
|
||||
- "5000:5000" # Web UI
|
||||
- "8971:8971" # Go2RTC internal
|
||||
- "1935:1935" # RTMP
|
||||
volumes:
|
||||
- ./frigate.yml:/config/config.yml:ro
|
||||
- frigate-media:/media/frigate
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
environment:
|
||||
- FRIGATE_RTSP_PASSWORD=password
|
||||
networks:
|
||||
- cameras
|
||||
depends_on:
|
||||
- go2rtc
|
||||
|
||||
networks:
|
||||
cameras:
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 172.25.0.0/24
|
||||
|
||||
volumes:
|
||||
frigate-media:
|
||||
driver: local
|
||||
|
||||
# Usage workflow:
|
||||
# 1. Use Strix to discover camera streams: http://localhost:4567
|
||||
# 2. Copy discovered stream URLs to go2rtc.yaml
|
||||
# 3. Configure go2rtc streams: http://localhost:1984
|
||||
# 4. Add streams to Frigate config: frigate.yml
|
||||
# 5. View recordings and detections: http://localhost:5000
|
||||
#
|
||||
# Network communication:
|
||||
# - Strix discovers streams from cameras (external network)
|
||||
# - go2rtc receives streams from cameras and re-streams
|
||||
# - Frigate receives streams from go2rtc (internal network)
|
||||
#
|
||||
# All services can communicate using container names:
|
||||
# - http://strix:4567
|
||||
# - http://go2rtc:1984
|
||||
# - http://frigate:5000
|
||||
@@ -0,0 +1,56 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
strix:
|
||||
image: eduard256/strix:latest
|
||||
# Or build locally:
|
||||
# build: .
|
||||
container_name: strix
|
||||
restart: unless-stopped
|
||||
|
||||
ports:
|
||||
- "4567:4567"
|
||||
|
||||
environment:
|
||||
# Logging configuration
|
||||
- STRIX_LOG_LEVEL=info
|
||||
- STRIX_LOG_FORMAT=json
|
||||
|
||||
# Optional: Override default port
|
||||
# - STRIX_API_LISTEN=:4567
|
||||
|
||||
# Optional: Custom data path
|
||||
# - STRIX_DATA_PATH=/app/data
|
||||
|
||||
# volumes:
|
||||
# Optional: Mount custom configuration
|
||||
# - ./strix.yaml:/app/strix.yaml:ro
|
||||
|
||||
# Optional: Mount custom camera database
|
||||
# - ./data:/app/data:ro
|
||||
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4567/api/v1/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
# Optional: Resource limits
|
||||
# deploy:
|
||||
# resources:
|
||||
# limits:
|
||||
# cpus: '1.0'
|
||||
# memory: 512M
|
||||
# reservations:
|
||||
# cpus: '0.5'
|
||||
# memory: 256M
|
||||
|
||||
# Usage:
|
||||
# 1. Start: docker-compose up -d
|
||||
# 2. View logs: docker-compose logs -f strix
|
||||
# 3. Stop: docker-compose down
|
||||
# 4. Restart: docker-compose restart strix
|
||||
#
|
||||
# Access WebUI: http://localhost:4567
|
||||
# Access API: http://localhost:4567/api/v1/health
|
||||
Reference in New Issue
Block a user