Core Concepts
Understanding how iop works under the hood
Core Concepts
Understanding the key concepts behind iop will help you deploy with confidence and troubleshoot issues effectively.
Philosophy
iop is built on a simple philosophy: own your infrastructure without the complexity.
No Rollback Commands Needed
Instead of complex rollback mechanisms, iop embraces Git as the source of truth:
- Want to rollback? Just 
git checkoutthe commit you want and runiopagain - Every deployment is tagged with the Git SHA for easy identification
 - Rollbacks are just another deployment, using the same reliable process
 
Architecture Overview
graph TB
    A[Your Machine] -->|SSH + Docker Save/Load| B[Your Servers]
    
    subgraph "Local (Your Machine)"
        A1[iop CLI]
        A2[Docker Build]
        A3[Git SHA]
    end
    
    subgraph "Server"
        B1[iop Proxy]
        B2[Blue Container]
        B3[Green Container]
        B4[Services]
    end
    
    A1 --> A2
    A2 --> A3
    B1 --> B2
    B1 --> B3
    B --> B4Components
- iop CLI (TypeScript) - Your local command-line tool
 - iop Proxy (Go) - Reverse proxy running on your servers
 - Docker - Container runtime (installed automatically if needed)
 
Apps vs Services
iop treats different types of workloads differently to optimize for their use cases:
Apps (Zero-Downtime)
Apps are user-facing applications that need zero-downtime deployments:
- ✅ Built locally and transferred via SSH
 - ✅ Blue-green deployment strategy
 - ✅ Health checks before traffic switching
 - ✅ Automatic rollback on failure
 - ✅ SSL termination and routing via proxy
 
Examples: Web applications, APIs, microservices
apps:
  web:
    server: your-server.com # Single server per app
    build:
      context: .
      dockerfile: Dockerfile
    proxy:
      app_port: 3000
      hosts:
        - example.com
    health_check:
      path: /upServices (Direct Replacement)
Services are infrastructure components that can tolerate brief downtime:
- ✅ Use pre-built Docker images
 - ✅ Direct container replacement
 - ✅ Persistent volumes preserved
 - ✅ Quick restart for updates
 
Examples: Databases, message queues, caches, monitoring tools
services:
  postgres:
    image: postgres:17
    server: db.example.com
    ports:
      - "5432:5432"
    environment:
      secret:
        - POSTGRES_PASSWORD
    volumes:
      - postgres_data:/var/lib/postgresql/dataZero-Downtime Deployments (Blue-Green)
iop achieves zero-downtime deployments using a blue-green strategy with Docker network aliases:
How It Works
- Current State: Traffic flows to "blue" container via network alias
 - New Deployment: Start "green" container with new version
 - Health Check: Verify green container is healthy
 - Atomic Switch: Change network alias from blue to green
 - Cleanup: Remove old blue container
 
sequenceDiagram
    participant P as Proxy
    participant A as App Alias
    participant B as Blue Container
    participant G as Green Container
    
    P->>A: Traffic
    A->>B: Forward to Blue
    
    Note over G: Deploy Green
    G->>G: Start & Health Check
    
    Note over A: Atomic Switch
    A->>G: Forward to Green
    
    Note over B: Cleanup
    B->>B: Remove BlueNetwork Aliases
The magic happens with Docker network aliases:
- Both blue and green containers join the same Docker network
 - Traffic is routed via a shared alias (e.g., 
myapp-web) - Switching the alias is atomic and instant
 - No external load balancer configuration needed
 
Example Flow
❯ iop
Using Git SHA for release ID: a1b2c3d
[✓] Building new version (green)
[✓] Health checking green version
[✓] Switching traffic: blue → green
[✓] Stopping old version (blue)Registry-Free Deployment
Unlike most deployment tools, iop doesn't require Docker registries:
Traditional Approach (with Registry)
graph LR
    A[Local Build] --> B[Push to Registry]
    B --> C[Server Pull from Registry]
    C --> D[Deploy]iop Approach (Registry-Free)
graph LR
    A[Local Build] --> B[Docker Save]
    B --> C[SSH Transfer]
    C --> D[Docker Load]
    D --> E[Deploy]Benefits
- No registry costs - Save money on Docker Hub Pro, ECR, etc.
 - No registry complexity - No authentication, access control, or availability concerns
 - Better security - Images never leave your control
 - Faster for small teams - No registry bottlenecks
 
How It Works
- Build locally: 
docker build -t myapp:sha123 . - Save to tar: 
docker save myapp:sha123 | gzip - Transfer via SSH: 
scporrsyncover existing SSH connection - Load on server: 
docker loadfrom the transferred tar - Deploy: Start containers using the loaded image
 
Automatic Infrastructure Setup
iop automatically prepares your servers without separate "setup" commands:
Fresh Server Bootstrap
When you run iop for the first time on a server, it automatically:
- Installs Docker (if not present)
 - Creates Docker networks for app communication
 - Deploys iop proxy for SSL and routing
 - Configures security hardening (firewall, fail2ban)
 - Sets up SSL automation with Let's Encrypt
 
No Separate Setup Command
Unlike other tools, iop doesn't require a separate iop setup command:
- Infrastructure setup happens automatically during deployment
 - Servers are configured on first deployment
 - Updates and changes are applied incrementally
 
Proxy and SSL Management
The iop proxy is a lightweight Go application that handles:
Reverse Proxy
- Routes incoming requests to the correct application containers
 - Load balances between multiple replicas
 - Handles SSL termination
 - Provides health check endpoints
 
SSL Certificate Management
- Automatic certificate acquisition via Let's Encrypt
 - Certificate renewal (happens automatically before expiration)
 - Multiple domains supported per application
 - Staging mode available for development/testing
 
HTTP to HTTPS Redirect
- Automatic HTTP to HTTPS redirects (configurable)
 - HSTS headers for enhanced security
 - Support for custom SSL configurations
 
apps:
  web:
    proxy:
      hosts:
        - myapp.com
        - www.myapp.com
      ssl: true # Automatic HTTPS (default)
      ssl_redirect: true # HTTP to HTTPS redirectState Management
Local State (Your Machine)
- Configuration: 
iop.ymland.iop/secrets - Git repository: Source of truth for deployments
 - Docker images: Built locally before deployment
 
Server State
- iop proxy state: Stored in 
/var/lib/iop-proxy/state.json - Container state: Managed by Docker
 - Volume data: Persisted in Docker volumes
 - SSL certificates: Stored by Let's Encrypt/proxy
 
No Central Database
iop doesn't require a central database or control plane:
- Each server maintains its own state
 - Configuration is distributed via SSH
 - Git serves as the coordination mechanism
 - Simpler architecture, fewer failure points
 
Multi-Server Support
iop supports deploying across multiple servers:
Deployment Strategy
- Each app/service instance targets a single server
 - Multiple instances can target different servers
 - Load balancing happens at the DNS/CDN level
 - Each server runs independently
 
Example Multi-Server Setup
apps:
  web-us-east:
    server: us-east.example.com
    proxy:
      hosts:
        - us-east.myapp.com
  
  web-eu-west:
    server: eu-west.example.com
    proxy:
      hosts:
        - eu-west.myapp.com
  web-primary:
    server: primary.example.com
    proxy:
      hosts:
        - myapp.com
        - www.myapp.comGit-Based Releases
iop uses Git SHAs as release identifiers:
Release ID Generation
- Clean working directory: Uses current Git SHA
 - Uncommitted changes: Prompts to commit first
 - No Git repository: Generates timestamp-based ID
 
Docker Image Tagging
Images are tagged with the Git SHA:
my-app/web:a1b2c3d
my-app/api:a1b2c3dBenefits
- Traceability - Every deployment linked to specific code
 - Rollbacks - Easy to identify and return to previous versions
 - Debugging - Know exactly what code is running in production
 - Collaboration - Team can see what's deployed via Git history
 
Health Checks
Health checks are fundamental to zero-downtime deployments:
How They Work
- New container starts with your application
 - Health check begins (default: HTTP GET /up)
 - Retries until healthy (or timeout)
 - Traffic switches only after health check passes
 - Old container removed after successful switch
 
Default Configuration
apps:
  web:
    health_check:
      path: /up # Default endpointImplementation Examples
// Express.js health check
app.get('/up', async (req, res) => {
  try {
    // Check database connectivity
    await db.ping();
    
    // Check external dependencies
    await redis.ping();
    
    // All good!
    res.status(200).send('OK');
  } catch (error) {
    // Something's wrong, don't switch traffic
    res.status(503).send('Not ready');
  }
});// Go health check
http.HandleFunc("/up", func(w http.ResponseWriter, r *http.Request) {
    // Check dependencies
    if err := db.Ping(); err != nil {
        w.WriteHeader(http.StatusServiceUnavailable)
        return
    }
    
    w.WriteHeader(http.StatusOK)
    w.Write([]byte("OK"))
})Health Check Failures
If health checks fail:
- No traffic switch occurs
 - Old container keeps running (zero downtime maintained)
 - New container is removed automatically
 - Deployment marked as failed
 - Detailed logs available for debugging
 
Scaling and Replicas
iop supports horizontal scaling via replicas:
How Replicas Work
apps:
  web:
    replicas: 3
    # ... other configThis creates:
myapp-web-blue-1,myapp-web-blue-2,myapp-web-blue-3- All containers share the same network alias
 - Docker's built-in load balancing distributes requests
 - Blue-green deployments work across all replicas
 
Benefits
- Higher throughput - Multiple containers handle requests
 - Better reliability - If one container fails, others continue
 - Rolling updates - Can deploy one replica at a time
 - No external load balancer needed - Docker handles it
 
Networking
iop creates isolated Docker networks for container communication:
Network Architecture
Internet → iop Proxy → Project Network → Your Apps & ServicesAutomatic Service Discovery
Apps and services can communicate using their names:
// In your app, connect to database service
const db = new Client({
  host: "postgres", // Service name from iop.yml
  port: 5432,
});Network Naming
- Project network: 
{project-name}-network - Container names: 
{project-name}-{app-name}-{color}(for apps) - Service containers: 
{project-name}-{service-name}(for services) 
Volume Management
iop handles volumes intelligently:
Named Volumes
volumes:
  - postgres_data:/var/lib/postgresql/data- Persistent across deployments - Data survives container restarts
 - Managed by Docker - No manual cleanup needed
 - Shared across replicas - Multiple containers can access same volume
 
Bind Mounts
volumes:
  - ./config:/app/config:ro- Direct access to host filesystem - Good for configuration files
 - Real-time updates - Changes on host immediately visible in container
 - Use sparingly - Can break containerization benefits
 
Security Model
iop follows security best practices:
SSH-Based Security
- Uses your existing SSH keys and access
 - No additional authentication required
 - Leverages proven SSH security model
 - Works with SSH jump hosts, bastion servers, etc.
 
Secrets Management
# .iop/secrets - stored locally, never transmitted in plain text
DATABASE_URL=postgres://...
API_KEY=secret-key- Secrets stored locally in 
.iop/secrets - Transmitted securely over SSH
 - Available as environment variables in containers
 - Never stored in logs or configuration files
 - Automatically added to 
.gitignore 
Network Security
- Minimal ports open - Only 22 (SSH), 80/443 (HTTP/S), 8080 (proxy API)
 - Internal networks - Containers communicate via private Docker networks
 - No external database - All state stored locally on servers
 
Automatic Security Hardening
When setting up fresh servers, iop automatically:
- Configures firewall rules
 - Sets up fail2ban for SSH protection
 - Configures non-root container execution
 - Sets up automatic security updates
 
Error Handling and Recovery
iop is designed to fail safely:
Deployment Failures
- Health check fails: Old container keeps running
 - Build fails: No deployment attempted
 - SSH fails: Clear error message with suggestions
 - Resource constraints: Graceful handling and cleanup
 
Automatic Recovery
- Proxy restarts: Automatic container restart on failure
 - Certificate renewal: Automatic renewal before expiration
 - Container crashes: Docker restart policies handle recovery
 
Manual Recovery
- Check status: 
iop status --verbose - View logs: 
iop proxy logs - Rollback: 
git checkout <previous-sha> && iop 
Command Overview
iop provides four main commands:
iop init
Initialize project configuration files (iop.yml and .iop/secrets)
iop (Default: Deploy)
Deploy apps and services with automatic infrastructure setup
iop status
Check deployment status across all servers with detailed information
iop proxy
Manage the reverse proxy (status, update, logs, delete-host)
Understanding these concepts will help you design and deploy robust applications with iop. Each concept builds on the others to provide a complete, reliable deployment solution.