Skip to content

Fly.Certificate reference

Source: src/Fly/Certificate.ts

A Fly.Certificate covers a hostname on an App. Default kind is "acme" (Let’s Encrypt). "custom" uploads a PEM.

IPs and certificates attach to the App. A Service publishes ports. Fly’s proxy terminates TLS on 443 once the certificate is configured.

Request Let’s Encrypt for a hostname. The Service does not change. Yield the certificate in the Stack. Point DNS at the App.

export const Www = Fly.Certificate("Www", {
app: Site,
hostname: "www.example.com",
});

Point an A record at a shared_v4 IpAssignment and an AAAA at v6. Plus whatever dnsRequirements lists for the ACME challenge. Alchemy re-checks via checkAppCertificate while configured is false.

Observed attrs include status, configured, acmeRequested, dnsRequirements, and validation.

export default Alchemy.Stack(
"MyApp",
{ providers: Fly.providers(), state: Alchemy.localState() },
Effect.gen(function* () {
const api = yield* Api;
const ip = yield* PublicIp;
const v6 = yield* V6;
const www = yield* Www;
return {
url: api.url,
ip: ip.ip,
v6: v6.ip,
dns: www.dnsRequirements,
};
}),
);

"custom" uploads fullchain and privateKey. Wrap the key with Redacted.make so it never logs. Never stored in attributes. Updating the PEM re-uploads in place.

export const Www = Fly.Certificate("Www", {
app: Site,
hostname: "www.example.com",
kind: "custom",
fullchain: pem,
privateKey: Redacted.make(key),
});

Source: src/Fly/WriteCertificates.ts

Manage an App’s TLS certificates at runtime — the companion to the deploy-time Certificate resource, for services that mint or rotate certificates on their own (a relay adding a tenant’s wildcard, a renewal loop).

The App is fixed by WriteCertificates(app); calls take a hostname.

WriteCertificates: Fly-managed (Let’s Encrypt)

Section titled “WriteCertificates: Fly-managed (Let’s Encrypt)”
const certs = yield* Fly.WriteCertificates(Site);
const requested = yield* certs.request("www.example.com");
// publish requested.dns_requirements, then:
const status = yield* certs.check("www.example.com");

A certificate issued elsewhere (an ACME.IssueCertificate wildcard from ZeroSSL, say) goes up as a custom certificate.

yield* certs.upload({
hostname: "*.tenant.example.com",
fullchain: issued.chain,
privateKey: issued.privateKey,
});

Source: src/Fly/WriteCertificatesHttp.ts Kind: Layer · Provides: Fly.WriteCertificates

HTTP implementation of WriteCertificates. Provide it on the Service or Action Effect.

Effect.gen(function* () {
const certs = yield* Fly.WriteCertificates(Site);
// ...
}).pipe(Effect.provide(Fly.WriteCertificatesHttp))