General description
Hi. I'm trying to come up with a solution to the following problem. I have one host machine running docker which should serve multiple independent web apps. Each app has a frontend (in angular) and backend (in NodeJS). I have nginx running on the same host machine (it has access to the SSL certificates, etc.).
See the diagram below describing what I'm trying to achieve. When a user requests app1.example.com the frontend files should be served. When app1.example.com/api/* is called, nginx passes the requst to the NodeJS backend.
Most of the articles I found online use containerized nginx and a single compose file. I want to have separate compose files for easy and independent updates - I just bump version numbers of web and API image in the .yml file and restart both containers with docker-compose. It won't affect other running containers or the nginx itself.
Core of my problem
I'm having issues on how to serve the static sites. One obvious solution would be to include another nginx in each of the web containers (Dockerfile.web in the diagram) and serve the static files from the container that way. I find that a bit wasteful to have more instances of nginx running when there is already one on the host.
Another way I thought about is to mount or copy the static files from the container to the host (for example to /var/www) when the container is started.
Ideal solution would be that if the container is running the static files are accessible to the host nginx. When the container is stopped, static files become inaccessible and nginx can return 404 or a "maintenance page".
Do you think I'm approaching this the right way? I don't want to end up devising some non-standard niche solution but I would still like to have host-running nginx and independent updates with docker-compose for reasons described above.
Dockerfiles
Dockerfile.api
# build stage
FROM node:14-alpine AS build
...
RUN yarn build
# run stage
FROM node:14-alpine
WORKDIR /app
COPY --from=build ...
RUN yarn install --prod
CMD ["node", "main.js"]
Dockerfile.web
# build stage
FROM node:14-alpine AS build
...
RUN yarn build
# run stage
FROM alpine
WORKDIR /app
COPY --from=build ...
# TODO: the files should be served here (or copied/mounted to the host)
CodePudding user response:
Thank you David for your suggestion. I settled with a solution using thttpd per-application instead of nginx (inspired by this article).
Resulting image serving my static site is around 5MB which is great. Everything else is still according to my original diagram. APIs are served by NodeJS, static sites by thttpd and on top is one nginx instance doing all the request-routing.