PHPackages                             veltix/zdt - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [DevOps &amp; Deployment](/categories/devops)
4. /
5. veltix/zdt

ActiveProject[DevOps &amp; Deployment](/categories/devops)

veltix/zdt
==========

Zero Downtime Deployment Tool - Deploy your applications safely with GitHub Actions

v1.0.4(5mo ago)294MITPHPPHP ^8.2CI passing

Since Dec 5Pushed 5mo agoCompare

[ Source](https://github.com/veltix/zdt)[ Packagist](https://packagist.org/packages/veltix/zdt)[ Docs](https://github.com/veltix/zdt)[ Fund](https://www.buymeacoffee.com/veltix)[ RSS](/packages/veltix-zdt/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (5)Dependencies (8)Versions (6)Used By (0)

    ![ZDT - Zero Downtime Deployment Tool](zdt-banner-light.png)

 [![Tests](https://github.com/veltix/zdt/actions/workflows/tests.yml/badge.svg)](https://github.com/veltix/zdt/actions) [![Latest Version](https://camo.githubusercontent.com/8b36dca0979aedcd9287194098cc4c83fa41d504a0d5ea6d432ca86376323016/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f76656c7469782f7a64742e737667)](https://packagist.org/packages/veltix/zdt) [![PHP Version](https://camo.githubusercontent.com/0389d62130b64296130f1696bb12b8f68654ac69229358a0369f524108883895/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f76656c7469782f7a64742e737667)](https://packagist.org/packages/veltix/zdt) [![License](https://camo.githubusercontent.com/074b89bca64d3edc93a1db6c7e3b1636b874540ba91d66367c0e5e354c56d0ea/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e737667)](LICENSE.md)

 **Deploy your applications with zero downtime.**
 Simple, secure, and reliable deployments using atomic symlink switching.

---

What is ZDT?
------------

[](#what-is-zdt)

ZDT (Zero Downtime Tool) is a deployment tool that ensures your application stays online during deployments. It deploys to a new directory, runs all setup tasks, then switches traffic atomically. If anything fails, it automatically rolls back.

**Perfect for:** PHP/Laravel applications, Node.js apps, static sites, or any web application.

How It Works
------------

[](#how-it-works)

```
1. Connect to server via SSH
2. Clone code to new release directory (releases/20231202143000/)
3. Install dependencies & run hooks
4. Run database migrations
5. Switch symlink atomically (current → new release)
6. Health check & cleanup old releases
7. Auto-rollback if anything fails

```

**Key Features:**

- ✅ Zero downtime - atomic symlink switching
- ✅ Automatic rollbacks on failure
- ✅ Health checks - validate deployments succeed
- ✅ Deployment locks - prevent concurrent deployments
- ✅ Database backups - automated pre-migration backups
- ✅ Notifications - Slack, Discord webhooks
- ✅ Release history &amp; instant rollback
- ✅ Deployment hooks for custom tasks
- ✅ Works with GitHub Actions, GitLab CI, or locally

Installation
------------

[](#installation)

```
composer global require veltix/zdt
```

Or install in your CI/CD workflow (no global install needed).

Quick Start
-----------

[](#quick-start)

### 1. Setup GitHub Secrets

[](#1-setup-github-secrets)

Go to your repository **Settings → Secrets → Actions** and add:

SecretExampleDescription`DEPLOY_HOST``your-server.com`Server hostname or IP`DEPLOY_USERNAME``deploy`SSH username`DEPLOY_SSH_KEY``-----BEGIN OPENSSH...`Private SSH key`DEPLOY_PATH``/var/www/myapp`Deployment path on server### 2. Create Workflow

[](#2-create-workflow)

Create `.github/workflows/deploy.yml`:

```
name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'

      - name: Deploy
        env:
          DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
          DEPLOY_USERNAME: ${{ secrets.DEPLOY_USERNAME }}
          DEPLOY_KEY_PATH: ${{ secrets.DEPLOY_SSH_KEY }}
          DEPLOY_REPO_URL: https://github.com/${{ github.repository }}.git
          DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
          DEPLOY_BRANCH: ${{ github.ref_name }}
        run: |
          composer global require veltix/zdt
          echo "$DEPLOY_KEY_PATH" > ~/.ssh/deploy_key
          chmod 600 ~/.ssh/deploy_key
          export DEPLOY_KEY_PATH=~/.ssh/deploy_key
          zdt deploy
```

### 3. Push &amp; Deploy

[](#3-push--deploy)

```
git push origin main
```

Your app deploys automatically with zero downtime! 🚀

---

Configuration Methods
---------------------

[](#configuration-methods)

ZDT supports **3 flexible configuration approaches**. Choose what works best for you:

### Method 1: GitHub Actions (Simplest)

[](#method-1-github-actions-simplest)

Perfect for CI/CD pipelines. Configuration lives in GitHub Secrets.

**Pros:**

- ✅ No config files
- ✅ Secure secrets
- ✅ Quick setup

**Cons:**

- ❌ GitHub-only
- ❌ Can't deploy locally

```
# .github/workflows/deploy.yml
- name: Deploy
  env:
    DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
    DEPLOY_USERNAME: ${{ secrets.DEPLOY_USERNAME }}
    DEPLOY_KEY_PATH: ${{ secrets.DEPLOY_SSH_KEY }}
    DEPLOY_REPO_URL: https://github.com/${{ github.repository }}.git
    DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
  run: |
    composer global require veltix/zdt
    zdt deploy
```

**[See full example →](examples/deploy.yml)**

---

### Method 2: Server Config (Recommended)

[](#method-2-server-config-recommended)

Store configuration in `.env.deployment` file on your server. Perfect for teams and multiple environments.

**Pros:**

- ✅ Deploy from anywhere
- ✅ Server-specific config
- ✅ No project files needed

**Cons:**

- ❌ Need server access
- ❌ Manual setup per server

**Setup:**

1. **Create config on server:**

    ```
    ssh user@your-server.com
    nano /var/www/myapp/shared/.env.deployment
    ```
2. **Add your settings:**

    ```
    DEPLOY_HOST=your-server.com
    DEPLOY_USERNAME=deploy
    DEPLOY_KEY_PATH=~/.ssh/id_rsa
    DEPLOY_REPO_URL=https://github.com/you/repo.git
    DEPLOY_PATH=/var/www/myapp
    DEPLOY_BRANCH=main
    ```
3. **Deploy (simple!):**

    ```
    - run: zdt deploy  # That's it! No env vars needed
    ```

**[See template →](examples/.env.deployment.example)**

---

### Method 3: Project Config (Flexible)

[](#method-3-project-config-flexible)

Commit a `deploy.php` file to your repository. Great for complex logic or team workflows.

**Pros:**

- ✅ Versioned with code
- ✅ Custom logic
- ✅ Team-friendly

**Cons:**

- ❌ One more file to manage

**Setup:**

1. **Add `deploy.php` to your project:**

    ```
    curl -o deploy.php https://raw.githubusercontent.com/veltix/zdt/main/examples/deploy-project-env.php
    git add deploy.php
    git commit -m "Add deployment config"
    ```
2. **Deploy:**

    ```
    - run: zdt deploy  # Uses deploy.php from your repo
    ```

**[See example →](examples/deploy-project-env.php)**

---

### Hybrid Approach (Best of All!)

[](#hybrid-approach-best-of-all)

**Use multiple methods together!** Priority order:

1. **Environment variables** (highest - CI/CD overrides)
2. **Server's `.env.deployment`** (persists across deployments)
3. **Project's `deploy.php`** (versioned with code)

Example: Use `.env.deployment` on server for defaults, override with GitHub secrets for staging:

```
env:
  DEPLOY_BRANCH: staging  # Override branch for staging deploy
run: zdt deploy
```

---

Commands
--------

[](#commands)

```
# Deploy application
zdt deploy

# Rollback to previous release
zdt rollback

# Rollback to specific release
zdt rollback --release=20231202-143000

# List all releases
zdt releases:list

# Clean up old releases (keep 3 most recent)
zdt releases:cleanup --keep=3

# Initialize deployment structure on server
zdt deploy:init
```

---

Advanced Features
-----------------

[](#advanced-features)

### 🏥 Health Checks

[](#-health-checks)

Validate your deployment succeeded with HTTP health checks. ZDT can ping a URL after activation and automatically rollback if it fails.

**Configuration:**

```
env:
  DEPLOY_HEALTH_CHECK_ENABLED: true
  DEPLOY_HEALTH_CHECK_URL: https://yourapp.com/health
  DEPLOY_HEALTH_CHECK_TIMEOUT: 30  # seconds
```

**How it works:**

1. Deploy completes and symlink switches
2. Health check pings your URL
3. If response is not 2xx, automatic rollback
4. If successful, continues with cleanup

**Example Health Check Endpoint** (Laravel):

```
// routes/web.php
Route::get('/health', function () {
    return response()->json(['status' => 'ok'], 200);
});
```

---

### 🔒 Deployment Locks

[](#-deployment-locks)

Prevent concurrent deployments that could corrupt your releases. ZDT automatically creates a lock file during deployment.

**Features:**

- Lock file at `{DEPLOY_PATH}/.deploy.lock`
- Prevents multiple simultaneous deployments
- Auto-removes stale locks (1 hour timeout)
- Always released even if deployment fails

**No configuration needed** - works automatically!

If a deployment is already running:

```
✗ Deployment failed: Another deployment is in progress.
  Lock file: /var/www/app/.deploy.lock (age: 120s, timeout in 3480s)

```

---

### 💾 Database Backups

[](#-database-backups)

Automatically backup your database before running migrations. Backups are compressed and stored with each release for easy restoration.

**Configuration:**

```
env:
  DEPLOY_DB_BACKUP_ENABLED: true
  DEPLOY_DB_CONNECTION: mysql        # or: pgsql, postgres, mariadb
  DEPLOY_DB_HOST: localhost
  DEPLOY_DB_PORT: 3306
  DEPLOY_DB_DATABASE: myapp
  DEPLOY_DB_USERNAME: dbuser
  DEPLOY_DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
  DEPLOY_DB_KEEP_BACKUPS: 5          # Keep last 5 backups
```

**Supported Databases:**

- MySQL / MariaDB
- PostgreSQL

**Backup Location:**

```
/var/www/app/
├── backups/
│   ├── db-backup-20231215-143000.sql.gz
│   ├── db-backup-20231215-120000.sql.gz
│   └── db-backup-20231215-100000.sql.gz

```

**Manual Restore:**

```
# On server
cd /var/www/app/backups
gunzip db-backup-20231215-143000.sql.gz
mysql -u dbuser -p myapp
