Architecture

Understand how Haloy’s components work together to manage your deployments.

System Components

Haloy consists of several components working in harmony:

  1. Haloy CLI (haloy) - Command-line interface for deployments from your local machine
  2. Haloy Admin CLI (haloyadm) - Setup and administration tool for the server
  3. Haloy Daemon (haloyd) - Service discovery, configuration, and container orchestration
  4. HAProxy - External load balancer for SSL termination and traffic routing
  5. Application Containers - Your deployed applications orchestrated by haloyd

Component Overview

Haloy CLI (haloy)

Runs on: Your local development machine, CI/CD systems, or any machine that can reach your server’s API

Purpose: Trigger deployments and manage applications

Key Functions:

  • Read and validate configuration files
  • Build Docker images locally (optional)
  • Upload images to servers
  • Send deployment commands to haloyd API
  • Display deployment status and logs

Location: ~/.local/bin/haloy

See the full command reference for available commands.

Haloy Admin CLI (haloyadm)

Runs on: Your server

Purpose: Set up and administrate the Haloy daemon

Key Functions:

  • Initialize haloyd and HAProxy
  • Start/stop/restart services
  • Generate API tokens
  • Configure API domains and SSL

Location: /usr/local/bin/haloyadm (system) or ~/.local/bin/haloyadm (user)

See the full command reference for available commands.

Haloy Daemon (haloyd)

Runs on: Your server (as a Docker container)

Purpose: Container orchestration and service discovery

Key Functions:

  • Accept deployment commands via REST API
  • Pull or load Docker images
  • Start and stop application containers
  • Monitor container health
  • Generate HAProxy configuration dynamically
  • Manage SSL certificates via ACME (Let’s Encrypt)
  • Track deployment history for rollbacks

Configuration: /etc/haloy/haloyd.yaml or ~/.config/haloy/haloyd.yaml

Data storage: /var/lib/haloy/ or ~/.local/share/haloy/

HAProxy

Runs on: Your server (as a Docker container)

Purpose: Load balancing and SSL termination

Key Functions:

  • Route external traffic to application containers
  • SSL/TLS termination
  • HTTP to HTTPS redirects
  • Domain routing
  • Load balancing across replicas
  • Health check integration

Configuration: Auto-generated by haloyd

Listens on: Ports 80 (HTTP) and 443 (HTTPS)

Application Containers

Runs on: Your server

Purpose: Your deployed applications

Managed by: haloyd

Networking: Connected to Haloy’s Docker network

Health monitoring: Via configured health check endpoints

Architecture Diagram

┌─────────────────────┐ │ Developer Machine │ │ │ │ ┌──────────────┐ │ │ │ haloy CLI │ │ │ └──────┬───────┘ │ └─────────┼───────────┘ │ HTTPS │ (API calls) ┌─────────────────────────────────────────┐ │ Server │ │ │ │ ┌──────────────────┐ │ │ │ haloyd (Docker) │ │ │ │ │ │ │ │ - API Server │ │ │ │ - Orchestration │ │ │ │ - Service Disc. │ │ │ └────┬─────────────┘ │ │ │ Generates │ │ │ config │ │ ▼ │ │ ┌──────────────────┐ │ │ │ HAProxy (Docker) │ │ │ │ │ │ │ │ Ports: 80, 443 │ │ │ └────┬─────────────┘ │ │ │ Routes traffic │ │ │ │ │ ├──────────┬──────────┐ │ │ ▼ ▼ ▼ │ │ ┌────────┐ ┌────────┐ ┌────────┐ │ │ │ App │ │ App │ │ App │ │ │ │ (8080) │ │ (8080) │ │ (8080) │ │ │ └────────┘ └────────┘ └────────┘ │ │ Replica 1 Replica 2 Replica 3 │ └─────────────────────────────────────────┘

Traffic Flow

Incoming Requests

Internet ├─ HTTP (port 80) │ └─► HAProxy → Redirects to HTTPS └─ HTTPS (port 443) └─► HAProxy ├─ SSL Termination ├─ Domain Routing (my-app.com → my-app) └─► Load Balance ├─► App Container 1 (port 8080) ├─► App Container 2 (port 8080) └─► App Container 3 (port 8080)

Deployment Flow

Developer: haloy deploy └─► Build image locally (if configured) └─► Upload to server or push to registry └─► API call to haloyd ├─► haloyd pulls/loads image ├─► haloyd starts new containers ├─► haloyd waits for health checks ├─► haloyd updates HAProxy config ├─► HAProxy routes to new containers └─► haloyd stops old containers

Service Discovery

Haloy uses Docker labels for service discovery. You can leverage this feature in two ways:

  1. Via Haloy CLI - Deploy using haloy deploy (recommended)
  2. Direct container labels - Start containers manually with appropriate labels

Using Haloy CLI

The standard approach is to use haloy deploy which handles labeling automatically based on your configuration.

Using Container Labels Directly

You can start containers manually (using docker run, Docker Compose, or other orchestration tools) and haloyd will automatically discover and route traffic to them:

# Start a container with Haloy labels docker run -d \ --name my-app \ --network haloy \ --label dev.haloy.appName=my-app \ --label dev.haloy.deployment-id=manual-001 \ --label dev.haloy.role=app \ --label dev.haloy.domain.0=example.com \ --label dev.haloy.domain.0.alias.0=www.example.com \ --label dev.haloy.port=8080 \ --label dev.haloy.health-check-path=/health \ my-image:latest
# Docker Compose example services: my-app: image: my-image:latest networks: - haloy labels: dev.haloy.appName: my-app dev.haloy.deployment-id: manual-001 # Make sure to increment this manually for the changes to take effect dev.haloy.role: app dev.haloy.domain.0: example.com dev.haloy.domain.0.alias.0: www.example.com dev.haloy.port: "8080" dev.haloy.health-check-path: /health networks: haloy: external: true

Required labels:

  • dev.haloy.appName - Application identifier
  • dev.haloy.deployment-id - Unique deployment identifier
  • dev.haloy.role - Must be set to app
  • dev.haloy.domain.0 - Primary domain (use .1, .2 for additional domains)

Optional labels:

  • dev.haloy.port - Container port (default: 8080)
  • dev.haloy.health-check-path - Health check endpoint (default: /)
  • dev.haloy.domain.0.alias.0 - Domain alias (use .1, .2 for additional aliases)
  • dev.haloy.acme.email - Email for Let’s Encrypt certificates

Discovery Process:

  1. haloyd monitors Docker for labeled containers
  2. Extracts routing information from labels
  3. Generates HAProxy configuration
  4. Reloads HAProxy with zero downtime

This allows you to integrate Haloy’s routing and SSL management with your existing deployment workflows.

Networking

Docker Networks

Haloy creates and uses Docker networks:

  • haloy (default): Application containers and HAProxy
  • Custom networks: Via network configuration option

Port Mapping

HAProxy: - 80:80 (HTTP) - 443:443 (HTTPS) Application Containers: - No direct port exposure - Internal network only - HAProxy routes traffic

Data Storage

System Installation

/etc/haloy/ ├── haloyd.yaml # Daemon configuration └── .env # API tokens /var/lib/haloy/ ├── haproxy-config/ # HAProxy configurations ├── cert-storage/ # SSL certificates └── db/ # Deployment database

User Installation

~/.config/haloy/ ├── haloyd.yaml # Daemon configuration └── .env # API tokens ~/.local/share/haloy/ ├── haproxy-config/ # HAProxy configurations ├── cert-storage/ # SSL certificates └── db/ # Deployment database

SSL/TLS Certificates

Certificate Management:

  • Automatic via ACME (Let’s Encrypt)
  • Certificates stored in cert-storage/
  • Auto-renewal before expiration
  • Per-domain certificates

Process:

  1. Domain configured in haloy.yaml
  2. haloyd requests certificate from Let’s Encrypt
  3. ACME challenge validation (HTTP-01)
  4. Certificate issued and stored
  5. HAProxy configured to use certificate
  6. Auto-renewal 30 days before expiration

Health Checks

Flow:

HAProxy → Health Check → App Container (/health endpoint) │ │ │ ├─ 200 OK → Healthy │ └─ Other → Unhealthy └─ Routes traffic only to healthy containers

Check Frequency: Every few seconds

Actions on Failure:

  • Container marked unhealthy
  • Traffic stops routing to container
  • Container visible in haloy status as unhealthy

High Availability

Haloy achieves HA through:

  1. Multiple replicas: Run 3+ instances
  2. Health monitoring: Remove unhealthy containers from rotation
  3. Rolling deployments: Update without downtime
  4. Load balancing: Distribute traffic evenly
  5. Automatic recovery: Restart failed containers

Deployment Strategies

Rolling Deployment

Old containers: [1] [2] [3] │ │ │ Step 1: │ │ │ New [1] starts Step 2: │ │ │ New [1] healthy → Old [1] stops Step 3: │ │ │ New [2] starts Step 4: │ │ │ New [2] healthy → Old [2] stops Step 5: │ │ │ New [3] starts Step 6: │ │ │ New [3] healthy → Old [3] stops ▼ ▼ ▼ New containers: [1] [2] [3]

Replace Deployment

Old containers: [1] [2] [3] │ │ │ Step 1: Stop all old containers Step 2: Start all new containers Step 3: Wait for health checks ▼ ▼ ▼ New containers: [1] [2] [3]

Security

API Authentication:

  • API tokens generated by haloyadm
  • Tokens stored securely with restrictive permissions
  • HTTPS for all API communication (when domain configured)

Container Isolation:

  • Docker network isolation
  • No direct container exposure to internet
  • All traffic through HAProxy

SSL/TLS:

  • Automatic certificate management
  • Strong cipher suites
  • HTTP to HTTPS redirect

Scalability

Horizontal Scaling:

  • Add more replicas in configuration
  • Load balanced automatically
  • Linear scaling for stateless apps

Multi-Server:

  • Deploy to multiple servers
  • Independent server scaling
  • Geographic distribution

Monitoring

Built-in Monitoring:

  • Container health checks
  • Deployment status tracking
  • Application logs via haloy logs
  • Service status via haloy status

External Monitoring:

  • Expose health check endpoints
  • Monitor via Prometheus/Grafana
  • Alert on health check failures

Limitations

  1. Single server orchestration: Each server managed independently
  2. No automatic scaling: Manual replica configuration
  3. No built-in monitoring: Use external tools
  4. Docker required: All components run in Docker
  5. Linux only: Server must be Linux-based

Next Steps