Home > OS >  Deploying Flask app with Gunicorn behind Nginx on Kubernetes cluster
Deploying Flask app with Gunicorn behind Nginx on Kubernetes cluster

Time:09-21

Is there any standard to deploy flask app with gunicorn and nginx on kubernetes cluster because I am trying to it by on dockerfile like below:

FROM nginx:latest as base-image
RUN apt update
RUN apt -y install python3 python3-pip
RUN apt -y install build-essential 

RUN mkdir /app
WORKDIR /app
COPY src src/
COPY src/.nginx/config /etc/nginx/conf.d/default.conf
COPY requirements.txt ./
RUN pip3 install -r requirements.txt

RUN pip3 install -e ./src
RUN pwd
RUN ls -l /app/src

# RUN pytest

EXPOSE 80

WORKDIR /app/src
CMD ["nginx", "-g", "daemon off;"]
ENTRYPOINT ["gunicorn" , "--bind","0.0.0.0:8000", "wsgi:app"]

Is the solution is to run two containers for each of gunicorn and nginx inside one pod of kubernetes?

CodePudding user response:

Is the solution is to run two containers for each of gunicorn and nginx inside one pod of kubernetes?

Yes. In Kubernetes or when simply running Docker on your local machine, it is always better to compose multiple containers rather than trying to stuff everything into a single container.

This part of your your Dockerfile:

CMD ["nginx", "-g", "daemon off;"]
ENTRYPOINT ["gunicorn" , "--bind","0.0.0.0:8000", "wsgi:app"]

Isn't doing what you seem to expect. These two directives operate in concert:

  • If defined, ENTRYPOINT is the command run by the container when it starts up.
  • The value of CMD is provided as an argument to the ENTRYPOINT script.

You can read more about ENTRYPOINT in the official documentation.

A better design would be to use the official Python image for your Python app:

FROM python:3.10

WORKDIR /app

COPY src src/
COPY requirements.txt ./
RUN pip3 install -r requirements.txt
RUN pip3 install -e ./src

WORKDIR /app/src
CMD ["gunicorn" , "--bind","0.0.0.0:8000", "wsgi:app"]

And then use the official nginx image to run the nginx service.


An example deployment that uses two containers, one for your Python app and one for Nginx, might look like:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: flask-example
  name: flask-example
spec:
  selector:
    matchLabels:
      app: flask-example
  template:
    metadata:
      labels:
        app: flask-example
    spec:
      containers:
      - image: quay.io/larsks/example:flaskapp
        name: app
      - image: docker.io/nginx:mainline
        name: nginx
        ports:
        - containerPort: 80
          name: http
        volumeMounts:
        - mountPath: /etc/nginx/conf.d
          name: nginx-config
      volumes:
      - configMap:
          name: nginx-config-c65tttk45k
        name: nginx-config

In the above deployment, we're mounting the configuration for nginx from a ConfigMap.

You can find a complete deployable example of the above here.

  • Related