Allow Vite React app to communicate with Flask API

I have a Vite React app deployed as follows:

fly.toml

app = 'app-name-123123'
primary_region = 'sea'

[build]

[http_service]
  internal_port = 5173
  force_https = true
  auto_stop_machines = true
  auto_start_machines = true
  min_machines_running = 0
  processes = ['app']

[[vm]]
  cpu_kind = 'shared'
  cpus = 1
  memory_mb = 1024

Dockerfile

FROM node:18

WORKDIR /web

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 5173

CMD ["npm", "run", "dev"]

And I also have a Flask API deployed as follows:

fly.toml

app = 'api-name-123123'
primary_region = 'sea'

[build]

[http_service]
  internal_port = 5000
  force_https = true
  auto_stop_machines = true
  auto_start_machines = true
  min_machines_running = 0
  processes = ['app']

[[vm]]
  cpu_kind = 'shared'
  cpus = 1
  memory_mb = 1024

Dockerfile

FROM python:3.9

WORKDIR /api

COPY requirements.txt requirements.txt

RUN pip install -r requirements.txt

COPY . .

CMD [ "flask", "run","--host","0.0.0.0","--port","5000"]

Both the React app and the API are up and running and I can visit them independently with their respective URLs.

When my React app tries to hit an endpoint on the Flask API, I get a App.tsx:30 POST http://127.0.0.1:5000/submit net::ERR_CONNECTION_REFUSED error.

I believe I might need to configure some environment variables.

What’s the process to ensure my React app can communicate with my Flask API?

Hi,

It’s hard to say for sure since there are so many different approaches now (especially with SSR, and e.g Remix/Next) but it sounds like you are running the React app as an SPA?

If it is an SPA and not server-rendered, that runs entirely client-side and so it can only call URLs your own browser would have access to. So in the browser, it would not be able to resolve http://127.0.0.1:5000 because that’s on Fly. So yes, you are right: you would need your React app to “know” to call your Flask API using its Fly-provided hostname e.g https://my-flask-api.fly.dev/users/123 instead. How you do that varies but yes, an environment variable is needed. Since you mention Vite, take a look at Env Variables and Modes | Vite.

Bonus: normally how an SPA works is the npm run dev is for local development, whereas for production you instead run npm run build. That tells Vite to bundle your static assets together. Creating a dist/index.html along with one or more bundled assets files like dist/assets/abcde.js. But maybe you do want the dev server.

Hi, thanks for the quick response.

I do have a .env file in my Vite React app:

VITE_API_URL="http://127.0.0.1:5000"

What’s the process to add an env file to the container running my Vite React app on Fly?

Can I exec into the container and create a similar env file, eg:

VITE_API_URL="https://my-flask-api.fly.dev"

Hi,

You can exec into the container and simply add an .env … but I wouldn’t. Since if you do it like that, that .env file would not be present if you were to ever need another machine. As Fly would not know to add it. And so your app would stop working again at some point, inevitably at an inconvenient time.

Instead …

For environment variables set at run-time, add those to the fly.toml in the env block:

[env]
  VITE_API_URL="https://my-flask-api.fly.dev"

And try that.

… but if your React app is an SPA its environment variables may be set at build-time rather than run-time. The npm run dev and npm run build differ in what they do. You may instead need to set the API URL at build time e.g

[build.args]
  VITE_API_URL="https://my-flask-api.fly.dev"

See which one works for your needs.

I managed to get it working by setting a secret from the Fly.io dashboard > Secrets > New Secret page.

Do you reckon there might be any issues doing it this way?

Also my Vite React app is a SPA which makes API calls Is there a better way to update the Dockerfile so it can run in production mode? Do I need to add nginx to my Dockerfile?

Open to suggestions.

1 Like

Using a secret will work just fine too.

Normally those are for environment variables you need to be secret (like an API key) but they are still provided to your app at run-time, just like the [env] block, so all good.

As for deploying the SPA, well yes, the npm run build will make static files and so that will work differently (build args).

It’s basically a static site. You’ll have an index.html along with some .js and .css files. So yes, you would need a web server as you wouldn’t have the Vite dev server. Nginx would be ideal.

Fly might have a guide else Google “React SPA nginx” and copy one of the example Dockerfiles.

Thanks, using a Dockerfile with nginx works!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.