PHPackages                             cyberwizard/laravel-ftp-deployer - 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. cyberwizard/laravel-ftp-deployer

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

cyberwizard/laravel-ftp-deployer
================================

Run Laravel Artisan commands on remote servers via FTP and HTTP triggers (useful for hosting without SSH).

1.3.0(1mo ago)32MITPHPPHP &gt;=8.1

Since May 14Pushed 1mo agoCompare

[ Source](https://github.com/cyberwizard-dev/laravel-ftp-deployer)[ Packagist](https://packagist.org/packages/cyberwizard/laravel-ftp-deployer)[ RSS](/packages/cyberwizard-laravel-ftp-deployer/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (2)Dependencies (2)Versions (6)Used By (0)

Laravel FTP Deployer
====================

[](#laravel-ftp-deployer)

A professional tool for managing Laravel applications on restricted hosting environments by executing Artisan commands and synchronizing files via an FTP-to-HTTP bridge.

The Problem
-----------

[](#the-problem)

Modern Laravel development relies heavily on the Artisan CLI for essential tasks such as database migrations, clearing caches, and managing maintenance mode. However, many shared hosting providers restrict server access to FTP/SFTP only, completely omitting SSH access.

This limitation creates a significant "deployment gap" where database syncing, maintenance control, and cache management become difficult and error-prone.

The Solution: ZIP + Manifest Workflow
-------------------------------------

[](#the-solution-zip--manifest-workflow)

This package provides a high-performance deployment strategy:

1. **Pre-Deployment Optimization**: The script automatically runs `php artisan optimize:clear` locally to ensure no cached configuration paths are zipped and deployed to the remote server.
2. **Incremental Detection**: The tool uses a local `.deploy_manifest.json` to track file content changes using MD5 hashes.
3. **Efficient Packaging**: Only new or modified files (detected by hash mismatch) are added to a timestamped `deploy_{timestamp}.zip` archive.
4. **Atomic Upload**: The single ZIP file is uploaded via FTP (much faster than thousands of small files).
5. **Remote Extraction &amp; Permissions**: A temporary PHP helper script is uploaded to extract the ZIP. It then automatically sets `chmod 775` on the remote `storage/` and `bootstrap/cache/` directories to prevent permission errors.
6. **Cache Purging**: The helper script manually deletes Laravel's `bootstrap/cache` files using native PHP. This prevents fatal "ReflectionException" errors that occur when Artisan tries to boot with a stale cache.
7. **Post-Extraction Tasks**: While the app is in maintenance mode, it runs a sequence of Artisan commands (migrations, cache clearing, etc.).
8. **Auto-Cleanup**: Both the ZIP and the helper script are deleted immediately after execution.

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

[](#installation)

Install the package via Composer:

```
composer require cyberwizard/laravel-ftp-deployer
```

Configuration
-------------

[](#configuration)

### Environment Variables

[](#environment-variables)

The tool automatically detects your credentials. It searches for a `.env.prod` file first (recommended for security), and falls back to `.env` if it's not found:

```
FTP_HOST=ftp.example.com
FTP_USERNAME=your-ftp-user
FTP_PASSWORD=your-ftp-password
FTP_PORT=21
FTP_ROOT=/path/to/laravel/root
APP_URL=https://example.com
```

### Deployment Configuration (deploy.json)

[](#deployment-configuration-deployjson)

The tool will automatically create a `deploy.json` file in your project root on its first run if it is missing. You should review this file to manage exclusions and remote Artisan commands:

```
{
    "_comment": "...",
    "exclude": { ... },
    "pre_deployment_commands": [
        "npm i",
        "npm run build"
    ],
    "post_extraction_commands": [
        "config:cache",
        "migrate --force",
        "up"
    ],
    "custom_commands": {
        "cache-clear": [
            "optimize:clear"
        ],
        "db-reset": [
            "migrate"
        ],
        "optimize": [
            "optimize:clear",
            "optimize"
        ]
    }
}
```

Usage
-----

[](#usage)

### CLI Commands

[](#cli-commands)

**Help** (Display usage and available commands):

```
vendor/bin/ftp-deploy help
# or
vendor/bin/ftp-deploy --help
```

**Full Deployment** (Code Sync + Post-Extraction Commands):

```
vendor/bin/ftp-deploy
```

**Custom Command Set** (Executes a specific group from `custom_commands` without syncing files):

```
vendor/bin/ftp-deploy db-reset
```

**Remote Artisan Runner** (Runs only allowlisted command sets from `deploy.json`):

```
vendor/bin/remote-artisan cache-clear
vendor/bin/remote-artisan db-migrate
vendor/bin/remote-artisan cache-clear db-migrate
vendor/bin/remote-artisan --list
```

This binary will refuse unknown names and only executes command groups defined under `custom_commands`.

**Remote Tinker Runner** (Paste a one-off PHP snippet to run inside Laravel):

```
vendor/bin/remote-tinker
vendor/bin/remote-tinker --file snippet.php
printf '%s' "User::count();" | vendor/bin/remote-tinker
```

This is for trusted snippets only. Like the artisan runner, it uses a one-time token in the `Authorization` header and deletes the helper after execution.

**First-Time / Forced Sync**:

```
vendor/bin/ftp-deploy --first-time
```

> **Note on First-Time Deployments:** Using `--first-time` (or `-f`) aggressively bypasses your standard `deploy.json` exclusion rules. It forces the inclusion of the `vendor` and `storage` directories (ignoring only `.git`, `node_modules`, `tests`, and `.env` files). It follows symlinks and deletes your local `.deploy_manifest.json` to guarantee a 100% fresh hash state. This is highly recommended when deploying to a brand new, empty server.

**Manage Environment Variables Interactively**: To quickly add or update keys in your **remote** `.env` file, you can use the included `update-env` utility. It connects via FTP, modifies the remote file, and uploads it securely:

```
./bin/update-env
```

It will prompt you for the variable name and value, and update or append it automatically on your remote server.

If you want to run remote Artisan commands without using the deploy workflow, define them in `deploy.json` and invoke them through `vendor/bin/remote-artisan`. The helper script uses a one-time authorization token sent in the `Authorization` header, not in the URL, and deletes itself after execution.

For ad hoc inspection or data fixes, `vendor/bin/remote-tinker` accepts pasted PHP from stdin or a file. It is not a sandbox; it runs the snippet with full application privileges on the remote server.

### Programmatic Usage

[](#programmatic-usage)

```
use Cyberwizard\LaravelFtpDeployer\RemoteExecutor;

$config = [
    'ftp_host' => '...',
    'ftp_user' => '...',
    'ftp_pass' => '...',
    'app_url'  => '...',
];

$executor = new RemoteExecutor($config);

// Run the full deployment workflow
$executor->deploy(isFirstTime: false);
```

Donations &amp; Custom Projects
-------------------------------

[](#donations--custom-projects)

If you find this tool useful and would like to support its development, or if you need a custom deployment solution for your specific infrastructure, feel free to reach out:

- **Email**:
- **WhatsApp**: [+2347085307378](https://wa.me/2347085307378)

Security
--------

[](#security)

- **Ephemeral Scripts**: Helper scripts use randomized filenames to prevent external discovery.
- **Instant Cleanup**: Files are deleted the moment the HTTP request completes.
- **Maintenance Mode**: The application is put into maintenance mode *before* extraction begins to ensure data integrity.

License
-------

[](#license)

The MIT License (MIT).

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance92

Actively maintained with recent releases

Popularity6

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~8 days

Total

5

Last Release

37d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/408541?v=4)[Eric Rogers](/maintainers/cyberwizard)[@Cyberwizard](https://github.com/Cyberwizard)

---

Top Contributors

[![cyberwizard-dev](https://avatars.githubusercontent.com/u/53139650?v=4)](https://github.com/cyberwizard-dev "cyberwizard-dev (7 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/cyberwizard-laravel-ftp-deployer/health.svg)

```
[![Health](https://phpackages.com/badges/cyberwizard-laravel-ftp-deployer/health.svg)](https://phpackages.com/packages/cyberwizard-laravel-ftp-deployer)
```

###  Alternatives

[in2code/in2publish_core

Content publishing extension to connect stage and production server

40143.4k](/packages/in2code-in2publish-core)[tiamo/phpas2

PHPAS2 is a php-based implementation of the EDIINT AS2 standard

4778.9k](/packages/tiamo-phpas2)[enygma/composerclean

An additional command for Composer that removes configured files/directory

171.8k](/packages/enygma-composerclean)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
