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 checkout
the commit you want and runiop
again - 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 --> B4
Components
- 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: /up
Services (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/data
Zero-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 Blue
Network 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:
scp
orrsync
over existing SSH connection - Load on server:
docker load
from 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 redirect
State Management
Local State (Your Machine)
- Configuration:
iop.yml
and.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.com
Git-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:a1b2c3d
Benefits
- 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 endpoint
Implementation 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 config
This 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 & Services
Automatic 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.