'nginx not working when deployed to Azure App Service

I have a program consisting of Fast API, Celery, Flower and nginx written in Python. I use docker compose to build the images and deploy them to Azure App Service as a multi-container app.

My issue is that I cannot access Flower when deployed to Azure App Service. Locally, it works fine.

My docker-compose-build.yml which is used to build the images which are then pushed to ACR:

version: '3.4'

services:

  fast_api:
    container_name: fast_api
    build:
      context: .
      dockerfile: ./Dockerfile
    volumes:
      - .:/app
    ports:
      - 8080:8080
    depends_on:
      - redis

  celery_worker:
    container_name: celery_worker
    build: .
    command: celery -A app.celery.worker worker --loglevel=warning --pool=eventlet --concurrency=1000 -O fair 
    volumes:
      - .:/app
    environment:
      - CELERY_BROKER_URL=redis://redis:6379/0
      - CELERY_RESULT_BACKEND=redis://redis:6379/0
    depends_on:
      - fast_api
      - redis

  redis:
    container_name: redis
    image: redis:6-alpine 
    ports: 
      - 6379:6379

  flower:
    container_name: flower
    build: .
    command: celery -A app.celery.worker flower --port=5555 --url_prefix=flower
    ports:
      - 5555:5555
    environment:
      - CELERY_BROKER_URL=redis://redis:6379/0
      - CELERY_RESULT_BACKEND=redis://redis:6379/0
    depends_on:
      - fast_api
      - redis
      - celery_worker

  nginx:
    container_name: nginx
    build:
      context: .
      dockerfile: ./Dockerfile.nginx
    ports:
      - 80:80
    depends_on:
      - flower
      - fast_api

My docker-compose.yml which is used by Azure App Service:

version: '3.4'

services:
  fast_api:
    container_name: fast_api
    image: name.azurecr.io/name_fast_api:latest
    volumes:
      - ${WEBAPP_STORAGE_HOME}/app
    ports:
      - 8080:8080
    depends_on:
      - redis

  celery_worker:
    container_name: celery_worker
    image: name.azurecr.io/name_celery_worker:latest
    command: celery -A app.celery.worker worker --loglevel=warning --pool=eventlet --concurrency=1000 -O fair 
    volumes:
      - ${WEBAPP_STORAGE_HOME}/app
    environment:
      - CELERY_BROKER_URL=redis://redis:6379/0
      - CELERY_RESULT_BACKEND=redis://redis:6379/0
    depends_on:
      - fast_api
      - redis

  redis:
    container_name: redis
    image: name.azurecr.io/redis:6-alpine 
    ports: 
      - 6379:6379

  flower:
    container_name: flower
    image: name.azurecr.io/name_flower:latest
    command: celery -A app.celery.worker flower --port=5555 --url_prefix=flower
    ports:
      - 5555:5555
    environment:
      - CELERY_BROKER_URL=redis://redis:6379/0
      - CELERY_RESULT_BACKEND=redis://redis:6379/0
    depends_on:
      - fast_api
      - redis
      - celery_worker

  nginx:
    container_name: nginx
    image: name.azurecr.io/name_nginx:latest
    # volumes:
    #   - ${WEBAPP_STORAGE_HOME}/etc/nginx/nginx.conf #   Storage:/etc/nginx/nginx.conf #/etc/nginx/ #/usr/share/nginx/html ##/etc/nginx/nginx.conf
    ports:
      - 80:80
    depends_on:
      - flower
      - fast_api

Initially, in the docker-compose.yml, I pulled the image directly from Docker Hub, and then stored the nginx.conf file in Azure File Share which I mounted to the App Service. I had a suspicion that the nginx.conf file was not used by nginx. Therefore, I build a custom nginx image by creating Dockerfile.nginx where I copy in the nginx.conf file.

FROM nginx:stable
COPY nginx.conf /etc/nginx/nginx.conf

My nginx.conf file:

events {
  worker_connections  4096;  ## Default: 1024
}

http {

server {
    listen 80 default_server;
    #listen [::]:80;
    server_name _; #app-name.azurewebsites.net;

    location / {
        proxy_pass http://fast_api:8080/;
        proxy_set_header Host $host;
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
        location /test {
        proxy_pass http://fast_api:8080/;
        proxy_set_header Host $host;
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
    location /flower {
        proxy_pass http://flower:5555/flower;
        proxy_set_header Host $host;
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}
}

When I then go to https://app-name.azurewebsites.net/flower I get:

{ "detail": "Not Found" }

I can without problem access https://app-name.azurewebsites.net/docs and the API works perfectly.

Does anyone have an idea why I cannot access Flower when deployed to Azure?

Any help and ideas is appreciated as I have run out of things to try!



Solution 1:[1]

The issue has been solved. The issue was that all the docker services' ports were exposed externally, and that port 8080 was used by the fast_api service which might have conflicting with the fact that App Service is listening to port 8080 or 80 (https://docs.microsoft.com/en-us/azure/app-service/configure-custom-container?pivots=container-linux#configure-port-number) The solution was to only expose the nginx service's ports with the port parameter, and all other services should only by exposed internally with the expose parameter.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 TobiasRD