LoginSignup
1
2

More than 3 years have passed since last update.

【Docker+Nginx+Angular】Dockerfileでイメージ作ってMacでアプリ立ち上げてみた

Last updated at Posted at 2021-03-29

はじめに

あるプロジェクトで、フロントでは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。
スクリーンショット 2021-03-29 10.55.06.png

Dockerfile

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上に書いてあげるイメージです。

linuxdockerコンテナに向いている超軽量の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

docker-compose.yml
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する感じ。

nginx.conf
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;
}
site.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

作成されたのでアクセス!!!

スクリーンショット 2021-03-29 10.55.06 2.png

おお、ちゃんと表示された。

localhost:80で起動してるので、URLをみると:80が省略されて、
ちゃんとlocalhostで立ち上がった。

デフォルトのままなので、これから何かしらのアプリでも作ってみたいと思いまする。

まとめ

今回の学びは、
マルチステージビルド
Dockerfileが参照できる範囲
等でした。

やっぱりまだまだ、相対パスだったり、マウントの仕方だったりが、なかなか難しいので、
その感覚をもっと養っていけたらと思いました。

あとは、nginxのconfiguration周りがトーシロ(素人)レベルで全くわかっていないので、
そこら辺を次は追求していきたいなと思ったりしてます。

以上、ありがとうございました。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2