feat: Phase 6 - Docker, systemd, and installation scripts
This commit is contained in:
55
Dockerfile
Normal file
55
Dockerfile
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# Build stage
|
||||||
|
FROM python:3.11-slim AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install build dependencies
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
build-essential \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install Python dependencies
|
||||||
|
COPY pyproject.toml .
|
||||||
|
RUN pip install --no-cache-dir -e ".[dev]" \
|
||||||
|
&& pip wheel --no-cache-dir --wheel-dir /app/wheels \
|
||||||
|
pydantic lancedb pyarrow requests watchdog typer rich numpy httpx sse-starlette fastapi uvicorn
|
||||||
|
|
||||||
|
# Production stage
|
||||||
|
FROM python:3.11-slim AS production
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install runtime dependencies
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Copy wheels and install
|
||||||
|
COPY --from=builder /app/wheels /wheels
|
||||||
|
RUN pip install --no-cache-dir /wheels/*
|
||||||
|
|
||||||
|
# Copy application code
|
||||||
|
COPY companion/ ./companion/
|
||||||
|
COPY companion/forge/ ./companion/forge/
|
||||||
|
COPY companion/indexer_daemon/ ./companion/indexer_daemon/
|
||||||
|
COPY companion/rag/ ./companion/rag/
|
||||||
|
|
||||||
|
# Create directories for data
|
||||||
|
RUN mkdir -p /data/vectors /data/memory /models
|
||||||
|
|
||||||
|
# Copy default config
|
||||||
|
COPY config.json /app/config.json
|
||||||
|
|
||||||
|
# Environment variables
|
||||||
|
ENV PYTHONPATH=/app
|
||||||
|
ENV COMPANION_CONFIG=/app/config.json
|
||||||
|
ENV COMPANION_DATA_DIR=/data
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||||
|
CMD python -c "import requests; requests.get('http://localhost:7373/health')" || exit 1
|
||||||
|
|
||||||
|
# API port
|
||||||
|
EXPOSE 7373
|
||||||
|
|
||||||
|
# Default command
|
||||||
|
CMD ["python", "-m", "uvicorn", "companion.api:app", "--host", "0.0.0.0", "--port", "7373"]
|
||||||
32
Dockerfile.indexer
Normal file
32
Dockerfile.indexer
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Indexer-only Dockerfile (lightweight, no API dependencies)
|
||||||
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
build-essential \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install Python dependencies
|
||||||
|
RUN pip install --no-cache-dir \
|
||||||
|
pydantic lancedb pyarrow requests watchdog typer rich numpy httpx
|
||||||
|
|
||||||
|
# Copy application code
|
||||||
|
COPY companion/ ./companion/
|
||||||
|
COPY companion/indexer_daemon/ ./companion/indexer_daemon/
|
||||||
|
COPY companion/rag/ ./companion/rag/
|
||||||
|
|
||||||
|
# Create directories for data
|
||||||
|
RUN mkdir -p /data/vectors
|
||||||
|
|
||||||
|
# Copy default config
|
||||||
|
COPY config.json /app/config.json
|
||||||
|
|
||||||
|
# Environment variables
|
||||||
|
ENV PYTHONPATH=/app
|
||||||
|
ENV COMPANION_CONFIG=/app/config.json
|
||||||
|
ENV COMPANION_DATA_DIR=/data
|
||||||
|
|
||||||
|
# Default command (can be overridden)
|
||||||
|
CMD ["python", "-m", "companion.indexer_daemon.cli", "index"]
|
||||||
76
docker-compose.yml
Normal file
76
docker-compose.yml
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
companion-api:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
target: production
|
||||||
|
container_name: companion-api
|
||||||
|
ports:
|
||||||
|
- "7373:7373"
|
||||||
|
volumes:
|
||||||
|
- ./config.json:/app/config.json:ro
|
||||||
|
- companion-data:/data
|
||||||
|
- ./models:/models:ro
|
||||||
|
environment:
|
||||||
|
- COMPANION_CONFIG=/app/config.json
|
||||||
|
- COMPANION_DATA_DIR=/data
|
||||||
|
networks:
|
||||||
|
- companion-network
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "python", "-c", "import requests; requests.get('http://localhost:7373/health')"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 5s
|
||||||
|
|
||||||
|
companion-indexer:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.indexer
|
||||||
|
container_name: companion-indexer
|
||||||
|
volumes:
|
||||||
|
- ./config.json:/app/config.json:ro
|
||||||
|
- companion-data:/data
|
||||||
|
- /home/san/KnowledgeVault:/vault:ro # Mount Obsidian vault as read-only
|
||||||
|
environment:
|
||||||
|
- COMPANION_CONFIG=/app/config.json
|
||||||
|
- COMPANION_DATA_DIR=/data
|
||||||
|
- VAULT_PATH=/vault
|
||||||
|
networks:
|
||||||
|
- companion-network
|
||||||
|
restart: unless-stopped
|
||||||
|
command: ["python", "-m", "companion.indexer_daemon.watcher"]
|
||||||
|
# Or use CLI mode for manual sync:
|
||||||
|
# command: ["python", "-m", "companion.indexer_daemon.cli", "index"]
|
||||||
|
|
||||||
|
# Optional: Ollama for local embeddings and LLM
|
||||||
|
ollama:
|
||||||
|
image: ollama/ollama:latest
|
||||||
|
container_name: companion-ollama
|
||||||
|
ports:
|
||||||
|
- "11434:11434"
|
||||||
|
volumes:
|
||||||
|
- ollama-data:/root/.ollama
|
||||||
|
networks:
|
||||||
|
- companion-network
|
||||||
|
restart: unless-stopped
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
reservations:
|
||||||
|
devices:
|
||||||
|
- driver: nvidia
|
||||||
|
count: 1
|
||||||
|
capabilities: [gpu]
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
companion-data:
|
||||||
|
driver: local
|
||||||
|
ollama-data:
|
||||||
|
driver: local
|
||||||
|
|
||||||
|
networks:
|
||||||
|
companion-network:
|
||||||
|
driver: bridge
|
||||||
110
scripts/install.ps1
Normal file
110
scripts/install.ps1
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Companion AI - Windows Installation Script
|
||||||
|
|
||||||
|
Write-Host "Companion AI Installation Script for Windows"
|
||||||
|
Write-Host "============================================="
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# Check if Python is installed
|
||||||
|
$python = Get-Command python -ErrorAction SilentlyContinue
|
||||||
|
if (-not $python) {
|
||||||
|
Write-Error "Python 3 is required but not found. Please install Python 3.11 or later."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$pythonVersion = python --version 2>&1
|
||||||
|
Write-Host "Found: $pythonVersion"
|
||||||
|
|
||||||
|
# Create directories
|
||||||
|
$installDir = "$env:LOCALAPPDATA\Companion"
|
||||||
|
$dataDir = "$env:LOCALAPPDATA\Companion\Data"
|
||||||
|
|
||||||
|
Write-Host "Creating directories..."
|
||||||
|
New-Item -ItemType Directory -Force -Path $installDir | Out-Null
|
||||||
|
New-Item -ItemType Directory -Force -Path $dataDir\vectors | Out-Null
|
||||||
|
New-Item -ItemType Directory -Force -Path $dataDir\memory | Out-Null
|
||||||
|
New-Item -ItemType Directory -Force -Path $dataDir\models | Out-Null
|
||||||
|
|
||||||
|
# Copy application files
|
||||||
|
Write-Host "Installing Companion AI..."
|
||||||
|
$sourceDir = $PSScriptRoot
|
||||||
|
if (Test-Path "$sourceDir\src") {
|
||||||
|
Copy-Item -Recurse -Force "$sourceDir\*" $installDir
|
||||||
|
} else {
|
||||||
|
Write-Error "Cannot find source files. Please run from the Companion AI directory."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create virtual environment
|
||||||
|
Write-Host "Creating Python virtual environment..."
|
||||||
|
Set-Location $installDir
|
||||||
|
python -m venv venv
|
||||||
|
|
||||||
|
# Activate and install
|
||||||
|
Write-Host "Installing dependencies..."
|
||||||
|
& .\venv\Scripts\Activate.ps1
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
python -m pip install -e ".[dev]"
|
||||||
|
|
||||||
|
# Copy config
|
||||||
|
if (-not (Test-Path "$dataDir\config.json")) {
|
||||||
|
Copy-Item "$installDir\config.json" "$dataDir\config.json"
|
||||||
|
# Update paths
|
||||||
|
$config = Get-Content "$dataDir\config.json" -Raw
|
||||||
|
$config = $config -replace '~/.companion', $dataDir.Replace('\', '/')
|
||||||
|
Set-Content "$dataDir\config.json" $config
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create startup scripts
|
||||||
|
Write-Host "Creating startup scripts..."
|
||||||
|
|
||||||
|
# API server startup script
|
||||||
|
$apiScript = @"
|
||||||
|
@echo off
|
||||||
|
set PYTHONPATH=$($installDir)
|
||||||
|
set COMPANION_CONFIG=$($dataDir)\config.json
|
||||||
|
set COMPANION_DATA_DIR=$($dataDir)
|
||||||
|
cd "$($installDir)"
|
||||||
|
.\venv\Scripts\python -m uvicorn companion.api:app --host 0.0.0.0 --port 7373
|
||||||
|
"@
|
||||||
|
Set-Content "$installDir\start-api.bat" $apiScript
|
||||||
|
|
||||||
|
# Indexer watcher startup script
|
||||||
|
$indexerScript = @"
|
||||||
|
@echo off
|
||||||
|
set PYTHONPATH=$($installDir)
|
||||||
|
set COMPANION_CONFIG=$($dataDir)\config.json
|
||||||
|
set COMPANION_DATA_DIR=$($dataDir)
|
||||||
|
cd "$($installDir)"
|
||||||
|
.\venv\Scripts\python -m companion.indexer_daemon.watcher
|
||||||
|
"@
|
||||||
|
Set-Content "$installDir\start-indexer.bat" $indexerScript
|
||||||
|
|
||||||
|
# CLI shortcut
|
||||||
|
$cliScript = @"
|
||||||
|
@echo off
|
||||||
|
set PYTHONPATH=$($installDir)
|
||||||
|
set COMPANION_CONFIG=$($dataDir)\config.json
|
||||||
|
set COMPANION_DATA_DIR=$($dataDir)
|
||||||
|
cd "$($installDir)"
|
||||||
|
.\venv\Scripts\python -m companion.indexer_daemon.cli %*
|
||||||
|
"@
|
||||||
|
Set-Content "$installDir\companion.bat" $cliScript
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Installation complete!"
|
||||||
|
Write-Host "====================="
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "To start the API server:"
|
||||||
|
Write-Host " $installDir\start-api.bat"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "To start the file watcher (auto-indexing):"
|
||||||
|
Write-Host " $installDir\start-indexer.bat"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "To run a manual index:"
|
||||||
|
Write-Host " $installDir\companion.bat index"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Config location: $dataDir\config.json"
|
||||||
|
Write-Host "Data location: $dataDir"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Edit the config to set your vault path, then start the services."
|
||||||
116
scripts/install.sh
Normal file
116
scripts/install.sh
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Companion AI Installation Script for Linux
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
INSTALL_DIR="/opt/companion"
|
||||||
|
DATA_DIR="/var/lib/companion"
|
||||||
|
USER="companion"
|
||||||
|
SERVICE_USER="${USER}"
|
||||||
|
REPO_URL="https://github.com/santhoshjan/companion.git"
|
||||||
|
|
||||||
|
echo "Companion AI Installation Script"
|
||||||
|
echo "================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check if running as root
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
echo "Please run as root (use sudo)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check dependencies
|
||||||
|
echo "Checking dependencies..."
|
||||||
|
if ! command -v python3 &> /dev/null; then
|
||||||
|
echo "Python 3 is required but not installed. Aborting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v pip3 &> /dev/null; then
|
||||||
|
echo "pip3 is required but not installed. Installing..."
|
||||||
|
apt-get update && apt-get install -y python3-pip
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create user
|
||||||
|
echo "Creating companion user..."
|
||||||
|
if ! id "$USER" &>/dev/null; then
|
||||||
|
useradd -r -s /bin/false -d "$INSTALL_DIR" "$USER"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create directories
|
||||||
|
echo "Creating directories..."
|
||||||
|
mkdir -p "$INSTALL_DIR"
|
||||||
|
mkdir -p "$DATA_DIR"/{vectors,memory,models}
|
||||||
|
mkdir -p /etc/companion
|
||||||
|
|
||||||
|
# Install application
|
||||||
|
echo "Installing Companion AI..."
|
||||||
|
if [ -d ".git" ]; then
|
||||||
|
# Running from git repo
|
||||||
|
cp -r . "$INSTALL_DIR/"
|
||||||
|
else
|
||||||
|
# Clone from remote
|
||||||
|
git clone "$REPO_URL" "$INSTALL_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create virtual environment
|
||||||
|
echo "Creating Python virtual environment..."
|
||||||
|
cd "$INSTALL_DIR"
|
||||||
|
python3 -m venv venv
|
||||||
|
source venv/bin/activate
|
||||||
|
pip install --upgrade pip
|
||||||
|
pip install -e ".[dev]"
|
||||||
|
|
||||||
|
# Set permissions
|
||||||
|
echo "Setting permissions..."
|
||||||
|
chown -R "$USER:$USER" "$INSTALL_DIR"
|
||||||
|
chown -R "$USER:$USER" "$DATA_DIR"
|
||||||
|
|
||||||
|
# Install systemd services
|
||||||
|
echo "Installing systemd services..."
|
||||||
|
if command -v systemctl &> /dev/null; then
|
||||||
|
cp systemd/companion-api.service /etc/systemd/system/
|
||||||
|
cp systemd/companion-indexer.service /etc/systemd/system/
|
||||||
|
cp systemd/companion-index@.service /etc/systemd/system/
|
||||||
|
cp systemd/companion-index.timer /etc/systemd/system/ 2>/dev/null || true
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Services installed. To start:"
|
||||||
|
echo " sudo systemctl enable companion-api"
|
||||||
|
echo " sudo systemctl start companion-api"
|
||||||
|
echo ""
|
||||||
|
echo "For auto-indexing:"
|
||||||
|
echo " sudo systemctl enable companion-indexer"
|
||||||
|
echo " sudo systemctl start companion-indexer"
|
||||||
|
else
|
||||||
|
echo "systemd not found. Manual setup required."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create config if doesn't exist
|
||||||
|
if [ ! -f /etc/companion/config.json ]; then
|
||||||
|
echo "Creating default configuration..."
|
||||||
|
cp "$INSTALL_DIR/config.json" /etc/companion/config.json
|
||||||
|
# Update paths in config
|
||||||
|
sed -i "s|~/.companion|$DATA_DIR|g" /etc/companion/config.json
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create symlink for CLI
|
||||||
|
echo "Installing CLI..."
|
||||||
|
ln -sf "$INSTALL_DIR/venv/bin/companion" /usr/local/bin/companion 2>/dev/null || true
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Installation complete!"
|
||||||
|
echo "======================"
|
||||||
|
echo ""
|
||||||
|
echo "Next steps:"
|
||||||
|
echo "1. Edit configuration: sudo nano /etc/companion/config.json"
|
||||||
|
echo "2. Update vault path in the config"
|
||||||
|
echo "3. Start services: sudo systemctl start companion-api companion-indexer"
|
||||||
|
echo "4. Check status: sudo systemctl status companion-api"
|
||||||
|
echo ""
|
||||||
|
echo "Data directory: $DATA_DIR"
|
||||||
|
echo "Config directory: /etc/companion"
|
||||||
|
echo "Install directory: $INSTALL_DIR"
|
||||||
35
systemd/companion-api.service
Normal file
35
systemd/companion-api.service
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Companion AI API Service
|
||||||
|
Documentation=https://github.com/santhoshjan/companion
|
||||||
|
After=network.target ollama.service
|
||||||
|
Wants=ollama.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=companion
|
||||||
|
Group=companion
|
||||||
|
WorkingDirectory=/opt/companion
|
||||||
|
Environment=PYTHONPATH=/opt/companion
|
||||||
|
Environment=COMPANION_CONFIG=/opt/companion/config.json
|
||||||
|
Environment=COMPANION_DATA_DIR=/var/lib/companion
|
||||||
|
|
||||||
|
# Start the API server
|
||||||
|
ExecStart=/opt/companion/venv/bin/python -m uvicorn companion.api:app --host 0.0.0.0 --port 7373
|
||||||
|
|
||||||
|
# Restart on failure
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
# Resource limits
|
||||||
|
MemoryMax=2G
|
||||||
|
CPUQuota=200%
|
||||||
|
|
||||||
|
# Security hardening
|
||||||
|
NoNewPrivileges=true
|
||||||
|
PrivateTmp=true
|
||||||
|
ProtectSystem=strict
|
||||||
|
ProtectHome=true
|
||||||
|
ReadWritePaths=/var/lib/companion
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
11
systemd/companion-index.timer
Normal file
11
systemd/companion-index.timer
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Companion AI Daily Full Index
|
||||||
|
Documentation=https://github.com/santhoshjan/companion
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnCalendar=daily
|
||||||
|
OnCalendar=*-*-* 03:00:00
|
||||||
|
Persistent=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
22
systemd/companion-index@.service
Normal file
22
systemd/companion-index@.service
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Companion AI Full Index (One-shot)
|
||||||
|
Documentation=https://github.com/santhoshjan/companion
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
User=companion
|
||||||
|
Group=companion
|
||||||
|
WorkingDirectory=/opt/companion
|
||||||
|
Environment=PYTHONPATH=/opt/companion
|
||||||
|
Environment=COMPANION_CONFIG=/opt/companion/config.json
|
||||||
|
Environment=COMPANION_DATA_DIR=/var/lib/companion
|
||||||
|
|
||||||
|
# Run full index
|
||||||
|
ExecStart=/opt/companion/venv/bin/python -m companion.indexer_daemon.cli index
|
||||||
|
|
||||||
|
# Security hardening
|
||||||
|
NoNewPrivileges=true
|
||||||
|
PrivateTmp=true
|
||||||
|
ProtectSystem=strict
|
||||||
|
ProtectHome=true
|
||||||
|
ReadWritePaths=/var/lib/companion
|
||||||
38
systemd/companion-indexer.service
Normal file
38
systemd/companion-indexer.service
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Companion AI Vault Indexer
|
||||||
|
Documentation=https://github.com/santhoshjan/companion
|
||||||
|
After=network.target companion-api.service
|
||||||
|
Wants=companion-api.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=companion
|
||||||
|
Group=companion
|
||||||
|
WorkingDirectory=/opt/companion
|
||||||
|
Environment=PYTHONPATH=/opt/companion
|
||||||
|
Environment=COMPANION_CONFIG=/opt/companion/config.json
|
||||||
|
Environment=COMPANION_DATA_DIR=/var/lib/companion
|
||||||
|
|
||||||
|
# Start the file watcher for auto-sync
|
||||||
|
ExecStart=/opt/companion/venv/bin/python -m companion.indexer_daemon.watcher
|
||||||
|
|
||||||
|
# Or use the CLI for scheduled sync (uncomment to use):
|
||||||
|
# ExecStart=/opt/companion/venv/bin/python -m companion.indexer_daemon.cli sync
|
||||||
|
|
||||||
|
# Restart on failure
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
# Resource limits
|
||||||
|
MemoryMax=1G
|
||||||
|
CPUQuota=100%
|
||||||
|
|
||||||
|
# Security hardening
|
||||||
|
NoNewPrivileges=true
|
||||||
|
PrivateTmp=true
|
||||||
|
ProtectSystem=strict
|
||||||
|
ProtectHome=true
|
||||||
|
ReadWritePaths=/var/lib/companion
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
Reference in New Issue
Block a user