{"id":41499509,"url":"https://github.com/ronanchilvers/deploy","last_synced_at":"2026-01-23T19:03:25.258Z","repository":{"id":38171685,"uuid":"178740029","full_name":"ronanchilvers/deploy","owner":"ronanchilvers","description":"A deployment tool for PHP web projects","archived":false,"fork":false,"pushed_at":"2025-03-20T11:40:48.000Z","size":1178,"stargazers_count":1,"open_issues_count":18,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-20T12:45:24.270Z","etag":null,"topics":["deployment"],"latest_commit_sha":null,"homepage":"","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/ronanchilvers.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-31T20:42:25.000Z","updated_at":"2024-09-12T07:11:14.000Z","dependencies_parsed_at":"2025-03-22T00:30:27.333Z","dependency_job_id":null,"html_url":"https://github.com/ronanchilvers/deploy","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/ronanchilvers/deploy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronanchilvers%2Fdeploy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronanchilvers%2Fdeploy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronanchilvers%2Fdeploy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronanchilvers%2Fdeploy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ronanchilvers","download_url":"https://codeload.github.com/ronanchilvers/deploy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronanchilvers%2Fdeploy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28698344,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-23T17:25:48.045Z","status":"ssl_error","status_checked_at":"2026-01-23T17:25:47.153Z","response_time":59,"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":["deployment"],"created_at":"2026-01-23T19:03:22.739Z","updated_at":"2026-01-23T19:03:25.246Z","avatar_url":"https://github.com/ronanchilvers.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# deploy\n\n[![Actions Status](https://github.com/ronanchilvers/deploy/workflows/Unit%20Tests/badge.svg)](https://github.com/ronanchilvers/deploy/actions)\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/ronanchilvers/deploy/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/ronanchilvers/deploy/?branch=master)\n\nA tool for simple deployments to a single server (for now) from common source control providers.\n\n* Github, Gitlab and Bitbucket support\n* Zero downtime deployments with rollbacks\n* Fine grained control of deployments using a repository based configuration file\n* Responsive UI - fully usable on any device\n* Shared and writable path support\n* Arbitrary hook support\n* Slack notifications\n* Simple user account management\n\n## Installation\n\n`deploy` has a couple of requirements to run.\n\n* PHP 7.1.8+\n* Beanstalkd work queue (available as standard in most linux distributions)\n* A backend database supported by [PDO](https://www.php.net/pdo) and [phinx](https://github.com/cakephp/phinx)\n* [composer](https://getcomposer.org/) for `deploy` dependency installation\n\nIn addition it is *strongly* recommended that you use an RDBMS like MySQL, MariaDB or PostgreSQL to host the database. The default SQLite database is suitable for development but you will almost certainly run into database contention locks if you use it in production.\n\n`deploy` includes a queue runner that does the heavy lifting. You can run this via cron if you want to but I recommend using supervisord (again available in most linux distributions in the standard package catalogue).\n\nOnce you have the required software installed on the host you can then get on with the installation.\n\n### Generating Provider Tokens\n\n`deploy` currently supports the three main VCS providers - Github, Gitlab and Bitbucket. Not all have to be configured for `deploy` to work but you will need at least one!\n\n**NB:** In the examples below we add each configuration variable to the `providers` section. Just in case its not clear, you should only have a single `providers` section and each set of credentials should be added below it. See the `local.yaml.dist` file as a reference.\n\n#### Github Personal Access Token\n\nTo generate a personal access token, navigate to [your Personal access tokens settings page](https://github.com/settings/tokens). Generate a token with the `repo` scope enabled - no others are needed. Add the token to your `deploy` configuration in the `providers` section like this:\n```yaml\nproviders:\n  github:\n    token: thisismysuperlongtokensecret\n```\n\n#### Gitlab Personal Access Token\n\nVisit the [Personal Access Tokens page](https://gitlab.com/profile/personal_access_tokens) in your Gitlab account and generate a token with `api` scope. You can add an expiry date if you want to but don't forget to replace it when the time comes!! (I'd recommend not setting an expiry or setting a very long one). Then add your token to the `providers` section like this:\n```yaml\nproviders:\n  gitlab:\n    token: fancygitlabtokengoeshere\n```\n\n#### Bitbucket App Password\n\nFor Bitbucket support `deploy` currently uses an app password. This may change in future though. At the moment you can generate one by visiting Bitbucket Settings \u003e Access Management | App Passwords. Once in there generate a new token with `Repositories \u003e Read` scope. Then add your username and app password to your `deploy` configuration like this:\n```yaml\nproviders:\n  bitbucket:\n    username: myusername\n    token: shineyapppasswordhere\n```\n\n### Codebase setup\n\n* Create a database and database user in your chosen DBMS. `deploy` needs CREATE, DROP, ALTER, SELECT, INSERT, UPDATE, DELETE, INDEX permissions. For MariaDB / MySQL it's likely to be something like this:\n```sql\nCREATE DATABASE `deploy`;\nCREATE USER `deploy`@`localhost` IDENTIFIED BY `verystrongpassword`;\nGRANT CREATE, DROP, ALTER, SELECT, INSERT, UPDATE, DELETE, INDEX ON `deploy`.* TO `deploy`@`localhost`;\n```\n\n* Clone this repository into an appropriate place on your server\n```bash\ngit clone https://github.com/ronanchilvers/deploy.git deploy\ncd deploy\n```\n\n* Install dependencies\n```bash\ncomposer install\n```\n\n* Create the local configuration. Instructions are provided within the file. See above for some guidance on generating tokens to use with the various VCS providers.\n```bash\ncp local.yaml.dist local.yaml\n```\n\n* Run phinx database migrations\n```bash\nphp vendor/bin/phinx migrate\n```\n\n* Create a user.\n```bash\nphp bin/console user:create \"Fred Bloggs\" fred@foobar.com\n```\n\n* Make sure the log and twig directories are writable by the web server. I'm assuming here that your web server runs as www-data group and that you've checked out the codebase with that group set.\n```bash\nchmod g+w var/log var/twig\n```\n\n* You should now be able to navigate to the URL you've installed `deploy` under and login.\n\n### Queue worker setup\n\nWe assume here that you're using supervisord to run the queue worker. You'll find a sample supervisord program configuration file in the `docs/` subdirectory. One point to note - in order to run correctly composer requires that either the `HOME` or `COMPOSER_HOME` environment variables are set. You can [read more about it here](https://getcomposer.org/doc/03-cli.md#composer-home).\n\n* Copy the sample config file into supervisor's program directory (usually something like `/etc/supervisor/conf.d`) or include the contents in supervisor's main configuration file.\n* Update the supervisor configuration appropriately for your environment.\n* Ask supervisor to update it's configuration\n```bash\nsudo supervisorctl update\n```\n* You should now see the queue worker running under supervisor control\n```bash\nsudo supervisorctl status\n```\n\n## Creating deployments\n\n`deploy` organises deployments by project. Each project is deployed into its own directory in the filesystem. `deploy` maintains a set of deployments for a project, one of which can be the active one. You can control how many deployments are kept for each project using the `deploy.yaml` configuration file (see below for details).\n\nCreating a project is simply a matter of clicking 'Add Project' in the navigation bar at the top, filling in the details and clicking 'Save'. You will then be show the project view. To deploy the project, click the 'Deploy' button at the top right, choose the branch or tag you want to deploy and then click the red 'Deploy Now' button. The 'Output' tab below will show you the progess of the deployment steps.\n\nYou can also deploy your project using a webhook. When you have added a project, on the project view, click the cog icon next to the 'Deploy' button to edit the project. At the bottom of the page is a 'Webhook Deployments' section which shows the unique URL for triggering a project deployment. You can call this URL in a commit hook or from your CI pipeline as a post-build hook so that the project is deployed automatically.\n\n## Controlling deployments\n\n`deploy` can be customised per project by using directives in a file named `deploy.yaml` placed in the root of the project working copy. Using this file you can assign paths that should be writable (folders only), define shared paths (files or folders), assign hooks to run before or after specific stages, define specific paths that should be removed when deploying (files or folders) and several other things.\n\n### Directives\n\n- `notify` - This directive controls notifications when deploying code. Currently only slack is implemented but support is planned for other services.\n```yaml\nnotify:\n  slack:\n    webhook: https://hooks.slack.com/services/12345679/ABCDE/FGHIJK\n```\n\n- `composer` - This directive allows you to control the behaviour of the composer dependency manager, assuming that it is used in your project. If `deploy` doesn't find a `composer.json` file in the root of your working copy, composer support is disabled and this directive has no effect.\n  - `command` - Define the command composer will install dependencies with. The default is `install --no-interaction --prefer-dist --no-dev --optimize-autoloader`\n```yaml\ncomposer:\n  command: install --no-dev -o\n```\n\n- `shared` - Define shared folders or files. These are locations that persist between deployments, for example a cache directory or configuration file. The `files` and `folders` subkeys can be used to define a list or files or folders that should be shared. Paths are always relative to the root of the deployment working copy.\n```yaml\nshared:\n  files:\n    - config.php\n    - .env\n  folders:\n    - var/cache\n    - var/uploads\n```\n\n- `writables` - Define writable folders. These locations will be configured to be writable by the using a `chmod` command. The default mode for writable folders is '0770' (user and group readable / writable). Note it is possible for a folder to be both shared *and* writable.\n```yaml\nwritables:\n  paths:\n    - var/cache\n    - var/uploads\n```\nNB: Changing the writable mode used cannot be done via `deploy.yaml` but can be done in your local.yaml file with the following keys. Note that using '0777' is *never* recommended - if you need it, you should take that as a sign that your permission structure is wrong.\n```yaml\nbuild:\n  chmod:\n    writable_folder: '0770'\n```\n\n* `clear_paths` - Define a list of files or folders that should be removed on deployment. This action happens right before activation (switching the new deployment live) and therefore its safe to delete files like composer.json / composer.lock / package.json, etc (unless you have a hook that needs them of course - see below). You can also remove the `deploy.yaml` file if you want to - its not required to be on disk.\n```yaml\nclear_paths:\n  paths:\n    - README.md\n    - package.json\n    - composer.json\n    - composer.lock\n    - deploy.yaml\n```\n\n### Hooks\n\n`deploy` supports running arbitrary hooks before and after each deployment action. You can specify any CLI command and it will run using the permissions of the user your queue worker runs as via supervisor. The deployment actions are:\n\n- `create_workspace`\n- `checkout`\n- `composer`\n- `shared`\n- `writables`\n- `clear_paths`\n- `activate`\n- `finalise`\n- `cleanup`\n\nYou can define `before` or `after` hooks for any of these actions by adding a new list to your `deploy.yaml` file. For example:\n```yaml\ncomposer:\n  after:\n    - /usr/bin/php scripts/post_dependency_script.php\n    - /bin/bash scripts/my_bash_script.sh arg1 arg2\nactivate:\n  before:\n    - /usr/bin/php vendor/bin/phinx migrate\nshared:\n  after:\n    - /usr/bin/php scripts/make_sure_shared_files_are_populated.php\n```\nObviously the above configuration is made up to illustrate the point - you can run anything you need to make your deployment work. The `activate.before` hook shows an example of running the [phinx](https://github.com/cakephp/phinx) database migrations tool to automatically update the database schema prior to activation.\n\n## Example deploy.yaml\n\n```yaml\n---\nnotify:\n  slack:\n    webhook: https://hooks.slack.com/services/12345679/ABCDE/FGHIJK\ncomposer:\n  install: install --no-dev -o\n  after:\n    - /usr/bin/php scripts/myscript.php\nshared:\n  files:\n    - \".env.config.ini\"\n  folders:\n    - var/log\n    - var/cache\n    - var/db\nwritables:\n  paths:\n    - var/log\n    - var/cache\nclear_paths:\n  paths:\n    - README.md\n    - package.json\n    - deploy.yaml\n  after:\n    - /usr/bin/php vendor/bin/phinx migrate\n```\n\n## Roadmap (sort of!)\n\n### Things to do\n\n* [ ] Unit tests!\n\n### Things that are done\n\n* [x] Bitbucket support\n* [x] Ability to trigger a deployment using a webhook\n* [x] Implement re-activation rather than deployment for old releases (change of symlink)\n* [x] Block deployments for a project when one is queued or in progress\n* [x] Better user account support\n* [x] User accounts\n* [x] Hooks\n* [x] Notifications\n* [x] Ability to deploy a specific branch\n* [x] Associate deployments with users\n* [x] Make sure project keys are unique\n\n## Things to think about\n\n* [ ] Show git history since the current active deployment\n* [ ] Environment variable support\n* [ ] Ability to keep specific releases\n* [ ] Allow different / extended defaults for specific frameworks\n* [ ] Multi-server support\n\n## Useful notes (for development)\n\n* https://developer.github.com/v3/repos/contents/#get-contents\n* https://mattstauffer.com/blog/introducing-envoyer.io/\n* https://docs.gitlab.com/ee/api/repositories.html#get-file-archive\n* https://stackoverflow.com/questions/35160169/bitbucket-how-to-download-latest-tar-gz-file-of-a-bitbucket-repo-programmatical\n* https://stackoverflow.com/questions/17682143/download-private-bitbucket-repository-zip-file-using-http-authentication\n* https://community.atlassian.com/t5/Bitbucket-questions/How-to-download-repository-as-zip-file-using-the-API/qaq-p/862113\n* https://confluence.atlassian.com/bitbucket/app-passwords-828781300.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fronanchilvers%2Fdeploy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fronanchilvers%2Fdeploy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fronanchilvers%2Fdeploy/lists"}