Part 2: Configure the Service
In Part 1 you deployed a Service on its own
fly.dev hostname. Now you will pin where it runs and which port it
listens on, add a health route, and ship a change.
Pin a region
Section titled “Pin a region”Fly Machines live in a region. The default
is iad (Ashburn). Set it explicitly so the Volume you add in
Part 3 can match:
export default class Api extends Fly.Service<Api>()( "Api", { main: import.meta.url }, { main: import.meta.url, region: "iad" },Set the port
Section titled “Set the port”Give the Service an explicit port so the Fly proxy knows where to forward:
export default class Api extends Fly.Service<Api>()( "Api", { main: import.meta.url, region: "iad" }, { main: import.meta.url, region: "iad", port: 3000 },The port is written to the process environment as PORT and used as
the Machine’s internal_port. By default Alchemy publishes HTTP 80
and HTTPS 443 on the Fly proxy in front of it.
Add a health route
Section titled “Add a health route”Add /health so you (and later, Fly checks) can probe the process:
import { HttpServerRequest } from "effect/http/HttpServerRequest";// ... return { fetch: Effect.succeed(HttpServerResponse.text("Hello from Fly!")), fetch: Effect.gen(function* () { const request = yield* HttpServerRequest; const url = new URL(request.url, "http://service"); if (url.pathname === "/health") { return HttpServerResponse.json({ ok: true }); } return HttpServerResponse.text("Hello from Fly!"); }), };Deploy
Section titled “Deploy”bun alchemy deploynpm run alchemy deploypnpm alchemy deployyarn alchemy deployPlan: 1 to update ~ Api (Fly.Service) Proceed? ◉ Yes ○ No ✓ Api (Fly.Service) updated { appName: "myapp-api-dev-a1b2c3d4", url: "https://myapp-api-dev-a1b2c3d4.fly.dev", }
iad and port 3000 match the defaults from Part 1, so the Machine
stays where it is. The new route changes the bundle hash, so Alchemy
builds a new image and updates the Machine in place. The App and its
URL stay the same.
Try it out
Section titled “Try it out”curl https://myapp-api-dev-a1b2c3d4.fly.dev/health# → {"ok":true}Ship a change
Section titled “Ship a change”Edit the greeting in src/api.ts and deploy again:
Plan: 1 to update ~ Api (Fly.Service) Proceed? ◉ Yes ○ No ✓ Api (Fly.Service) updated
Alchemy hashes the bundle: if your code didn’t change, the Service is a no-op; if it did, a new image is built, pushed, and the Machine updated in place.
You now have:
- An HTTP Service running as a Fly Machine in
iadon port 3000 - A
/healthroute on its publichttps://{appName}.fly.devURL - A code-hash-based update loop — edit, deploy, new image
In Part 3, you’ll attach a Volume and persist data across deploys.