diff --git a/app-guides/6pndemochat.mdx b/app-guides/6pndemochat.mdx index c857b89f06..7dc62de9af 100644 --- a/app-guides/6pndemochat.mdx +++ b/app-guides/6pndemochat.mdx @@ -71,7 +71,7 @@ let natsapphost=process.env.NATSAPPHOST const nc = NATS.connect(natsapphost+".internal"); ``` -The combination of an app name and `.internal` in 6PN networking resolves to the IPv6 addresses of the first instance of all instances if that app currently running. So, if we set NATSAPP to `myclusterapp` then scaling and adding nodes to `myclusterapp` would automatically be reflected in `myclusterapp.internal`. 6PN has a number of `.internal` addresses an app can query which you can read about in the [6PN documentation](/networking/services#internal-addresses). +The combination of an app name and `.internal` in 6PN networking resolves to the IPv6 addresses of the first instance of all instances if that app currently running. So, if we set NATSAPP to `myclusterapp` then scaling and adding nodes to `myclusterapp` would automatically be reflected in `myclusterapp.internal`. 6PN has a number of `.internal` addresses an app can query which you can read about in the [6PN documentation](/networking/private-networking#fly-io-internal-dns). Once the chat server has connected to the NATS cluster, it subscribes to a topic `msg` and any message written to `msg` will be broadcast to all web socket clients that are connected. If any of those web socket clients sends a message to the chat server, then it will publish that message to the `msg` topic on the NATs cluster. It doesn't even try to echo it locally, relying on the NATS cluster to publish to subscribers. diff --git a/app-guides/grpc-and-grpc-web-services.mdx b/app-guides/grpc-and-grpc-web-services.mdx index 425c2a2957..1e1415cc7c 100644 --- a/app-guides/grpc-and-grpc-web-services.mdx +++ b/app-guides/grpc-and-grpc-web-services.mdx @@ -102,7 +102,7 @@ You'll notice that the clock stops streaming after exactly 10 seconds – this i While gRPC works really well when communicating between servers on the same rack or same datacenter, the principles it uses apply equally well to clients on websites or mobile devices. The HTTP/2 communication channel remains open as much as possible to provide a low-latency and low-energy way to speak to your server, and the underlying [Protocol Buffers](https://developers.google.com/protocol-buffers) serialization/de-serialization system is very low-overhead, so it's great for cellular or metered-bandwidth connections. -Running your backend services on Fly lets you put your services really close to every user in your global client base. If your data is in a central location, your services can use the local Redis cache that Fly provides at each edge location to cache data, and broadcast changes or invalidations via the [global Redis command broadcast](/upstash/redis#managing-redis-data-globally). There are also data solutions from other cloud providers like [DynamoDB Global Tables](https://aws.amazon.com/dynamodb/global-tables/) (NoSQL), [Aurora Multi-Master](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-global-database.html) (SQL) or [Google Cloud Spanner](https://cloud.google.com/spanner) (SQL) that can help spread your data across the world and closer to your application servers. +Running your backend services on Fly lets you put your services really close to every user in your global client base. If your data is in a central location, your services can use the local Redis cache that Fly provides at each edge location to cache data, and broadcast changes or invalidations via the [global Redis command broadcast](/upstash/redis). There are also data solutions from other cloud providers like [DynamoDB Global Tables](https://aws.amazon.com/dynamodb/global-tables/) (NoSQL), [Aurora Multi-Master](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-global-database.html) (SQL) or [Google Cloud Spanner](https://cloud.google.com/spanner) (SQL) that can help spread your data across the world and closer to your application servers. The reduced latency from having your servers close to your clients is especially useful in gRPC where you want all your calls to finish as quickly as possible. If your clients are mobile applications, they'll benefit even more from the latency reduction when they're running on cellular networks, where bandwidth is low and re-connections are common. diff --git a/app-guides/openresty-nginx-plus-lua.mdx b/app-guides/openresty-nginx-plus-lua.mdx index 840ac522bf..182df0848d 100644 --- a/app-guides/openresty-nginx-plus-lua.mdx +++ b/app-guides/openresty-nginx-plus-lua.mdx @@ -36,7 +36,7 @@ mkdir fly-openresty && cd fly-openresty ``` ### Configuring the Dockerfile -Fly will build and run your Docker image in a [Firecracker VM](/reference/architecture#microvms) on the edge, but you need to select and configure a Dockerfile first. +Fly will build and run your Docker image in a [Firecracker VM](/reference/architecture#compute) on the edge, but you need to select and configure a Dockerfile first. OpenResty provides [several Docker images](https://github.com/openresty/docker-openresty) you can use for your application. I opted for Centos, but because of [an apparent bug in their Docker image](https://github.com/openresty/docker-openresty/issues/124), specified the `1.15.8.1-4-centos` tag. @@ -195,7 +195,7 @@ server { } ``` -This configuration passes your request through using the `proxy_pass` directive at the end, as the previous version did. Before it does, it checks if the visitor has reached their request limit using the `Fly-Client-IP` header [attached to the request by Fly](/networking/services#http). If the IP address has called the endpoint in the past 2 seconds, it returns a 503 response and logs the error. +This configuration passes your request through using the `proxy_pass` directive at the end, as the previous version did. Before it does, it checks if the visitor has reached their request limit using the `Fly-Client-IP` header [attached to the request by Fly](/networking/services#http-handler). If the IP address has called the endpoint in the past 2 seconds, it returns a 503 response and logs the error. You can re-deploy this configuration file to Fly (again using `flyctl deploy`) and call the endpoint twice in quick succession to test it. @@ -204,7 +204,7 @@ You've now got a working rate limiter, but you're still not finished. In the las ### Checking API Keys Against a Redis Store Fly offers a [region-local Redis instance](/upstash/redis) to all deployments, which can be used to persist data for longer periods. While this volatile datastore is not meant for permanent use, you can use it to cache data so that it's accessible on the edge. -In this last step, you'll connect to the Fly Redis instance using the OpenResty [Redis driver](https://github.com/openresty/lua-resty-redis). You'll authenticate requests using a `key` passed in by the user through a query string argument and return a 401 response code if authentication fails. In a real application, you would probably push data to the Fly Redis instance using [their global data store](/upstash/redis#managing-redis-data-globally), but because this is a demonstration app, you'll hard code a few sample API keys. +In this last step, you'll connect to the Fly Redis instance using the OpenResty [Redis driver](https://github.com/openresty/lua-resty-redis). You'll authenticate requests using a `key` passed in by the user through a query string argument and return a 401 response code if authentication fails. In a real application, you would probably push data to the Fly Redis instance using [their global data store](/upstash/redis), but because this is a demonstration app, you'll hard code a few sample API keys. First, write a Lua script to parse the connection string. Fly's `FLY_REDIS_CACHE_URL` must be split at the `:` and `@` characters, so you can write a function that takes any number of characters as possible delimiters ([credit to Walt Howard on Stack Overflow](https://stackoverflow.com/a/29497100/977192) for this one). Create a new file called `split.lua` and add the following: diff --git a/app-guides/puppeteer-js-renderer.mdx b/app-guides/puppeteer-js-renderer.mdx index 98fa812f60..b43307ebc3 100644 --- a/app-guides/puppeteer-js-renderer.mdx +++ b/app-guides/puppeteer-js-renderer.mdx @@ -63,7 +63,7 @@ To show the YouTube video views count, a small scraper written with [Axrio](http The `yt-views.js` is a basic scraper which performs a GET request for the given YouTube URL with Puppeteer. This will return the final DOM after the page's JavaScript executes. Then it parses the title and views count out of the rendered page's markup and prints it on the console. -It uses the puppeteer-js-renderer service that is already deployed and running on Fly.io. Have a look at he "[how to use it as a service](#how-to-use-it-as-a-service)" section for more information. To start your own instance on Fly.io jump to the "[how to deploy on fly.io](#how-to-deploy-it-on-flyio)" section. +It uses the puppeteer-js-renderer service that is already deployed and running on Fly.io. Have a look at he "[how to use it as a service](#how-to-use-it-as-a-service)" section for more information. To start your own instance on Fly.io jump to the "[how to deploy on fly.io](#how-to-deploy-it-on-fly-io)" section. ## Run locally diff --git a/app-guides/run-a-global-image-service.mdx b/app-guides/run-a-global-image-service.mdx index c384ff6716..b93bf7a39b 100644 --- a/app-guides/run-a-global-image-service.mdx +++ b/app-guides/run-a-global-image-service.mdx @@ -93,7 +93,7 @@ If you've already installed `flyctl`, move on to the next step. If not, hop over ### Sign In (or Up) for Fly -If you have a Fly account, all you need to do is [sign-in with `flyctl`](#returning-user). +If you have a Fly account, all you need to do is [sign-in with `flyctl`](#sign-in-or-up-for-fly). ##### New User? diff --git a/app-guides/run-a-private-dns-over-https-service.mdx b/app-guides/run-a-private-dns-over-https-service.mdx index 7a50196de1..8f7386b53a 100644 --- a/app-guides/run-a-private-dns-over-https-service.mdx +++ b/app-guides/run-a-private-dns-over-https-service.mdx @@ -296,4 +296,4 @@ Fly apps support an unlimited number of hostnames and SSL certificates. To set o ### Handle your own TLS -Fly can take care of TLS + HTTPS for you, but it doesn't have to. If you'd prefer to terminate your own TLS, you can generate your own certificates, store them as encrypted Fly secrets, and tweak [the Dockerfile](#write-a-custom-dockerfile) to pull them from your app environment. We'll happily forward encrypted TCP to your app and let you worry about the rest. +Fly can take care of TLS + HTTPS for you, but it doesn't have to. If you'd prefer to terminate your own TLS, you can generate your own certificates, store them as encrypted Fly secrets, and tweak [the Dockerfile](#1-write-a-custom-dockerfile) to pull them from your app environment. We'll happily forward encrypted TCP to your app and let you worry about the rest. diff --git a/apps/app-availability.mdx b/apps/app-availability.mdx index 5fc165a68a..03539d88c3 100644 --- a/apps/app-availability.mdx +++ b/apps/app-availability.mdx @@ -28,7 +28,7 @@ If you're deploying Fly Postgres, our un-managed database app, then you need to When you use [Fly Volumes](/volumes) with your app, your app needs to implement replication and backups. Volumes are block devices that live on a single disk array and get mounted directly by your Machine. There's no magic. And there's no built-in replication between volumes. If your app provides a clustering mechanism with data replication, like most databases do, we recommend you take advantage of that and run multiple instances with attached volumes. When possible, we place your app's volumes in different hardware zones within a region to mitigate hardware failures. -This brings us to disaster recovery and being prepared. You should have backups of your data and understand how to recover that data if needed. Fly.io takes daily snapshots of volumes and stores them for 5 days by default. You can [restore a volume's data](/volumes/volume-manage#restore-a-volume-from-a-snapshot) from one of these daily snapshots. If your use case requires more frequent backups, then you'll need to set up tooling and processes to backup your volumes on the required schedule. +This brings us to disaster recovery and being prepared. You should have backups of your data and understand how to recover that data if needed. Fly.io takes daily snapshots of volumes and stores them for 5 days by default. You can [restore a volume's data](/volumes/snapshots#restore-a-volume-from-a-snapshot) from one of these daily snapshots. If your use case requires more frequent backups, then you'll need to set up tooling and processes to backup your volumes on the required schedule. ## Fly.io features for app resiliency diff --git a/blueprints/cell-based.mdx b/blueprints/cell-based.mdx index b6f3022f39..56f696547e 100644 --- a/blueprints/cell-based.mdx +++ b/blueprints/cell-based.mdx @@ -87,7 +87,7 @@ fly machines list -q In order to prepare for a multiple Machine deployment, we are going to need to ensure that each request is routed to the correct Machine. We can accomplish this via middleware that makes use of the -[fly-replay](/networking/dynamic-request-routing#the-fly-replay-response-header) +[fly-replay](/networking/dynamic-request-routing#how-fly-replay-works) response header. Place the following into `config/initializers/fly_router.rb`: diff --git a/blueprints/connecting-to-user-machines.mdx b/blueprints/connecting-to-user-machines.mdx index b2a93cca7d..d197503008 100644 --- a/blueprints/connecting-to-user-machines.mdx +++ b/blueprints/connecting-to-user-machines.mdx @@ -55,7 +55,7 @@ The [private-network-router](https://github.com/fly-apps/private-network-router) 1. Receives requests on any port 2. Determines the target app and machine based on the request -3. Sends a `fly-replay` response header with parameters like `app` and `instance` to route the request to the correct app and machine. For more details on the parameters, see the [fly-replay documentation](/networking/dynamic-request-routing#the-fly-replay-response-header). +3. Sends a `fly-replay` response header with parameters like `app` and `instance` to route the request to the correct app and machine. For more details on the parameters, see the [fly-replay documentation](/networking/dynamic-request-routing#how-fly-replay-works). This pattern allows you to: - Keep management APIs private by running them with flycast @@ -68,7 +68,7 @@ Validation of replayed requests should happen within the user machine. We recomm 1. **Create a preshared key for each user app** and set it as an app secret. 2. When issuing a replay, set the header: `fly-replay: app=,state=`. -3. On the user machine, parse the `fly-replay-src` header. This header contains fields such as `instance`, `region`, `t`, and `state` (see [fly-replay documentation](/networking/dynamic-request-routing#the-fly-replay-response-header)). +3. On the user machine, parse the `fly-replay-src` header. This header contains fields such as `instance`, `region`, `t`, and `state` (see [fly-replay documentation](/networking/dynamic-request-routing#how-fly-replay-works)). 4. Check the `state` value in `fly-replay-src` against the preshared key for the app. If it matches, the request is validated. See the [TypeScript example below](#example-authenticating-a-replayed-request-in-typescript) for a practical implementation of this validation. diff --git a/blueprints/opensshd.mdx b/blueprints/opensshd.mdx index 2833507202..e92ea8a3f9 100644 --- a/blueprints/opensshd.mdx +++ b/blueprints/opensshd.mdx @@ -13,7 +13,7 @@ copying files ([rsync](https://rsync.samba.org/), [scp](https://en.wikipedia.org editing ([emacs](https://www.gnu.org/software/emacs/manual/html_node/emacs/Remote-Files.html), [vim](https://www.vim.org/scripts/script.php?script_id=1075), [vscode](https://code.visualstudio.com/docs/remote/ssh)), and deployment ([ansible](https://www.ansible.com/), [github actions](https://github.com/marketplace/actions/ssh-deploy), and [kamal](https://kamal-deploy.org/)). -One way to use these tools is to [set up a wireguard VPN](/networking/private-networking#install-your-wireguard-app) and +One way to use these tools is to [set up a wireguard VPN](/networking/private-networking#1-install-your-wireguard-app) and [issue a new SSH credential](/flyctl/cmd/fly_ssh_issue). This may be impractical for some use cases (example: github actions). As an alternative, you can configure and deploy an SSH server on your machine(s). This guide will walk you through the process. diff --git a/blueprints/per-user-dev-environments.mdx b/blueprints/per-user-dev-environments.mdx index 94d1dedcef..dc0a8177c0 100644 --- a/blueprints/per-user-dev-environments.mdx +++ b/blueprints/per-user-dev-environments.mdx @@ -55,7 +55,7 @@ You'll want to spin up at least one Machine per user app (but apps can have as m ## Pointers & Footguns {#pointers-amp-footguns} -- **Machines & volumes are tied to physical hardware:** hardware failures can destroy machines and attached volumes. **Always persist important user data** (code, config, outputs) to external storage (like [Tigris Data](/tigris#main-content-start) or AWS S3). +- **Machines & volumes are tied to physical hardware:** hardware failures can destroy machines and attached volumes. **Always persist important user data** (code, config, outputs) to external storage (like [Tigris Data](/tigris) or AWS S3). - **Your users will break their environments:** pre-create standby machines to handle hardware & runtime failures, or the inevitable user or robot poisoned environment. Pre-create standby machines that you can quickly activate in these scenarios. - **Machine restarts reset ephemeral filesystem:** the temporary Fly Machine filesystem state resets on Machine restarts, ensuring clean environments. However, volume data remains persistent, making it useful for retaining user progress or state. - **One app per user:** Putting all user Machines into a single app and routing to them with dynamic routing works, but `auto_stop` won't behave the way you expect once you scale. The Fly Proxy's stop loop is rate-limited: it [stops or suspends at most one Machine per region each pass, and runs every few minutes](/reference/fly-proxy-autostop-autostart#fly-proxy-process-to-stop-or-suspend-machines). That's fine for a normal app; with thousands of Machines the loop can't keep up, and most of your idle Machines stay running. Machines in a single app also share app-level secrets and a flat [private network](/networking/private-networking). A compromised user environment can reach every other Machine in the app. If you do keep all user Machines in one app, implement stop-when-idle behavior in your app or orchestrator (see [apps that shut down when idle](/launch/autostop-autostart#apps-that-shut-down-when-idle)). Don't rely on the Fly Proxy to keep most Machines stopped. diff --git a/blueprints/shared-nothing.mdx b/blueprints/shared-nothing.mdx index c5d5d2f0f8..2a639ef89e 100644 --- a/blueprints/shared-nothing.mdx +++ b/blueprints/shared-nothing.mdx @@ -132,7 +132,7 @@ This application use three separate techniques to route requests. The first technique is to [listen](https://github.com/rubys/showcase/blob/main/app/javascript/controllers/region_controller.js) for [turbo:before-fetch-requests](https://turbo.hotwired.dev/reference/events#http-requests) events and -insert a [fly-prefer-region header](/networking/dynamic-request-routing#the-fly-prefer-region-request-header). +insert a [fly-prefer-region header](/networking/dynamic-request-routing#the-fly-prefer-region-header). The region is extracted from a data attribute added to the [body](https://github.com/rubys/showcase/blob/aae08a6d57f92335b2cdbb94756e5416b7b50f83/app/views/layouts/application.html.erb#L16) tag. This all made possible by how [Turbo works](https://turbo.hotwired.dev/handbook/introduction#turbo-drive%3A-navigate-within-a-persistent-process): @@ -158,7 +158,7 @@ location /showcase/2024/raleigh { This replays action cable (web socket) requests to the correct region, and [reverse proxies](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/) -all other requests to the correct machine using its [`.internal` address](/networking/private-networking#fly-io-internal-addresses). The latter is done because [fly-replay](/networking/dynamic-request-routing#limitations) +all other requests to the correct machine using its [`.internal` address](/networking/private-networking#fly-io-internal-dns). The latter is done because [fly-replay](/networking/dynamic-request-routing#requirements-and-limitations) is limited to 1MB requests, and uploading audio files may exceed this limit. ## Appliances diff --git a/blueprints/sticky-sessions.mdx b/blueprints/sticky-sessions.mdx index c06f3a1f4c..5a58adce7c 100644 --- a/blueprints/sticky-sessions.mdx +++ b/blueprints/sticky-sessions.mdx @@ -63,7 +63,7 @@ This code will subscribe and unsubscribe from ## Fly-Replay -This approach is implemented entirely on the server. Your application examines each request, determines which Machine should handle it, and returns a `fly-replay` response header to route the request accordingly. Initial requests will require an additional "hop" to route, and [requests are limited to payloads of 1 megabyte](/networking/dynamic-request-routing#limitations). +This approach is implemented entirely on the server. Your application examines each request, determines which Machine should handle it, and returns a `fly-replay` response header to route the request accordingly. Initial requests will require an additional "hop" to route, and [requests are limited to payloads of 1 megabyte](/networking/dynamic-request-routing#requirements-and-limitations). The example below creates [Express Middleware](https://expressjs.com/en/guide/using-middleware.html) that routes requests based on a session cookie: diff --git a/deep-dive/tigris.mdx b/deep-dive/tigris.mdx index 40ddc6ffd8..b1726ef1d5 100644 --- a/deep-dive/tigris.mdx +++ b/deep-dive/tigris.mdx @@ -10,4 +10,4 @@ source_url: https://fly.io/docs/deep-dive/tigris/ Unlike relational databases, there may be reasons why you want to make your object store available via the internet. In this demo, the object store starts out private, but you can make it [public](/tigris#public-buckets) if you want. Public buckets serve objects without authentication at `https://bucket-name.t3.tigrisfiles.io/key-name`. -And if you happen to have an existing S3 object store, check out [shadow buckets](/tigris#migrating-to-tigris-with-shadow-buckets), which enable you to incrementally migrate your data. +And if you happen to have an existing S3 object store, check out [shadow buckets](/tigris#migrate-from-another-s3-compatible-provider-with-zero-downtime), which enable you to incrementally migrate your data. diff --git a/django/getting-started/existing.mdx b/django/getting-started/existing.mdx index a142bc4705..0c2089fd38 100644 --- a/django/getting-started/existing.mdx +++ b/django/getting-started/existing.mdx @@ -174,13 +174,13 @@ This also means that `.gitignore` files are not ignored. If you have secrets or ### Databases -Fly.io has a [Postgres offering](/unmanaged-postgres) to automate provisioning, maintenance, and snapshot tasks for your Postgres database, but it does not manage it. If you run out of disk space, RAM, or other resources on your Fly Postgres instances, you'll have to scale those virtual machines from the Fly CLI. If you prefer, you can instead connect to an [external fully-managed Postgres database](/unmanaged-postgres#fully-managed-postgres). +Fly.io has a [Postgres offering](/unmanaged-postgres) to automate provisioning, maintenance, and snapshot tasks for your Postgres database, but it does not manage it. If you run out of disk space, RAM, or other resources on your Fly Postgres instances, you'll have to scale those virtual machines from the Fly CLI. If you prefer, you can instead connect to an [external fully-managed Postgres database](/postgres). ### Custom Domain & SSL Certificates {#custom-domain-amp-ssl-certificates} After you finish deploying your application to Fly.io and have tested it extensively, [read through the Custom Domain docs](/networking/custom-domain) and point your domain at Fly. -In addition to supporting [`CNAME` DNS records](/networking/custom-domain#option-i-cname-records), Fly.io also supports [`A` and `AAAA` records](/networking/custom-domain#option-ii-a-and-aaaa-records) for those who want to point `example.com` (without the `www.example.com`) directly at Fly. +In addition to supporting [`CNAME` DNS records](/networking/custom-domain#cname-records), Fly.io also supports [`A` and `AAAA` records](/networking/custom-domain#a-and-aaaa-records-recommended) for those who want to point `example.com` (without the `www.example.com`) directly at Fly. ### flyctl Commands diff --git a/elixir/getting-started/index.mdx b/elixir/getting-started/index.mdx index 922dda7b5a..22c1a1b855 100644 --- a/elixir/getting-started/index.mdx +++ b/elixir/getting-started/index.mdx @@ -30,7 +30,7 @@ mix archive.install hex phx_new If you just want to see how Fly.io deployment works, this is the section to focus on. Here we'll bootstrap the app and deploy it with a Postgres database. -First, [install flyctl](/flyctl/install), the Fly.io CLI, and [sign up to Fly.io](/getting-started/sign-up-sign-in#first-time-or-no-fly-account-sign-up-for-fly) if you haven't already. +First, [install flyctl](/flyctl/install), the Fly.io CLI, and [sign up to Fly.io](/getting-started/sign-up-sign-in#no-account-sign-up-for-fly-io) if you haven't already. Now let's generate a shiny, new Phoenix app: diff --git a/elixir/getting-started/migrate-from-heroku.mdx b/elixir/getting-started/migrate-from-heroku.mdx index 75dfed9ae1..f94e4a94c9 100644 --- a/elixir/getting-started/migrate-from-heroku.mdx +++ b/elixir/getting-started/migrate-from-heroku.mdx @@ -224,7 +224,7 @@ If you have a Redis server, there's a good chance you need to set that up. After you finish deploying your application to Fly.io and have tested it extensively, [read through the Custom Domain docs](/networking/custom-domain) and point your domain at it. -In addition to supporting [`CNAME` DNS records](/networking/custom-domain#option-i-cname-records), Fly.io also supports [`A` and `AAAA` records](/networking/custom-domain#option-ii-a-and-aaaa-records) for those who want to point `example.com` (without the `www.example.com`) directly at their App on Fly.io. +In addition to supporting [`CNAME` DNS records](/networking/custom-domain#cname-records), Fly.io also supports [`A` and `AAAA` records](/networking/custom-domain#a-and-aaaa-records-recommended) for those who want to point `example.com` (without the `www.example.com`) directly at their App on Fly.io. ## Cheat Sheet @@ -282,7 +282,7 @@ This is a great way to get comfortable with Fly.io if you prefer a managed datab The most important thing you'll want to be comfortable with using Fly.io's database offering is [backing up and restoring your database](/unmanaged-postgres/managing/backup-and-restore). -As your application grows, you'll probably first [scale disk and RAM resources](/unmanaged-postgres#scaling-vertically-adding-more-vm-resources), then [scale out with multiple replicas](/unmanaged-postgres#scaling-horizontally-adding-more-replicas). Common maintenance tasks will include [upgrading Postgres](/unmanaged-postgres#upgrading-the-postgres-app) as new versions are released with new features and security updates. +As your application grows, you'll probably first [scale disk and RAM resources](/unmanaged-postgres/managing/scaling), then [scale out with multiple replicas](/unmanaged-postgres/managing/horizontal-scaling). Common maintenance tasks will include [upgrading Postgres](/unmanaged-postgres/managing/upgrades) as new versions are released with new features and security updates. [See here](/unmanaged-postgres) for a more comprehensive guide for what's required when running your Postgres databases on Fly.io. diff --git a/getting-started/launch-demo.mdx b/getting-started/launch-demo.mdx index f340d6c90a..432084b06e 100644 --- a/getting-started/launch-demo.mdx +++ b/getting-started/launch-demo.mdx @@ -20,7 +20,7 @@ The first step is installing all the tools you need to work with Fly Launch. Whi ## 2. Sign up or sign in -Sign up for an account or [sign in](#sign-in-to-your-flyio-account) to your existing account. +Sign up for an account or [sign in](#sign-in-to-your-fly-io-account) to your existing account. ### Sign up for a Fly.io account diff --git a/getting-started/troubleshooting.mdx b/getting-started/troubleshooting.mdx index 06c278d412..6999ee08d5 100644 --- a/getting-started/troubleshooting.mdx +++ b/getting-started/troubleshooting.mdx @@ -156,7 +156,7 @@ docker build . ### Release command failures -[Release commands](/reference/configuration#deploy) run in an ephemeral Machine before your app starts. +[Release commands](/reference/configuration#the-deploy-section) run in an ephemeral Machine before your app starts. ``` error running release_command machine: machine not found diff --git a/languages-and-frameworks/dockerfile.mdx b/languages-and-frameworks/dockerfile.mdx index fa66e4935a..685730c16c 100644 --- a/languages-and-frameworks/dockerfile.mdx +++ b/languages-and-frameworks/dockerfile.mdx @@ -16,7 +16,7 @@ Run `fly launch` from your project's source directory. If you want to configure more than the basic settings, things like secrets or environment variables for example, run - `fly launch --no-deploy` so that you can [edit the `fly.toml` file](#more-config) before the first deployment. + `fly launch --no-deploy` so that you can [edit the `fly.toml` file](/reference/configuration) before the first deployment. diff --git a/languages-and-frameworks/wordpress.mdx b/languages-and-frameworks/wordpress.mdx index ab476f2fd8..eeac734c6e 100644 --- a/languages-and-frameworks/wordpress.mdx +++ b/languages-and-frameworks/wordpress.mdx @@ -6,7 +6,7 @@ source_url: https://fly.io/docs/languages-and-frameworks/wordpress/ Setting up a WordPress application on Fly.io is quite simple. In this guide, we'll learn just how simple it is! -There's one thing you need before setting up a WordPress application: a MySQL database. You can find out how to get one set up on Fly.io in [this handy guide](/app-guides/mysql-on-fly#main-content-start). +There's one thing you need before setting up a WordPress application: a MySQL database. You can find out how to get one set up on Fly.io in [this handy guide](/app-guides/mysql-on-fly). Make sure you remember the hostname (this will be `.internal`), the database name and the database credentials. Ready? Let's get started! diff --git a/laravel/advanced-guides/global-sqlite-litefs.mdx b/laravel/advanced-guides/global-sqlite-litefs.mdx index 95a45ee454..74275ff42e 100644 --- a/laravel/advanced-guides/global-sqlite-litefs.mdx +++ b/laravel/advanced-guides/global-sqlite-litefs.mdx @@ -47,5 +47,5 @@ Take note of the following important steps in configuring your [Laravel Fly App] ``` 5. Include a ( [etc/fuse.conf](https://github.com/fly-apps/fly-laravel-litefs/blob/main/etc/fuse.conf) ) file to enable `allow-other` option above to work. 6. Revise the generated [Dockerfile](https://github.com/fly-apps/fly-laravel-litefs#dockerfile) to include the `LiteFS` image, install required packages, and copy the configuration files `etc/litefs.yml` and `etc/fuse.conf` to a [proper location](/litefs/config#config-file-search-path) `LiteFS` can read. -7. Create a [middleware](https://github.com/fly-apps/fly-laravel-litefs/blob/main/app/Http/Middleware/FlyReplayLiteFSWrite.php) to forward write requests to the [primary node](/litefs/primary) using [fly-replay](/networking/dynamic-request-routing#fly-replay) +7. Create a [middleware](https://github.com/fly-apps/fly-laravel-litefs/blob/main/app/Http/Middleware/FlyReplayLiteFSWrite.php) to forward write requests to the [primary node](/litefs/primary) using [fly-replay](/networking/dynamic-request-routing#how-fly-replay-works) 8. Use a non-file session driver to [allow fly-replay to work](https://github.com/fly-apps/fly-laravel-litefs#fly-replay-and-csrf-tokens) on Laravel CSRF protection. diff --git a/laravel/advanced-guides/using-inertia-ssr.mdx b/laravel/advanced-guides/using-inertia-ssr.mdx index ff68ae5f79..369e9edc7f 100644 --- a/laravel/advanced-guides/using-inertia-ssr.mdx +++ b/laravel/advanced-guides/using-inertia-ssr.mdx @@ -109,7 +109,7 @@ Now that you have more than one process group for your Fly.io app, you'll have t ### Web and SSR Communication -The SSR server will be created as a separate VM from your web app. You'll have to configure your Laravel web VM to [talk with it](https://community.fly.io/t/process-group-aware-internal-dns-route-between-processes-with-ease/13063/4). To do so, first revise the `fly.toml` file to include an `SSR_URL` that will contain the ssr process' [.internal address](/networking/private-networking#fly-io-internal-addresses) routed to SSR's applicable port ( in the case below, 13714): +The SSR server will be created as a separate VM from your web app. You'll have to configure your Laravel web VM to [talk with it](https://community.fly.io/t/process-group-aware-internal-dns-route-between-processes-with-ease/13063/4). To do so, first revise the `fly.toml` file to include an `SSR_URL` that will contain the ssr process' [.internal address](/networking/private-networking#fly-io-internal-dns) routed to SSR's applicable port ( in the case below, 13714): ```.env [env] SSR_URL="ssr.process..internal:13714" diff --git a/laravel/database-guides/laravel-mysql.mdx b/laravel/database-guides/laravel-mysql.mdx index 855d598d05..70e2fb8399 100644 --- a/laravel/database-guides/laravel-mysql.mdx +++ b/laravel/database-guides/laravel-mysql.mdx @@ -14,7 +14,7 @@ To run MySQL as a [Fly App](/app-guides/mysql-on-fly), follow our guide [here](/ ### _Connect from a Laravel Fly App_ -1. Revise the `[env]` configuration in your Laravel application's `fly.toml` file to connect with your MySQL Fly App's [Fly .internal address](/networking/private-networking#fly-io-internal-addresses): +1. Revise the `[env]` configuration in your Laravel application's `fly.toml` file to connect with your MySQL Fly App's [Fly .internal address](/networking/private-networking#fly-io-internal-dns): ```toml [env] diff --git a/laravel/database-guides/laravel-redis.mdx b/laravel/database-guides/laravel-redis.mdx index 538c626cef..477d931576 100644 --- a/laravel/database-guides/laravel-redis.mdx +++ b/laravel/database-guides/laravel-redis.mdx @@ -90,7 +90,7 @@ If you would like to use [Redis' official docker image](https://hub.docker.com/_ Now that you have your Redis Fly App running, the next step is to connect it with your Laravel Fly App! Follow the steps below: -1. First, retrieve your Redis Fly App's [Fly .internal Address](/networking/private-networking#fly-io-internal-addresses). +1. First, retrieve your Redis Fly App's [Fly .internal Address](/networking/private-networking#fly-io-internal-dns). 2. Next, make sure you move to your Laravel Fly App's directory for better navigation: diff --git a/laravel/index.mdx b/laravel/index.mdx index eb73eac2ad..4cecc25f7d 100644 --- a/laravel/index.mdx +++ b/laravel/index.mdx @@ -60,7 +60,7 @@ Tigris: (not re ? Do you want to tweak these settings before proceeding? (y/N) ``` -Extensions like [Postgres](/postgres/index) ( database ), [Redis](/upstash/redis) ( cache ), and [Tigris](/tigris#main-content-start) ( storage ) can also be added by default based on whether there's an existing, similar connection found for your Laravel project. +Extensions like [Postgres](/postgres/index) ( database ), [Redis](/upstash/redis) ( cache ), and [Tigris](/tigris) ( storage ) can also be added by default based on whether there's an existing, similar connection found for your Laravel project. **Please note** that these extension apps will also incur their own **usage costs**! You can select "y" in order to adjust the default settings and remove any extension you don't need. diff --git a/laravel/the-basics/laravel-volume-storage.mdx b/laravel/the-basics/laravel-volume-storage.mdx index 5c4dbb6452..7669f49661 100644 --- a/laravel/the-basics/laravel-volume-storage.mdx +++ b/laravel/the-basics/laravel-volume-storage.mdx @@ -119,4 +119,4 @@ Take note however, that a Volume can only be used by one at any given time. One way to fix this issue is to separate each process into [different Fly.io apps](/app-guides/multiple-processes#maybe-you-want-multiple-apps-though). Of course, separate application per process might require inter-communication between the applications. -Fly.io applications can easily communicate with each other over a [private network](/networking/private-networking). Not only that, but Fly.io also offers the `fly-replay` [response header](/networking/dynamic-request-routing#the-fly-replay-response-header) which can be used to "redirect" request from one application to another, and return response from the correct application. +Fly.io applications can easily communicate with each other over a [private network](/networking/private-networking). Not only that, but Fly.io also offers the `fly-replay` [response header](/networking/dynamic-request-routing#how-fly-replay-works) which can be used to "redirect" request from one application to another, and return response from the correct application. diff --git a/launch/autostop-autostart.mdx b/launch/autostop-autostart.mdx index 70c206420a..66321379e4 100644 --- a/launch/autostop-autostart.mdx +++ b/launch/autostop-autostart.mdx @@ -85,7 +85,7 @@ In general, unless your app shuts itself down when idle, we recommend setting `a To keep one or more Machines running all the time in your primary region, set `min_machines_running` to `1` or higher. If `min_machines_running = 1` and there's no traffic to your app, then Fly Proxy will stop Machines until eventually there is only one Machine running in your primary region. `min_machines_running` has no effect unless you set `auto_stop_machines` to `"stop"` or `"suspend"`. -**`min_machines_running`:** This setting only maintains the specified minimum number of running Machines in your app's primary region. It has no effect on other regions where your app is deployed. If you need to maintain minimum running Machines in multiple regions, you'll need to manage those separately through other means like [`fly scale count`](/flyctl/cmd/fly_scale_count#main-content-start). +**`min_machines_running`:** This setting only maintains the specified minimum number of running Machines in your app's primary region. It has no effect on other regions where your app is deployed. If you need to maintain minimum running Machines in multiple regions, you'll need to manage those separately through other means like [`fly scale count`](/flyctl/cmd/fly_scale_count). ### Maximum number of Machines running diff --git a/launch/deploy.mdx b/launch/deploy.mdx index b6bfe4ceb3..86d206493f 100644 --- a/launch/deploy.mdx +++ b/launch/deploy.mdx @@ -97,7 +97,7 @@ Updating existing machines in 'example-app-8803' with canary strategy ## Not all changes require a new App release -You can [add an IP address](/networking/services#ip-addresses) to an App, for example, without redeploying. +You can [add an IP address](/networking/services#anycast-ip-addresses) to an App, for example, without redeploying. Adding a [secret](/apps/secrets) to the App does require a restart, so `fly secrets set` triggers a new deployment. diff --git a/launch/processes.mdx b/launch/processes.mdx index 79a9a77ff1..207fb87f67 100644 --- a/launch/processes.mdx +++ b/launch/processes.mdx @@ -63,7 +63,7 @@ For more information about how many Machines are created by `fly launch` and `fl ## Scale a process group horizontally -There are two ways to scale the number of Machines in an app. This section provides a summary of horizontal scaling. For more information, refer to [Scale the Number of Machines](/launch/scale-count#change-the-number-of-machines-in-a-process-group). +There are two ways to scale the number of Machines in an app. This section provides a summary of horizontal scaling. For more information, refer to [Scale the Number of Machines](/launch/scale-count#scale-by-process-group). ### Scale a process group horizontally with `fly scale count` diff --git a/launch/scale-count.mdx b/launch/scale-count.mdx index 1f7dd4d03b..feb5706399 100644 --- a/launch/scale-count.mdx +++ b/launch/scale-count.mdx @@ -56,7 +56,7 @@ This app has 10 Machines total. The `app` process group has two in scl (Santiago The following examples apply to a Fly App's default process group: the `app` process group. If you don't define [process groups](/launch/processes), then all of the app's Machines belong to the `app` process group, with the exception of any Machines created with `fly machine` commands or the Machines API. -`fly scale count` applies changes to the default process group if it is not [passed explicit per-process target counts](#change-the-number-of-machines-in-a-process-group). +`fly scale count` applies changes to the default process group if it is not [passed explicit per-process target counts](#scale-by-process-group). Here's the `fly scale show` output for a newly deployed web app, with two machines in yyz (Toronto): diff --git a/launch/scale-machine.mdx b/launch/scale-machine.mdx index 7a2287570e..438c681bac 100644 --- a/launch/scale-machine.mdx +++ b/launch/scale-machine.mdx @@ -148,7 +148,7 @@ Looks good! If you are happy with the provisioned CPU resources, but want more memory, then use `fly scale memory` to top up the RAM. -If your app crashes with an out-of-memory error, then scale up its RAM. Flyctl restarts the Machines to use the new setting. Scaling memory this way lets you test your app with more or less RAM, before optionally [setting memory more permanently in `fly.toml`](#add-machine-size-configuration-to-flytoml). +If your app crashes with an out-of-memory error, then scale up its RAM. Flyctl restarts the Machines to use the new setting. Scaling memory this way lets you test your app with more or less RAM, before optionally [setting memory more permanently in `fly.toml`](#add-machine-size-configuration-to-fly-toml). ```bash cmd diff --git a/machines/flyctl/fly-machine-run.mdx b/machines/flyctl/fly-machine-run.mdx index aa99faec2d..c28a886ad5 100644 --- a/machines/flyctl/fly-machine-run.mdx +++ b/machines/flyctl/fly-machine-run.mdx @@ -251,7 +251,7 @@ The default restart policy for a Machine created using `fly machine run` is `alw By default, when a Machine is `stopped`, its file system is reset using its config and Docker image, and it sits ready to be `started` again. Use the `--rm` flag to cause the Machine to instead be destroyed when it stops. -The default [restart policy](#set-a-restart-policy-on-process-exit) for a Machine created with `fly machine run --rm` is `no`, to ensure that flyd doesn't ignore the exit code and restart the Machine. +The default [restart policy](#stop-or-restart-the-machine-on-process-exit) for a Machine created with `fly machine run --rm` is `no`, to ensure that flyd doesn't ignore the exit code and restart the Machine. ## Mount a Fly Volume diff --git a/machines/flyctl/fly-machine-update.mdx b/machines/flyctl/fly-machine-update.mdx index 4f0dab458d..1f0d0d3e79 100644 --- a/machines/flyctl/fly-machine-update.mdx +++ b/machines/flyctl/fly-machine-update.mdx @@ -84,7 +84,7 @@ As for [`fly machine run`](/machines/flyctl/fly-machine-run#set-environment-vari As for [`fly machine run`](/machines/flyctl/fly-machine-run#define-a-fly-proxy-network-service). ## Set Fly Proxy auto start and auto stop -As for [`fly machine run`](/machines/flyctl/fly-machine-run#set-fly-proxy-auto-start-and-auto-stop). +As for [`fly machine run`](/machines/flyctl/fly-machine-run#set-fly-proxy-autostop-autostart). ## Stop or restart the Machine on process exit diff --git a/machines/runtime-environment.mdx b/machines/runtime-environment.mdx index 2815c3ccbc..a07918e46e 100644 --- a/machines/runtime-environment.mdx +++ b/machines/runtime-environment.mdx @@ -13,7 +13,7 @@ Environment variables make several kinds of information available within a Machi ## _Environment variables_ ### `FLY_APP_NAME` -**App name**: Each app running on Fly.io has a unique app name. This identifies the app for the user, and can also identify its Machines on their IPv6 private network, using internal DNS. For example, `syd.$FLY_APP_NAME.internal` can refer to the app's Machines running in the `syd` region. Read more about [6PN Naming](/networking/private-networking#fly-io-internal-addresses) in the [Private Networking](/networking/private-networking) docs. +**App name**: Each app running on Fly.io has a unique app name. This identifies the app for the user, and can also identify its Machines on their IPv6 private network, using internal DNS. For example, `syd.$FLY_APP_NAME.internal` can refer to the app's Machines running in the `syd` region. Read more about [6PN Naming](/networking/private-networking#fly-io-internal-dns) in the [Private Networking](/networking/private-networking) docs. ### `FLY_MACHINE_ID` **Machine ID**: The Machine's unique ID on the Fly.io platform. This is the ID you use to target the Machine using flyctl and the Machines API. You can also see it in the [log](/flyctl/cmd/fly_logs) messages emitted by the Machine. diff --git a/monitoring/error-codes.mdx b/monitoring/error-codes.mdx index dfe951436f..f172173a7e 100644 --- a/monitoring/error-codes.mdx +++ b/monitoring/error-codes.mdx @@ -66,7 +66,7 @@ This indicates a problem with your application aborting a TCP connection prematu This indicates a problem with connections timing out to your application. Check the following to diagnose: * Application logs may indicate the cause of a timeout -* Ensure your app isn't overloaded by properly set its [concurrency limits](/apps/concurrency#main-content-start) +* Ensure your app isn't overloaded by properly set its [concurrency limits](/apps/concurrency) * Check [application metrics](/monitoring/metrics#managed-grafana) for signs of resource exhaustion (CPU, memory, disk I/O) #### PC06: Unidentified I/O error {#pc06-unidentified-i-o-error} @@ -178,26 +178,26 @@ The current threshold for 'recently stopped' is 5 minutes. #### PA01: Replay/retry buffer exceeded {#pa01-replay-retry-buffer-exceeded} -To prepare for the possibility of receiving [`fly-replay` response header](/networking/dynamic-request-routing#the-fly-replay-response-header), or for retrying failed requests, Fly edge proxies buffer requests up to 10MB. +To prepare for the possibility of receiving [`fly-replay` response header](/networking/dynamic-request-routing#how-fly-replay-works), or for retrying failed requests, Fly edge proxies buffer requests up to 10MB. If a request grows larger than 10MB, buffering stops, making it impossible to replay or retry the request. When this happens, `PA01` is emitted. #### PA02: Excess fly-replay headers -After a ['fly-replay' response header](/networking/dynamic-request-routing#the-fly-replay-response-header) replays a request, the application may respond normally, or it may issue another `fly-replay`, up to 10 times. `PA02` is emitted when `fly-replay` is returned more than 10 times. +After a ['fly-replay' response header](/networking/dynamic-request-routing#how-fly-replay-works) replays a request, the application may respond normally, or it may issue another `fly-replay`, up to 10 times. `PA02` is emitted when `fly-replay` is returned more than 10 times. #### PA03: Invalid fly-replay -Your app returned an invalid ['fly-replay' response](/networking/dynamic-request-routing#the-fly-replay-response-header). +Your app returned an invalid ['fly-replay' response](/networking/dynamic-request-routing#how-fly-replay-works). #### PA04: Replay target app not found -Your app returned a ['fly-replay' response header](/networking/dynamic-request-routing#the-fly-replay-response-header) targeting a non-existent application in the `app` parameter. +Your app returned a ['fly-replay' response header](/networking/dynamic-request-routing#how-fly-replay-works) targeting a non-existent application in the `app` parameter. #### PA05: Unauthorized replay target app -Your app returned a ['fly-replay' response header](/networking/dynamic-request-routing#the-fly-replay-response-header) targeting an application belonging to a different Fly.io organization. Only apps in the same +Your app returned a ['fly-replay' response header](/networking/dynamic-request-routing#how-fly-replay-works) targeting an application belonging to a different Fly.io organization. Only apps in the same organization may replay requests to each other. ### Edge proxy errors @@ -260,7 +260,7 @@ The proxy failed to retrieve a static file from the specified Tigris storage buc #### PL01: Bypassed connection concurrency limit -[Concurrency limits](/apps/concurrency#main-content-start) set in `fly.toml` define how traffic should be balanced across machines in your app. +[Concurrency limits](/apps/concurrency) set in `fly.toml` define how traffic should be balanced across machines in your app. This error occurs when concurrency is measured as the number of concurrent **connections**. diff --git a/networking/app-services.mdx b/networking/app-services.mdx index c8e36a21b3..adc27279cf 100644 --- a/networking/app-services.mdx +++ b/networking/app-services.mdx @@ -86,7 +86,7 @@ Fly.io runs a specialized internal DNS service to find 6PN addresses for VMs. Qu Internal DNS gives us some useful presets for targeting requests. For instance, a DNS query on the address `..internal` yields the 6PN addresses of the VMs of app `` in region ``. Addressing a request to `..internal` gets it delivered to one of those VMs. -Our [private networking docs](/networking/private-networking#fly-io-internal-addresses) list the `.internal` names and what kind of information a DNS query returns for each. +Our [private networking docs](/networking/private-networking#fly-io-internal-dns) list the `.internal` names and what kind of information a DNS query returns for each. ## A note on IPv4 and IPv6 wildcards diff --git a/networking/custom-private-networks.mdx b/networking/custom-private-networks.mdx index 277b7d49f7..767b0dc13c 100644 --- a/networking/custom-private-networks.mdx +++ b/networking/custom-private-networks.mdx @@ -79,7 +79,7 @@ The `fly-replay` response header tells Fly Proxy to forward HTTP requests to ano For example, you could receive HTTP requests on a public "router" app and then forward the requests to specific apps or Machines on different customer 6PNs. The customer apps need to have services configured to expose a port on which to receive the requests. Make sure the customer apps don't have public IP addresses: apps created with the Machines API or with `fly apps create` don't get public IPs by default, but most apps created with `fly launch` do. -Learn more about using the [`fly-replay` response header](/networking/dynamic-request-routing#the-fly-replay-response-header). +Learn more about using the [`fly-replay` response header](/networking/dynamic-request-routing#how-fly-replay-works). ## Connect directly to Machines on custom 6PNs diff --git a/networking/dynamic-request-routing.mdx b/networking/dynamic-request-routing.mdx index 5b730a8e0a..db2a49f814 100644 --- a/networking/dynamic-request-routing.mdx +++ b/networking/dynamic-request-routing.mdx @@ -311,7 +311,7 @@ If your app needs to know whether a request was served from the replay cache, it For large uploads that exceed the 1MB limit, consider: - Using direct-to-storage uploads where possible -- Using the [fly-prefer-region](#the-fly-prefer-region-request-header) header instead +- Using the [fly-prefer-region](#the-fly-prefer-region-header) header instead For `fly-replay-cache`, the following limitations apply: - The `state` field cannot be set in the `fly-replay` intended to be cached diff --git a/networking/services.mdx b/networking/services.mdx index c58c59c0a1..0e526ee8a4 100644 --- a/networking/services.mdx +++ b/networking/services.mdx @@ -79,7 +79,7 @@ fly ips release The following steps should allow you to switch an app with a custom domain from a dedicated IPv4 address to a free shared IPv4 without downtime. 1. Add a shared IPv4 address with `flyctl ips allocate-v4 --shared`. -2. If you don't use a CNAME to `.fly.dev`, [add the shared IPv4 as an A record](/networking/custom-domain#set-the-a-record). +2. If you don't use a CNAME to `.fly.dev`, [add the shared IPv4 as an A record](/networking/custom-domain#a-and-aaaa-records-recommended). 3. Confirm your app works via shared IP: `curl -Iv http:// --resolve :80:`. You should receive a 301 redirect response. 4. If you are using a custom domain and don't already have an SSL certificate for this app, [create one](/networking/custom-domain#add-your-domain-to-your-app). The cert is required for routing to your app via the custom domain, even for HTTP connections. 5. Wait for DNS caches to clear. Five minutes is likely enough, but this varies wildly. This is determined by the larger of your DNS record’s TTL and that of our `.fly.dev` record. @@ -104,7 +104,7 @@ Valid handler strings: * [`"http"`:](#http-handler) Convert TCP connection to HTTP * [`"tls"`](#tls-handler): Convert TLS connection to unencrypted TCP * [`"pg_tls"`](#postgres-tls-handler): Handle TLS for PostgreSQL connections -* [`"proxy_proto"`](#proxy-protocol): Wrap TCP connection in PROXY protocol +* [`"proxy_proto"`](#proxy-protocol-handler): Wrap TCP connection in PROXY protocol You can also configure [TLS options](/reference/configuration#http_service-tls_options) for the `[http_service]` section, which has a TLS (and HTTP) handler by default on port 443. diff --git a/rails/advanced-guides/anycable.mdx b/rails/advanced-guides/anycable.mdx index c587c2372c..e81a14bd64 100644 --- a/rails/advanced-guides/anycable.mdx +++ b/rails/advanced-guides/anycable.mdx @@ -22,8 +22,7 @@ on the anycable site. ## Prepare your application -If you haven't already dones so, perform the steps described in the -[Provisioning Redis](/rails/getting-started#provisioning-redis) section of the Getting Started guide. Also be sure that the `pg` gem is listed +If you haven't already done so, [create an Upstash Redis database](/upstash/redis). Also be sure that the `pg` gem is listed in your `Gemfile`. Now add the `anycable-rails` gem: diff --git a/rails/advanced-guides/machine.mdx b/rails/advanced-guides/machine.mdx index 849a680394..78f7223dfe 100644 --- a/rails/advanced-guides/machine.mdx +++ b/rails/advanced-guides/machine.mdx @@ -217,9 +217,9 @@ end Note in particular the calls to `Fly::Machines`: - * [`Fly::Machines.create_and_start_machine`](/machines/overview#create-and-start-a-machine) - * [`Fly::Machines.get_a_machine`](/machines/overview#get-a-machine) - * [`Fly::Machines.delete_machine`](/machines/overview#delete-a-machine-permanently) + * [`Fly::Machines.create_and_start_machine`](/machines/api/machines-resource#create-a-machine) + * [`Fly::Machines.get_a_machine`](/machines/api/machines-resource#get-a-machine) + * [`Fly::Machines.delete_machine`](/machines/api/machines-resource#delete-a-machine-permanently) Each of the lines in the list above is a link to the documentation for that API. diff --git a/rails/cookbooks/index.mdx b/rails/cookbooks/index.mdx index 91c10e4c46..09c6ae08f4 100644 --- a/rails/cookbooks/index.mdx +++ b/rails/cookbooks/index.mdx @@ -34,7 +34,7 @@ application, and then proceed from there, running `fly deploy` after you make changes. The recipes the follow contain fragments that can be added to multiple cookbooks. -For best results, you are encouraged to try out each step. To do so, you will need to [Log in to Fly](/getting-started/sign-up-sign-in). Nothing you do in this tutorial will exceed the [Free Allowances](/about/pricing#free-allowances) provided. +For best results, you are encouraged to try out each step. To do so, you will need to [Log in to Fly](/getting-started/sign-up-sign-in). These cookbooks can be more than mere educational materials. Using throwaway applications is often better than experimenting in production when you want to make configuration changes. Starting a minimal application, using `flyctl ssh console` to shell into that machine and diff --git a/rails/the-basics/turbo-streams-and-action-cable.mdx b/rails/the-basics/turbo-streams-and-action-cable.mdx index d6c660e693..8f923abd0b 100644 --- a/rails/the-basics/turbo-streams-and-action-cable.mdx +++ b/rails/the-basics/turbo-streams-and-action-cable.mdx @@ -138,5 +138,4 @@ for the student. You have successfully built, deployed, and connected to your first Rails application on Fly.io. We've accomplished a lot with only just over a handful of lines of code and -just over a dozen commands. When you are ready, proceed to a -[recap](/rails/getting-started#recap). +just over a dozen commands. diff --git a/reference/aws-to-fly-guide.mdx b/reference/aws-to-fly-guide.mdx index 7ef17694c8..357d9c643e 100644 --- a/reference/aws-to-fly-guide.mdx +++ b/reference/aws-to-fly-guide.mdx @@ -22,7 +22,7 @@ But here's the catch: unless you mount a volume, the root filesystem is ephemera [Fly Volumes](/volumes/overview) are our answer to persistent storage. They're slices of NVMe mounted directly on the physical host. They're not network-attached. This means they're fast and simple, but they're tied to a specific host. If your machine dies, you can boot another and reattach the volume. Think EBS, minus the network indirection and regional abstraction. You can also store large static assets like ML models in volumes, which keeps your Docker images lean and your deploys snappy. -For object storage, we offer [Tigris](/tigris). It's S3-compatible and runs on Fly.io itself. If you're migrating from AWS S3, there's a handy [shadow bucket](/tigris#migrating-to-tigris-with-shadow-buckets) mode: Tigris can fall back to fetching from your existing S3 bucket if a file isn't yet copied over. First request pulls from S3; future requests hit local. Writes are synced, too, which makes a gradual migration painless. +For object storage, we offer [Tigris](/tigris). It's S3-compatible and runs on Fly.io itself. If you're migrating from AWS S3, there's a handy [shadow bucket](/tigris#migrate-from-another-s3-compatible-provider-with-zero-downtime) mode: Tigris can fall back to fetching from your existing S3 bucket if a file isn't yet copied over. First request pulls from S3; future requests hit local. Writes are synced, too, which makes a gradual migration painless. ### Networking diff --git a/snippets/docs/volumes-access.mdx b/snippets/docs/volumes-access.mdx index 5bebd9c614..c36221e02b 100644 --- a/snippets/docs/volumes-access.mdx +++ b/snippets/docs/volumes-access.mdx @@ -2,4 +2,4 @@ Access and write to a volume on a Machine just like a regular directory. For Machines managed with Fly Launch, the `destination` under `[mounts]` in `fly.toml` is the path for the mounted volumes. -For unmanaged Machines, you specify the mount path when you [add a volume to a cloned Machine](#add-a-volume-to-an-unmanaged-machine) or [create a Machine and attach a volume](/machines/flyctl/fly-machine-run#mount-a-fly-volume). +For unmanaged Machines, you specify the mount path when you [add a volume to a cloned Machine](/volumes/volume-manage#add-a-volume-to-an-unmanaged-machine) or [create a Machine and attach a volume](/machines/flyctl/fly-machine-run#mount-a-fly-volume). diff --git a/snippets/gpus/ollama-create.mdx b/snippets/gpus/ollama-create.mdx index 98d2442161..1a4efcf580 100644 --- a/snippets/gpus/ollama-create.mdx +++ b/snippets/gpus/ollama-create.mdx @@ -33,7 +33,7 @@ fly launch -c fly.ollama.toml --flycast There are a couple of things to note here: - The `ollama` image is a GPU image, so you need to specify a GPU size in the `[[vm]]` section. -- Not all regions have GPUs available, refer to [region GPU availability](/gpus#regions-with-gpus) for more info +- Not all regions have GPUs available, refer to region GPU availability for more info - The `[[mounts]]` section is used to mount a volume to store the models. This is a good practice to keep the models separate from the app code. - The volume size in this config file is 10gb, that's enough for small models. Change this value if you need more. - The `--flycast` flag creates a private IPv6 address for the app. diff --git a/snippets/js/frameworks/flyctl.mdx b/snippets/js/frameworks/flyctl.mdx index e89e2fb332..865928d398 100644 --- a/snippets/js/frameworks/flyctl.mdx +++ b/snippets/js/frameworks/flyctl.mdx @@ -1 +1 @@ -First, [install flyctl](/flyctl/install), the Fly.io CLI, and [sign up to Fly.io](/getting-started/sign-up-sign-in#first-time-or-no-fly-account-sign-up-for-fly) if you haven't already. +First, [install flyctl](/flyctl/install), the Fly.io CLI, and [sign up to Fly.io](/getting-started/sign-up-sign-in#no-account-sign-up-for-fly-io) if you haven't already. diff --git a/snippets/languages-and-frameworks/flyctl.mdx b/snippets/languages-and-frameworks/flyctl.mdx index e89e2fb332..865928d398 100644 --- a/snippets/languages-and-frameworks/flyctl.mdx +++ b/snippets/languages-and-frameworks/flyctl.mdx @@ -1 +1 @@ -First, [install flyctl](/flyctl/install), the Fly.io CLI, and [sign up to Fly.io](/getting-started/sign-up-sign-in#first-time-or-no-fly-account-sign-up-for-fly) if you haven't already. +First, [install flyctl](/flyctl/install), the Fly.io CLI, and [sign up to Fly.io](/getting-started/sign-up-sign-in#no-account-sign-up-for-fly-io) if you haven't already. diff --git a/unmanaged-postgres/index.mdx b/unmanaged-postgres/index.mdx index 0b0af0b838..e7831998e0 100644 --- a/unmanaged-postgres/index.mdx +++ b/unmanaged-postgres/index.mdx @@ -19,7 +19,7 @@ When you create a Fly Postgres cluster, you're offered several preset configurat Flyctl also offers a single-instance "Development" config. If you choose this option and the hardware it's running on has network problems or the SSD fails, your database will go down. In the latter case, you will lose any data accumulated since the last snapshot. Fly Postgres is designed so that you can turn a single-node cluster into a high-availability one just by adding a second instance in the same region. -In the single-instance "Development" config, you'll also be given the option to activate "automatic scale to zero". It's not magic: it's just [how our apps work](/launch/scale-count#scale-to-zero). If you have an app that connects to your database, make sure that [it also scales to zero](/launch/scale-count#scale-to-zero) (otherwise the connection remaining open will prevent it from "going to sleep"). +In the single-instance "Development" config, you'll also be given the option to activate "automatic scale to zero". It's not magic: it's just [how our apps work](/launch/scale-count#scale-to-zero-and-back-up). If you have an app that connects to your database, make sure that [it also scales to zero](/launch/scale-count#scale-to-zero-and-back-up) (otherwise the connection remaining open will prevent it from "going to sleep"). You can also add read-only replicas in other regions and take advantage of the Fly.io platform's proxy features to build a [Globally Distributed Postgres cluster](/unmanaged-postgres/advanced-guides/high-availability-and-global-replication). diff --git a/volumes/snapshots.mdx b/volumes/snapshots.mdx index b1f3e2c406..dee68360b5 100644 --- a/volumes/snapshots.mdx +++ b/volumes/snapshots.mdx @@ -10,7 +10,7 @@ A snapshot is a point-in-time copy of a volume's data. We automatically take dai If the data stored on your volume updates frequently, then you should have other methods to back up or replicate your data in addition to daily snapshots. If you only have a single copy of your data on a single volume, and the host fails, then any data stored between the time when the snapshot was taken and the time when the failure occurred will be lost. -You can use a volume snapshot to [restore the data into a new volume](#restore-a-deleted-volume). You can even use the same process to [restore data from a deleted volume](/volumes/volume-manage#restore-a-deleted-volume). +You can use a volume snapshot to [restore the data into a new volume](#restore-a-volume-from-a-snapshot). You can even use the same process to [restore data from a deleted volume](/volumes/volume-manage#restore-a-deleted-volume). ## Set or change the snapshot retention period