# Process Groups and Internal Networking

**URL:** <https://community.fly.io/t/process-groups-and-internal-networking/8205>\
**Category:** Questions / Help\
**Created:** [October 27, 2022, 10:12am UTC](https://community.fly.io/t/process-groups-and-internal-networking/8205 "2022-10-27T10:12:38Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![LeoAdamek](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/leoadamek/32/39302_2.png) [@LeoAdamek](https://community.fly.io/u/LeoAdamek)\
**Post date:** [October 27, 2022, 10:12am UTC](https://community.fly.io/t/process-groups-and-internal-networking/8205/1 "2022-10-27T10:12:38Z")

</div>

I’ve got an app which has two process groups:

- `web` serves API requests.
- `worker` recieves background jobs from SQS and processes them.

External requests all work just fine, requests are routed to a `web` process.

However, internal requests (e.g. [http://top3.nearest.of.my-service.internal/](http://top3.nearest.of.my-service.internal/) ) – seem to be routed to any process, causing requests to fail if they get sent to a non-web process.

How do I define that only `web` processes listen on a port and should serve requests?

---

<div class="post-metadata">

**Author:** ![kurt](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/kurt/32/43757_2.png) [@kurt](https://community.fly.io/u/kurt)\
**Post date:** [October 27, 2022, 2:30pm UTC](https://community.fly.io/t/process-groups-and-internal-networking/8205/2 "2022-10-27T14:30:30Z")

</div>

This is not currently possible with internal DNS. There are two possible workarounds:

1. You may be able to use a private flycast IP to talk to the web processes. You can create a private load balancer IP with `fly ips allocate-v6 --private`
2. If you need separate DNS namespaces, you can also run two apps. It’s not as simple as multiple processes, but it’ll give you a lot more control.

---

<div class="post-metadata">

**Author:** ![LeoAdamek](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/leoadamek/32/39302_2.png) [@LeoAdamek](https://community.fly.io/u/LeoAdamek)\
**Post date:** [October 27, 2022, 3:30pm UTC](https://community.fly.io/t/process-groups-and-internal-networking/8205/3 "2022-10-27T15:30:19Z")

</div>

Okay, if I allocate a load balancer IP how do I pin it so it’s only the `web` processes which are routed?

---

<div class="post-metadata">

**Author:** ![fixlr](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/fixlr/32/3674_2.png) [@fixlr](https://community.fly.io/u/fixlr)\
**Post date:** [November 29, 2022, 4:24pm UTC](https://community.fly.io/t/process-groups-and-internal-networking/8205/4 "2022-11-29T16:24:41Z")

</div>

From the [Flycast Private Load Balancing documentation](https://fly.io/docs/reference/private-networking/#flycast-private-load-balancing), it sounds like traffic should be automatically routed to the `web` processes, the same way it works for public traffic?

> This traffic is routed through the Fly proxy - like [public traffic](https://fly.io/docs/reference/services/#anycast) - arriving in the geographically closest region with active VMs.

It isn’t clear to me from the documentation whether there are other differences between using a private Flycast IP instead of `.internal` addresses. We have a similar use case with `web` and `worker` processes for one app, and a second app that needs to connect via private networking.

---

<div class="post-metadata">

**Author:** ![jsierles](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/jsierles/32/595_2.png) [@jsierles](https://community.fly.io/u/jsierles)\
**Post date:** [November 29, 2022, 6:54pm UTC](https://community.fly.io/t/process-groups-and-internal-networking/8205/5 "2022-11-29T18:54:19Z")

</div>

Flycast will actually send your traffic through the proxy, where using `.internal` will using DNS to address your app instances directly. Flycast could work for your use case. This is actually how our [managed Redis offering](https://fly.io/docs/reference/redis/) works.

It may not be clear from the docs, but Flycast will use the same `[services]` block from your `fly.toml` as the public proxy does. You can control which process groups respond by placing each one on a different internal port.

One caveat. If your Flycast target app has a public IPv4 address, any service you setup for use with Flycast will also be available to the public internet. We don’t have a workaround for this yet besides creating two separate apps.

---

<div class="post-metadata">

**Author:** ![fixlr](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/fixlr/32/3674_2.png) [@fixlr](https://community.fly.io/u/fixlr)\
**Post date:** [November 30, 2022, 11:46pm UTC](https://community.fly.io/t/process-groups-and-internal-networking/8205/6 "2022-11-30T23:46:48Z")

</div>

@jsierles Thanks! It’s great to know that we’re looking in the right direction.

One problem we ran into when switching to the private IPv6 Flycast address is that we see an error in the proxy logs.

```auto
Error: no host specified in headers or uri

```

(The Flycast target app is using `force_https`.)

We resolved this by configuring a `Host: <app-name>.fly.dev` header in our HTTP client, but I’m wondering if there’s a more convenient way to configure this?

> One caveat. If your Flycast target app has a public IPv4 address, any service you setup for use with Flycast will also be available to the public internet. We don’t have a workaround for this yet besides creating two separate apps.

Does this only apply to ports configured in `[[services.ports]]` blocks? Here’s a heavily edited snippet of our Flycast target app, for more context. If I’m understanding correctly, 80 will redirect, 443 will be passed through to port 8080 on the `web` process, and 8081 will **not** be public.

```auto
[processes]
  web = "..."
  worker = "..."

[[services]]
  internal_port = 8080
  processes = ["web"]
  protocol = "tcp"

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

  [[services.ports]]
    handlers = ["tls", "http"]
    port = 443
    
  [[services.http_checks]]
  (... snip ...)

[[services]]
  internal_port = 8081
  processes = ["worker"]
  protocol = "tcp"

  [[services.http_checks]]
  (... snip ...)

```

---

<div class="post-metadata">

**Author:** ![jsierles](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/jsierles/32/595_2.png) [@jsierles](https://community.fly.io/u/jsierles)\
**Post date:** [December 1, 2022, 4:03pm UTC](https://community.fly.io/t/process-groups-and-internal-networking/8205/7 "2022-12-01T16:03:29Z")

</div>

Setting the Host header is probably the simplest approach for now - what else did you have in mind?

Flycast uses the exact same proxy rules as our public proxy. So your service on port 8081 will not be available over the Flycast IP address. You’d have to add a `[[services.ports]]` section for it. Right now I don’t think there’s a good workaround besides running a totally separate app to handle internal Flycast requests.
