Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.7k views
in Technique[技术] by (71.8m points)

docker-compose 如何将对多个 Vue 项目执行构建,并将构建后的内容放到 nginx 下?

对于单独一个 Vue 项目,一个 Dockerfile 文件搞掂,内容如下:

# build stage
FROM node:14.15.3-slim as build-stage
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm ci --production --registry=https://registry.npm.taobao.org
COPY . .
RUN npm run build

# production stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /usr/src/app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

现在,我想利用 docker-compose 将多个 Vue 项目进行构建,并将构建后的项目文件,放到一个 nginx 服务下。

文件结构:

docker-compose.yml
html/
    client/ # 空目录
    admin/ # 空目录
nginx/
    logs/
    conf.d/
    nginx.conf
    Dockerfile
client/
    Dockerfile-for-compose
admin/
    Dockerfile-for-compose

具体的实现思路是:多个 Vue 项目,通过自身的 Dockerfile 文件仅进行构建。然后在 docker-compose.yml 文件通过 volumes 将构建后的 Vue 项目同步到 nginx 下。docker-compose.yml 内容如下:

version: "3"

services:
    client_frontend:
        build:
            context: ./client
            dockerfile: Dockerfile-for-compose
        volumes: 
            - ./html/client:/usr/src/app/dist

    admin_frontend:
        build:
            context: ./admin
            dockerfile: Dockerfile-for-compose
        volumes:
            - ./html/admin:/usr/src/app/dist

    nginx:
        build: ./nginx
        restart: always
        volumes:
            - ./nginx/nginx.conf:/etc/nginx/nginx.conf
            - ./nginx/conf.d:/etc/nginx/conf.d
            - ./nginx/logs:/var/log/nginx
            - ./html/client:/usr/share/nginx/html/client
            - ./html/admin:/usr/share/nginx/html/admin

其中,上述两个 Vue 项目中的 Dockerfile-for-compose 内容如下:

# build stage
FROM node:14.15.3-slim as build-stage
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm ci --production --registry=https://registry.npm.taobao.org
COPY . .
RUN npm run build

现在遇到的问题是:执行 docker-compose up --build 后,./html/client./html/admin 均为空目录,即它们没拿到 Vue 项目构建后的内容。

另外,你们还有其他方式实现这个需求吗?

补充 Nginx 的配置文件:

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;
    
    server {
        listen 8001;
        location / {
            root /usr/share/nginx/html/admin;
            index index.html;
            try_files $uri $uri/ /index.html;
        } 
    }

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;
        
        # S client
        location / {
            root /usr/share/nginx/html/client;
            index index.html;
            try_files $uri $uri/ /index.html;
        }
    
        location /api/ {
            proxy_pass $scheme://$host:7001;
        }
        # E client
        
        # S admin
        location /admin/ {
            proxy_redirect off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:8001/;
        }

        location /admin/api/ {
            proxy_pass $scheme://$host:7002;
        }
        # E admin

        location ~* .(eot|otf|ttf|woff|woff2|svg)$ {
            add_header Access-Control-Allow-Origin *;
        }     

        error_page 404 /404.html;
            location = /40x.html {
        }

        # error_page 500 502 503 504 /50x.html;
        #    location = /50x.html {
        # }

        error_page 500 502 503 504 = @50x;
        location @50x {
            default_type application/json;
            return 500 '{"code": 500, "msg": "服务器有问题,请稍后再试哦~"}';
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

正常不应该是每个 vue的项目单独打包镜像时,里面就应该包含一个 nginx么.镜像启动之后镜像內的 nginx 作为 web 服务器对外提供静态文件服务. 前端还有一个 nginx 的反向代理或者 网关来向这些vue的镜像提供反向代理服务嘛..你打包成一个不对对外服务,也不对外调用的纯静态镜像,是想干啥啊.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...