I am running a containerized web app in Azure App Services that has two container images pulled from my Azure Container Registry and spun up by a single docker-compose file:
gunicorn -w 2 --bind 0.0.0.0:8000 app:app
)When I successfully run this dual-container app locally, the base-url of my front-end axios http request is 'http://localhost:8000' like below:
axios.get('http://localhost:8000/getSomething', { params: {foo: bar}});
This makes sense to me because upon gunicorn's startup, it says 'Listening at: http://0.0.0.0:8000'.
This does not work in the azure web app however, and I think it is because of 1 (or maybe both) of the following:
I have no idea what base-url to use in the axios request. Should it remain 'localhost'? Should I change it to '0.0.0.0', or the Default domain url, or the Virtual IP address (the latter being properties from the web app)?
My web app also forces https so it might not allow http requests. But if that is the case, what do i do since gunicorn listens to http://0.0.0.0:8000. (I got this thinking from one error that said something like 'This request has been blocked; the content must be served over HTTPS' when I used 'http://0.0.0.0:8000' as my axios base-url).
The above two potential problems are what I'm currently looking into but any guidance on what is actually needed to connect my front-end with my back-end api containers would be much appreciated. (side note: for now my CORS policy is set to allow all so I'm pretty sure that's not related to the issue.)
I was also having same issue. react was working perfectly fine but it was not able to connect to back end. As Docker compose is in preview state some feature still may not be supported direct communication between containers.
Using NGINX
as proxy worked for me.
Here are my all the files
default.conf
:
server {
listen 80;
server_name azurewebsites.net;
location / {
proxy_pass http://react:80/;
}
location /api/ {
proxy_pass http://flask:8000/;
}
}
Dockerfile
:
# Use a lightweight Nginx image as the base
FROM nginx:1.25
COPY default.conf /etc/nginx/conf.d
App.jsx
:
import { useEffect, useState } from 'react';
import './App.css';
function App() {
const [data,setData] = useState({})
useEffect(()=>{
fetch('/api/data')
.then(res => res.json())
.then(imgurl=> setData(imgurl))
},[])
return (
<>
<img src={data.message} alt="image" />
</>
);
}
export default App;
Dockerfile
:
FROM node:18-alpine AS build
WORKDIR /app
COPY . .
RUN npm install && npm run build
FROM nginx:stable-alpine
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
app.py
:
from flask import Flask, jsonify
from flask_cors import CORS
import requests
app = Flask(__name__)
CORS(app)
@app.route('/')
def home():
return "Welcom to Flask app"
@app.route('/data')
def fetch_articles():
response= requests.get("https://dog.ceo/api/breeds/image/random")
return response.json()
if __name__ == '__main__':
app.run()
requirements.txt
:
flask
requests
gunicorn
flask-cors
Dockerfile
:
FROM python:3.11-alpine
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
CMD gunicorn -b 0.0.0.0:8000 app:app
docker-compose.yml
version: '3.3'
services:
nginx:
image: vivek.azurecr.io/nginx
ports:
- "80:80"
container_name: nginx
react:
image: vivek.azurecr.io/react
ports:
- "80"
depends_on:
- flask
container_name: react
flask:
image: vivek.azurecr.io/flask
ports:
- "8000"
container_name: flask
OUTPUT
:react
flask