Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Git
.git
.gitignore

# Python
__pycache__
*.pyc
*.pyo
*.pyd
.Python
env
pip-log.txt
pip-delete-this-directory.txt
.tox
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.log
.git
.mypy_cache
.pytest_cache
.hypothesis

# Virtual environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# OS
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Docker
Dockerfile*
docker-compose*
.dockerignore

# Documentation
*.md
docs/

# Development files
.isort.cfg
mypy.ini
pylintrc

# Logs and runtime files
*.log
logs/
custom_wakewords/

# Test files
tests/
63 changes: 63 additions & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# GitHub Actions Workflows

## Docker Image Publishing

The `docker-publish.yaml` workflow automatically builds and publishes Docker images to GitHub Container Registry (ghcr.io).

### How It Works

**Triggers:**
- Push to `main` branch → builds and tags as `latest`
- Push tags matching `v*` (e.g., `v1.0.0`) → builds and tags with version numbers
- Pull requests → builds only (doesn't push)

**Multi-Architecture Support:**
The workflow builds for multiple architectures:
- `linux/amd64` (x86_64)
- `linux/arm64` (ARM 64-bit, like Raspberry Pi 4)
- `linux/arm/v7` (ARM 32-bit, like older Raspberry Pi models)

### Setup Requirements

**No additional setup needed!** The workflow uses `GITHUB_TOKEN` which is automatically provided by GitHub Actions.

### Usage

Once the workflow runs successfully, users can pull the image:

```bash
docker pull ghcr.io/ohf-voice/linux-voice-assistant:latest
```

Or use it in docker-compose.yaml:

```yaml
services:
linux-voice-assistant:
image: ghcr.io/ohf-voice/linux-voice-assistant:latest
# ... rest of configuration
```

### Creating a Release

To publish a versioned image:

```bash
git tag v1.0.0
git push origin v1.0.0
```

This creates images tagged as:
- `ghcr.io/ohf-voice/linux-voice-assistant:1.0.0`
- `ghcr.io/ohf-voice/linux-voice-assistant:1.0`
- `ghcr.io/ohf-voice/linux-voice-assistant:1`
- `ghcr.io/ohf-voice/linux-voice-assistant:latest`

### Making Images Public

By default, GitHub Container Registry images are private. To make them public:

1. Go to the package page: `https://github.com/orgs/OHF-Voice/packages/container/linux-voice-assistant`
2. Click "Package settings"
3. Scroll to "Danger Zone"
4. Click "Change visibility" → "Public"
65 changes: 65 additions & 0 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Build and Publish Docker Image

on:
push:
branches:
- main
tags:
- 'v*'
pull_request:
branches:
- main

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- 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 GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels)
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ 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 Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./docker/dockerfile
platforms: linux/amd64,linux/arm64,linux/arm/v7
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ venv/
/dist/
/preferences.json
/local/

# Docker personal config (use .env.example as template)
.env
67 changes: 67 additions & 0 deletions docker/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Linux Voice Assistant - Docker Environment Configuration
# Copy this file to .env and customize for your setup:
# cp .env.example .env

# =============================================================================
# USER CONFIGURATION
# =============================================================================

# User/Group IDs for file permissions (run: id -u && id -g)
# For root user, use 0:0
PUID=1000
PGID=1000

# =============================================================================
# VOICE ASSISTANT SETTINGS
# =============================================================================

# Device name shown in Home Assistant
LVA_NAME=Linux Voice Assistant

# MAC address for consistent Home Assistant device identity
# Without this, HA may see a "new" device after each container restart
# Get your host's MAC: ip link show | grep ether | head -1 | awk '{print $2}'
# Leave empty to use container's auto-generated MAC (may cause duplicate devices in HA)
LVA_MAC_ADDRESS=

# Wake word model
# Options: okay_nabu, hey_jarvis, alexa, hey_mycroft, hey_luna, okay_computer, hey_rhasspy
LVA_WAKE_MODEL=okay_nabu

# =============================================================================
# AUDIO CONFIGURATION
# =============================================================================

# PulseAudio socket path on the host
# Standard user: /run/user/$(id -u)/pulse (e.g., /run/user/1000/pulse)
# Root user: /var/run/pulse (requires pulseaudio-root.service, see systemd/)
PULSE_RUNTIME_PATH=/run/user/1000/pulse

# Audio devices (leave as 'default' unless you have multiple audio devices)
AUDIO_INPUT_DEVICE=default
AUDIO_OUTPUT_DEVICE=

# =============================================================================
# NETWORK CONFIGURATION
# =============================================================================

# ESPHome API port (default: 6053)
# Change if running multiple instances or port conflict
LVA_PORT=6053

# =============================================================================
# DEBUGGING
# =============================================================================

# Enable debug logging (remove or set to false for production)
LVA_DEBUG=false

# =============================================================================
# OPTIONAL PATHS
# =============================================================================

# Custom wake word directory (mount your own .tflite models)
# CUSTOM_WAKEWORDS_DIR=./custom_wakewords

# Preferences file location
# PREFERENCES_FILE=./preferences.json
Loading