minideploy 0.1.1
Simple deployment tool for your VPS
Requires Python: >=3.11

# minideploy

Simple deployment tool for your VPS. Deploy applications with rolling updates, health checks, and automatic rollbacks.

## Features

- **Simple Configuration**: Single `deploy.yml` file per project
- **JSON Schema**: Full schema validation for IDE support
- **Multiple Service Managers**: Systemd, Docker Compose, PM2
- **Rolling Deployments**: Zero-downtime deployments with health checks
- **Release Management**: Automatic versioning with easy rollback
- **Built-in Health Checks**: Verify deployments before switching traffic
- **SSH-based**: No agents required on the server
- **Shell Completions**: Tab completion for bash, zsh, and fish

## ⚠️ Service Manager Status

> **Systemd** ✅ Fully implemented and tested  
> **Docker Compose** ⚠️ Implemented but not fully tested  
> **PM2** ⚠️ Implemented but not fully tested  
>
> While Docker Compose and PM2 are implemented, they have not been extensively tested. Please report any issues you encounter.

## Installation

```bash
uv tool install minideploy
```

Or with pip:

```bash
pip install minideploy
```

## Quick Start

### 1. Initialize Configuration

```bash
cd your-project
minideploy init
```

This creates a `deploy.yml` file. Edit it for your project:

```yaml
app:
  name: "myapp"
  type: "web"

build:
  type: "custom"
  command: "echo 'Replace with your build command'"
  output_dir: "dist"

server:
  host: "your-server.com"
  user: "deploy"
  deploy_dir: "/opt/myapp"

service:
  type: "systemd"
  instances:
    - id: "1"
      port: 8080
      health_endpoint: "/health"
  systemd_options:
    user: "deploy"
    restart: "always"
    working_directory: "/opt/myapp/current"
    exec_start: "/opt/myapp/current/myapp"

deploy:
  strategy: "rolling"
  keep_releases: 3
  health_check:
    timeout: 30
    retries: 3
    wait_between_instances: 5
```

### 2. Setup Server (run once)

```bash
minideploy setup
```

This creates the directory structure and sets up systemd services.

### 3. Deploy

```bash
minideploy deploy
```

## Commands

- `minideploy init` - Create a sample deploy.yml
- `minideploy setup` - Initial server setup
- `minideploy setup --regenerate` - Recreate service configuration
- `minideploy build` - Build the application locally
- `minideploy upload` - Upload build to server
- `minideploy deploy` - Full deployment (build + upload + deploy)
- `minideploy status` - Show deployment status
- `minideploy releases` - List all releases
- `minideploy rollback` - Rollback to previous release
- `minideploy health` - Run health checks
- `minideploy logs` - View service logs
- `minideploy service start|stop|restart|status` - Manage services
- `minideploy destroy` - Remove all server setup (services and directories)
- `minideploy ssh` - Open SSH session to server
- `minideploy completion <shell>` - Generate shell completions

## Shell Completions

minideploy supports tab completion for **bash**, **zsh**, and **fish** shells.

### Bash

Add to `~/.bashrc`:

```bash
eval "$(_MINIDEPLOY_COMPLETE=bash_source minideploy)"
```

Or use the built-in install command:

```bash
minideploy completion bash --install
source ~/.bashrc
```

### Zsh

Add to `~/.zshrc`:

```zsh
eval "$(_MINIDEPLOY_COMPLETE=zsh_source minideploy)"
```

Or use the built-in install command:

```bash
minideploy completion zsh --install
source ~/.zshrc
```

### Fish

Create file `~/.config/fish/completions/minideploy.fish`:

```fish
_MINIDEPLOY_COMPLETE=fish_source minideploy | source
```

Or use the built-in install command:

```bash
minideploy completion fish --install
```

## Managing Server Setup

### Regenerate Service Configuration

If you need to update the service configuration (e.g., change systemd options):

```bash
# This removes existing services and recreates them
minideploy setup --regenerate
```

### Destroy Server Setup

To completely remove a project from the server (services and all files):

```bash
# This will prompt for confirmation
minideploy destroy

# Force destroy without confirmation
minideploy destroy --force
```

**Warning**: This permanently deletes:
- All systemd/docker/pm2 services for the app
- The entire deployment directory (`/opt/<app-name>/`)
- All releases and uploaded files

## Options

- `-c, --config` - Path to configuration file (default: deploy.yml)
- `-v, --verbose` - Enable verbose output
- `--dry-run` - Show what would be done without executing

## Directory Structure on Server

```
/opt/<app-name>/
├── current -> releases/<current-release>  # Symlink to active release
├── releases/                              # Versioned releases
│   ├── release_20240213_143022/
│   ├── release_20240213_120000/
│   └── ...
└── uploads/                               # Temporary upload directory
```

## Configuration Reference

### App
- `name` - Application name
- `type` - Application type (for documentation)

### Build
- `type` - Build type: `dotnet`, `npm`, `custom`, `docker`, etc.
- `command` - Build command to execute
- `output_dir` - Build output directory
- `env_file` - Environment file to upload (optional)
- `pre_build` - Command to run before build (optional)
- `post_build` - Command to run after build (optional)

### Server
- `host` - Server hostname or IP
- `user` - SSH user (default: deploy)
- `port` - SSH port (default: 22)
- `ssh_key` - Path to SSH private key (optional)
- `deploy_dir` - Deployment directory on server

### Service
- `type` - Service manager: `systemd`, `docker-compose`, `pm2`
- `instances` - List of service instances
  - `id` - Instance identifier
  - `port` - Port for health checks
  - `health_endpoint` - Health check endpoint
- `template` - Custom service template file (optional)

#### Systemd Options
- `user` - User to run service as
- `group` - Group to run service as (optional)
- `restart` - Restart policy (default: always)
- `working_directory` - Working directory
- `exec_start` - Command to execute (use `%i` for instance id)
- `environment_file` - Path to environment file (optional)
- `environment` - Environment variables as key-value pairs (optional)
- `additional_options` - Additional [Service] section options

### Deploy
- `strategy` - Deployment strategy: `rolling`, `blue-green`
- `keep_releases` - Number of releases to keep (default: 3)
- `health_check` - Health check configuration
  - `timeout` - Timeout in seconds (default: 30)
  - `retries` - Number of retries (default: 3)
  - `wait_between_instances` - Wait time between deployments (default: 5)

## Examples

### .NET Application

```yaml
app:
  name: "myapi"
  type: "dotnet"

build:
  type: "dotnet"
  command: "dotnet publish -c Release -r linux-x64 --self-contained -o publish"
  output_dir: "publish"

server:
  host: "myvps"
  user: "deploy"
  deploy_dir: "/opt/myapi"

service:
  type: "systemd"
  instances:
    - id: "1"
      port: 5001
      health_endpoint: "/health"
    - id: "2"
      port: 5002
      health_endpoint: "/health"
  systemd_options:
    user: "deploy"
    restart: "always"
    working_directory: "/opt/myapi/current"
    exec_start: "/opt/myapi/current/MyApi --urls http://localhost:500%i"
```

### Node.js Application with PM2

```yaml
app:
  name: "myapp"
  type: "node"

build:
  type: "npm"
  command: "npm ci && npm run build"
  output_dir: "dist"

server:
  host: "myvps"
  user: "deploy"
  deploy_dir: "/opt/myapp"

service:
  type: "pm2"
  instances:
    - id: "1"
      port: 3000
      health_endpoint: "/health"
  pm2_config: "ecosystem.config.js"
```

## JSON Schema

A JSON Schema is available for `deploy.yml` validation and IDE autocomplete support:

**schema.json**

Add the schema to your `deploy.yml` for IDE support:

```yaml
# yaml-language-server: $schema=https://raw.githubusercontent.com/hamidriaz1998/minideploy/main/schema.json

app:
  name: "myapp"
  # ... rest of your config
```

### VS Code

Install the [YAML extension](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml) and add to your settings:

```json
{
  "yaml.schemas": {
    "https://raw.githubusercontent.com/hamidriaz1998/minideploy/main/schema.json": "deploy.yml"
  }
}
```

### PyCharm / IntelliJ

Go to **Settings → Languages & Frameworks → Schemas and DTDs → JSON Schema Mappings** and add:

- **Schema file or URL**: `https://raw.githubusercontent.com/hamidriaz1998/minideploy/main/schema.json`
- **File path pattern**: `deploy.yml`

### Other Editors

Most modern editors support JSON Schema validation through the [YAML Language Server](https://github.com/redhat-developer/yaml-language-server).

## License

MIT