Reputation: 697
I am trying to build a FastAPI application with ubuntu 22.04 docker image, gunicorn and uvicorn and nginx as webserver. Gunicorn and uvicorn services are started using supervisord.
python is installed in a virtual environment located in /opt/venv
Dockerfile
FROM ubuntu:22.04
LABEL maintainer="test"
ENV GROUP_ID=1000 \
USER_ID=1000
RUN apt-get update && apt-get install -y apt-transport-https ca-certificates supervisor procps cron python3.10-venv python3-gdbm wget gnupg unzip curl
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV VIRTUAL_ENV=/opt/venv
RUN python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
RUN ["python", "-m", "pip", "install", "--upgrade", "pip", "wheel"]
RUN apt-get install -y python3-wheel
COPY ./requirements.txt /app/requirements.txt
RUN ["python", "-m", "pip", "install", "--no-cache-dir", "--upgrade", "-r", "/app/requirements.txt"]
COPY ./app /app
RUN which python
nginx is using a separate docker image. Mongodb is the database and the content of docker-compose is
docker-compose.yml
version: '3.10'
services:
web:
container_name: "fastapi"
build: ./
volumes:
- ./app:/app
ports:
- "8000:8000"
environment:
- DEPLOYMENT_TYPE=production
depends_on:
- mongo
links:
- mongo
nginx:
container_name: "nginx"
restart: always
image: nginx
volumes:
- ./app/nginx/conf.d:/etc/nginx/conf.d
ports:
- 80:80
- 443:443
links:
- web
python packages are specified in requirements.txt
requirements.txt
setuptools>=59.1.1,<59.7.0
fastapi==0.87.0
uvicorn==0.19.0
gunicorn==20.1.0
python-decouple==3.5
nginx configuration file is
app.conf
upstream web {
server web:8000;
}
server {
listen 80;
charset utf-8;
server_name 0.0.0.0;
client_max_body_size 20m;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_send_timeout 300;
location / {
proxy_pass http://web/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
uvicorn and gunicorn are started using supervisor
supervisord.conf
[supervisord]
nodaemon=true
[program:fastapi_guni]
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
command=/opt/venv/bin/gunicorn app.main:app --workers 4 --name main --worker-class /opt/venv/bin/uvicorn.workers.UvicornWorker --host 0.0.0.0:8000 --reload
the python main.py is
main.py
import uvicorn
from fastapi.middleware.cors import CORSMiddleware
from fastapi import FastAPI
from app.routes.api import router as api_router
app = FastAPI()
origins = ["http://localhost:8000"]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(api_router)
if __name__ == '__main__':
uvicorn.run(host='127.0.0.1', debug=True, port=8000, log_level="info", reload=True)
print("running")
when i try to bring up the containers, fastapi container will get stopped immediately once the container starts with the following message
fastapi exited with code 0
and nginx will also get stopped throwing the following message
nginx | 2022/11/15 19:10:46 [emerg] 1#1: host not found in upstream "web:8000" in /etc/nginx/conf.d/app.conf:2
nginx | nginx: [emerg] host not found in upstream "web:8000" in /etc/nginx/conf.d/app.conf:2
nginx exited with code 1
I am sitting on this for several hours and how can bring the service up and running.
update
Folder structure
Upvotes: 1
Views: 4251
Reputation: 153
In the mentioned Dockerfile, I don't see any command for running the server. Something like this should work:
CMD ["python", "<path-to>/main.py"]
Also, to make it discoverable within the docker network, I had to run the application on '0.0.0.0' instead of localhost. (It might be an issue specifically on my system, But I didn't have time to debug that.)
Also, you should consider making the web
service a dependency for nginx
, so that nginx will start only after web is up and running.
Upvotes: 2