Set up a Proxy(Nginx) for a FastApi application (Part Two)

Adebisi Olayinka
4 min readDec 2, 2023

--

This is the second part of a three-part series. If you still haven't read part one, please check it out here as I will be building up on what was done in the previous tutorial.

Recap:

From the previous tutorial, we were able to get our Fast API app containerized

You could also clone the GitHub repository to follow along.

Setting up config for Nginx

We have to provide the configuration for our proxy so it would be able to communicate with our API when they’ve both been containerized.

Create a new directory in the project directory, you may name it whatever you wish but I’m choosing to go with nginx. Now create another file in this directory called nginx.conf as this file will hold our configuration for nginx.

Now add the following lines to the nginx.conf file:

server {
listen 80;
server_name http://127.0.0.1;

client_max_body_size 32m;

location ^~ /.well-known/acme-challenge {
default_type text/plain;
root /var/www/letsencrypt;
}

location / {
proxy_pass http://app:8000;
return 301 https://$host$request_uri;
}
}

# server {
# listen 443 default_server ssl;
# server_name example.com;
# server_tokens off;

# ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# ssl_dhparam /etc/letsencrypt/dhparams/dhparams.pem;

# client_max_body_size 32m;

# location / {
# proxy_pass http://app:8000;
# proxy_set_header Host $http_host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto $scheme;
# }
# }

The server_name http://127.0.0.1; directive specifies the server name clients should use to reach this server. In this case, the server name is 127.0.0.1, which is the loopback address for my local machine.

This config will tell nginx to proxy requests to our app container that we specified in the docker-compose, notice this where I specified the proxy_pass parameter. This configuration also includes commented-out boilerplate for enabling SSL which will definitely be useful when we might eventually need to add a domain name.

Updating docker-compose.yml

We need to update our docker-compose to include a container for Nginx.

version: "3"

services:
app:
build: .
ports:
- "8000:8000"
restart: unless-stopped
logging:
driver: "json-file"
options:
max-file: "1"
max-size: "100k"


nginx:
restart: unless-stopped
image: nginx
container_name: nginx
ports:
- "80:80"
# - "443:443"
# environment:
# - CERTBOT_EMAIL=youremail@gmail.com
volumes:
- ./nginx:/etc/nginx/user_conf.d:ro
# - letsencrypt:/etc/letsencrypt
depends_on:
- app
logging:
driver: "json-file"
options:
max-size: "100k"
max-file: "1"

This updated configuration file defines a multi-service Docker application consisting of two services: our app which we configured earlier and the newly added nginx.

Nginx configuration explained:

restart: unless-stopped: This tells Docker to restart the container if it crashes or is stopped manually.

image: nginx: This specifies that the default Nginx image from Dockerhub should be used for the container.

container_name: nginx: This assigns the name ‘nginx’ to the container.

ports:: This defines the ports that the container will expose.

- “80:80”: This exposes the Nginx container's port 80 on the host machine as port 80.

volumes: This defines volumes that will be mounted into the container.

- ./nginx:/etc/nginx/user_conf.d:ro: This mounts the nginx directory from the current directory into the /etc/nginx/user_conf.d directory inside the container. The :ro flag indicates that the volume should be read-only.

depends_on:: This specifies that the nginx container depends on the app container. This means that the nginx container will not start until the app container is up and running.

logging:: This defines the logging configuration for the container.

driver: “json-file”: This specifies that JSON-formatted logs should be written to files.

options:: This defines options for the JSON file logging driver.

max-size: “100k”: This limits the size of each log file to 100 kilobytes.

max-file: “1”: This limits the number of log files to 1.

SSL-related configurations are present but commented out.

Now that we have our services containerized, we can then

docker-compose up

While the containers are up and running, if you’ve been following along, you should now be able to visit http://127.0.0.1:8000/docs to view the default page for FastApi

Congratulations! 😊 You’ve successfully containerized your application and it’s now accessible through a proxy as well. Please look out for the third and final part of this series where I will be deploying this app to the web.

--

--