Netlify is a powerful platform for deploying web applications, offering seamless integration with Git repositories and automatic deployment previews for pull requests. However, for private repositories with a large number of contributors, Netlify's billing model can lead to unexpectedly high costs. Each Git contributor who sends a pull request and creates a deployment preview in a private repository is counted towards your bill, even if they're not part of your Netlify team.
In this technical guide, we'll explore how to optimize your deployment workflow to reduce Netlify costs. We'll leverage GitHub Actions to create custom deployment previews, ensuring only authorized Netlify users contribute to your bill. Additionally, we'll discuss how tools like Warp Runners (not sponsored) can further optimize your CI/CD pipeline.
Understanding Netlify's Billing Model
Netlify charges for each user who triggers a build in private repositories. Specifically:
- Git Contributors: Any user who opens a pull request that results in a deployment preview is considered a billable user.
- Team Members: Users explicitly added to your Netlify team are also billable.
This means that in collaborative projects, especially those with many external contributors, costs can escalate quickly. For detailed information, refer to Netlify's Roles and Permissions documentation.
Solution Overview
To mitigate these costs, we can:
- Create Custom Deployment Previews: Use GitHub Actions to handle deployment previews instead of relying on Netlify's automatic previews.
- Authenticate Deployments with a Single Netlify User: Use a Netlify authentication token from a single team member to perform deployments.
- Optimize CI/CD Pipeline: Optionally integrate with services like Warp Runners to reduce build times and costs.
By implementing this solution, only the authenticated Netlify user contributes to your bill, regardless of how many contributors interact with your repository.
Implementing Custom Deployment Previews with GitHub Actions
Prerequisites
- GitHub Repository: A private repository where you have administrative access.
- Netlify Account: Access to your Netlify site's settings and the ability to generate personal access tokens.
- Node.js Project: Adjust commands accordingly if you're using a different technology stack.
Step 1: Set Up Netlify Authentication
Generate a Personal Access Token
- Log in to Netlify: Navigate to your Netlify dashboard.
- Access User Settings: Click on your avatar and select User Settings.
- Create a Token: Under Applications > Personal Access Tokens, click New access token.
-
Configure Token: Name the token (e.g.,
GitHub Actions Deploy
) and set the desired scopes. - Save the Token: Copy the generated token immediately, as it won't be shown again.
Add Secrets to GitHub
In your GitHub repository:
- Navigate to Settings: Go to Settings > Secrets and variables > Actions.
-
Create Repository Secrets:
-
NETLIFY_AUTH_TOKEN
: Paste the Netlify personal access token. -
NETLIFY_SITE_ID
: Find this in your Netlify site's settings under Site Information > Site ID.
-
Step 2: Create the Deployment Preview Workflow
Create a workflow file at .github/workflows/netlify-preview.yml
:
name: Netlify Preview Deployment
on:
pull_request:
branches: [main]
jobs:
deploy-preview:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build project
run: npm run build
- name: Install Netlify CLI
run: npm install -g netlify-cli
- name: Deploy Preview to Netlify
id: deploy
run: |
netlify deploy \
--auth ${{ secrets.NETLIFY_AUTH_TOKEN }} \
--site ${{ secrets.NETLIFY_SITE_ID }} \
--dir=build \
--message "${{ github.event.pull_request.title }}" \
--alias "deploy-preview-${{ github.event.pull_request.number }}"
- name: Post Deployment Comment
uses: marocchino/sticky-pull-request-comment@v2
with:
number: ${{ github.event.pull_request.number }}
header: deployment-preview
message: |
### ✅ Deployment Preview Ready
| Environment | URL |
|-------------|-----|
| <span aria-hidden="true">🔨</span> Latest commit | ${{ github.event.pull_request.head.sha }} |
| Preview | https://deploy-preview-${{ github.event.pull_request.number }}--your-site-name.netlify.app |
Important Considerations
-
Alias Uniqueness: The alias
deploy-preview-${{ github.event.pull_request.number }}
ensures each preview is isolated. - Authentication: The deployment uses the Netlify token from a single user, preventing additional contributors from affecting billing.
-
Environment Variables: Ensure
NETLIFY_AUTH_TOKEN
andNETLIFY_SITE_ID
are correctly set in your repository secrets. -
Site Name Replacement: Replace
your-site-name
with your actual Netlify site name in the preview URL.
Step 3: Test the Deployment Preview Workflow
- Open a Pull Request: Create or update a pull request in your repository.
- Check Actions Tab: Monitor the workflow's progress in the Actions tab.
-
Review Deployment:
- Confirm that the Netlify deployment preview is created.
- Verify that a comment with the preview URL is added to the pull request.
Step 4: Automate Deployment Status Updates (Optional)
To provide visual feedback in the pull request checks:
- name: Create Deployment Status
uses: actions/create-deployment@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
environment: 'Preview'
environment_url: 'https://deploy-preview-${{ github.event.pull_request.number }}--your-site-name.netlify.app'
This step updates the deployment status and integrates it with GitHub's deployment APIs.
Setting Up Production Deployments
For production deployments, we can use a separate workflow that triggers pushes to the main
branch or manually:
Step 1: Create the production deployment workflow
Create a file at .github/workflows/netlify-production.yml
:
name: Deploy Netlify Build to Production
'on':
workflow_dispatch: null
push:
branches:
- main
jobs:
trigger:
runs-on: ubuntu-latest
steps:
- name: Webhook Call to Netlify
run: 'curl -s -X POST -d {} "${NETLIFY_BUILD_HOOK_URL}"'
env:
NETLIFY_BUILD_HOOK_URL: '${{ secrets.NETLIFY_BUILD_HOOK_URL }}'
Step 2: Set Up Netlify Build Hook
- In your Netlify site dashboard, navigate to Site Settings > Build & Deploy > Build Hooks.
- Create a new build hook for production deployments.
- Copy the build hook URL.
- Add this URL as a secret (
NETLIFY_BUILD_HOOK_URL
) in your GitHub repository.
Step 3: Test the Workflow
Push a commit to the main branch or trigger the workflow manually. Netlify should start a production deployment of your site.
Optimizing CI/CD with Warp Runners
While GitHub Actions provides a robust platform, build times can become a bottleneck, especially with limited concurrent runners. Warp Runners offers a solution:
- Scalable Runners: Provides additional runners to handle increased workload.
- Cost Efficiency: Potentially reduces costs compared to upgrading GitHub Actions plans.
- Easy Integration: Compatible with existing GitHub Actions workflows.
Integration Steps
- Sign Up for Warp Runners: Create an account on their platform.
- Configure Runners: Set up runners according to your project's needs.
Update Workflows: Modify your workflows to use Warp Runners by specifying
runs-on
. Learn moreTest Workflows: Ensure that your workflows execute correctly with the new runners.
Additional Considerations
Security
- Access Tokens: Keep your Netlify access tokens secure. Use GitHub's encrypted secrets.
- Least Privilege: Generate tokens with the minimum required permissions.
- Audit Logs: Monitor Netlify and GitHub audit logs for unauthorized access.
Cleanup Deployments
Netlify retains all deployments by default. To prevent clutter:
- Manual Cleanup: Periodically delete old deployments from the Netlify dashboard.
- Automated Cleanup: Implement a script using Netlify's API to delete deployments associated with closed pull requests.
Environment Variables
If your build requires environment variables:
- Define in Netlify: Set environment variables in Netlify's UI for production builds.
-
Pass in Workflows: For previews, pass variables via the CLI or use a
.env
file.
Example:
- name: Set Environment Variables
run: |
echo "API_KEY=${{ secrets.API_KEY }}" >> .env
Conclusion
By shifting deployment previews to GitHub Actions and authenticating with a single Netlify user, you can significantly reduce Netlify billing costs associated with Git contributors in private repositories. This approach maintains the convenience of deployment previews while optimizing expenses.
Benefits Recap
- Cost Reduction: Only one Netlify user contributes to billing.
- Control: Full customization of the deployment pipeline.
- Scalability: Supports a large number of contributors without additional costs.
- Flexibility: Easily integrate with other tools and services.
By adopting these practices, you position your team to scale efficiently while keeping operational costs in check.
Stay connected and get more insights
If you found this guide helpful and are dealing with similar challenges, don't hesitate to reach out me on X. For more tech insights and updates, consider following me on GitHub. Let's innovate together!
Top comments (0)