Running as Service
Configure TAD to run as a system service on Linux and macOS.
Linux (systemd)
Installation
TAD includes a systemd service file. Install with:
bash
sudo ./install.sh --serviceOr manually:
bash
# Copy service file
sudo cp tad.service /etc/systemd/system/
# Reload systemd
sudo systemctl daemon-reload
# Enable service
sudo systemctl enable tad
# Start service
sudo systemctl start tadService File
/etc/systemd/system/tad.service:
ini
[Unit]
Description=TAD - Tactical Autonomous Zone Communications
After=network.target
[Service]
Type=simple
User=tad
Group=tad
WorkingDirectory=/opt/tad
ExecStart=/opt/tad/venv/bin/python -m tad.main
Restart=always
RestartSec=10
# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/tad/data
[Install]
WantedBy=multi-user.targetManaging the Service
bash
# Start TAD
sudo systemctl start tad
# Stop TAD
sudo systemctl stop tad
# Restart TAD
sudo systemctl restart tad
# Check status
sudo systemctl status tad
# View logs
sudo journalctl -u tad -f
# Enable auto-start on boot
sudo systemctl enable tad
# Disable auto-start
sudo systemctl disable tadCreating Service User
For better security, run as dedicated user:
bash
# Create user
sudo useradd -r -s /bin/false -d /opt/tad tad
# Create directories
sudo mkdir -p /opt/tad/data
sudo chown -R tad:tad /opt/tad
# Install TAD
sudo -u tad git clone https://github.com/fabriziosalmi/tad.git /opt/tad
cd /opt/tad
sudo -u tad ./install.shmacOS (launchd)
Launch Agent
Create ~/Library/LaunchAgents/com.tad.plist:
xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.tad</string>
<key>ProgramArguments</key>
<array>
<string>/Users/YOUR_USERNAME/tad/venv/bin/python</string>
<string>-m</string>
<string>tad.main</string>
</array>
<key>WorkingDirectory</key>
<string>/Users/YOUR_USERNAME/tad</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/Users/YOUR_USERNAME/tad/logs/stdout.log</string>
<key>StandardErrorPath</key>
<string>/Users/YOUR_USERNAME/tad/logs/stderr.log</string>
</dict>
</plist>Managing Launch Agent
bash
# Load service
launchctl load ~/Library/LaunchAgents/com.tad.plist
# Unload service
launchctl unload ~/Library/LaunchAgents/com.tad.plist
# Start service
launchctl start com.tad
# Stop service
launchctl stop com.tad
# Check status
launchctl list | grep tad
# View logs
tail -f ~/tad/logs/stdout.logDocker
Docker Compose
Create docker-compose.yml:
yaml
version: '3.8'
services:
tad:
build: .
container_name: tad
restart: unless-stopped
network_mode: host
volumes:
- ./data:/app/data
- ./exports:/app/exports
environment:
- TAD_PORT=8765
- TAD_AUTO_DISCOVER=trueDockerfile
dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY tad/ ./tad/
COPY tad.py .
VOLUME ["/app/data", "/app/exports"]
EXPOSE 8765/udp
EXPOSE 8765/tcp
CMD ["python", "-m", "tad.main"]Running with Docker
bash
# Build image
docker-compose build
# Start service
docker-compose up -d
# View logs
docker-compose logs -f
# Stop service
docker-compose down
# Restart
docker-compose restartProcess Management (Alternative)
Using screen
bash
# Start in screen session
screen -S tad -dm python -m tad.main
# Attach to session
screen -r tad
# Detach: Ctrl+A, D
# Kill session
screen -X -S tad quitUsing tmux
bash
# Start in tmux session
tmux new-session -d -s tad 'python -m tad.main'
# Attach to session
tmux attach -t tad
# Detach: Ctrl+B, D
# Kill session
tmux kill-session -t tadUsing supervisor
Install supervisor:
bash
sudo apt install supervisor # Ubuntu/Debian
sudo yum install supervisor # CentOS/RHELCreate /etc/supervisor/conf.d/tad.conf:
ini
[program:tad]
command=/opt/tad/venv/bin/python -m tad.main
directory=/opt/tad
user=tad
autostart=true
autorestart=true
stderr_logfile=/var/log/tad/stderr.log
stdout_logfile=/var/log/tad/stdout.logManage:
bash
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start tad
sudo supervisorctl status tadAuto-Start Configuration
Environment Variables
Create /opt/tad/.env:
bash
TAD_PORT=8765
TAD_DISCOVERY=true
TAD_AUTO_JOIN=general,dev
TAD_LOG_LEVEL=INFOUpdate service to load env:
ini
[Service]
EnvironmentFile=/opt/tad/.envConfiguration File
Create /opt/tad/config.yaml:
yaml
network:
port: 8765
discovery: true
channels:
auto_join:
- general
- dev
logging:
level: INFO
file: /var/log/tad/tad.logMonitoring
Health Checks
Create health check script:
bash
#!/bin/bash
# /usr/local/bin/tad_health_check.sh
STATUS=$(systemctl is-active tad)
if [ "$STATUS" != "active" ]; then
echo "TAD is not running. Attempting restart..."
systemctl start tad
# Send alert
echo "TAD restarted at $(date)" | mail -s "TAD Service Alert" admin@example.com
fiAdd to crontab:
bash
*/5 * * * * /usr/local/bin/tad_health_check.shLog Rotation
Create /etc/logrotate.d/tad:
/var/log/tad/*.log {
daily
rotate 7
compress
delaycompress
notifempty
create 0640 tad tad
sharedscripts
postrotate
systemctl reload tad > /dev/null 2>&1 || true
endscript
}Troubleshooting
Service Won't Start
bash
# Check service status
sudo systemctl status tad
# View recent logs
sudo journalctl -u tad -n 50
# Check configuration
sudo systemctl cat tad
# Verify executable
sudo -u tad /opt/tad/venv/bin/python -m tad.mainPermission Issues
bash
# Fix ownership
sudo chown -R tad:tad /opt/tad
# Fix permissions
sudo chmod -R 755 /opt/tad
sudo chmod 640 /opt/tad/.envPort Already in Use
bash
# Find process using port
sudo lsof -i :8765
# Kill process
sudo kill -9 <PID>
# Or change port in configSee Also
- Deployment - System-wide installation
- Docker Guide - Container deployment
- Troubleshooting - Common issues