Create machines using CLI non interactively

# fly.toml file generated for summer-paper-9787 on 2022-10-09T13:46:06+02:00

app = "summer-paper-9787"
primary_region = "fra"

[build]

[http_service]
  internal_port = 8080
  force_https = true

[env]

[deploy]

flyctl machines launch --remote-only --push --generate-name --region fra

Keeps asking…

automatically selected personal organization: <redacted>@gmail.com
Created app summer-paper-9787 in org personal
Detected a Dockerfile app
? Does this app run an HTTP service? Yes
? Which port does your service listen on? 8080
Wrote to fly.toml
? Would you like to deploy now? Yes

I tried this

echo "y 8080 y" | flyctl machine launch --generate-name --region fra

but get this

automatically selected personal organization: <redacted>@gmail.com
Created app shy-sky-2917 in org personal
Detected a Dockerfile app
Error prompt: non interactive

Adding flags that are not supported (like --port 8080) is not allowed see -h

flyctl m launch -h                                                  
Create and configure a new app from source code or a Docker image.

Usage:
  flyctl machine launch [flags]

Flags:
      --build-arg strings      Set of build time variables in the form of NAME=VALUE pairs. Can be specified multiple times.
      --build-only             Build but do not deploy
      --build-secret strings   Set of build secrets of NAME=VALUE pairs. Can be specified multiple times. See https://docs.docker.com/develop/develop-images/build_enhancements/#new-docker-build-secret-information
      --build-target string    Set the target build stage to build if the Dockerfile has more than one stage
      --dockerfile string      Path to a Dockerfile. Defaults to the Dockerfile in the working directory.
      --generate-name          Always generate a name for the app, without prompting
  -h, --help                   help for launch
  -i, --image string           The image tag or ID to deploy
      --image-label string     Image label to use when tagging and pushing to the fly registry. Defaults to "deployment-{timestamp}".
      --local-only             Only perform builds locally using the local docker daemon
      --nixpacks               Deploy using nixpacks to generate the image
      --no-cache               Do not use the build cache when building the image
      --no-deploy              Do not prompt for deployment
      --now                    Deploy now without confirmation
  -o, --org string             The organization to operate on
      --path string            Path to the app source root, where fly.toml file will be saved (default ".")
      --push                   Push image to registry after build is complete
  -r, --region string          The region to operate on
      --remote-only            Perform builds on a remote builder instance instead of using the local docker daemon
      --strategy string        The strategy for replacing running instances. Options are canary, rolling, bluegreen, or immediate. Default is canary, or rolling when max-per-region is set.

Global Flags:
  -t, --access-token string   Fly API Access Token
  -j, --json                  json output
      --verbose               verbose output

Dockerfile

FROM node:16

# Create app directory

WORKDIR /usr/src/app

# Install app dependencies

# A wildcard is used to ensure both package.json AND package-lock.json are copied

# where available (npm@5+)

COPY package\*.json ./

RUN npm install

# If you are building your code for production

# RUN npm ci --only=production

# Bundle app source

COPY . .

EXPOSE 8080
CMD [ "node", "server.mjs" ]

The —now flag will skip that prompt and deploy immediately.

I’m not in front of my PC right now, but I feel like I’ve tried this. I’ll report back in 3h latest. Not sure how I skipped past reading that today tho, thanks

It’s totally possible the “machine” launcher and deployer is not following the rules - using machines via CLI is extremely beta.

(running apps outside of machines is still good!)

You probably saw that machines has an API which might be easier to automate. Up to you!

flyctl machine launch --now --generate-name --region fra
automatically selected personal organization: <redacted>@gmail.com
Created app autumn-river-2510 in org personal
Detected a Dockerfile app
? Does this app run an HTTP service? (y/N)
# aborted

TBH the api is not easier to work with, that’s why im trying to automate the CLI. I’ll run a service that runs flyctl machine api-proxy and I’ll go that route then… I haven’t looked into how Wireguard works… I hope it’s not stateful and drops eventually over time

I wonder if you add a [services] section to your fly.toml if that would remove that prompt.

Here’s one generated for Laravel apps that you may want to try out:

[[services]]
  http_checks = []
  internal_port = 8080
  processes = ["app"]
  protocol = "tcp"
  script_checks = []

  [services.concurrency]
    hard_limit = 25
    soft_limit = 20
    type = "connections"

  [[services.ports]]
    force_https = true
    handlers = ["http"]
    port = 80

  [[services.ports]]
    handlers = ["tls", "http"]
    port = 443

  [[services.tcp_checks]]
    grace_period = "1s"
    interval = "15s"
    restart_limit = 0
    timeout = "2s"

Note on Machines:

  1. If you’re running this automation within other Fly apps, you don’t need the api-proxy
  2. The machines API will eventually be public (not require the proxy/wireguard)

Did not help, still asks for port

flyctl machine launch --now --generate-name --region fra --verbose
automatically selected personal organization: <redacted>@gmail.com
Created app purple-snowflake-9119 in org personal
Detected a Dockerfile app
? Does this app run an HTTP service? (y/N) 
# aborted

FYI probably easier for you to create your own reproduction-repo than what I’ve got going on since I’m honestly still trying to understand how to make use of Fly for my service, I’m still fiddling around trying to see what works out of the box for me and what doesn’t

Also, removing my Dockerfile makes --now work i guess for that specific use case, but the deployment fails for whatever reasons… (output using --verbose)

# ...
image size: 746 MB
Oops, something went wrong! Could you try that again?