How to create a remote build machine in a github action

Hi, first thanks to the geniuses at Fly, I’ve had a blast this week learning it all.

I’m trying to create a Fly app through Github actions. I’ve had reasonable success but I hit a block when I tried to deploy. I believe now that it’s because I’m not getting a build machine on fly to deploy my applications.

When I run the following command from the terminal, it creates a remote builder for me.

flyctl launch --remote-only --org personal --name demo-keycloak-app-actions

Funnily enough it seems to do this with or without the --remote-only flag too.

When I run this same command in the Github Action however, with --remote-only, no remote builder is created, so when I later do

flyctl deploy -a demo-keycloak-app-actions --remote-only --config ${{ github.workspace }}/../../fly.toml, it fails with

Error: failed to grab app config from existing machines, error: could not create a fly.toml from any machines :-(

Am I right in thinking that it’s because of not having a remote builder that I’m failing to deploy? For reference, I’m building a Keycloak application with the following steps (still a work in progress)

  1. Create a postgres cluster
  2. Launch the docker image
  3. Attach the DB to the application from 2)
  4. Set some DB secrets to the app
  5. Deploy

Thanks! Happy to provide any more info you need

hi @Stefan

Just to clarify, do you want your GitHub action to keep creating a brand new app? Or do you just want it to re-deploy an app?

About the builder:

  • You will only have one remote builder at a time per Fly organization. Every new app does not get its own builder.
  • --remote-only is the default, but it’s fine to include it in the github action anyway

The error indicates that the app exists, but thatfly deploy can’t find your fly.toml file. Is it in main directory of your github repo?

1 Like

Hey Andie, thanks for the reply.

Cool I missed that about --remote-only, that explains a lot! I want to create an app just once. At the moment my goals for this Action would be to be able to reuse it to create Dev and Prod environments, and be able to create apps based on whatever the repo name is, so all I need to do is create a repo with a dockerfile, create this Action and it should just deploy my application automatically.

I’ll paste the Action file I have at the moment, just bear in mind it’s still a work in progress lol, it’s my first time creating a yaml file like this, I was going to make it clean after I got it all working.

I captured the fly.toml file from the Launch step and pushed it to my repo, but I’m just realising now that although it pushes to the repo before the Deploy stage, the action may have it’s own lifecycle or something and use the older version of the repo, I’m not sure. Maybe I should use artifacts.

name: Fly Deploy
on:
  push:
    branches: [ main ]

jobs:
  postgres:
    name: Create postgres cluster
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
        
      - name: Setup flyctl
        uses: superfly/flyctl-actions/setup-flyctl@master
        id: postgres

      - name: Create database
        run: |
          postgres_output=$(flyctl postgres create --org personal --name demo-keycloak-app-actions-db --region lhr --vm-size shared-cpu-1x --volume-size 1 --initial-cluster-size 1)
          password=$(echo "$postgres_output" | grep -o 'Password: *[[:alnum:]]*' | awk '{print $2}')
          echo "POSTGRES_PASSWORD=$password" >> $GITHUB_ENV
        env:
          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
          
      - name: Echo captured password
        run: echo "${{ env.POSTGRES_PASSWORD }}"
          
  launch:
    name: Launch keycloak to Fly
    needs: postgres
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: superfly/flyctl-actions/setup-flyctl@master
      - run: flyctl launch --remote-only --org personal --name demo-keycloak-app-actions --region lhr --vm-memory 2048 --vm-size dedicated-cpu-1x --dockerfile ${{ github.workspace }}/../../dockerfile
        env:
          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

      - name: Set up Git
        run: |
          git config --global user.name 'username'
          git config --global user.email 'username@github.com'
          
      - name: Commit and push fly.toml file
        run: |
          git add fly.toml
          git commit -m "feat: Add fly.toml file (automated)"
          git push


  attach:
    name: Attach DB to keycloak app
    needs: [postgres, launch]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: superfly/flyctl-actions/setup-flyctl@master
      - run: flyctl postgres attach demo-keycloak-app-actions-db -a demo-keycloak-app-actions
        env:
          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

  secrets:
    name: Configure secrets
    needs: [postgres, launch, attach]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: superfly/flyctl-actions/setup-flyctl@master
      - run: flyctl secrets set -a demo-keycloak-app-actions secret=stuff 
        env:
          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

  deploy:
    name: Deploy keycloak app
    needs: [postgres, launch, attach, secrets]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: superfly/flyctl-actions/setup-flyctl@master
      - run: flyctl deploy --remote-only -a demo-keycloak-app-actions --vm-memory 2048 --vm-size dedicated-cpu-1x --config ${{ github.workspace }}/../../fly.toml
        env:
          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

That workflow always launches the app, and that will cause error when it runs the second time after the app has been created.

It’s not particularly clear to me what you’re trying to achieve here. I think you can find examples in the fly.io docs on how to use it in CI/CD. I’d also recommend checking out flycd.dev if you’re struggling with YAML and creating a good workflow.

Hi Peter, thank you for your useful links.

I’m not quite sure what you mean by ‘always launches the app’. Do you mean just the fact that it happens every time on push? I don’t intend to let that happen when I’m finished.

I’m just trying to achieve the last deploy step. But I’m struggling with Fly not being able to do that, the only error I get is Error: failed to grab app config from existing machines, error: could not create a fly.toml from any machines :-(. I assume it means a toml file from one of the remote build machines because I’m supplying it from my git repository.

I’ll be honest, I’ve only ever used some pretty simple github actions. So it might be helpful if someone else chimes in on how to achieve what you want to do.

Usually I’ll see users deploying apps on push. So the app gets re-deployed whenever there’s a code change.

You should clone your repo locally. Run fly launch from your terminal. And then push the resulting fly.toml into the repo. Then just have the fly deploy steps in the github action. If your fly.toml is in the repo’s top level working directory, then you won’t get the error anymore and you won’t need to use the --config flag.

This doc shows a simple example: Continuous Deployment with Fly.io and GitHub Actions · Fly Docs

Thanks Andie,

I agree with the deployment on push. I was just experimenting to see if I could do the entire thing automated, but it’s starting to become more of a pain than it’s worth to be honest lol. It works perfectly fine from the console.

Cheers!

Hi all, thank you all for the help! It set me in the right direction.

I’ve ‘solved’ this by just launching from the command line. It’s far far simpler, it wasn’t worth the effort to get it all going purely by a GitHub action.

I have a simple Github repo now that we can just fork from, name our repo/app name, clone it, launch, push the Toml file, and the Action will do all those other steps nice and easy. So fast too.

Cheers all!

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.