diff --git a/.env.template b/.env.template new file mode 100644 index 0000000..3d9fa1f --- /dev/null +++ b/.env.template @@ -0,0 +1,26 @@ +# TAK Server Docker Compose Environment Variables +# Copy this file to .env and customize the values + +# Path to your TAK Server archive +TAK_ARCHIVE_PATH=/path/to/takserver-docker-5.4-RELEASE-19.zip + +# TAK Server Ports (adjust as needed for your environment) +TAK_HTTPS_PORT=8443 +TAK_CERT_PORT=8444 +TAK_FEDERATION_PORT=8446 +TAK_STREAMING_API_PORT=9000 +TAK_STREAMING_API_TLS_PORT=9001 + +# Reverse Proxy Configuration (optional) +# Set to true to enable reverse proxy with your own SSL cert +ENABLE_REVERSE_PROXY=false + +# Domain for your TAK Server (used by reverse proxy) +TAK_DOMAIN=takserver.example.com + +# SSL Certificate paths (for reverse proxy) +SSL_CERT_PATH=/path/to/your/ssl/cert.pem +SSL_KEY_PATH=/path/to/your/ssl/private.key + +# Optional: Override the default TAK archive path inside the container +# TAK_ARCHIVE_CONTAINER_PATH=/tak-archive/takserver-docker-5.4-RELEASE-19.zip diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 0000000..421ec08 --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,88 @@ +# TAK Server Docker Compose Deployment Guide + +## Quick Start + +1. **Copy the environment template**: + ```bash + cp .env.template .env + ``` + +2. **Edit the .env file** to set your TAK archive path: + ```bash + nano .env + ``` + Update the `TAK_ARCHIVE_PATH` to point to your actual TAK Server archive. + +3. **Deploy the stack**: + ```bash + docker-compose up -d + ``` + +4. **Monitor the deployment**: + ```bash + # Check service status + docker-compose ps + + # View logs + docker-compose logs -f takserver + docker-compose logs -f takserver-db + ``` + +## Configuration + +### Required Setup +- Set `TAK_ARCHIVE_PATH` in your `.env` file to point to your TAK Server archive +- Ensure the archive file is accessible to Docker + +### Optional Configuration +- Modify port mappings in `.env` if you have port conflicts +- Adjust healthcheck settings in `docker-compose.yml` if needed + +## Management Commands + +```bash +# Start the services +docker-compose up -d + +# Stop the services +docker-compose down + +# Restart services +docker-compose restart + +# Update to latest image +docker-compose pull +docker-compose up -d + +# View service logs +docker-compose logs -f [service-name] + +# Access TAK Server shell +docker-compose exec takserver bash + +# Access database shell +docker-compose exec takserver-db psql -U postgres +``` + +## Accessing TAK Server + +Once deployed, TAK Server will be available at: +- **Web UI**: https://localhost:8443 +- **Certificate Enrollment**: https://localhost:8444 +- **Federation**: Port 8446 +- **Streaming API**: Port 9000 (HTTP), 9001 (HTTPS) + +## Data Persistence + +The following data is persisted across container restarts: +- Database data in `takserver-db-data` volume +- TAK Server logs in `takserver-logs` volume +- SSL certificates in `takserver-certs` volume +- Configuration files in `takserver-config` volume + +## Troubleshooting + +- **Services not starting**: Check that your TAK archive path is correct in `.env` +- **Port conflicts**: Modify the port mappings in `.env` +- **Database connection issues**: Wait for the database healthcheck to pass before the server starts +- **Certificate issues**: Check the `takserver-certs` volume for SSL certificate files diff --git a/Dockerfile b/Dockerfile index 05546cf..5865c5a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1 +1,25 @@ -FROM alpine:3.12 \ No newline at end of file +FROM postgres:15.1 + +# Install required packages +RUN apt-get update && apt install -y \ + postgresql-15-postgis-3 \ + openjdk-17-jdk \ + emacs-nox \ + net-tools \ + netcat \ + vim \ + unzip \ + && rm -rf /var/lib/apt/lists/* + +# Create the tak directory and logs directory +RUN mkdir -p /opt/tak /opt/tak/logs + +# Create entrypoint script that handles TAK archive extraction +COPY entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + +# Set environment variables +ENV TAK_MODE=server +ENV TAK_ARCHIVE_PATH=/tak-archive/takserver-docker-5.4-RELEASE-19.zip + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..65c97a4 --- /dev/null +++ b/README.md @@ -0,0 +1,242 @@ +# TAK Server Docker Setup + +This directory contains a unified Docker configuration for running TAK Server components. + +## Prerequisites + +You must have the official TAK Server Docker release archive. The archive should be in ZIP format and contain both `docker` and `tak` folders. + +## Setup Instructions + +1. **Build the Docker Image**: + ```bash + docker build -t takserver . + ``` + +2. **Run TAK Server**: + ```bash + docker run -d --name takserver \ + -e TAK_MODE=server \ + -v /path/to/your/takserver-docker-5.4-RELEASE-19.zip:/tak-archive/takserver-docker-5.4-RELEASE-19.zip:ro \ + takserver + ``` + +3. **Run TAK Database**: + ```bash + docker run -d --name takserver-db \ + -e TAK_MODE=database \ + -v /path/to/your/takserver-docker-5.4-RELEASE-19.zip:/tak-archive/takserver-docker-5.4-RELEASE-19.zip:ro \ + takserver + ``` + +4. **Alternative: Mount the archive directory** (for automatic latest version detection): + ```bash + # Mount the directory containing TAK archives + docker run -d --name takserver \ + -e TAK_MODE=server \ + -v /path/to/tak-archives-directory:/tak-archive:ro \ + takserver + ``` + +## How It Works + +- **Unified Image**: One Docker image serves both TAK Server and Database functions +- **Mode Selection**: Use the `TAK_MODE` environment variable to choose between `server` (default) or `database` +- **Runtime Extraction**: The container checks for and extracts the TAK archive on startup +- **Automatic Version Detection**: If you mount a directory, the container will automatically find and use the latest TAK archive +- **Flexibility**: The same image can be used with different TAK archive versions +- **Persistence**: Once extracted, the TAK files persist in the container until it's removed + +## File Structure Expected + +Your TAK Server archive should have this structure: +``` +takserver-docker-5.4-RELEASE-19.zip +├── docker/ # Docker-related files (not used) +└── tak/ # TAK Server files (this is what gets copied) + ├── configureInDocker.sh + ├── db-utils/ + │ └── configureInDocker.sh + └── ... (other TAK files) +``` + +## Environment Variables + +- `TAK_MODE`: Set to `server` (default) or `database` to determine the container's function +- `TAK_ARCHIVE_PATH`: Override the default TAK archive path (default: `/tak-archive/takserver-docker-5.4-RELEASE-19.zip`) + +## Usage Notes + +- The TAK archive is mounted as read-only (`ro`) to prevent accidental modifications +- **Server Mode**: Starts automatically with the `configureInDocker.sh init` command +- **Database Mode**: Starts with the database configuration script +- Logs will be written to `/opt/tak/logs/takserver.log` in server mode +- The container will extract the TAK archive on first run and reuse the extracted files on subsequent runs + +## Data Persistence + +To persist data across container restarts and updates, you should mount the following directories: + +### TAK Server Data Volumes: +- `/opt/tak/logs` - TAK Server logs +- `/opt/tak/certs` - SSL certificates and keys +- `/opt/tak/conf` - Configuration files +- `/opt/tak/db-utils/pg_hba.conf` - PostgreSQL authentication configuration + +### Database Data Volumes (when using TAK_MODE=database): +- `/var/lib/postgresql/data` - PostgreSQL database files +- `/opt/tak/db-utils/logs` - Database utility logs + +### Example with Data Persistence: + +```bash +# TAK Server with persistent data +docker run -d --name takserver \ + -e TAK_MODE=server \ + -v /path/to/takserver-docker-5.4-RELEASE-19.zip:/tak-archive/takserver-docker-5.4-RELEASE-19.zip:ro \ + -v takserver-logs:/opt/tak/logs \ + -v takserver-certs:/opt/tak/certs \ + -v takserver-config:/opt/tak/conf \ + takserver + +# TAK Database with persistent data +docker run -d --name takserver-db \ + -e TAK_MODE=database \ + -v /path/to/takserver-docker-5.4-RELEASE-19.zip:/tak-archive/takserver-docker-5.4-RELEASE-19.zip:ro \ + -v takserver-db-data:/var/lib/postgresql/data \ + -v takserver-db-logs:/opt/tak/db-utils/logs \ + takserver +``` + +## Docker Compose Example + +```yaml +version: '3.8' +services: + takserver-db: + image: takserver + environment: + - TAK_MODE=database + volumes: + - /path/to/takserver-docker-5.4-RELEASE-19.zip:/tak-archive/takserver-docker-5.4-RELEASE-19.zip:ro + - takserver-db-data:/var/lib/postgresql/data + - takserver-db-logs:/opt/tak/db-utils/logs + container_name: takserver-db + + takserver: + image: takserver + environment: + - TAK_MODE=server + volumes: + - /path/to/takserver-docker-5.4-RELEASE-19.zip:/tak-archive/takserver-docker-5.4-RELEASE-19.zip:ro + - takserver-logs:/opt/tak/logs + - takserver-certs:/opt/tak/certs + - takserver-config:/opt/tak/conf + container_name: takserver + depends_on: + - takserver-db + +volumes: + takserver-db-data: + takserver-db-logs: + takserver-logs: + takserver-certs: + takserver-config: +``` + +## Reverse Proxy with Custom SSL Certificate + +You can use a reverse proxy (like Nginx, Traefik, or Caddy) to terminate SSL with your own certificate instead of using TAK Server's built-in SSL. This is recommended for production deployments. + +### Benefits: +- Use your own SSL certificates (Let's Encrypt, corporate CA, etc.) +- Centralized certificate management +- Better security practices +- Easier certificate renewal + +### Basic Nginx Configuration Example: + +```nginx +upstream takserver { + server takserver:8443; +} + +server { + listen 443 ssl http2; + server_name your-domain.com; + + ssl_certificate /path/to/your/cert.pem; + ssl_certificate_key /path/to/your/private.key; + + # SSL security settings + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384; + ssl_prefer_server_ciphers off; + + # Proxy to TAK Server + location / { + proxy_pass https://takserver; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # Important for WebSocket connections + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + # SSL verification settings for upstream + proxy_ssl_verify off; + proxy_ssl_session_reuse on; + } +} +``` + +### Docker Compose with Nginx Reverse Proxy: + +```yaml +version: '3.8' + +services: + # ... your existing takserver and takserver-db services ... + + nginx: + image: nginx:alpine + ports: + - "443:443" + - "80:80" + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf:ro + - /path/to/your/ssl-certs:/etc/nginx/ssl:ro + depends_on: + - takserver + networks: + - takserver-network +``` + +### Configuration Notes: + +1. **Remove External Port Mapping**: When using a reverse proxy, remove the port mappings from the `takserver` service in docker-compose.yml since the proxy will handle external access. + +2. **Internal Communication**: TAK Server will still use its internal SSL certificate for communication between the reverse proxy and the container. + +3. **Certificate Management**: Your reverse proxy handles the public-facing SSL certificate, while TAK Server's internal certificate is only used for proxy-to-container communication. + +4. **WebSocket Support**: Ensure your reverse proxy configuration supports WebSocket upgrades for real-time features. + +5. **Security Headers**: Consider adding security headers in your reverse proxy configuration for enhanced security. + +### Alternative: Traefik with Automatic Let's Encrypt + +For automatic SSL certificate management, consider using Traefik: + +```yaml +# Add labels to your takserver service +labels: + - "traefik.enable=true" + - "traefik.http.routers.takserver.rule=Host(`your-domain.com`)" + - "traefik.http.routers.takserver.tls.certresolver=letsencrypt" + - "traefik.http.services.takserver.loadbalancer.server.port=8443" + - "traefik.http.services.takserver.loadbalancer.server.scheme=https" +``` diff --git a/Readme.md b/Readme.md deleted file mode 100644 index 2904b26..0000000 --- a/Readme.md +++ /dev/null @@ -1,36 +0,0 @@ -# README for Docker Image Build and Publish Workflows - -## Overview - -This repository contains two GitHub Actions workflows that automate the building and publishing of Docker images to an OCI registry. - -### Workflows - -1. **On Commit to Main** - - **Trigger:** Activates on commits to the `main` branch (tags are excluded). - - **Purpose:** Builds and publishes a Docker image for each commit. - -2. **On Tag Push** - - **Trigger:** Activates when a new tag is pushed. - - **Purpose:** Builds and publishes a Docker image for the tag and tags it as `latest`. - -## Prerequisites - -- **Secrets Needed:** - - `OCI_TOKEN`: Your OCI registry token. - - `OCI_USER`: Your OCI registry username. - -## How to Use - -1. **Clone the Repository:** Get a local copy of this repository. -2. **Modify Dockerfile:** Update the `Dockerfile` for your application. -3. **Push Changes:** Push changes to the `main` branch or create a new tag. -4. **Check Workflow Status:** View the Actions tab in Forgjo to monitor workflow runs. - -## Notes - -- Ensure your Docker environment is compatible with multi-platform builds if necessary. - -## License - -This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..248d8a8 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,73 @@ +version: '3.8' + +services: + takserver-db: + image: git.merith.xyz/oci/takserver:nightly + environment: + - TAK_MODE=database + volumes: + # TAK Archive - replace with your actual archive path + - ${TAK_ARCHIVE_PATH:-/path/to/takserver-docker-5.4-RELEASE-19.zip}:/tak-archive/takserver-docker-5.4-RELEASE-19.zip:ro + # Persistent data volumes + - takserver-db-data:/var/lib/postgresql/data + - takserver-db-logs:/opt/tak/db-utils/logs + container_name: takserver-db + restart: unless-stopped + networks: + - takserver-network + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + + takserver: + image: git.merith.xyz/oci/takserver:nightly + environment: + - TAK_MODE=server + volumes: + # TAK Archive - replace with your actual archive path + - ${TAK_ARCHIVE_PATH:-/path/to/takserver-docker-5.4-RELEASE-19.zip}:/tak-archive/takserver-docker-5.4-RELEASE-19.zip:ro + # Persistent data volumes + - takserver-logs:/opt/tak/logs + - takserver-certs:/opt/tak/certs + - takserver-config:/opt/tak/conf + container_name: takserver + restart: unless-stopped + depends_on: + takserver-db: + condition: service_healthy + networks: + - takserver-network + ports: + # Common TAK Server ports - adjust as needed + - "${TAK_HTTPS_PORT:-8443}:8443" # HTTPS Web UI + - "${TAK_CERT_PORT:-8444}:8444" # Certificate enrollment + - "${TAK_FEDERATION_PORT:-8446}:8446" # Federation + - "${TAK_STREAMING_API_PORT:-9000}:9000" # Streaming API + - "${TAK_STREAMING_API_TLS_PORT:-9001}:9001" # Streaming API TLS + healthcheck: + test: ["CMD-SHELL", "curl -f https://localhost:8443/Marti/api/version/config || exit 1"] + interval: 60s + timeout: 10s + retries: 3 + start_period: 120s + +# Named volumes for data persistence +volumes: + takserver-db-data: + driver: local + takserver-db-logs: + driver: local + takserver-logs: + driver: local + takserver-certs: + driver: local + takserver-config: + driver: local + +# Network for inter-container communication +networks: + takserver-network: + driver: bridge diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..a3127cb --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,130 @@ +#!/bin/bash + +# TAK Server Unified Entrypoint Script +# This script handles both TAK Server and Database modes + +set -e + +TAK_ARCHIVE_PATH="${TAK_ARCHIVE_PATH:-/tak-archive/takserver-docker-5.4-RELEASE-19.zip}" +TAK_ARCHIVE_DIR="/tak-archive" +TAK_INSTALL_DIR="/opt/tak" +TAK_MODE="${TAK_MODE:-server}" + +# Function to log messages +log() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" +} + +# Function to find the latest TAK archive +find_latest_tak_archive() { + local latest_archive="" + + # Check if the specific archive exists + if [ -f "$TAK_ARCHIVE_PATH" ]; then + log "Found specified TAK archive: $TAK_ARCHIVE_PATH" + echo "$TAK_ARCHIVE_PATH" + return 0 + fi + + # Look for any takserver-docker-*.zip files in the archive directory + if [ -d "$TAK_ARCHIVE_DIR" ]; then + latest_archive=$(find "$TAK_ARCHIVE_DIR" -name "takserver-docker-*.zip" -type f | sort -V | tail -n 1) + + if [ -n "$latest_archive" ]; then + log "Found latest TAK archive: $latest_archive" + echo "$latest_archive" + return 0 + fi + fi + + # If no archive found, return empty + echo "" + return 1 +} + +# Function to check if TAK is already installed +is_tak_installed() { + if [ "$TAK_MODE" = "database" ]; then + [ -f "$TAK_INSTALL_DIR/db-utils/configureInDocker.sh" ] && [ -x "$TAK_INSTALL_DIR/db-utils/configureInDocker.sh" ] + else + [ -f "$TAK_INSTALL_DIR/configureInDocker.sh" ] && [ -x "$TAK_INSTALL_DIR/configureInDocker.sh" ] + fi +} + +# Function to extract TAK archive +extract_tak_archive() { + local archive_path + archive_path=$(find_latest_tak_archive) + + if [ -z "$archive_path" ]; then + log "ERROR: No TAK archive found" + log "Please mount your TAK Server archive to the /tak-archive directory." + log "Expected format: takserver-docker-X.X-RELEASE-XX.zip" + log "Example: docker run -v /path/to/takserver-docker-5.4-RELEASE-19.zip:/tak-archive/takserver-docker-5.4-RELEASE-19.zip ..." + log "Or mount the directory: docker run -v /path/to/tak-archives:/tak-archive ..." + exit 1 + fi + + log "Extracting TAK archive from $archive_path" + + # Create temporary directory for extraction + TEMP_DIR=$(mktemp -d) + + # Extract the archive (handling both .zip and .tar.gz formats) + if [[ "$archive_path" == *.zip ]]; then + unzip -q "$archive_path" -d "$TEMP_DIR" + else + tar -xzf "$archive_path" -C "$TEMP_DIR" + fi + + # Copy the tak folder contents to /opt/tak + if [ -d "$TEMP_DIR/tak" ]; then + log "Copying TAK files to $TAK_INSTALL_DIR" + cp -r "$TEMP_DIR/tak/"* "$TAK_INSTALL_DIR/" + + # Set proper permissions + [ -f "$TAK_INSTALL_DIR/configureInDocker.sh" ] && chmod +x "$TAK_INSTALL_DIR/configureInDocker.sh" + [ -f "$TAK_INSTALL_DIR/db-utils/configureInDocker.sh" ] && chmod +x "$TAK_INSTALL_DIR/db-utils/configureInDocker.sh" + + # Clean up temporary directory + rm -rf "$TEMP_DIR" + + log "TAK archive extracted successfully" + else + log "ERROR: TAK archive does not contain expected 'tak' folder structure" + log "Archive contents:" + ls -la "$TEMP_DIR" + rm -rf "$TEMP_DIR" + exit 1 + fi +} + +# Main execution +if [ "$TAK_MODE" = "database" ]; then + log "Starting TAK Server Database container..." +else + log "Starting TAK Server container..." +fi + +# Check if TAK is already installed +if ! is_tak_installed; then + log "TAK not found in $TAK_INSTALL_DIR, checking for archive..." + extract_tak_archive +else + log "TAK already installed in $TAK_INSTALL_DIR" +fi + +# Verify TAK installation +if ! is_tak_installed; then + log "ERROR: TAK installation verification failed" + exit 1 +fi + +# Execute the appropriate command based on mode +if [ "$TAK_MODE" = "database" ]; then + log "Starting TAK Database configuration" + exec /opt/tak/db-utils/configureInDocker.sh +else + log "Starting TAK Server with configureInDocker.sh init" + exec /bin/bash -c "/opt/tak/configureInDocker.sh init &>> /opt/tak/logs/takserver.log" +fi