Angular的Dockerfile编写方式

大家好,有人在使用Angular吗?

我在工作和兴趣方面都喜欢使用Angular,但是在共同开发中,当要求其他人进行功能验证时,往往需要安装node,然后安装@angular/cli并运行ng serve… 这样环境会变得很杂乱,这是一个问题我一直在思考的。

另外,我也想找个方法在正式环境时能使用 WinSCP 直接上传通过 ng build –prod 命令生成的构建文件。每次都要打开命令行并启动 WinSCP 真是太麻烦了…

但是@angular/cli的便利之处很难放弃…尤其是自动重新加载功能…

所以,我尝试在Docker上运行Angular应用,并记录下我的经验。

规格

    • 本番環境としても開発環境としても使えること

 

    • 本番環境ではnginxを用いること

 

    • 開発環境ではオートリロードしたい

 

    一つのDockerfileにまとめる

途径

使用Docker的多阶段构建。

### ベースステージ ###
FROM node:lts-alpine as base

# @angular/cliをグローバルインストール
RUN npm install -g @angular/cli

# ワーキングディレクトリの設定
WORKDIR /some-angular-app

# package.jsonをコピー
COPY ./package*.json /some-angular-app/

# 一度node_modulesを削除してからnpm install
RUN rm -rf node_modules && npm install


### ビルドステージ ###
FROM base as build

# 全てのソースファイルをコピー
COPY ./ /some-angular-app/

# 本番用ビルド
RUN ng build --prod --output-path=./dist/build-by-docker


### プロダクションステージ ###
FROM nginx:alpine as prod

# ビルドステージで生成されたファイルをnginxの公開用ディレクトリにコピー
COPY --from=build /some-angular-app/dist/build-by-docker /usr/share/nginx/html

# nginx.confをコピー
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf

在Dockerfile中,只需进行源代码的复制、构建过程和构建结果的复制操作,主要命令将写在docker-compose.yml中。

version: "3.4"

services:
    node:
        build:
            context: ./
            dockerfile: "Dockerfile"
            target: base
        ports:
            - "4200:4200"
        command: sh -c "ng serve --host 0.0.0.0 --poll=1000"
        volumes:
            - .:/some-angular-app
            - node_modules:/some-angular-app/node_modules
        tty: true
volumes:
    node_modules:
        driver: "local"

这是用于开发环境的docker-compose.yml文件。它继承了Dockerfile中的base阶段并运行。

请确保在Dockerfile内不需要特别进行COPY操作,因为已经在volumes中挂载了源代码。
请记得将node_modules排除在挂载目标之外。

指令如下:ng serve –host 0.0.0.0 –poll=1000 是关键所在。

Docker容器与主机PC共享localhost,但在Docker容器中运行的@angular/cli并不知道这一点,所以@angular/cli所谓的”localhost”只是Docker容器的”localhost”。
注意:使用谷歌翻译,结果可能不准确。

换句话说,你需要在–host选项中允许”与你同处于同一网络的所有IP地址”访问。

此外,我們使用”–poll”選項來設定以毫秒為單位的輪詢文件變更情況,以便正確啟用自動重新載入。

version: "3.4"

services:
    node:
        build:
            context: ./
            dockerfile: "Dockerfile"
            target: prod
        ports:
            - "8080:80"
        tty: true

这是用于生产环境的docker-compose.prod.yml文件。它继承了prod阶段并运行,但并没有特别地执行任何操作。

.dockerignore
.git
dist
*Dockerfile*
*docker-compose*
node_modules

为了防止node_modules被复制,我们将其列入.dockerignore文件。

server {
    listen 80;
    server_name  localhost;

    root   /usr/share/nginx/html;
    index  index.html index.htm;
    include /etc/nginx/mime.types;

    gzip on;
    gzip_min_length 1000;
    gzip_proxied expired no-cache no-store private auth;
    gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

最后,这是将default.conf复制到nginx的conf文件夹中。
它只是进行了必要的处理,以便在nginx上运行Angular并将“所有URI的访问流向index.html”。请根据需要进行适当修改。

启动方式

# 開発
$ docker-compose up --build

# 本番
$ docker-compose -f docker-compose.prod.yml up --build 

总结

使用多阶段构建,可以通过docker-compose命令一键启动Angular应用的环境,但与在主机PC上直接使用ng serve相比,构建的速度要慢得多,这一点出乎意料。

如果只是为了不破坏别人的环境,那么也有相当多的好处。但是,如果我是一个积极开发的人,我会坦率地认为最好是在自己的主机上安装@angular/cli。

广告
将在 10 秒后关闭
bannerAds