innocenzi/deployer-recipe-forge
Composer 安装命令:
composer require innocenzi/deployer-recipe-forge
包简介
Seamless zero-downtime deployment on Forge with Deployer
README 文档
README
Seamless zero-downtime deployment on Forge with Deployer
composer require --dev innocenzi/deployer-recipe-forge
About
deployer-recipe-forge is a recipe for Deployer that helps implementing zero-downtime on Laravel Forge.
It uses Forge's API to fetch a site's credentials, such as its IP address and the remote username, so you don't have to hardcode them in your deploy.php. It automatically finds the right Forge site using your repository's name, so the only configuration to do happens on Forge.
Additionally, it's able to send notifications on Slack with either Deployer's integration, which requires that you setup a webhook, or by pinging Forge's deployment URL.
Installation
Install the package as a development dependency:
composer require --dev innocenzi/deployer-recipe-forge
Then, create a deploy.php file at the root of your project. Import the autoloader, and call \Deployer\Forge::make()->configure();. You may then customize your deployment script as usual with Deployer.
namespace Deployer; // This is required require __DIR__ . '/vendor/autoload.php'; \Deployer\Forge::make()->configure(); // This is your custom deployment script task('deploy:build', function () { // build assets here runLocally('bun i'); runLocally('bun run build'); });
Usage
Setting up the repository
This recipe is designed to be used within a GitHub workflow, using the action provided by Deployer.
Setting it up requires at least two repository secrets:
- Your server's private SSH key, which will be used by
deployphp/actionto SSH - Your Forge API token, which will be used by the recipe to fetch your site and server's credentials
These repository secrets must then be forwarded to the action as environment variables, or, for the SSH key, as the private-key argument:
- uses: deployphp/action@v1 with: private-key: ${{ secrets.PRIVATE_SSH_KEY }} dep: deploy env: FORGE_API_KEY: ${{ secrets.FORGE_API_KEY }} REPOSITORY_BRANCH: ${{ github.ref_name }} REPOSITORY_NAME: ${{ github.repository }}
Warning
Note that the REPOSITORY_BRANCH and REPOSITORY_NAME variables are required for the recipe to work, since they are used to match your site and branch to your site Forge.
Note
For convenience, if you are using a paid GitHub plan, you may setup your Forge API token and Slack webhook as organization-wide secrets.
Setting up Forge
Creating a new site
The following steps explain how to setup a new site on Forge to work with this recipe on GitHub Actions.
-
Create an isolated site.
Currently, this recipe only works with isolated Forge sites. You must then create an isolated site.
-
Install the repository using the GitHub integration.
You may uncheck "install composer dependencies" to make the installation faster, as the site directory will be erased anyway.
If you haven't associated the server's deploy key with your GitHub repository, make sure that you do or that you create a deploy key for this site. -
If necessary, add the server's public key (
~/.ssh/id_rsa.pub) to the repository's deploy keys.This will allow Deployer to clone the repository from its SSH session on the server.
-
SSH into the server to copy its public key (
~/.ssh/id_rsa.pub) and add it to the server's authorized keys on Forge.This is the first step to allow the Deployer action to SSH into the server.
The key should be associated to the correct isolated site username. -
Finally, copy the server's private key (
~/.ssh/id_rsa) and add it to the repository's secrets.This is the last step to allow the Deployer action to SSH into the server.
We suggest naming the secret after the target environment. For instance, if you are creating a staging site, it may be namedSTAGING_SSH_KEY. -
You may then trigger the deployment workflow.
Adding to an existing site
First, make sure the website is isolated. It must be located at /home/<isolated-username>/<site-name> on the server. Otherwise, you must create a new isolated site.
You must first backup your .env file and storage directory, since Deployer will delete the site's directory to replace it with a symlink.
After backing them up, you may follow steps 3 to 6. Once the deployment is complete, you may restore your .env and storage in /home/<isolated-username>/deployer/<site-name>/shared.
Warning
Proceed with caution. Make sure to put the site on maintenance and think of the potential side-effects that may happen during this migration.
Slack notifications
Using Deployer
This recipe supports sending Slack notifications using a webhook. To create it, you may follow Slack's documentation on the topic. You must then add the webhook as a repository or organization secret, and forward it to the action as an environment variable.
- uses: deployphp/action@v1 with: private-key: ${{ secrets.PRIVATE_SSH_KEY }} dep: deploy env: # ... # Add these two SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} RUNNER_ID: ${{ github.run_id }}
Note
Note that RUNNER_ID is required, because the Slack notifications link to the associated GitHub workflow.
Using Forge
Alternatively, you may set up Slack notifications on Forge, and trigger a deployment on Forge. This way, you also get to use Forge's deployment history.
To trigger the deployment on Forge, simply call triggerDeploymentsOnForge:
\Deployer\Forge::make() ->triggerDeploymentsOnForge() ->configure();
Warning
When using this strategy, make sure to empty the default deployment script configured by Forge.
Multiple environments
This recipe supports deploying to multiple environments, such as staging or production, without any specific configuration, other than adding the different private SSH keys to your repository secrets.
It works by associating the repository branch to the one defined on the Forge site. For instance, you may have a main branch associated to example.com, and a develop branch associated to staging.example.com.
For two environments
The private SSH key must be provided to the private-key argument, for instance using a conditional, as follows:
- uses: deployphp/action@v1 with: private-key: ${{ github.ref_name == 'develop' && secrets.STAGING_SSH_KEY || secrets.PRODUCTION_SSH_KEY }} dep: deploy env: # ...
For more environments
If you have more than two environments, you may simply duplicate the actions and use an if statement to ensure they run for the correct branches:
steps: - name: Deploy (staging) if: github.ref_name == 'develop' uses: deployphp/action@v1 with: private-key: ${{ secrets.STAGING_SSH_KEY }} dep: deploy # ... - name: Deploy (production) if: github.ref_name == 'main' uses: deployphp/action@v1 with: private-key: ${{ secrets.PRODUCTION_SSH_KEY }} dep: deploy # ...
Building on CI or on server
By default, the recipe will build assets on CI, and upload them on the server after. To build on the server, call buildOnServer:
\Deployer\Forge::make() ->buildOnServer() ->configure();
Note that, by default, no deploy:build task is provided, and you should write your own. For instance, you may build assets using Bun:
\Deployer\Forge::make()->configure(); task('deploy:build', function () { runLocally('bun i'); runLocally('bun run build'); });
Obviously, make sure Bun is installed on CI before using that example.
Example workflow
This workflow deploys on production or staging, depending on the branch that pushed, after running the test.yml and style.yml workflows. It will skip deployments if the commit body contains [skip deploy], and will notify about deployments on Slack.
Additionally, you may dispatch the workflow manually.
name: Deploy on: workflow_dispatch: push: branches: [main, develop] concurrency: group: ${{ github.ref }} jobs: test: uses: ./.github/workflows/test.yml style: uses: ./.github/workflows/style.yml deploy: needs: [test, style] if: ${{ !contains(github.event.head_commit.message, '[skip deploy]') }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: shivammathur/setup-php@v2 with: php-version: 8.2 - uses: oven-sh/setup-bun@v1 with: bun-version: latest - name: Install dependencies run: composer install --no-interaction --prefer-dist - uses: deployphp/action@v1 with: private-key: ${{ github.ref_name == 'develop' && secrets.STAGING_SSH_KEY || secrets.PRODUCTION_SSH_KEY }} dep: deploy env: FORGE_API_KEY: ${{ secrets.FORGE_API_KEY }} SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} REPOSITORY_BRANCH: ${{ github.ref_name }} REPOSITORY_NAME: ${{ github.repository }} RUNNER_ID: ${{ github.run_id }}
Using dep locally
Since the recipe depends on multiple environment variables, you cannot easily call vendor/bin/dep locally.
You may work around that limitation by adding FORGE_API_KEY to your .env, as well as REPOSITORY_NAME and REPOSITORY_BRANCH:
FORGE_API_KEY="abc...123" REPOSITORY_NAME="yourorg/repo" REPOSITORY_BRANCH="develop"
Then, you may add the following script to composer.json, and run composer dep instead of vendor/bin/dep:
"dep": "set -o allexport && source ./.env && set +o allexport && vendor/bin/dep"
Warning
Using dep locally will create a .deployer_cache file, which you should add to .gitignore.
Note
If you get denied SSH access, make sure to add your public key on your server and associate it to your site's user.
Q&A
Why not Envoyer?
Envoyer's integration with Forge removes the convenience of being able to manage everything within Forge directly, instead forcing us to juggle between two different user interfaces. Our developer experience is better with Deployer and this recipe.
Why are issues closed?
This recipe is mostly used internally at Jetfly, and we are not willing to do support for it nor add many features. Pull requests for fixes and small additions may be welcome, though.
innocenzi/deployer-recipe-forge 适用场景与选型建议
innocenzi/deployer-recipe-forge 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 16.67k 次下载、GitHub Stars 达 19, 最近一次更新时间为 2023 年 09 月 09 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「laravel」 「deployment」 「deployer」 「laravel-force」 「zero-downtime」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 innocenzi/deployer-recipe-forge 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 innocenzi/deployer-recipe-forge 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 innocenzi/deployer-recipe-forge 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Automated deployment template for Laravel Envoy based on Capistrano.
Deployer.org based deployment for Symfony4 with media and database synchronisation.
Morpht Development Tools
blueways deployer recipes
A Highly Opinionated Symfony3/4 Deployer Recipe
Composer based WordPress deployment with deployer.org.
统计信息
- 总下载量: 16.67k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 19
- 点击次数: 17
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2023-09-09