Answers you can trust, from Codeables
Every page on Codeables is structured and verified — built so people and the AI agents they rely on can trust it. Explore more from the source behind this answer.
Explore CodeablesHow do I SSH into a running Fly.io Machine to debug (and what’s the safest way to do it)?
Most debugging sessions start with “it works locally” and end with you poking a running Machine to see what’s actually happening in production. With Fly.io you can SSH straight into a Fly Machine, but you want to do it in a way that’s safe, auditable, and doesn’t quietly mutate your runtime into something you can’t reproduce.
Quick Answer: Use
fly ssh console(orfly ssh console -sfor a shell) to connect to a running Fly Machine, preferably in a non‑production app or a dedicated debug Machine. Rely on Fly‑issued short‑lived SSH certs instead of manually managing keys, and treat SSH as a last‑mile tool on top of logs, metrics, and snapshots.
The Quick Overview
- What It Is: SSH access to Fly Machines via
flyctl, using short‑lived certificates issued by Fly.io to connect directly to a running Machine for inspection and debugging. - Who It Is For: Developers and platform engineers running apps, agents, or Sprites on Fly.io who need to debug issues in real time without rebuilding images or redeploying.
- Core Problem Solved: Gives you a precise, low‑level view into what’s happening inside a specific Machine—processes, filesystem, network—without introducing long‑lived credentials or production snowflakes.
How It Works
SSH to Fly Machines is built around Fly‑issued SSH certificates. You don’t open up random ports or copy‑paste keys into authorized_keys. Instead, flyctl talks to the Fly API, gets a short‑lived SSH cert for your identity, and uses that to connect to the Machine you choose.
At a high level:
-
Authenticate with Fly.io:
You log in withflyctl auth loginor useFLY_API_TOKEN.flyctluses this to ask the platform for an SSH cert. -
Target a Machine and establish SSH:
You runfly ssh console(optionally with-sfor a shell) against an app.flyctlfinds the running Machines, negotiates the connection, and drops you into the selected Machine. -
Debug safely inside the Machine:
Once connected, you run your usual Linux debug tools, inspect logs and environment, maybe tweak configs temporarily—then exit. For repeatability and safety, you apply permanent fixes via code + deploy, not by hand inside SSH.
Step‑by‑Step: SSH into a Running Fly Machine
1. Make sure you’re authenticated
If you haven’t logged in recently, do:
fly auth login
For CI or headless environments, export a token:
export FLY_API_TOKEN="your-token"
2. List Machines and pick your target
From your app directory (or with -a):
fly machines list
You’ll see output like:
ID NAME STATE REGION IMAGE
machine-1234 web-1 started iad registry.fly.io/my-app:latest
machine-5678 web-2 started lhr registry.fly.io/my-app:latest
Grab the Machine ID you want to debug.
3. Open an SSH console to a specific Machine
To connect to that Machine:
fly ssh console --select
This will prompt you to choose from running Machines.
If you already know the ID:
fly ssh console -s -C "machine-1234"
-s tells fly ssh console to start a shell for you. Once it connects, you’re inside the Machine:
Connected to machine-1234
root@fdaa:0:1234:a7b:1::2:~#
From here, you can:
-
Check environment:
env | sort -
See the public IP the Machine is using:
echo $FLY_PUBLIC_IP -
Confirm the external view of that IP:
curl text.ipv6.wtfismyip.com -
Look at processes:
ps aux
4. Run a single debug command (no shell)
If you just want to run one command and exit:
fly ssh console -C "machine-1234" --command "ls -lah /app"
This runs ls inside the Machine, prints output, and disconnects.
5. Exit cleanly
When you’re done:
exit
Or Ctrl‑D. This closes the SSH session; the Machine keeps running unless you explicitly stop it.
Features & Benefits Breakdown
| Core Feature | What It Does | Primary Benefit |
|---|---|---|
fly ssh console | Opens an SSH session to a running Machine (interactive or one‑off command). | Lets you inspect live Machines without exposing raw SSH keys or ports. |
| Short‑lived SSH certs | Uses Fly‑issued, time‑bound credentials instead of static keys. | Reduces credential sprawl; easier to audit and revoke. |
| Per‑Machine targeting | Lets you choose the exact Machine (region, role) to inspect. | Debug the instance that’s actually misbehaving, not a random sibling. |
Safest Ways to SSH for Debugging
SSH is powerful, and like all sharp tools, it can cause some damage if you treat it like a long‑term config mechanism. Here’s how to keep it safe and sane.
1. Prefer non‑prod or dedicated debug Machines
Best practice is:
- Keep production “boring”: configuration and behavior come from code, artifacts, and
fly.toml, not from manual edits. - For messy debugging, use:
- A staging app with the same image:
fly apps create my-app-staging # configure fly.toml for staging, then: fly deploy - Or a dedicated debug Machine launched from the same image and volume, then SSH into that instead of prod.
- A staging app with the same image:
Why: if you fix something by hand inside a prod Machine and forget to move it into your repo, you’ve just created a snowflake that you can’t reproduce later.
2. Treat SSH as a “read‑mostly” interface
Things that are usually safe:
- Inspecting logs in
/var/logor your app’s log path. - Running
ps,top,netstat/ss,lsof. - Checking environment variables, mounts, and network connectivity.
- Tailing app logs that aren’t already in
fly logs.
Things that should be temporary or followed by a code change:
- Editing config files baked into the image.
- Installing packages with
apt/apkinside the running Machine. - Restarting services manually.
Use SSH to discover the fix; apply the fix via a code change + fly deploy.
3. Scope and rotate access via Fly’s SSH certificates
Under the hood, fly ssh uses:
fly ssh issueto request a new SSH certificate.- Short‑lived certs instead of static keys.
You can inspect issued certs:
fly ssh log
This gives you an audit trail for who got SSH access and when.
If you need to script SSH access for a team or CI:
- Use
FLY_API_TOKENscoped to the app/org. - Issue certs with
fly ssh issue. - Avoid hard‑coding private keys in repos.
4. Don’t use SSH as a deployment mechanism
If you catch yourself:
- Copying new binaries via
fly ssh sftp. - Editing app code inline on Machines.
- Restarting processes by hand after changes.
…you’re basically building a configuration‑by‑hand system that will diverge across Machines. Instead:
- Fix code in your repo.
- Rebuild and deploy:
fly deploy - Use SSH only to verify the behavior of the new release if needed.
5. Be mindful of stateful workloads
If a Machine has attached volumes (databases, file storage):
- Avoid making irreversible changes without a backup or snapshot strategy.
- For databases, prefer using the database’s own tooling (e.g.,
psqlvia TCP) rather than ad‑hoc edits to files on disk. - For serious surgery, consider:
- Stopping traffic to that Machine.
- Taking a snapshot (if applicable).
- Doing the work on a clone in a safe environment first.
Ideal Use Cases
-
Best for “I need to see what this Machine is doing right now”:
Because it lets you drop into the exact Machine and check processes, logs, env, and network paths in real time. -
Best for “staging or reproduction debugging”:
Because you can create a staging app or clone a Machine from the same image, reproduce the bug with real traffic patterns, and debug via SSH without touching production state.
Limitations & Considerations
-
You still need
flyctland API access:
SSH to Machines flows through Fly’s control plane. That means:- You must be authenticated with
flyctl auth loginorFLY_API_TOKEN. - Your network must be able to reach Fly’s APIs. No “direct console” if the control plane is unreachable.
- You must be authenticated with
-
SSH won’t fix bad deploy hygiene:
If you’re relying on ad‑hoc shell edits, you’ll accumulate drift between Machines. SSH is not a substitute for proper build pipelines, health checks, and rollbacks. Use it as a diagnostic scalpel, not a deployment system.
Pricing & Plans
SSH access is part of the normal Fly.io developer experience, not a separate paid add‑on. You pay for:
- Machines: CPU and RAM per second while they run.
- Storage: NVMe volumes and object storage (Tigris) if you’re using them.
- Traffic: Data transfer in/out as usual.
There’s no extra line item for “SSH” itself.
- Individual / Team Projects: Best for developers and small teams needing flexible debugging tools on top of elastic, per‑Machine billing.
- Enterprise: Best for larger orgs needing SSO, guaranteed support response times, SOC2 Type 2, and tighter auditing of access—including who SSH’d into what and when.
Frequently Asked Questions
Do I need to open any ports or manage SSH keys myself?
Short Answer: No. You use fly ssh and Fly‑issued certs; you don’t manage raw keys or expose ports manually.
Details:
Fly.io doesn’t ask you to poke holes in security groups or copy an SSH public key into your image. When you run:
fly ssh console
flyctl:
- Authenticates with the Fly API using your login or
FLY_API_TOKEN. - Requests a short‑lived SSH certificate bound to your identity.
- Uses that cert to connect to the target Machine.
There’s no ~/.ssh/id_rsa you need to distribute, and you don’t have to bind a TCP port for SSH in fly.toml. It’s all mediated by the platform and scoped to your app/org.
How do I verify which Machine I’m actually inside once I SSH?
Short Answer: Use fly machines list to identify the Machine, then check IP and environment from inside the shell.
Details:
When you run:
fly machines list
you’ll see IDs and regions. After you connect with:
fly ssh console -s -C "machine-1234"
you can verify where you landed:
echo $FLY_PUBLIC_IP
hostname
env | grep FLY_
You can also call an external IP echo service:
curl text.ipv6.wtfismyip.com
This helps confirm you’re in the correct Machine (and region) before you start digging into logs or state.
Summary
SSH into Fly.io Machines is intentionally straightforward: authenticate with flyctl, pick a Machine, and run fly ssh console. Under the hood, Fly.io issues short‑lived SSH certificates, so you get per‑Machine, audited access without juggling keys or opening ports. The safest workflow is to treat SSH as a read‑mostly, last‑mile debug tool, lean on staging or dedicated debug Machines when possible, and always push permanent fixes through your normal deploy pipeline instead of hand‑editing production.