Skip to main content

Introduction

Laravel Forge makes it easy to deploy your applications on demand, whether that be manually, automatically when pushing new code to your source control provider, or via a webhook from your CI platform of choice. You can see a list of your site’s deployments by navigating to the “Deployments” tab within your site’s management dashboard. Laravel Forge provides a paginated list of your site’s deployments, including what was deployed, when it was deployed, how long it took to be deployed, and also the output of your deploy script.
Deployments are limited to 10 minutes. If a deployment takes longer, it will fail automatically. If your site is integrated with Envoyer, Envoyer’s deployment limits apply instead.

Deployment strategies

Laravel Forge supports two deployment strategies, letting you choose the one that best fits your workflow.

Zero-downtime deployments

Zero-downtime deployments use a strategy where your new code is cloned into a special releases directory, and then a symbolic link is used to “activate” the new code once deployment is completed. This strategy greatly reduces the risk of your site going down during deployments, as the new code is only activated once all deployment steps have completed successfully. If any step in the deployment process fails, your site will continue to use the previous release.
Zero-downtime deployments are exclusively available for new sites and must be configured at the time of creation — they cannot be added to existing sites later.Laravel Forge automatically enables zero-downtime deployments for all new sites by default. If you prefer not to use this feature, you can disable it by toggling the “Zero-downtime deployments” option in the “Advanced settings” modal during site creation.

Release creation and activation

If you create a new site with zero-downtime deployments enabled, Laravel Forge will configure your site’s deployment script to include three special “macros”:
  • $CREATE_RELEASE() – creates the new release directory and clones your site’s code into it.
  • $ACTIVATE_RELEASE() – activates the new release by creating a symbolic link from the current directory to the new release directory.
  • $RESTART_QUEUES() - restarts any Laravel queues that are running for the site. Additionally, if your site is using Horizon, it will also restart the Horizon process.
It’s important that these commands are included in your deployment script as they are responsible for handling zero-downtime deployments. Failure to include these commands will result in your site not being deployed correctly.

Running tasks during deployments

Commands located after the $CREATE_RELEASE() macro will be executed in the context of the new release directory. This means that if you need to run any tasks that depend on your new code, you should place those commands after the macro. If you need to run any tasks after a new release has been activated, you should place those commands after the $ACTIVATE_RELEASE() macro.

Configuring deployment retention

By default, Laravel Forge retains the last 4 deployments when using zero-downtime deployments. This allows you to quickly rollback to a previous release if needed. You can change the number of deployments to retain by navigating to your site’s Settings tab and clicking Deployments. From there, you can adjust the number of deployments that Forge will keep on your server.

Shared paths

When using zero-downtime deployments, shared paths allow you to specify files or directories that should remain consistent across all releases. These paths are automatically symlinked from a shared storage location into each new release directory, ensuring that important data persists between deployments. Common use cases for shared paths include:
  • Storage directories – User uploads, generated files, and other application storage
  • Cache directories – Application caches that should persist between releases
  • Log files – Application logs that should be preserved across deployments
  • Environment files – The .env file (automatically shared by default)
For example, if you want to share the storage directory, you would add storage as a shared path. During each deployment, Laravel Forge will create a symbolic link from /home/forge/example.com/current/storage to the shared storage directory at /home/forge/example.com/storage.
By default, Laravel Forge automatically configures the .env file as a shared path for all sites using zero-downtime deployments.

Laravel Octane

Enabling zero-downtime is not necessary for applications running Laravel Octane, as Octane already provides zero-downtime deployments via its built-in graceful server restarts.

Standard deployments

The standard deployment strategy uses a simpler approach where your site’s code is kept in a single directory and updated in place during deployment. This strategy can be faster than zero-downtime deployments, but it does come with the risk of your site going down if a deployment step fails midway through the deployment process. edited api-reference/rate-limiting.mdx

Push to deploy

Laravel Forge’s “Push to deploy” feature allows you to easily deploy your projects when you push new code to your source control provider. When code is pushed to your site’s configured branch, Laravel Forge will automatically trigger a new deployment and run your site’s deployment script. Push to deploy is enabled by default for new sites created with GitHub, GitLab, or Bitbucket. If you wish to disable this feature, you may do so by toggling the “Push to deploy” toggle inside of the “Advanced settings” modal. To enable push to deploy for existing sites, you may do so by enabling the “Push to deploy” toggle on the “Deployments” tab of your site’s settings. For sites using a custom source control provider you will need to manually set up a “Deployment hook” to have your code deployed when you push to your source provider.

Deploy script

When a deployment is triggered, Laravel Forge will execute the commands defined in your site’s deploy script. At a minimum, your deploy script should contain the commands needed to update your site’s codebase (such as a git pull or $CREATE_RELEASE() macro), install any dependencies (such as composer install or npm ci), and perform any other tasks needed to get your application up and running (such as php artisan migrate --force).

Environment variables

Laravel Forge will automatically inject a number of environment variables into your deployment script at runtime. These variables are configured to provide information about the deployment itself, the site, and the server.
KeyDescription
FORGE_COMPOSERThe path to the Composer installation.
FORGE_CUSTOM_DEPLOYWhether the deployment was triggered with a custom deployment trigger request.
FORGE_DEPLOY_AUTHORThe author of the commit.
FORGE_DEPLOY_COMMITThe Git hash of the commit being deployed.
FORGE_DEPLOY_MESSAGEThe Git commit message.
FORGE_DEPLOYMENT_IDThe Laravel Forge assigned ID of this deployment.
FORGE_MANUAL_DEPLOYWhether the deploy was triggered by clicking “Deploy Now”.
FORGE_PHP_FPMThe PHP-FPM process name that is being used by Laravel Forge.
FORGE_PHPThe php binary that is being used by the Laravel Forge site or server.
FORGE_QUICK_DEPLOYWhether the deploy was triggered by a source control provider webhook.
FORGE_REDEPLOYWhether this is a re-deployed commit.
FORGE_RELEASE_DIRECTORYThe path of the current release when zero-downtime deployment is enabled.
FORGE_SERVER_IDThe ID of the Laravel Forge server that is being deployed to.
FORGE_SITE_BRANCHThe name of the branch that is being deployed.
FORGE_SITE_IDThe ID of the Laravel Forge site that is being deployed to.
FORGE_SITE_PATHThe root of the deployment path, e.g., /home/forge/mysite.com/current
FORGE_SITE_ROOTThe site’s root directory, e.g., /home/forge/mysite.com
FORGE_SITE_USERThe name of the user deploying the site.
You may use these variables as you would any other Bash variable:
if [[ $FORGE_MANUAL_DEPLOY -eq 1 ]]; then
    echo "This deploy was triggered manually."
fi
For example, you may wish to prevent deployments if the commit message contains “wip”:
if [[ $FORGE_DEPLOY_MESSAGE =~ "wip" ]]; then
    echo "WORK IN PROGRESS, DO NOT CONTINUE."
    exit 1
fi
Laravel Forge prefixes injected variables with FORGE_.We do not recommend using this “namespace” when defining your own variables to avoid potential conflicts.

Making .env variables available

Laravel Forge makes it easy to include your site’s .env variables in your deploy script. You may enable this feature by navigating to the “Deployments” tab of your site’s settings and checking the “Make .env variables available to deployment script” checkbox. When enabled, Laravel Forge will automatically inject the variables in your site’s .env file into the deploy script, allowing them to be accessed like any normal Bash variable:
echo "${APP_NAME} is deploying..."

PHP versions

New sites created with Laravel Forge will use the $FORGE_PHP environment variable when invoking PHP commands in the deployment script. This variable will always point to the correct PHP binary for the site, so no additional changes are needed to your deployment script when switching your site’s PHP version.
The php command will always point to the active version of PHP used on the CLI. This is configured at the server level and may be different to the PHP version used by your site.If you need to use a specific version of PHP, you must use the phpx.x command where x.x reflects on the version required (e.g., php8.4).

Restarting background processes

When deploying applications that use background processes such as daemons, you may need to restart the process to ensure it picks up your code changes. You can do this by adding the restart command to your deployment script:
# Restart your daemon (replace 12345 with your daemon's ID)...
sudo supervisorctl restart daemon-12345:*
If your site is using zero-downtime deployments, you should place the restart command after the $ACTIVATE_RELEASE() macro to ensure the new code is activated before the process is restarted.

Deploying from CI

If you wish to trigger deployments from CI, or from a source control provider that is not currently supported by Laravel Forge, you may do so by using “deployment hooks” or the Forge CLI.

Deployment hooks

Deployment hooks are special webhooks that Laravel Forge provides for each site. You may trigger a deployment by making a GET or POST request to the deployment trigger URI provided. To find your site’s deployment hook URI, navigate to the “Deployments” tab of your site’s settings. You will find a “Deploy hook” section with the URI that you can quickly copy to your clipboard.

Refreshing the deployment token

Each deploy hook contains a unique token that is used to authenticate the request. If you wish to regenerate this token, you may do so by clicking the “Refresh” icon button next to the deploy hook URI.
Refreshing the deployment token will immediately invalidate the previous token. Any services that are using the previous token will need to be updated to use the new token.

Using query parameters

You may pass additional data when triggering a deployment using query parameters. Laravel Forge will detect the following “reserved” query parameters and use them to populate specific information about the deployment:
ParameterEnvironment variableDescription
forge_deploy_branchThe branch that contains the commit. The deployment is only triggered if the branch matches the site’s configured deployment branch.
forge_deploy_commitFORGE_DEPLOY_COMMITThe hash of the commit being deployed.
forge_deploy_authorFORGE_DEPLOY_AUTHORThe author of the commit.
forge_deploy_messageFORGE_DEPLOY_MESSAGEThe commit message.
In addition to the reserved parameters, you may also pass custom parameters that will be injected into your deployment script. For example, if you pass the query parameter &env=staging to the deployment hook URL, Laravel Forge will inject a FORGE_VAR_ENV variable into your deployment script that will evaluate to "staging".

Forge CLI

If you need to have access to the deployment output or execute additional deployment actions such as restarting services, you should use the Forge CLI. Once you have installed and configured the Forge CLI on your CI platform, you may execute the forge deploy command.
To authenticate with Laravel Forge from your CI platform, you will need to add a FORGE_API_TOKEN environment variable to your CI build environment.You may generate an API token from your Laravel Forge API settings dashboard. Your CI platform will also require SSH access to your server.

GitHub Actions example

If your site uses GitHub Actions as its CI platform, the following guidelines will assist you in configuring Laravel Forge deployments so that your application is automatically deployed when someone pushes a commit to the main branch:
  1. First, add the FORGE_API_TOKEN environment variable to your “GitHub > Project Settings > Secrets” settings so that GitHub can authenticate with Laravel Forge while running actions.
  2. Next, add the SSH_PRIVATE_KEY environment variable to your “GitHub > Project Settings > Secrets” settings so that GitHub can have SSH Access to your site’s server.
  3. Then, create a deploy.yml file within the your-project/.github/workflows directory. The file should have the following contents:
.github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Setup SSH
        uses: webfactory/[email protected]
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: 8.4
          tools: composer:v2
          coverage: none
      - name: Require Laravel Forge CLI
        run: composer global require laravel/forge-cli
      - name: Deploy Site
        run: |
          forge server:switch your-server-name
          forge deploy your-site-name.com
        env:
          FORGE_API_TOKEN: ${{ secrets.FORGE_API_TOKEN }}
  1. Finally, you can edit the deploy.yml file to fit your site’s deployment needs, as it may require a different PHP version or a library like npm. Once you are done, commit and push the deploy.yml file to the main branch so GitHub Actions can run the first deployment job.

Deployment branch

It is possible to change which branch is deployed on the “Deployments” tab of your site’s settings. If your site uses the zero-downtime deployment strategy, Laravel Forge will automatically use the newly configured branch on the next deployment. For standard deployments, ensure that your deployment script uses the $FORGE_SITE_BRANCH environment variable when pulling new code, or update any manual references to the branch in your deployment script.

Deployment health checks

After enabling deployment health checks, Forge will ping your application from several regions around the world to make sure the application is still accessible and returns a successful HTTP status code. If the site is not accessible after a deployment, Forge will notify you. To enable health checks, navigate to your site’s “Settings” tab, then click “Deployments”. Then, enable the “Health check” toggle. After enabling health checks, you can optionally configure the URL that Forge will ping after each deployment.

Deployment notifications

You can enable deployment notifications for your site from the site management dashboard’s “Notifications” tab. Laravel Forge supports several notification channels:
  • Email
  • Slack
  • Telegram
  • Discord
By default, Laravel Forge will automatically notify you by email for failed deployments.

Slack

To enable Slack notifications, first enter the Channel name that you wish to send messages to, and then click “Enable Slack Notifications”. You will be redirected to the Slack application authorization page, where you need to click “Allow”. If you wish to modify the channel that Laravel Forge messages, you should first disable Slack notifications and then re-enable them for your site.

Telegram

To enable Telegram notifications, open Telegram and create or select a group chat that you want Laravel Forge to send deployment notifications to. Next, you should add the Laravel Forge bot to the chat by searching for the user laravel_forge_telegram_bot. Finally, copy the /start command, provided by Forge under the Telegram Deployment Notifications section, and paste it into the chat. If you wish to change the group that Laravel Forge messages, you should disable Telegram notifications and then follow the above steps again to reactivate notifications.

Discord

To enable Discord notifications, you first need to create a new “Incoming Webhook” integration on your Discord server. Once Discord has generated a webhook, you need to copy the URL into the “Webhook URL” field, then click “Enable Discord Notifications”. Laravel Forge will now notify the configured channel for both successful and failed deployments. If you wish to change the webhook URL, you first need to disable Discord notifications and then re-enable the notifications.

Webhooks

Laravel Forge can also send an HTTP POST request to arbitrary URLs after each deployment. The payload of the request will contain the server ID, site ID, deployment status, and the relevant commit information:
{
  "status": "success",
  "server": {
    "id": 123,
    "name": "my-awesome-server"
  },
  "site": {
    "id": 456,
    "name": "my-awesome-site.dev"
  },
  "commit_hash": "382b0f5185773fa0f67a8ed8056c7759",
  "commit_url": "https://github.com/johndoe/my-awesome-site/commit/382b0f5185773fa0f67a8ed8056c7759",
  "commit_author": "John Doe",
  "commit_message": "deploying!"
}
I