{"id":45852505,"url":"https://github.com/merchantprotocol/protocol","last_synced_at":"2026-04-05T00:02:09.355Z","repository":{"id":48410979,"uuid":"470769553","full_name":"merchantprotocol/protocol","owner":"merchantprotocol","description":"Stupid-simple CI/CD for Docker apps. One-command deploy, encrypted secrets, automatic rollback, SOC 2 Type II ready.","archived":false,"fork":false,"pushed_at":"2026-04-04T04:18:28.000Z","size":2865,"stargazers_count":1,"open_issues_count":10,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-04-04T06:14:35.555Z","etag":null,"topics":["cicd","deployment","devops","docker","soc2"],"latest_commit_sha":null,"homepage":"https://protocol.merchantprotocol.com","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/merchantprotocol.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-03-16T22:23:31.000Z","updated_at":"2026-04-04T04:11:09.000Z","dependencies_parsed_at":"2025-04-01T03:29:32.396Z","dependency_job_id":"13f20089-fc2c-450d-a18e-00b923f33625","html_url":"https://github.com/merchantprotocol/protocol","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/merchantprotocol/protocol","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/merchantprotocol%2Fprotocol","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/merchantprotocol%2Fprotocol/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/merchantprotocol%2Fprotocol/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/merchantprotocol%2Fprotocol/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/merchantprotocol","download_url":"https://codeload.github.com/merchantprotocol/protocol/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/merchantprotocol%2Fprotocol/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31419549,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T20:09:54.854Z","status":"ssl_error","status_checked_at":"2026-04-04T20:09:44.350Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cicd","deployment","devops","docker","soc2"],"created_at":"2026-02-27T03:07:05.676Z","updated_at":"2026-04-05T00:02:09.337Z","avatar_url":"https://github.com/merchantprotocol.png","language":"PHP","readme":"\u003cp align=\"center\"\u003e\n  \u003ch1 align=\"center\"\u003eProtocol\u003c/h1\u003e\n  \u003cp align=\"center\"\u003e\n    Deploy your Docker app with one command. Encrypted secrets, automatic rollback, zero build servers.\n    \u003cbr /\u003e\n    \u003ca href=\"docs/getting-started.md\"\u003e\u003cstrong\u003eGetting Started\u003c/strong\u003e\u003c/a\u003e\n    \u0026middot;\n    \u003ca href=\"docs/deployment-types.md\"\u003e\u003cstrong\u003eDeployment Strategies\u003c/strong\u003e\u003c/a\u003e\n    \u0026middot;\n    \u003ca href=\"docs/secrets.md\"\u003e\u003cstrong\u003eSecrets\u003c/strong\u003e\u003c/a\u003e\n    \u0026middot;\n    \u003ca href=\"docs/commands.md\"\u003e\u003cstrong\u003eCommands\u003c/strong\u003e\u003c/a\u003e\n    \u0026middot;\n    \u003ca href=\"docs/configuration.md\"\u003e\u003cstrong\u003eConfiguration\u003c/strong\u003e\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg\" alt=\"MIT License\"\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/php-8.1%2B-8892BF.svg\" alt=\"PHP 8.1+\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/SOC2-Type%20II%20Ready-green.svg\" alt=\"SOC 2 Type II Ready\"\u003e\n\u003c/p\u003e\n\n---\n\n## Stupid Simple CI/CD. Deployed in Seconds. More Reliable Than Anything Else You've Tried.\n\nTwo commands. That's your entire deployment pipeline.\n\n```bash\nprotocol init     # Set up your project (once)\nprotocol start    # Stay in sync with millisecond rollouts\n```\n\nYour Docker containers come up. Your `.env` files decrypt themselves. Your nginx and cron configs link into place. A watcher starts polling for new releases. Push a git tag, and every server in your fleet deploys it automatically. Roll back with one command if anything goes wrong.\n\nNo Jenkins. No GitHub Actions workflows. No webhook endpoints. No deploy scripts. No build servers. Just git, Docker, and Protocol.\n\n### What you get out of the box\n\n- **One-command deploy** to any number of servers\n- **Encrypted secrets** that version-control your `.env` files safely in git\n- **Instant rollback** to any previous release\n- **Blue-green shadow deploys** — build in the background, swap in one second\n- **Auto-restart** after server reboots\n- **Zero coordination** between nodes — they all figure it out independently\n- **SOC 2 Type II ready** with audit logging and encrypted credentials\n\n---\n\n## The Old Way vs. Protocol\n\nMost teams go through the same painful evolution:\n\n**Stage 1:** SSH into the server and `git pull`. It works until you forget which server you updated.\n\n**Stage 2:** Set up a CI/CD pipeline. Now you're maintaining build runners, webhook endpoints, deploy scripts, artifact storage, and environment variables scattered across three different dashboards.\n\n**Stage 3:** Add a second production node. Now your deploy scripts need to handle multiple targets, health checks, rolling deploys, and rollback logic. Your CI/CD config file is 200 lines long.\n\n**Stage 4:** Your `.env` file on production gets overwritten during a deploy. The database password is gone. It was in a Slack DM from six months ago. Maybe.\n\nProtocol skips all of that. Every node runs `protocol start` and manages itself. You tag a release, set a pointer, and every node picks it up. Your secrets are encrypted in git and decrypt themselves on arrival.\n\n## Quick Start\n\n### Install\n\n```bash\ncurl -L \"https://raw.githubusercontent.com/merchantprotocol/protocol/master/bin/install\" | sudo bash\n```\n\n### Set Up Your Project\n\n```bash\ncd /path/to/your/project\nprotocol init\n```\n\nA wizard walks you through it — pick your Docker image, choose a deploy strategy, optionally encrypt your secrets. Arrow keys to navigate, Enter to confirm.\n\n### Start Everything\n\n```bash\nprotocol start\n```\n\nDocker containers come up. Config files get linked. Secrets get decrypted. You're running.\n\n### Deploy to Production\n\nOn your production server:\n\n```bash\ngit clone git@github.com:yourorg/yourapp.git /opt/yourapp\ncd /opt/yourapp\nprotocol config:env production\nprotocol secrets:setup \"your-encryption-key\"\nprotocol start\n```\n\nFrom then on, deploying is:\n\n```bash\n# On your dev machine\nprotocol release:create\nprotocol deploy:push 1.0.0\n```\n\nEvery node picks up the new release automatically. Something wrong? `protocol deploy:rollback` — instant.\n\n## How Secrets Work\n\nYour `.env` files are too important to pass around in Slack messages and too dangerous to commit in plain text. Protocol encrypts them with AES-256-GCM before they touch git.\n\n```\nYour Machine                    Git                     Production\n─────────────                   ───                     ──────────\n.env (plaintext)  ──encrypt──▶  .env.enc (encrypted)  ──▶  .env (plaintext)\n```\n\nThe encryption key stays on your machines. Only encrypted data travels through git.\n\n```bash\n# Set up encryption (interactive wizard)\nprotocol config:init\n\n# View your key and transfer options\nprotocol secrets:key\n\n# Copy key to production server\nprotocol secrets:key --scp=deploy@production\n\n# Or push to GitHub for CI/CD\nprotocol secrets:key --push\n```\n\nWhen `protocol start` runs on any node with the key, encrypted files are decrypted automatically. Your app just reads `.env` like it always has.\n\nFull guide: [docs/secrets.md](docs/secrets.md)\n\n## How Deployment Works\n\n### Release-Based (Recommended)\n\nYou create versioned releases. A GitHub variable tells all nodes which version to run. Change the variable, every node deploys.\n\n```\nYou run:                              Every node:\n─────────                             ───────────\nprotocol release:create 1.2.0        (watching...)\nprotocol deploy:push 1.2.0     ───▶  \"1.2.0? Deploying now.\"\n                                      ✓ Node 1: v1.2.0\n                                      ✓ Node 2: v1.2.0\n                                      ✓ Node 3: v1.2.0\n```\n\nRollback is instant — `protocol deploy:rollback` sets the pointer back to the previous version. Every node follows.\n\n### Shadow Deploys (Zero Downtime)\n\nFor applications with long build times, enable shadow deployment. Each version gets its own self-contained sibling directory (`\u003cproject\u003e-releases/v1.3.0/`) with a full git clone, config, and Docker containers named with the release tag. Build in the background, swap ports in under a second.\n\n```bash\nprotocol shadow:init              # Configure shadow deployment (wizard)\nprotocol shadow:build v1.3.0     # Clone + build on shadow ports\nprotocol shadow:start             # Swap to production (~1 second)\nprotocol shadow:rollback          # Instant rollback if needed\n```\n\nFull guide: [docs/blue-green.md](docs/blue-green.md)\n\n### Branch-Based (Simple)\n\nNodes watch a git branch and pull changes automatically. Good for local development and simple setups. No versioning, no rollback history.\n\n## How Config Works\n\nYour project has a sibling directory that holds environment-specific files:\n\n```\nyour-project/           ← your code\nyour-project-config/    ← .env, nginx.conf, cron jobs (separate git repo)\n```\n\nEach environment is a branch: `localhost`, `staging`, `production`. When Protocol starts, it symlinks the right files into your project. When the config repo changes, the watcher picks it up automatically.\n\n```bash\n# Set up the config repo (interactive wizard)\nprotocol config:init\n\n# Move a file into the config repo\nprotocol config:mv .env\n\n# Switch environments\nprotocol config:switch staging\n```\n\n## Common Commands\n\n| What you want to do | Command |\n|---|---|\n| Set up a new project | `protocol init` |\n| Start everything | `protocol start` |\n| Stop everything | `protocol stop` |\n| Check what's running | `protocol status` |\n| Set up configs \u0026 secrets | `protocol config:init` |\n| Create a release | `protocol release:create` |\n| Deploy to all nodes | `protocol deploy:push 1.2.0` |\n| Roll back | `protocol deploy:rollback` |\n| Run a command in Docker | `protocol docker:exec \"php artisan migrate\"` |\n| View your encryption key | `protocol secrets:key` |\n| Update Protocol itself | `protocol self:update` |\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eAll Commands\u003c/strong\u003e\u003c/summary\u003e\n\n**Releases \u0026 Deployment**\n\n| Command | Description |\n|---|---|\n| `release:create [version]` | Tag a new release |\n| `release:list` | List all releases |\n| `release:prepare` | Prepare codebase for next release |\n| `release:changelog` | Generate CHANGELOG from git history |\n| `deploy:push \u003cversion\u003e` | Deploy a release to all nodes |\n| `deploy:rollback` | Roll back all nodes |\n| `deploy:status` | Show active vs local version |\n| `deploy:strategy [strategy]` | View or change deployment strategy |\n| `deploy:log` | View deployment history |\n| `node:deploy \u003cversion\u003e` | Deploy on this node only |\n| `node:rollback` | Roll back this node only |\n\n**Shadow Deployment**\n\n| Command | Description |\n|---|---|\n| `shadow:init` | Configure shadow deployment (wizard) |\n| `shadow:build \u003cversion\u003e` | Build a release in a version-named slot |\n| `shadow:start` | Promote shadow to production (~1s) |\n| `shadow:rollback` | Revert to previous version (~1s) |\n| `shadow:status` | Show version slots and states |\n\n**Secrets**\n\n| Command | Description |\n|---|---|\n| `secrets:setup [key]` | Generate or store encryption key |\n| `secrets:key` | View key and transfer options |\n| `secrets:key --push` | Push key to GitHub as a secret |\n| `secrets:key --scp=user@host` | Copy key to remote server |\n| `secrets:encrypt [file]` | Encrypt a file |\n| `secrets:decrypt [file]` | Decrypt a file |\n\n**Configuration**\n\n| Command | Description |\n|---|---|\n| `config:init` | Config repo wizard (create, encrypt, decrypt) |\n| `config:env \u003cname\u003e` | Set this machine's environment name |\n| `config:mv \u003cfile\u003e` | Move file to config repo + symlink |\n| `config:cp \u003cfile\u003e` | Copy file to config repo |\n| `config:new` | Create a new config repo from scratch |\n| `config:link` | Create all config symlinks |\n| `config:unlink` | Remove all config symlinks |\n| `config:refresh` | Clear and rebuild config symlinks |\n| `config:switch \u003cenv\u003e` | Switch environment branch |\n| `config:save` | Commit and push config changes |\n\n**Docker**\n\n| Command | Description |\n|---|---|\n| `docker:compose` | Start containers |\n| `docker:compose:down` | Stop containers |\n| `docker:compose:rebuild` | Rebuild and restart |\n| `docker:exec [cmd]` | Run command in container |\n| `docker:logs` | Follow container logs |\n| `docker:build` | Build image from local Dockerfile |\n| `docker:pull` | Pull image from registry |\n| `docker:push` | Push image to registry |\n| `docker:status` | Audit containers, images, and volumes |\n| `docker:cleanup [full]` | Prune stopped containers and unused images |\n| `docker:cleanup:schedule` | Enable/disable scheduled cleanup via cron |\n\n**Security \u0026 Monitoring**\n\n| Command | Description |\n|---|---|\n| `security:audit` | Run security scan on codebase and server |\n| `security:trojansearch` | Deep scan for trojan patterns in PHP files |\n| `security:changedfiles` | List recently modified files |\n| `soc2:check` | Validate SOC 2 Type II readiness |\n| `incident:status` | Live incident dashboard |\n| `incident:report` | Generate incident report and GitHub issue |\n| `incident:snapshot` | Capture forensic snapshot |\n| `siem:install` | Install Wazuh SIEM agent |\n| `siem:status` | Check SIEM agent health |\n| `top` | Real-time system command center |\n| `top:shadow` | Visual dashboard of shadow deployments |\n\n**Plugins**\n\n| Command | Description |\n|---|---|\n| `plugin:list` | List all available plugins and status |\n| `plugin:enable \u003cplugin\u003e` | Enable a plugin globally |\n| `plugin:disable \u003cplugin\u003e` | Disable a plugin globally |\n\n**System**\n\n| Command | Description |\n|---|---|\n| `self:update` | Update to latest release |\n| `self:update --nightly` | Update to latest commit |\n| `self:global` | Install Protocol as global command |\n| `cron:add` | Auto-restart on reboot |\n| `cron:remove` | Remove reboot crontab entry |\n| `key:generate` | Generate SSH deploy key |\n| `open` | Open project in browser |\n| `nginx:logs` | Tail nginx and PHP-FPM logs |\n| `migrate` | Convert from branch to release mode |\n\n\u003c/details\u003e\n\nFull reference: [docs/commands.md](docs/commands.md)\n\n## Production Setup\n\nEvery production node follows the same recipe:\n\n```bash\n# 1. Install Protocol\ncurl -L \"https://raw.githubusercontent.com/merchantprotocol/protocol/master/bin/install\" | sudo bash\n\n# 2. Clone your app\ngit clone git@github.com:yourorg/yourapp.git /opt/yourapp\ncd /opt/yourapp\n\n# 3. Set environment and encryption key\nprotocol config:env production\nprotocol secrets:setup \"your-64-char-hex-key\"\n\n# 4. Start\nprotocol start\n\n# 5. Survive reboots\nprotocol cron:add\n```\n\nRepeat on every node. They're all identical. Scale up by adding nodes, scale down by stopping them.\n\n## The Big Picture\n\n```\n                          GitHub\n                    ┌──────────────────┐\n                    │  App Repo        │\n                    │  Config Repo     │\n                    │  Encrypted .env  │\n                    │  Release Tags    │\n                    └────────┬─────────┘\n                             │\n              ┌──────────────┼──────────────┐\n              ▼              ▼              ▼\n         Dev Machine    Staging Node   Prod Nodes\n         (localhost)    (staging)      (production)\n\n         protocol       protocol       protocol\n         start          start          start\n\n         Own branch     Own branch     Own branch\n         in config      in config      in config\n         repo           repo           repo\n```\n\nEach machine runs `protocol start`. Each gets its own config branch. They all share the same encryption key. Push code, tag a release, set the pointer — done.\n\n## Requirements\n\n| Requirement | Version |\n|---|---|\n| PHP | 8.1+ |\n| Git | 2.x+ |\n| Docker + Compose | 20.x+ / v2+ |\n| GitHub CLI (`gh`) | For release-based deployment |\n\nComposer is bundled — no separate install needed.\n\n## Documentation\n\n| Guide | What it covers |\n|---|---|\n| [Getting Started](docs/getting-started.md) | Full walkthrough from install to production |\n| [Deployment Strategies](docs/deployment-types.md) | Branch, release, and shadow mode compared |\n| [Secrets Management](docs/secrets.md) | Encryption, key distribution, GitHub Actions |\n| [Commands](docs/commands.md) | Every command with options and examples |\n| [Configuration](docs/configuration.md) | protocol.json, config repos, environments |\n| [Architecture](docs/architecture.md) | System design and data flow |\n| [SOC 2 Ready](docs/soc2.md) | Trust Service Criteria mapping, readiness checks, auditor guide |\n| [SOC 2 Controls Matrix](docs/soc2-controls-matrix.md) | Auditor evidence matrix — every SOC 2 criterion mapped to controls and evidence |\n| [Security \u0026 Hardening](docs/security.md) | Security controls, encryption internals, vulnerability scanning |\n| [Blue-Green Deploys](docs/blue-green.md) | Shadow deployments with instant rollback |\n| [Migration](docs/migration.md) | Upgrade from branch-based to release-based |\n| [Troubleshooting](docs/troubleshooting.md) | Common issues and fixes |\n\n## License\n\nMIT License. Copyright (c) 2019 [Merchant Protocol, LLC](https://merchantprotocol.com/)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmerchantprotocol%2Fprotocol","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmerchantprotocol%2Fprotocol","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmerchantprotocol%2Fprotocol/lists"}