#はじめに
あるプロジェクトで、フロントではAngularを使用していたけど、
ローカルに直にWebサーバーを立ち上げる感じだったので、
Dockerコンテナ上にAngularを入れて、Webサーバー起動できないかなと思い、
挑戦してみました!
#TL;DR
- 構成の説明
- Angularのローカル上のセットアップ
- Dockerfile解説
- docker-compose.yml解説
- nginx.conf紹介
- 実践とキャプチャ
#構成
とりあえず自分は以下のようなディレクトリ構成で進めました。
docker-local
├── .env
├── docker-compose.yml
├── docker
│ └── nginx
│ ├── Dockerfile
│ └── nginx.conf
└── web
├── app ── (Angular一式)
└── env
└── nginx ── site.conf
#Angularのローカル上のセットアップ
Angularに関連するファイル等をDockerコンテナ側にマウントするために、
一旦ローカルで、Angularのセットアップをします。
###1.Node.js
のインストール
nodejs.orgに行って、
2021/03時点で、LTS(長期サポート)の推奨版14.16.0 LTS
をダウンロード。
###2.npmの関連ディレクトリのオーナーを自分のアカウントに権限変更
$ npm config get prefix
/usr/local
$ sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
自分の環境では、アクセス権限エラーが出たので、
/usr/local/bin, /usr/local/share, /usr/local/lib/node_modules
に対してオーナー権限を自分に与えた。
###3.angular/cli
のインストール
npm install -g @angular/cli
-
-g, --global
:グローバルインストール- npmのインストール場所にパッケージインストール
- つけない場合は、カレントディレクトリのnode_modules内にインストール
###4.Angularアプリの作成
$ cd ./web
$ ng new app
? Do you want to enforce stricter type checking and stricter bundle budgets in t
he workspace?
This setting helps improve maintainability and catch bugs ahead of time.
For more information, see https://angular.io/strict Yes
? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? Less [ http://lesscss.org
web
のディレクトリに移動してから、angular
アプリをapp
と言う名前で作成。
3つほど、質問されるので、適宜選択。
-
strict mode
でインストールするか -
routing
を追加するか -
stylesheet
のフォーマットはどうするか
###5.一応、立ち上げ確認
localhost:4200
上に立ち上がりました!
これで、マウント用のフォルダはOK。
#Dockerfile
FROM node:14.16.0-alpine3.12 as build-stage
WORKDIR /app
COPY ./web/app/package*.json /app/
RUN npm install
COPY ./web/app/ /app/
ARG configuration=production
RUN npm run build -- --output-path=./dist/out --configuration $configuration
FROM nginx:1.17.3-alpine
COPY --from=build-stage /app/dist/out/ /var/www/html
COPY ./docker/nginx/nginx.conf /etc/nginx/
###解説
ローカル上でやった手順をDockerfile
上に書いてあげるイメージです。
linux
はdocker
コンテナに向いている超軽量のalpine
を使用。
今回は、マルチステージビルドを利用してます。Dockerfileに複数のFROM
命令を記述し、異なるベースイメージ使って、それぞれで新しいビルドステージを開始する感じです。
-
Angualr
のビルド環境としてnode:14.16.0-alpine3.12
をインストール。(build-stage
と名付け) - Angularのビルド生成物を、Nginxのステージでコピーして使ってます。
- docker側のワーキングディレクトリを
/app
に指定 - ローカルの
package.json
を/app/
配下にコピー - その
package.json
を使って、npm install
- ローカルのAngularのソースをコピー
- ビルドを走らせて、生成物は
./dist/out
に出力-
configuration
はオプションだと思う。
-
-
nginx
のイメージをインストール - 先述の
Angular
のビルド生成物をDocker
上のNginx
のドキュメントとして扱うため、nginx
のルートディレクトリ/var/www/html
にコピー - Nginx の設定ファイル
nginx.conf
もコピー
###※ビルドのポイント
docker-compose up
をする前に、docker-compose.yml
がある場所をカレントディレクトリとして、事前にdockerイメージのビルドをしておきます。
理由として、
./web/app/
のファイル等をコピーしたいが、
Dockerfile
は親のディレクトリを参照することができないので、
今回のフォルダ構成的に、コピーすることができず、こういったやり方にしてます。(他にももっと良いやり方あるかも。)
# buildコマンド実行場所を docker build のカレントディレクトリにできる
$ docker build -f ./docker/nginx/Dockerfile -t image-name:nginx-1.17.3-alpine .
※最後のドット . が大事
※buildにcache
使いたくない場合は、--no-cache
つける。
※docker-compose up --build
とかでも良いかもしれないが、自分はまだ試していない、
#docker-compose
version: "3.8"
services:
nginx:
image: image-name:nginx-1.17.3-alpine
build:
context: ./docker/nginx
dockerfile: Dockerfile
container_name: nginx
ports:
- 80:80
volumes:
- ./web/env/nginx:/etc/nginx/conf.d
logging:
driver: "none"
restart: always
※site.conf
は、docker-compose側でマウントしちゃう感じ。(実際Dockerfile内でもかけるかも)
※image
の設定を、build
した時のイメージ名にすることが大切
#nginx.conf
※nginxについて内容の精査がまだできていないので、一旦自分のローカルで動いたものの貼り付け。
nginx.conf
内でsite.conf
をincludeする感じ。
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
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;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}
server {
listen 80;
listen 8080;
server_name localhost;
root /var/www/html;
location / {
index index.html index.htm;
root /var/www/html;
try_files $uri $uri/ /index.html =404;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/html/error;
}
}
#実際に立ち上がるか確認
###コマンドを打ってコンテナ起動・・・
$ cd docker-local
$ docker-compose up -d --remove-orphans
Creating nginx ... done
###おお、ちゃんと表示された。
localhost:80
で起動してるので、URLをみると:80
が省略されて、
ちゃんとlocalhost
で立ち上がった。
デフォルトのままなので、これから何かしらのアプリでも作ってみたいと思いまする。
#まとめ
今回の学びは、
マルチステージビルドと
Dockerfileが参照できる範囲
等でした。
やっぱりまだまだ、相対パスだったり、マウントの仕方だったりが、なかなか難しいので、
その感覚をもっと養っていけたらと思いました。
あとは、nginx
のconfiguration周りがトーシロ(素人)レベルで全くわかっていないので、
そこら辺を次は追求していきたいなと思ったりしてます。
以上、ありがとうございました。