Quick Start
Deploy your first application with iop in minutes
Quick Start
Get your first application deployed with iop in just a few minutes. This guide will walk you through creating a simple web application and deploying it to your server.
Prerequisites
Before you begin, make sure you have:
- A server with SSH access (Ubuntu/Debian recommended)
 - Docker installed locally for building images
 - A domain name pointing to your server (optional, but recommended for SSL)
 
Step 1: Initialize Your Project
Navigate to your project directory and initialize iop:
cd your-project
iop initYou'll be prompted for a project name, or you can use non-interactive mode:
iop init --name my-app --non-interactiveThis creates two files:
iop.yml- Your deployment configuration.iop/secrets- Secure credentials storage (automatically added to.gitignore)
Step 2: Configure Your Deployment
Edit the generated iop.yml file:
name: my-app
ssh:
  username: iop # or root, or your deployment user
apps:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    server: your-server.com # Replace with your server IP or domain
    environment:
      plain:
        - NODE_ENV=production
      secret:
        - DATABASE_URL # Optional: from .iop/secrets
    proxy:
      app_port: 3000 # Port your app runs on inside the container
    health_check:
      path: /up # Health check endpoint (default: /up)
# Optional: Add a database service
# services:
#   db:
#     image: postgres:17
#     server: your-server.com
#     ports:
#       - "5432:5432"
#     environment:
#       plain:
#         - POSTGRES_USER=postgres
#         - POSTGRES_DB=my-app
#       secret:
#         - POSTGRES_PASSWORD
#     volumes:
#       - ./pgdata:/var/lib/postgresql/dataKey Configuration Options
name- Your project name (used for Docker networks and container naming)server- Your server IP or domain nameproxy.app_port- Port your application runs on inside the containerbuild.context- Docker build context (usually.)health_check.path- Health check endpoint (default:/up)
Step 3: Add Secrets (Optional)
If your app needs environment variables with sensitive values, add them to .iop/secrets:
# .iop/secrets
DATABASE_URL=postgres://user:pass@localhost:5432/myapp
API_KEY=your-secret-api-key
POSTGRES_PASSWORD=supersecretImportant: .iop/secrets is automatically added to your .gitignore file for security.
Step 4: Prepare Your Dockerfile
Make sure you have a Dockerfile in your project. Here's a simple example for a Node.js app:
FROM node:18-alpine
WORKDIR /app
# Copy package files
COPY package*.json ./
RUN npm ci --only=production
# Copy source code
COPY . .
# Build the app (if needed)
RUN npm run build
EXPOSE 3000
# Start the application
CMD ["npm", "start"]Important: Health Check Endpoint
Your app must implement a health check endpoint. By default, iop expects /up:
// Express.js example
app.get("/up", (req, res) => {
  res.status(200).send("OK");
});You can customize the health check path in iop.yml:
health_check:
  path: /api/health # Custom health check endpointStep 5: Deploy!
Deploy your application with a single command:
iopThat's it! iop will automatically:
- ✅ Build your Docker image locally
 - ✅ Set up your server if needed (install Docker, create networks, set up proxy)
 - ✅ Transfer the image securely via SSH (no registry required)
 - ✅ Deploy with zero downtime using blue-green deployment
 - ✅ Configure the reverse proxy for routing and SSL
 - ✅ Verify health checks before switching traffic
 
Example Output
❯ iop
Using Git SHA for release ID: a1b2c3d
Starting deployment with release a1b2c3d
[✓] Configuration loaded (0ms)
[✓] Git status verified (3ms)
[✓] Infrastructure ready (1.2s)
Building Images
  [✓] web → my-app/web:a1b2c3d (45.2s)
Deploying to Servers
  └─ your-server.com
     ├─ [✓] Loading image (3.2s)
     ├─ [✓] Zero-downtime deployment (2.8s)
     └─ [✓] Configuring proxy (0.8s)
[✓] Deployment completed successfully in 52.1s
Your app is live at:
  └─ https://your-server.com (web)Step 6: Verify Your Deployment
Check the status of your deployment:
iop statusOutput:
❯ iop status
📱 App: web
   Status: ✅ RUNNING (green active)
   Replicas: 1/1 running
   Image: my-app/web:a1b2c3d
   Servers: your-server.com
   Last Deployed: 2 minutes ago
   Uptime: 2m 15s
   Resource Usage: CPU 2.3%, Memory 125MB
🔧 Proxy Status:
   your-server.com: ✅ RUNNING (port 80, 443)
   - Version: elitan/iop-proxy:latest
   - Uptime: 2m 30s
   - Active routes: 1Visit your domain - it should be live with automatic HTTPS!
What Happened Behind the Scenes?
During deployment, iop:
- Validated configuration and checked git status
 - Built your Docker image locally using your Dockerfile
 - Set up the server automatically:
- Installed Docker (if needed)
 - Created Docker networks
 - Deployed the iop reverse proxy for SSL and routing
 
 - Transferred the image securely via SSH (compressed with docker save/load)
 - Performed zero-downtime deployment using blue-green strategy:
- Started new container alongside old one
 - Ran health checks on new container
 - Switched traffic atomically via network aliases
 - Removed old container
 
 - Configured SSL certificates automatically via Let's Encrypt
 - Updated proxy routing to direct traffic to your app
 
Adding Custom Domains
To use a custom domain instead of your server IP:
- Point your domain to your server's IP address
 - Add the domain to your config:
 
apps:
  web:
    # ... other config
    proxy:
      hosts:
        - myapp.com
        - www.myapp.com
      app_port: 3000
      ssl: true # Automatic HTTPS (default: true)- Redeploy:
 
iopiop will automatically:
- Obtain SSL certificates from Let's Encrypt
 - Configure HTTPS redirect
 - Update proxy routing
 
Next Steps
Now that you have your first app deployed, explore more features:
Multi-Server Deployment
Deploy the same app to multiple servers for load balancing:
apps:
  web:
    # ... other config
    server: server1.com # Just change to single server per app
    # For multiple servers, deploy multiple apps:
  web-backup:
    # ... same config
    server: server2.comAdd a Database Service
Add a PostgreSQL database to your deployment:
services:
  db:
    image: postgres:17
    server: your-server.com
    ports:
      - "5432:5432"
    environment:
      plain:
        - POSTGRES_USER=postgres
        - POSTGRES_DB=my-app
      secret:
        - POSTGRES_PASSWORD
    volumes:
      - ./pgdata:/var/lib/postgresql/dataDon't forget to add the password to .iop/secrets:
POSTGRES_PASSWORD=your-secure-passwordMultiple Replicas
Scale your app with multiple replicas:
apps:
  web:
    # ... other config
    replicas: 3 # Run 3 instances for load balancingEnvironment-Specific Deployments
Create different config files for different environments:
# iop.staging.yml
name: my-app-staging
# ... staging config
# iop.production.yml  
name: my-app-production
# ... production configDeploy to specific environments:
iop -c iop.staging.yml    # Deploy to staging
iop -c iop.production.yml # Deploy to productionCommon Issues and Solutions
Build Failures
Problem: Docker build fails
Solutions:
- Test locally: 
docker build . - Check your Dockerfile syntax
 - Ensure all files are included in build context
 - Use 
iop --verbosefor detailed build output 
Health Check Failures
Problem: Deployment fails with "Health check failed"
Solutions:
- Ensure your app has a health check endpoint (default: 
/up) - Make sure the endpoint returns HTTP 200
 - Check that your app is listening on the correct port
 - Verify 
app_portin config matches your app's port 
SSH Connection Issues
Problem: Cannot connect to server
Solutions:
- Test SSH manually: 
ssh user@your-server.com - Verify the username in 
iop.ymlmatches your server - Check firewall settings (ports 22, 80, 443 should be open)
 - Use 
iop --verbosefor detailed connection info 
SSL Certificate Issues
Problem: HTTPS not working
Solutions:
- Ensure your domain points to your server IP
 - Check DNS propagation: 
dig your-domain.com - Verify domain is correctly configured in 
proxy.hosts - Wait a few minutes for certificate generation
 
Example Projects
Check out these complete examples:
- Basic Go Application - Simple HTTP server with database
 - Next.js Application - Full-stack React app
 - Plausible Analytics - Real-world analytics deployment
 
Getting Help
Need help? Here are your options:
- Use help commands: 
iop --helporiop <command> --help - Verbose output: Add 
--verboseto any command for detailed logs - Check status: 
iop status --verboseshows detailed deployment info - View proxy logs: 
iop proxy logs --lines 100 
You're now ready to deploy with confidence! 🚀