Regarding app deployment on Fly, their documentation excellently outlines the simplicity of utilizing commands like
fly launch
followed by fly deploy
, which seamlessly sets up an app on the Fly dashboard and assigns VMs for both
the main application and its database. However, a notable omission is the inability to establish preview environments
directly from the main application. Luckily I found one github action called superfly/fly-pr-review-apps,
but there are some issues with the action , which throws an error if we directly implement it. So we have forked (codemancers/fly-pr-review-apps)
the repository into our organization and made some modifications and optimizations, which resulted in generating a preview URL smoothly.
Brief Overview of What This Blog Will Guide You Through
This guide is designed to assist in creating a preview environment on Fly upon the initiation of a pull request, ensuring that the primary application and database instances remain unaffected.
Diving straight into the magic!
Requirements
- Make sure you have a personal/organisation account in fly.
- Create an organization token in Fly by navigating to dashboard -> tokens.
- Ensure you have an existing Dockerfile that is used for building our app in the production environment.
- Ensure you have an existing fly.toml file that is used for the production environment.
- Make sure to set all the app secrets beforehand in GitHub secrets.
- Provision a Postgres cluster in Fly that will be exclusively used for preview environments (the reason will be clarified in later steps).
Once all the prerequisites are ready, we can proceed.
Create a preview YAML file in your .github/workflows
directory. I will name it as fly-preview.yml.
Obviously, I will explain each and every step; don't worry, I've got you covered.
Workflow Name
This sets the name of the workflow as "Preview App," which appears in the GitHub Actions section of your repository.
Trigger Event
The workflow is activated by pull request events, specifically when a PR is opened, reopened, synchronized (updated), or closed.
Environment Variables
Global environment variables are defined:
FLY_API_TOKEN: The Fly.io API token, fetched from GitHub Secrets, for authentication. FLY_REGION: Specifies the deployment region on Fly.io. FLY_ORG: The Fly.io organization under which the apps will be deployed.
Jobs
The workflow includes a job named staging_app that utilizes the latest Ubuntu runner from GitHub Actions.
Concurrency
This configuration ensures a single deployment per PR at any time, avoiding conflicts or resource duplication.
Environment
Creates a unique GitHub deployment environment for each staging app, linked to the PR UI, with the url dynamically reflecting the deployed app's URL.
Steps
The job comprises several steps for deploying the application:
- Checkout: Fetches the repository code for workflow use.
- Setup Flyctl: Installs Fly CLI (flyctl) to interact with Fly.io.
- Deploy: Deploys the app to Fly.io using a custom action
codemancers/fly-pr-review-apps@main
, specifying the Dockerfile and an existing Postgres clusteryourapp-preview-db
. name for the attachment. - Set Secrets in Fly: Applies app-specific secrets on Fly.io. Executes only when the PR is opened, reopened, or updated.
- Update Image: Ensures the app uses the latest image on Fly.io, this will make sure our PR changes are reflected in the preview URL. It is only triggered when PR is opened, reopened, or updated.
- Clean up the GitHub Environment: Cleans up the GitHub deployment environment upon PR closure using strumwolf/delete-deployment-environment@v2, managing resources efficiently.
The good news is that it will automatically destroy the preview app on Fly when the PR is merged or closed. Additionally, we can open multiple PRs in parallel, and each PR will be distinct from the others.
This workflow streamlines the deployment, updates, and management of preview environments for PRs, facilitating live review and testing of changes before merging.
That's it! What are you waiting for? Go ahead and start implementing it to improve your development workflow. Thank me later 😄