Sollosa
Sollosa

Reputation: 431

How To Mount Directory Of Conainter Into Another After containers are run?

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

Answers (2)

David Maze
David Maze

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

bellackn
bellackn

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

Related Questions