Deploy your Dockerised app to Fly.io with BitBucket Pipelines in 15 minutes
Fly.io pitches itself as a quick and hassle-free way to deploy and host web infrastructure for your web applications. Here I will give a quick walkthrough of how I set up a CD pipeline for Fly with BitBucket Pipelines. Feel free to skip around the article to the part that you might need help with!
Do some Coding!
It’s time to code the thing you want to deploy - this could be anything as Fly supports deployment via
Dockerfile
. I’m assuming you’ve got something you want to deploy in mind.Ensure that your application runs inside a
Dockerfile
locally.I was deploying a lightweight API in Java, so my
Dockerfile
looked something like:FROM openjdk:11 COPY . /usr/src/api WORKDIR /usr/src/api ENV CLASSPATH=/usr/src/api RUN find . -name "*.class" -exec rm {} \; RUN javac opt/api/Server.java ENTRYPOINT ["java", "opt.api.Server"]
I built this image with
docker build . -t api
and run a container with something like docker run -p 8080:8080 --name java-api api
.Deploy to Fly.io Locally with the flyctl CLI
Create an account on Fly.io and sign in to see your dashboard (you won’t have anything deployed yet)!
# Mac brew install flyctl # Linux curl -L https://fly.io/install.sh | sh # Windows pwsh -Command "iwr https://fly.io/install.ps1 -useb | iex"
Login in your terminal with
flyctl auth login
(or you can use the alias fly auth login
).Now you need to create a
fly.toml
in your repo which will tell fly
the configuration that you’re using to deploy. You can do this automatically with fly launch
!You can deploy right away when
launch
asks you Would you like to deploy now?
. Once the command is finished deploying, you should see the new app appear in your dashboard.Setup your BitBucket Repository
I’m not going to go through all the details, but hopefully the links will help:
- Setup SSH keys and Two Factor Authentication (you need to setup 2FA to enable pipelines in your repo).
- Enable the pipelines feature in your repo:
Repository Settings > Pipelines > Settings
.
Add your FLY_API_TOKEN as a Repository Secret
Get an API key from
fly
with:fly auth token
Go to
Repository Settings > Pipelines > Repository Variables
and add in your variable and call it FLY_API_TOKEN
(or something).Create your Bitbucket Pipeline Definition
Create a file (which must be in the root of your repo) called
bitbucket-pipelines.yml
.I wanted my deployment to run on commits to
develop
and master
:image: ubuntu # Using the latest ubuntu image definitions: steps: # Define a reusable step which we can call from different branches - step: &deploy-to-fly name: Deploy to Fly IO script: - apt-get update && apt-get install -y curl - curl -L https://fly.io/install.sh | sh # Install flyclt in the container - export FLYCTL_INSTALL="/root/.fly" - export PATH="$FLYCTL_INSTALL/bin:$PATH" # Make flyctl available in the path - export FLY_API_TOKEN=$FLY_API_TOKEN # Get the FLY_API_TOKEN from our env - flyctl deploy --remote-only --dockerfile <path-to-dockerfile> --config <path-to-fly.toml> pipelines: branches: master: - step: *deploy-to-fly develop: - step: *deploy-to-fly
When running
flyctl deploy
, we can pass in optional locations for the Dockerfile
and fly.toml
files which I needed in my case.This pipelines uses YAML Anchors and Aliases to avoid duplication:
Anchors (
&
): Anchors are used to mark a YAML data structure that you want to reuse later. An anchor is denoted by an ampersand (&
) followed by a name. The anchor is placed on the line of the data structure you want to reference later.Aliases (
*
): Aliases are used to reference an anchor within the YAML document. An alias is denoted by an asterisk (*
) followed by the name of the anchor you want to reuse. The alias can be used in place of the full data structure, which simplifies the YAML file and prevents redundancy.Summary
Whenever you push new commits to your
develop
or master
branches (e.g. on merge of a pull request), the changes made in that pull request should be reflected live on your deployment of Fly.io automatically!Reach out and let me know if I missed anything!