openverse-api
openverse-api copied to clipboard
Add nginx to the API multi-stage Dockerfile
Problem
For the ECS deployment of the frontend, we need to be able to deploy a Django and an Nginx image. To reduce the time it takes for the Django image to go from running to ready and to reduce the complexity of the deployment, we want to front load as much work as possible into the build.
Currently, the API deployment is complicated by the following:
collectstaticrun in Django container with output shared to Nginx via compose volumes- Nginx configuration configured entirely during the init script of our EC2 instances
- Version information passed as environment variables rather than baked into the images themselves at build time (meaning you could run image 1 and pass it version 2 and it would report the wrong version to you :scream:)
Description
All three of those complexities can be moved into a multi-stage Docker build. Something roughly like this:
FROM python:10-slim as builder
# ... the existing builder stuff
RUN collectstatic
FROM python:10-slim as django
# ... the existing stuff for this
FROM nginx as nginx
# VERSION is the git ref the image was built from
ARG VERSION
RUN echo "{\"version\":\"$VERSION\"}"
COPY --from=builder collectstatic-output
COPY nginx.conf .
Obviously this is missing everything that exists in the current Dockerfile which should be kept.
Additional context
Part of ongoing work to get the API deployed in ECS.
Implementation
- [ ] 🙋 I would be interested in implementing this feature.
@rbadillap did some work related to this in the feat/init-to-dockerfile branch from which we could recover something.
I don't know what Ronny's plan was in that branch, really :confused:. The only thing that looks like it might be useful is the Nginx configuration, but it's probably wiser to copy the one from the infrastructure repo as it is today, just in case things have changed there.
The docker-compose changes are completely unnecessary as we will not be using docker-compose to deploy the API in ECS and the existing docker-compose configuration in the openverse-api module's init.tpl would just need to have the nginx image swapped out for the published image and the volume configuration removed. Though if it's helpful for testing locally it could be nice to have the other docker-compose file.
Hi @sarayourfriend @krysal !
Initially, the branch was created with the purpose of replacing the init.tpl file, which is a file that is executed when the instance is created, which generates little traceability of the events and inability to obtain timely information about something that has failed.
At the time, we considered creating an API docker image and generating new tags each time a release was made; however, the migration plan is more complex than originally planned, mainly because replacing NGINX would require a better strategy to avoid breaking changes.
From the mentioned branch, I proposed a new file structure divided by environments, where each environment has a configuration folder with each service and its corresponding env vars (this provides the possibility of modifying parameters based on the environment to be deployed). However, the biggest challenge I encountered at that time was 1) understanding the .env of each service and 2) how to use the existing docker-compose.yaml files of each service and introduce them into my building process. In other words, I had to understand each docker-compose of each service, plus its corresponding .env file before I started using it.
Only the proposed file structure is salvageable from the branch, since it provides configuration flexibility and extensibility, but the files per se may be outdated over time.
Greetings from Spain!
Great, thanks Ronny. I think we just need to add a new step to the existing Dockerfile to produce the nginx image. If we want to add nginx to the local docker-compose as an additional service that would be a way to test it more easily. I don't think we need to go further than that right now in order to get the API able to be deployed in ECS.