8000 GitHub - elitan/luma: Ship Docker Anywhere
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

elitan/luma

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Luma: Ship Docker Anywhere ⚑

Zero-downtime deployments and automatic HTTPS on your own servers.

❯ luma deploy --force
Using Git SHA for release ID: 80d0f8c
Starting deployment with release 80d0f8c

[βœ“] Configuration loaded (1ms)
[βœ“] Git status verified (4ms)
[βœ“] Infrastructure ready (879ms)
[βœ“] web β†’ web:80d0f8c (1.8s)
[βœ“] Building Images (1.8s)
[βœ“] App State Reconciliation (884ms)
  └─ web β†’ 157.180.25.101
     β”œβ”€ [βœ“] Loading web image (1.7s)
     β”œβ”€ [βœ“] Zero-downtime deployment of web (3.5s)
     └─ [βœ“] Configuring proxy for web (805ms)
[βœ“] Deploying Apps (6.2s)
[βœ“] Deployment completed successfully in 9.8s

Your app is live at:
  └─ https://test.eliasson.me

Luma automatically handles:

  • βœ… Zero-downtime blue-green deployments
  • βœ… Automatic SSL certificates via Let's Encrypt
  • βœ… Health checks and automatic rollbacks
  • βœ… Docker image building and secure transfer
  • βœ… Multi-server deployments

πŸš€ Quick Start

1. Install Luma

npm install -g @elitan/luma

2. Initialize your project

cd your-project
luma init

This creates:

  • luma.yml - Your deployment configuration
  • .luma/secrets - Secure credentials (add to .gitignore)

3. Configure your app

Edit luma.yml:

name: my-app

apps:
  web:
    image: my-app/web
    servers:
      - your-server.com
    build:
      context: .
      dockerfile: Dockerfile
    proxy:
      hosts:
        - myapp.com
      app_port: 3000

4. Set up your server

luma setup

Luma will:

  • Install Docker if needed
  • Set up the reverse proxy
  • Start services

5. Deploy!

luma deploy

Watch as Luma builds, deploys, and switches traffic with zero downtime.


πŸ“‹ Prerequisites

  • Local machine: Bun or Node.js 18+
  • Target servers:
    • Ubuntu/Debian Linux
    • SSH access with sudo privileges
    • Ports 80 and 443 open

πŸ†š Why Luma vs Alternatives?

vs Kamal (37signals)

  • TypeScript/Bun instead of Ruby
  • Registry-less deployments - no need for external Docker registries

vs Vercel/Netlify

  • Your own servers - full control, no vendor lock-in
  • Any Docker app - not limited to specific frameworks
  • Cost-effective - pay only for your servers
  • No cold starts - your containers are always running

vs Docker Compose

  • Zero-downtime deployments - compose restarts cause downtime
  • Multi-server support - deploy across multiple machines
  • Automatic SSL and reverse proxy included
  • Git-based releases and rollback capabilities

🎯 Core Concepts

Apps vs Services

Apps are your main applications (web servers, APIs) that you build and deploy with zero-downtime:

apps:
  web:
    image: my-app/web
    build:
      context: .
      dockerfile: Dockerfile
    proxy:
      hosts:
        - example.com
      app_port: 3000

  api:
    image: my-app/api
    build:
      context: ./api
    proxy:
      hosts:
        - api.example.com
      app_port: 8080

Services are supporting infrastructure (databases, caches) that use pre-built images:

services:
  postgres:
    image: postgres:15
    environment:
      secret: [POSTGRES_PASSWORD]
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:7

Zero-Downtime Deployments

Luma automatically uses blue-green deployment for apps:

  1. Build and transfer your Docker image securely to servers
  2. Deploy new version alongside the current one
  3. Health check the new version via configured health endpoint
  4. Switch traffic atomically (sub-millisecond)
  5. Clean up old version

No Docker registry required - images are transferred directly!

Registry-Free Operation

Built apps are transferred using secure Docker save/load:

  • Build locally - your Docker images are built on your machine
  • Transfer securely - images are saved as tar archives and uploaded via SSH
  • Load remotely - Docker loads the image directly on your servers
  • No registry needed - eliminates external dependencies and credentials

Services can still use registries for pre-built images like postgres:15.

Automatic SSL

Luma includes a smart reverse proxy that automatically:

  • Obtains SSL certificates via Let's Encrypt
  • Routes traffic to your apps
  • Handles health checks
  • Manages zero-downtime deployments with blue-green switching

Health Checks

Luma performs automatic health checks during deployments to ensure zero-downtime deployments. Your application must implement a health check endpoint that returns HTTP 200 when healthy.

The default health check endpoint is /up but you can configure it to any path you want.

apps:
  api:
    health_check:
      path: /health # Health check endpoint (default: /up)

Health Check Behavior (Automatic):

  • Method: HTTP GET request
  • Success criteria: HTTP 200 response
  • Timeout: 5 seconds
  • Retries: 3 attempts
  • Port: Uses the configured app_port (defaults to 80)

The only configurable option is:

  • path: Health check endpoint path (default: /up)

All other health check behavior is handled automatically by Luma to ensure reliable deployments.


πŸ“– Configuration Reference

Basic Configuration

name: my-project # Required: Project name

# Optional: Global settings
ssh:
  username: deploy # SSH user (default: root)
  port: 22 # SSH port

# Optional: Docker registry (only needed for services using private registries)
docker:
  registry: ghcr.io # Docker registry
  username: myuser # Registry username

apps:
  web:
    image: my-app/web # Docker image name
    servers:
      - server1.com
      - server2.com # Target servers

    # Build configuration (apps are built locally and transferred)
    build:
      context: .
      dockerfile: Dockerfile
      platform: linux/amd64

    # Proxy configuration for web apps
    proxy:
      hosts:
        - example.com
        - www.example.com
      app_port: 3000

    # Environment variables
    environment:
      plain:
        - NODE_ENV=production
        - PORT=3000
      secret:
        - DATABASE_URL # From .luma/secrets
        - API_KEY

    # Health check (optional)
    health_check:
      path: /health # Health check endpoint (default: /up)

services:
  database:
    image: postgres:15
    servers:
      - db.example.com
    environment:
      secret:
        - POSTGRES_PASSWORD
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data

Secrets Management

Store sensitive values in .luma/secrets:

# .luma/secrets
DATABASE_URL=postgres://user:pass@localhost:5432/myapp
API_KEY=supersecretkey
# Only needed if using private registries for services
DOCKER_REGISTRY_PASSWORD=myregistrypassword

Important: Add .luma/secrets to your .gitignore!


πŸ› οΈ Commands

luma init

Initialize a new project with configuration files.

luma setup [service...]

Prepare servers for deployment. Installs Docker, creates networks, sets up the proxy.

luma setup              # Set up all servers
luma setup web api      # Set up only servers for web and api

luma deploy [app...]

Deploy apps or services with zero downtime.

luma deploy             # Deploy all apps
luma deploy web         # Deploy specific app
luma deploy --services  # Deploy services instead
luma deploy --force     # Skip git status checks
luma deploy --verbose   # Detailed logging

luma status [app...]

Check the status of your deployments.

luma status             # Status of all apps
luma status web         # Status of specific app

# Example output:
πŸ“± App: web
   Status: βœ… RUNNING (green active)
   Replicas: 2/2 running
   Servers: server1.com, server2.com

πŸ—οΈ Examples

Simple Web App

name: blog
apps:
  web:
    image: my-blog
    servers:
      - server.com
    build:
      context: .
    proxy:
      hosts:
        - blog.com
      app_port: 3000
    environment:
      secret: [DATABASE_URL]

Full-Stack App with Database

name: ecommerce

apps:
  web:
    image: ecommerce/frontend
    servers:
      - web1.com
      - web2.com
    build:
      context: ./frontend
    proxy:
      hosts:
        - shop.com
        - www.shop.com
      app_port: 3000

  api:
    image: ecommerce/backend
    servers:
      - api.com
    build:
      context: ./backend
    proxy:
      hosts:
        - api.shop.com
      app_port: 8080
    environment:
      secret: [DATABASE_URL, JWT_SECRET]

services:
  postgres:
    image: postgres:15
    servers:
      - db.com
    environment:
      secret: [POSTGRES_PASSWORD]
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:7
    servers:
      - cache.com

Microservices with Load Balancing

name: platform

apps:
  user-service:
    image: platform/users
    replicas: 3
    servers:
      - app1.com
      - app2.com
    build:
      context: ./services/users
    proxy:
      hosts:
        - users.platform.com
      app_port: 8080

  order-service:
    image: platform/orders
    replicas: 2
    servers:
      - app1.com
      - app2.com
    build:
      context: ./services/orders
    proxy:
      hosts:
        - orders.platform.com
      app_port: 8081

πŸ”’ Security Best Practices

Server Preparation Guide (from root)

Follow these steps to securely prepare your server for Luma deployments. All commands should be run as the root user (or with sudo).

  1. Create a dedicated user for Luma:
sudo adduser luma
# Follow the prompts to set a password (it will be disabled later) and user details.
sudo usermod -aG sudo luma # Add luma to the sudo group
  1. Install Docker Engine:

Luma requires Docker to be installed on your target servers.

# Update package lists
sudo apt-get update

# Install prerequisites
sudo apt-get install -y ca-certificates curl

# Create keyrings directory
sudo install -m 0755 -d /etc/apt/keyrings

# Add Docker's official GPG key
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add Docker's stable repository
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Update package lists again
sudo apt-get update

# Install Docker CE with all plugins
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Add the luma user to the docker group
sudo usermod -aG docker luma

# Verify installation
sudo docker run hello-world

Note: You might need to log out and log back in as the luma user for the group changes to take effect, or use newgrp docker in the luma user's session.

  1. Set up SSH Key-Based Authentication for luma:

    Prerequisites: This step assumes you already have SSH keys generated on your local machine. If you don't have SSH keys yet, generate them first:

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
# Follow the prompts. It's recommended to use a passphrase for your key.

Copy your public key to the server: Replace your-server.com with your server's IP address or hostname.

ssh-copy-id luma@your-server.com

This command will copy your local machine's public SSH key to the luma user's ~/.ssh/authorized_keys file on the server.

  1. Secure SSH Configuration:

Disable password authentication and make other security improvements to your SSH server. Edit the SSH daemon configuration file (/etc/ssh/sshd_config) on the server:

sudo nano /etc/ssh/sshd_config

Make the following changes:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
UsePAM no # If you are sure you don't need PAM for SSH

After 8000 saving the changes, restart the SSH service:

sudo systemctl restart ssh

Important: Ensure your SSH key authentication is working correctly before disabling password authentication, or you could lock yourself out of the server. Test by logging in from a new terminal window: ssh luma@your-server.com.

  1. Install Fail2Ban:

Fail2Ban helps protect your server from brute-force attacks.

sudo apt-get update
sudo apt-get install -y fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

Fail2Ban works out-of-the-box with default settings for SSH. You can customize its configuration in /etc/fail2ban/jail.local.

  1. Configure Luma:

In your luma.yml file, ensure you specify the luma user for SSH connections:

ssh:
  username: luma
  # port: 22 # If you changed the SSH port

After completing these steps, your server will be more secure and ready for Luma deployments.

Secrets Management

  • Never commit .luma/secrets to version control
  • Use environment-specific secrets

πŸ“š Advanced Usage

Multi-Environment Deployments

# luma.staging.yml
name: myapp-staging
apps:
  web:
    image: myapp/web
    build:
      context: .
    servers:
      - staging.myapp.com

# luma.production.yml
name: myapp-prod
apps:
  web:
    image: myapp/web
    build:
      context: .
    servers:
      - prod1.myapp.com
      - prod2.myapp.com

Deploy with:

luma deploy -c luma.staging.yml
luma deploy -c luma.production.yml

Using Docker Registries (Optional)

For services that need private registries or when you prefer registry-based workflows:

# Global registry configuration
docker:
  registry: my-registry.com
  username: myuser

services:
  private-service:
    image: my-registry.com/private-service:latest
    # Uses global registry config

apps:
  web:
    # Per-app registry override
    registry:
      url: ghcr.io
      username: different-user
      password_secret: GITHUB_TOKEN
    # Still uses build + transfer, registry only for pre-built images

Development Setup

git clone https://github.com/elitan/luma
cd luma
bun install
bun run dev

Running Tests

bun test

πŸ“„ License

MIT License


Made with ❀️ for developers who want simple, reliable deployments on their own infrastructure.

About

Ship Docker Anywhere

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published
0