EAS Station Installation Details
Installation Process
How install.sh Works
The install.sh script uses an interactive TUI (Text User Interface) similar to raspi-config. Here's what happens when you run it:
git clone https://github.com/KR8MER/eas-station.git && \
cd eas-station && \
sudo bash install.sh
Interactive Configuration (New!)
The installer now collects all configuration during installation using blue/gray dialog boxes (whiptail):
You'll be asked to configure:
- Administrator Account - Username, password, email
- System Settings - Hostname, domain, EAS originator, station callsign
- Location & Timezone - Timezone, state, county, optional FIPS codes
- Alert Sources - Enable/disable NOAA and IPAWS, set poll intervals
- Audio & Streaming - Icecast streaming with auto-generated passwords
- Hardware Integration - GPIO, LED signs, VFD displays
Benefits:
- ✅ All configuration done upfront - no post-install wizard needed
- ✅ Input validation with helpful error messages
- ✅ Default values provided for quick setup
- ✅ Can cancel and restart anytime
- ✅ Settings saved to
/opt/eas-station/.env
Installation Flow
1. Pre-Installation Checks & Welcome (10-30 seconds)
- ✓ Verifies script is run as root (sudo)
- ✓ Detects system architecture (x86_64, ARM, etc.)
- ✓ Detects OS (Debian, Ubuntu, Raspberry Pi OS)
- ⚠️ If OS is not Debian/Ubuntu, asks for confirmation to continue
- 🎨 Displays welcome screen with installation overview
- 📝 Collects administrator account - username, password, email (TUI dialogs)
- ⚙️ Collects system configuration - hostname, domain, originator, callsign (TUI dialogs)
- 📍 Collects location settings - timezone, state, county, FIPS codes (TUI dialogs)
- 📡 Collects alert sources - NOAA, IPAWS settings (TUI dialogs)
- 🎵 Collects audio settings - Icecast configuration (TUI dialogs)
- 🔌 Collects hardware settings - GPIO, LED, VFD (TUI dialogs)
- ✅ Shows configuration summary for confirmation
2. System Dependencies (2-5 minutes)
- Updates package lists (
apt-get update) - Installs system packages:
- Python 3, pip, venv
- PostgreSQL 17 + PostGIS 3
- Redis server
- Nginx web server
- FFmpeg, espeak (audio processing)
- SDR libraries (SoapySDR, RTL-SDR, Airspy)
- Build tools (gcc, g++, make)
- SSL tools (certbot)
3. User and Directory Setup (5-10 seconds)
- Creates
eas-stationsystem user and group - Creates
/opt/eas-stationdirectory - Creates
/var/log/eas-stationdirectory - Adds user to hardware access groups (dialout, plugdev, gpio, audio)
4. Application Installation (30-60 seconds)
- Copies entire repository to
/opt/eas-station - Excludes: .git, pycache, .pyc files
- Preserves: All application code, scripts, templates, static files
- Sets ownership to
eas-station:eas-station
5. Python Environment (2-5 minutes)
- Creates Python virtual environment in
/opt/eas-station/venv - Upgrades pip, setuptools, wheel
- Installs all Python dependencies from
requirements.txt
6. Database Setup (10-30 seconds)
- Starts PostgreSQL service
- Creates
alertsdatabase - Creates
eas_stationdatabase user with password - Grants all privileges to user
- Installs PostGIS and PostGIS Topology extensions
- Optionally installs pgAdmin 4 for database management
7. Redis Setup (5 seconds)
- Enables and starts Redis server
- Default configuration on localhost:6379
8. Configuration File Generation (1 second)
- Automatically generates
/opt/eas-station/.envwith all settings collected during TUI - Auto-generates secure SECRET_KEY using Python's secrets module (64 character hex)
- Auto-generates secure database password (43 character urlsafe)
- Auto-generates Icecast passwords if streaming enabled (16 characters each)
- Includes all user-provided configuration:
- Administrator email
- Hostname and domain
- EAS originator and station callsign
- Timezone, state, county, FIPS codes
- Alert source settings (NOAA, IPAWS)
- Icecast streaming configuration
- Hardware integration settings (GPIO, LED, VFD)
- Sets file permissions to 600 (owner read/write only)
9. Database Initialization (10-30 seconds)
- Runs Alembic migrations if any exist
- Creates all database tables
- Initializes schema with proper indexes and constraints
- Sets up RBAC roles and permissions
- Initializes NWS zone catalog
10. Hardware Configuration (5 seconds)
- Creates udev rules for SDR devices (RTL-SDR, Airspy, HackRF)
- Grants proper USB device permissions
11. Systemd Services (5 seconds)
- Copies service files to
/etc/systemd/system/ - Services installed:
eas-station.target- Master service (controls all)eas-station-web.service- Web UI (Flask/Gunicorn)eas-station-sdr.service- SDR hardware serviceeas-station-audio.service- Audio processingeas-station-eas.service- EAS monitoringeas-station-hardware.service- GPIO/displayseas-station-noaa-poller.service- NOAA alertseas-station-ipaws-poller.service- IPAWS alerts
- Reloads systemd daemon
- Enables services for auto-start on boot
12. Nginx Configuration (5-10 seconds)
- Copies nginx configuration to
/etc/nginx/sites-available/eas-station - Generates self-signed SSL certificate for immediate HTTPS
- Enables site by symlinking to sites-enabled
- Removes default site
- Tests and reloads nginx
13. Service Startup (5-10 seconds)
- Automatically starts all EAS Station services
- Waits 3 seconds for startup
- Checks if services are running
- Reports status
14. Completion (immediate)
- Displays comprehensive summary
- Shows access URLs (localhost and detected IP)
- Lists next steps
- Shows useful commands
Total Installation Time
- Configuration: 2-5 minutes (TUI dialogs)
- Package Installation: 5-7 minutes (fast hardware, good internet)
- Total Minimal: 7-12 minutes
- Total Typical: 12-20 minutes
- Total Maximum: 25-35 minutes (slower hardware/internet)
What's Interactive vs Automated
Interactive Configuration (TUI Dialogs):
- ✅ Administrator account (username, password, email)
- ✅ System settings (hostname, domain, originator, callsign)
- ✅ Location & timezone (state, county, FIPS codes)
- ✅ Alert sources (NOAA, IPAWS, poll intervals)
- ✅ Audio settings (Icecast streaming)
- ✅ Hardware integration (GPIO, LED signs, VFD)
Fully Automated (No User Input):
- ✅ All package installation
- ✅ User and directory creation
- ✅ Application file copying
- ✅ Python dependency installation
- ✅ Database creation and configuration
- ✅ SECRET_KEY generation
- ✅ Database password generation
- ✅ Icecast password generation
- ✅ Configuration file creation with collected settings
- ✅ SSL certificate generation
- ✅ Service installation and startup
Optional Post-Installation:
- Fine-tune settings via web interface at
/setup- Advanced features like FIPS code lookup/builder
- Zone code derivation from FIPS codes
- Reconfigure anytime using
sudo eas-configcommand- Provides same raspi-config style TUI
- Update any setting without reinstalling
- Manual editing of
/opt/eas-station/.envfor advanced users
No Post-Install Wizard Required! All essential configuration is collected during installation.
Configuration File: Why .env?
Why .env and Not .cfg?
The application uses .env because:
- Industry Standard -
.envfiles are the de facto standard for 12-factor app configuration - Python-Dotenv Library - The application uses
python-dotenv==1.0.1which specifically reads.envfiles - Environment Variables -
.envfiles are designed to export environment variables, which is how Flask and other Python frameworks read configuration - Wide Support - Most deployment tools, IDEs, and frameworks recognize
.envfiles automatically - Git-Friendly -
.envis in.gitignoreby convention, preventing accidental commits of secrets
.env vs .cfg Comparison
| Feature | .env | .cfg |
|---|---|---|
| Flask/Django support | ✅ Native | ❌ Custom parser needed |
| Environment variables | ✅ Automatic | ❌ Manual loading |
| Systemd integration | ✅ Native | ⚠️ Requires conversion |
| IDE support | ✅ Built-in | ⚠️ Generic |
| Industry standard | ✅ Yes | ⚠️ For INI files |
| Secret management | ✅ Common | ⚠️ Less common |
Configuration File Location
/opt/eas-station/.env
Permissions: 600 (owner read/write only)
Owner: eas-station:eas-station
How Configuration is Loaded
# In app.py
from dotenv import load_dotenv
# Load from custom path or default .env
_config_path = os.environ.get('CONFIG_PATH')
if _config_path:
load_dotenv(_config_path, override=True)
else:
load_dotenv(override=True) # Loads .env from current directory
Configuration Priority
- Environment Variables - Highest priority (system environment)
- .env File - Middle priority (file in /opt/eas-station/)
- Application Defaults - Lowest priority (hardcoded defaults)
This allows:
- Production: Use environment variables for secrets
- Development: Use .env for local overrides
- Testing: Use in-memory configuration
Alternative: CONFIG_PATH Environment Variable
You can specify an alternate configuration file location:
# In systemd service file
Environment="CONFIG_PATH=/etc/eas-station/config.env"
But the file should still use .env format:
KEY=value
SECRET_KEY=abc123
DATABASE_URL=postgresql://...
Post-Installation
Verify Installation
# Check services
sudo systemctl status eas-station.target
# Check web service specifically
sudo systemctl status eas-station-web.service
# View logs
sudo journalctl -u eas-station-web.service -f
# Check database
sudo -u postgres psql -l | grep alerts
# Check configuration
sudo ls -lh /opt/eas-station/.env
First-Time Access
- Open browser to
https://your-server-ip - Accept self-signed certificate (click "Advanced" → "Proceed")
- Create admin account
- Complete setup wizard
No Manual Configuration Files to Edit!
Unlike traditional installations that require:
- ❌ Editing configuration files with nano/vi
- ❌ Manually generating secret keys
- ❌ Running database migrations
- ❌ Starting services manually
EAS Station does everything automatically and provides a web-based setup wizard for all configuration.
Troubleshooting Installation
Installation Fails
# Check where it failed
sudo journalctl -xe
# Re-run with verbose output
sudo bash -x install.sh 2>&1 | tee install.log
Services Won't Start
# Check status
sudo systemctl status eas-station.target
# Check individual service
sudo systemctl status eas-station-web.service
# View detailed logs
sudo journalctl -u eas-station-web.service -n 100 --no-pager
Database Issues
# Check if PostgreSQL is running
sudo systemctl status postgresql
# Test connection
sudo -u postgres psql -d alerts -c "SELECT version();"
# Check if user exists
sudo -u postgres psql -c "\du" | grep eas_station
Permission Issues
# Fix ownership
sudo chown -R eas-station:eas-station /opt/eas-station
sudo chown -R eas-station:eas-station /var/log/eas-station
# Fix permissions
sudo chmod -R 755 /opt/eas-station
sudo chmod 600 /opt/eas-station/.env
Summary
Installation is:
- ✅ Fully Automated - No manual steps during installation
- ✅ Non-Interactive - Runs without prompts (except OS warning)
- ✅ Complete - Installs and configures everything
- ✅ Idempotent - Safe to re-run if it fails
- ✅ Fast - 10-15 minutes on typical hardware
Configuration is:
- ✅ Auto-Generated -
.envfile created automatically - ✅ Secure by Default - Random SECRET_KEY, proper permissions
- ✅ Web-Based - All user settings configured via UI
- ✅ Standard Format - Uses industry-standard
.envformat
User Experience:
- Run one command
- Wait 10-15 minutes
- Open web browser
- Create account and configure
- Done!
No command-line configuration, no editing files with nano, no manual service management.
Alternative Installation Methods
Current Method: Bash Shell Script
The current install.sh provides an interactive TUI-based installation that:
- ✅ Works on any Debian/Ubuntu system without additional tools
- ✅ Provides visual feedback and progress indicators
- ✅ Handles all configuration in one session
- ✅ Requires only
bashandwhiptail(auto-installed) - ✅ Easy to debug and modify
- ⚠️ Must be run as root/sudo
- ⚠️ Not idempotent (can't safely re-run)
1. Ansible Playbook (Recommended for Production)
Pros:
- ✅ Idempotent - can safely re-run
- ✅ Version controlled configuration
- ✅ Multi-system deployment
- ✅ Role-based installation
- ✅ Better secret management (Ansible Vault)
- ✅ Built-in error handling and rollback
Cons:
- ❌ Requires Ansible to be installed first
- ❌ Steeper learning curve
- ❌ More complex for single-system installs
Implementation:
# playbook.yml
- hosts: eas_stations
roles:
- postgresql
- redis
- eas-station
vars:
eas_admin_user: admin
eas_state_code: OH
2. Docker / Docker Compose (Recommended for Development)
Pros:
- ✅ Isolated environment
- ✅ Easy to reset/rebuild
- ✅ No host system modifications
- ✅ Portable across platforms
- ✅ Built-in dependency management
Cons:
- ❌ SDR hardware access is complex
- ❌ GPIO access requires privileged mode
- ❌ Performance overhead
- ❌ Not suitable for production EAS
Implementation:
# Dockerfile
FROM python:3.12-slim
RUN apt-get update && apt-get install -y postgresql postgis redis
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
CMD ["gunicorn", "app:app"]
3. Debian Package (.deb)
Pros:
- ✅ Native package management
- ✅ Automatic dependency resolution
- ✅ Clean uninstall
- ✅ Version tracking
- ✅ Signed packages
Cons:
- ❌ Complex to create and maintain
- ❌ Still requires post-install configuration
- ❌ Debian/Ubuntu only
- ❌ Package repository hosting
Implementation:
# Build .deb package
dpkg-deb --build eas-station_1.0.0_amd64
# Install
sudo dpkg -i eas-station_1.0.0_amd64.deb
sudo apt-get install -f # Fix dependencies
4. Snap Package
Pros:
- ✅ Auto-updates
- ✅ Sandboxed
- ✅ Cross-distro (Ubuntu, Fedora, etc.)
- ✅ Centralized distribution
Cons:
- ❌ Hardware access restrictions
- ❌ Not suitable for SDR/GPIO
- ❌ Snapd overhead
5. Python Package (pip/PyPI)
Pros:
- ✅ Easy Python-based installation
- ✅ Virtual environment friendly
- ✅ Standard Python tooling
Cons:
- ❌ Doesn't handle system dependencies (PostgreSQL, Redis, nginx)
- ❌ No systemd service setup
- ❌ User must handle configuration
Implementation:
pip install eas-station
eas-station-setup # Interactive config wizard
6. Makefile-based Installation
Pros:
- ✅ Standard Unix tool
- ✅ Fine-grained control
- ✅ Parallel execution
- ✅ Dependency tracking
Cons:
- ❌ Less user-friendly than bash script
- ❌ No built-in prompting/TUI
- ❌ Makefiles can be complex
Recommendation Matrix
| Use Case | Best Method | Why |
|---|---|---|
| First-time user / single Pi | Current bash script | Interactive, simple, works immediately |
| Multiple stations | Ansible | Consistent deployment, centralized config |
| Development / testing | Docker Compose | Easy reset, isolated |
| Production (single) | Ansible or .deb | Professional, maintainable |
| Air-gapped systems | Bash script or .deb | No internet dependency |
| CI/CD pipeline | Docker | Automated testing |
Improving the Current Bash Script
Instead of replacing the bash script, we can improve it:
- Add idempotency checks - detect existing installation
- Configuration file support - accept pre-configured values
- Silent mode - non-interactive for automation
- Modular structure - separate functions for each component
- Better error recovery - rollback on failure
Example:
# Support pre-configured installation
sudo ./install.sh --config /path/to/config.env --silent
# Or interactive mode (current behavior)
sudo ./install.sh
Hybrid Approach (Recommended)
Keep the current bash script as the primary method but add:
- Ansible roles for multi-system deployment
- Docker Compose for development
- Configuration templates for automation
- --silent mode to the bash script for CI/CD
This gives users flexibility while maintaining simplicity for the common case.
Conclusion
The current bash script installation is appropriate and efficient for EAS Station's target audience because:
- Target users are familiar with command-line tools
- Single-system installation is the primary use case
- Hardware integration (SDR, GPIO) requires host access
- Real-time audio processing benefits from native installation
Recommendation: Keep the bash script, add silent/config mode for automation.
This document is served from docs/installation/INSTALLATION_DETAILS.md in the EAS Station installation.