実行環境
- Amazon Linux2(シンガポールリージョンのEC2上で動作)
- Cloud9
- zsh
やりたいこと
Cloud9上で
- Vue.jsをビルドできるコンテナを作成する
- Firebaseにデプロイできるコンテナを作成する
目標のディレクトリ構成
以下のようなディレクトリ構成になるように設定していく
.
├── docker-compose.yml
├── firebase.dockerfile
├── LICENSE
├── markdown
│ ├── babel.config.js
│ ├── dist
│ │ ├── css
│ │ │ └── app.a2762106.css
│ │ ├── favicon.ico
│ │ ├── img
│ │ │ └── logo.82b9c7a5.png
│ │ ├── index.html
│ │ └── js
│ │ ├── app.485b9e24.js
│ │ ├── app.485b9e24.js.map
│ │ ├── chunk-vendors.f3d3e1a9.js
│ │ └── chunk-vendors.f3d3e1a9.js.map
│ ├── firebase.json
│ ├── node_modules
│ │ └── ...
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ └── index.html
│ ├── README.md
│ ├── src
│ │ ├── App.vue
│ │ ├── assets
│ │ │ └── logo.png
│ │ ├── components
│ │ │ └── HelloWorld.vue
│ │ └── main.js
│ ├── vue.config.js
│ └── yarn.lock
├── README.md
└── vue.dockerfile
方法
- Dockerfileは作成するコンテナ毎に分ける
- docker-composeでコンテナを管理
vue-cli3をインストールするコンテナの作成
vue.dockerfile
まずはVue.js用のdockerfileを作成する
# 最初のvue.dockerfile
FROM node:8.11.3-alpine
WORKDIR /markdown
RUN apk update && \
npm install -g @vue/cli && \ #vue-cli3をインストール
Firebaseのcliツールをインストールするコンテナの作成
firebase.dockerfile
Firebaseのcliツールをインストールし、コードをデプロイするためのコンテナを作成する
# firebase.dockerfile
FROM node:8.11.3-alpine
WORKDIR /markdown
RUN apk update && \
npm install -g firebase-tools
コンテナを管理するdocker-compose.yml
version: '3'
services:
vue:
build:
context: ./
dockerfile: vue.dockerfile
volumes:
- ./markdown:/markdown
ports:
- '8080:8080'
tty: true
firebase:
build:
context: ./
dockerfile: firebase.dockerfile
volumes:
- ./markdown:/markdown
ports:
- '9005:8081'
tty: true
コンテナを立ち上げて、vue-cli3でプロジェクトを作成する
# tty: trueでコンテナをupしたままにする
% docker-compose up &
# vue(コンテナ名)のコンテナ内に入る
% docker-compose exec vue sh
#vue create コマンドで新しいVue.jsのプロジェクトを作成する
root# vue create
#実行後に色々な質問に答えていく
#プロジェクト名はmarkdown
#パッケージ管理は今回はyarnを選択
#全て終わると、markdownという名前のディレクトリが作成される
vue.dockerfileとdocker-compose.ymlを修正
yarn
markdown以下でyarnが使えるようになっているので、vue.dockerfileとdocker-compose.ymlでコンテナを立ち上げたときに、yarn installとyarn run serveで開発ビルドと開発サーバが立ち上がるように変更を加える
FROM node:8.11.3-alpine
WORKDIR /markdown
RUN apk update && \
npm install -g @vue/cli && \
+ yarn install
version: '3'
services:
vue:
build:
context: ./
dockerfile: vue.dockerfile
user: "${CURRENT_UID}"
volumes:
- ./markdown:/markdown
ports:
- '8080:8080'
+ command: 'yarn run serve'
- tty: true
省略
これで、docker-compose up
した時に開発ビルドと開発サーバが立ち上がるようになる
コンテナを立ち上げてFirebaseにログインをする
続いて、Firebaseにログインをする
コンテナ内でfirebase login叩いた後に出るURLに飛んでgoogleアカウントの認証をするが、その後飛ばされるlocalhost:9005はCloud9からアクセスできない
なので、--no-localhost
オプションをつけると、URLが表示され、その遷移先で表示されるトークンを入力することでログインができる
firebaseコンテナに入る
% docker-compose exec firebase sh
root# firebase login --no-localhost
#login後にfirebaseのprojectの作成
root# firebase init
#色々な質問に答える
#deployするディレクトリはmarkdown/dist以下に設定する
Vue.js本番ビルドをmarkdown/dist以下からdeploy
vue.config.jsでビルドファイルの出力先をmarkdown/dist以下にする
module.exports = {
devServer: {
contentBase: 'dist',
},
}
その後、vueコンテナに入るビルドコマンドを叩くと、markdown/dist以下にビルドファイルが出力される
% docker-compose up &
% docker-compose exec vue sh
root# yarn run build
ビルド後に
% docker-compose exec firebase sh
root# firebase deploy
を実行するとfirebaseにdeployされる
これで、Dockerを使った、Vue.jsとFirebaseの開発環境設定ができた
ハマったポイント
Invalid Host header
vueコンテナ内でビルドしたVue.jsの開発ビルドをプレビューしようと、Cloud9の'Previewタブ' -> 'Running Preview Application'クリックするとInvalid Host header
というエラーメッセージが出てしまう
最初はコンテナのPortの設定がうまくいっていないのかと、いろいろ検索したが、最終的にWebpackの設定の問題ということがわかった
Webpackの何が問題なのか、またなぜこのように設定を書くと接続できるようになるかはわかっていないがvue.config.js
に以下のように設定すると
module.exports = {
devServer: {
disableHostCheck: true,
contentBase: 'dist',
},
}
Vue.jsの最初の画面がCloud9上のプレビューに表示される
Webpackの設定に関してはまだまだわかっていないことが多いので、実践して知識とノウハウをつけていきたい
コンテナ内でのrootユーザでのコマンド実行
コンテナ内に入ってシェルを立ち上げると、何も設定しなければrootユーザで立ち上がると思います
そのまま、rootユーザでVue.jsやFirebaseの新規プロジェクトを作成すると、ファイルの所有者がrootユーザになってしまい
ボリューム(ディレクトリ)を共有しているコンテナのホスト側からファイルを編集、削除などできなくなってしまいます
また、プロジェクトを作成した後も、Vue.jsの本番ビルドもコンテナから行うので、出力ファイルの所有者もrootになってしまいます
そのつど、chown -R ec2-user markdown/
などすれば問題ないといえばないのですが、なんか気持ち悪い...
なので、以下のようにdocker-compose.yml
を変更しました
version: '3'
services:
vue:
build:
context: ./
dockerfile: vue.dockerfile
+ user: "${CURRENT_UID}"
volumes:
- ./markdown:/markdown
ports:
- '8080:8080'
command: 'yarn run serve'
tty: true
firebase:
build:
context: ./
dockerfile: firebase.dockerfile
volumes:
- ./markdown:/markdown
ports:
- '9005:8081'
tty: true
そして、
% CURRENT_UID=$(id -u):$(id -g) docker-compose up
こうすることで、コンテナ内でシェルを実行したさいのUIDとGIDが、ホストのUIDとGIDと同じになります
この状態でコンテナからファイルを作成しても、ホストからそのファイルを見たときの所有者が、ホストのユーザになるので便利です
ただ、firebaseやvueコマンドの実行権限がないので、新たにプロジェクトなどは作成できませんが...
が、これがベストプラクティスかというと、かなり怪しいですが
もっと良い方法があれば、知りたいです