Reputation: 431
I have angular app, which is built when container is run as shown in Dockerfile
, that's built from two images.
FROM node:10.15.3-alpine as builder
RUN mkdir -p /usr/src/banax_education_platform
WORKDIR /usr/src/banax_education_platform
RUN apk add git
COPY package*.json /usr/src/banax_education_platform/
RUN npm i
COPY . /usr/src/banax_education_platform
RUN npm i -g @angular/cli && npm run-script build
FROM nginx:1.13.12-alpine
RUN rm -rf /usr/share/nginx/html/*
COPY /nginx/default.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /usr/src/banax_education_platform/dist/edu-app /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
So first of all, it fetches node image and build the app with all requirments. and then it fetches another image of nginx and creates server block to show the app. Now I want to split both images, so one container holds angular app and second does nginx reverse proxy.
Came up with this docker-compose.yml
version: "2"
services:
nginx:
build: ./nginx
container_name: angular-nginx
ports:
- "80:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- web
web:
build: ./angular
container_name: angular-app
ports:
- "8000"
But the issue is, I want this task:
COPY --from=builder /usr/src/banax_education_platform/dist/edu-app /usr/share/nginx/html
to be done via docker-compose, cause now I have 2 Dockerfiles, one for angular, and one for nginx, so I don't know how to link that angular container's directory with nginx container. Someone has any idea?
Upvotes: 0
Views: 424
Reputation: 158908
In a typical Web application, you run some sort of packager (for instance, Webpack) that "compiles" your application down to a set of static files. You then need some Web server to send those files to clients, but nothing runs that code on the server side once it's built.
This matches the multi-stage Docker image that you show in the question pretty well. The first stage only builds artifacts, and once it's done, nothing ever runs the image it builds. (Note for example the lack of CMD
.) The second stage COPY --from=build
the static artifacts it builds, and that's it.
Since there's no actual application to run in the first stage, it doesn't make sense to run this as a separate Docker Compose service or to otherwise "split this up" in the way you're showing.
If you don't mind having multiple build tools, one thing you can do is to treat the packaged application as "data" from the point of view of Nginx (it doesn't know anything about the content of these files, it just sends data over the network). You can pick some directory on your host and mount that into the Nginx container
version: "3"
services:
nginx:
image: nginx:1.13.12-alpine
ports:
- "80:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./dist:/usr/share/nginx/html
and then npm run-script build
on your host system when you need to rebuild and redeploy the application.
Upvotes: 2
Reputation: 2184
I think there is a conceptual misunderstanding. I'm not familiar with Angular, but here's how I would approach this (not tested).
The reverse proxy itself does not need the compiled files that you generate in your Dockerfile. This container (web
in your case) is just there to pass HTTP(S) requests to the correct endpoint (which is another webserver, let's call it app
). app
itself is an Nginx webserver that serves your Angular application.
So, what you would have to do is something like this:
version: "3.7"
services:
web:
image: nginx
volumes:
- ./config/with/proxy/rules:/etc/nginx/conf.d/default.conf
ports:
- 80:80
- 443:443
app:
build: ./path/to/your/dockerfile
expose:
- "8000"
volumes:
- ./path/to/nice/config:/etc/nginx/conf.d/default.conf
depends_on:
- web
The config file of the first volume would have to include all the proxy rules that you need. Basically, something like this should occur somewhere:
location / {
proxy_pass http://app:8000;
}
That's all your reverse proxy has to know.
Upvotes: 1