as the title states, I have created a full stack application that uses FastAPI as the backend, and ReactJS as the frontend. I also have a third container for my Nginx reverse proxy. Reason I have this third container is so that I can make calls to my backend from the client's browser using the service/container names I create in the docker-compose.yaml file.
I then use the compose file to build and run all 3 of those containers. When I am working locally, everything works great at the localhost endpoint on my browser. However, when I try to deploy to Azure Web App Service, I am only able to load the frontend (React) home page. When I open the console, I receive an error saying 502 (Bad Gateway).
Below is a snippet of my ReactJS code that makes a post request for authentication
import React, { useEffect, useContext } from 'react';
import { Redirect, Route } from 'react-router-dom';
import Cookies from 'js-cookie';
import { AuthContext } from './contexts/AuthContext';
const PrivateRoute = ({ component: Component, ...rest }) => {
// Import the functions to set states
const { isAuthenticated, setIsAuthenticated, setUsername } =
useContext(AuthContext);
// Read in the access token; if not available, make empty string
const accessToken =
Cookies.get('access_token') == null ? '' : Cookies.get('access_token');
// Create the use effect function to generate the component
useEffect(() => {
fetch(`${window.location.protocol}//${window.location.hostname}/backend/auth/validate_token`, {
method: 'POST',
mode: 'cors',
credentials: 'include',
headers: {
Accept: 'application/json',
},
body: JSON.stringify({
token: accessToken,
}),
})
.then((response) => {
return response.json();
})
.then((response) => {
// Set the view based on the return
if (response) {
setIsAuthenticated(true);
setUsername(response.username);
} else {
setIsAuthenticated(false);
}
});
});
return (
<>
<Route
{...rest}
render={() => {
if (isAuthenticated) {
return <Component {...rest} />;
} else {
return <Redirect to='/login' />;
}
}}
/>
</>
);
};
export { PrivateRoute };
Below is my docker compose file
version: "3"
services:
reverse-proxy:
container_name: reverse-proxy
build:
context: ./proxy
dockerfile: Dockerfile
image: ilecontainerregistry.azurecr.io/proxy:latest
ports:
- 80:80
- 443:443
depends_on:
- frontend
- backend
frontend:
container_name: frontend
domainname: "usps-ile"
# Remove the build command for configuration file in azure web app service
build:
context: ./frontend
dockerfile: Dockerfile
image: ilecontainerregistry.azurecr.io/frontend:latest
ports:
- 8080:80
env_file:
- ./frontend/.env
backend:
container_name: backend
domainname: "usps-ile"
# Remove the build command for configuration file in azure web app service
build:
context: ./backend
dockerfile: Dockerfile
image: ilecontainerregistry.azurecr.io/backend:latest
ports:
- 3000:3000
env_file:
- ./backend/app/.env
Below is my dockerfile for the nginx container
FROM nginx:latest
COPY nginx.conf /etc/nginx/
And lastly, here is my nginx.conf file
events {
worker_connections 1024;
}
http {
upstream backend{
server backend:3000;
}
server {
listen 80;
listen 443;
server_name _;
location / {
proxy_pass http://frontend:80/;
}
location /backend/ {
proxy_pass http://backend/;
}
}
}
Below is a snippet from the FastAPI backend for the authentication post route in Python
@auth_router.post("auth/validate_token", tags=["Auth"])
async def validate_token(token: Token):
'''
This function is responsible for
reading in the token in an object
and validating if it is still valid
'''
try:
# Get the access token from the request cookie
authorization: str = token.token
# Split the access token on the space "Bearer" "xxxxxxxxx-token"
scheme, access_token = get_authorization_scheme_param(authorization)
# Decode the token and check if it is valid
decoded_token = jwt.decode(
token=access_token,
key=os.getenv("SECRET_KEY"),
algorithms=[os.getenv("ALGORITHM")]
)
return decoded_token
except Exception as e:
return False
Thank you in advance!
Looks like I figured out a solution that worked for me, I originally had the PORT for FastAPI exposed at 3000 (what i set it during development) but when I tried to deploy it with docker compose, I was having some issues with container communication.
I defaulted back to the normal PORT 80 for the fastapi container and changed my nginx conf file to look like the following and it worked like a charm! Hope I can help anyone else that was stuck.
events {
worker_connections 1024;
}
http {
server {
listen 80;
server_name _;
location / {
proxy_pass http://frontend:80/;
}
location /backend/ {
proxy_pass http://backend:80/;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With