この記事のアピールポイント
- 初心者に最適
- フロントエンド開発者に最適
0.事前準備
インストール
以下のソフトウェアと環境のインストールが必要です。
- Docker以及docker-compose(必須)
- Docker图形化界面(なくてもよい)
- Node.js(必須)
- MongoDB图形化界面(なくてもよい)
- yarn (なくてもよい,npm,pnpmを使っても構いません)
知識
Dockerコンテンツの説明と構築がメインとなりますので、
フロントエンドとバックエンド開発の説明は特にしません。
なので、以下の知識はあった方がいいです
- Dockerの基礎知識
- Mongodbの基礎知識
- Nginxの基礎知識
- フロントエンド(vue,react..),バックエンド(node,koa..)の基礎知識
環境
- OS:Windows 10
- エディター:VS Code
- Node.js:v16.3.0
- Docker:v20.10.13
demo
文章で作成したdemoはGitHubにアップロードしましたので、ご参照ください
1.フロントエンドの準備
ここはviteでvue3を作りますが、好きなJSフレームワークを使ってください
フロントエンドフォルダ参照
rootフォルダでfrontendフォルダを新規作成、viteを初期化
yarn create vite
好きなJSフレームワークを選択して、インストールしてください
いらないコンポーネントを削除して、Axiosをインストール
yarn add -D axios
App.vue
で以下のコードを使ってください(ここでTSをつかいましたが、JSでも構いません)
フロントエンドを起動すると、Axiosを使うメソッドapi()
はAPIをリクエストして、レスを画面にプリントします
/test
はバックエンドが提供しているAPIアドレス(後で説明)
<template>
<main>
<div><strong>データ:</strong></div>
<br />
<div>{{ data }}</div>
</main>
</template>
<script setup lang="ts">
import { ref } from "vue";
import axios from "axios";
const host: number = 7021;
interface IDocker {
id: number;
}
// リクエスト
const data = ref<IDocker[]>();
const api = async (): Promise<void> => {
await axios.get<IDocker[]>("/test").then((res): void => {
console.log(res.data);
data.value = res.data;
});
};
api();
</script>
package.json
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview"
},
フロントエンドの準備は完了
2.バックエンドの準備
ここでNode.jsのフレームワークKoa.jsとTSで構築しますが、好きなNode.jsフレームワークを使ってください
バックエンドフォルダ参照
rootフォルダでbackendフォルダを新規作成
Koa.js + TSの構築方法はこの記事に参照して作成しました
koaルートをインストール
yarn add koa-router
index.ts
で以下のコードを使ってください
バックエンドを起動すると,testというAPIのルートを作成します
testがリクエストされたら,データベースからデータを取得して、レスとして返します
import Koa from "koa";
import Router from "koa-router";
import { connect, Schema, model } from "mongoose";
const app = new Koa();
const router = new Router();
const host: number = 7022;
const url: string = "mongodb://foo:foo@database:27017/docker";
// #################### データベース関連 ####################
const connectMongoDB = async (): Promise<void> => {
await connect(url)
.then((): void => {
console.log("mongodb connect success");
})
.catch((): void => {
console.log("mongodb connect failed");
});
};
interface IDocker {
id: number;
}
const schema = new Schema<IDocker>(
{ id: { type: Number, required: true } },
{ versionKey: false }
);
const dockerModel = model<IDocker>("tests", schema);
// #################### ルート関連 ####################
router.get("/test", async (ctx: Koa.Context): Promise<void> => {
console.log("requested");
await dockerModel.find({}, { _id: 0 }).then((res: IDocker[]): void => {
console.log(res);
ctx.body = {
message: "取得成功",
result: res,
};
});
});
// サーバー起動
connectMongoDB();
app.use(router.routes()).use(router.allowedMethods());
app.listen(host, async (): Promise<void> => {
console.log(`backend on port ${host} 🚀`);
});
ご注意
定数url
のはデータベースのdockeコンテンツ内アドレスです(後で説明)
バックエンドの準備は完了
3.データの準備
ここでMongodbとそのGUIのMongoDBCompassを使います
データフォルダを参照
rootフォルダでdatabaseフォルダを新規作成して、databaseフォルダでjsファイルmongo-init.jsを新規作成\
mongo-init.jsとは
データベースへのアクセスは管理者IDとパスワードが必要です
本来はターミナルでコマンドでデータをinsertして、管理者IDとパスワードを追加しますが
このmongo-init.jsは、dockerコンテンツ起動の時に自動で必要なデータをinsert、管理員を追加する便利なスクリプトです
rootの管理員はDockerfile指定されましたので、ここで作ったのはCRUD管理員です\
以下のコードを使ってください、dockerコレクションのtestsテーブルに[{ id: 1 }, { id: 2 }]
をinsertします。
// テーブル管理者とコレクションの作成
db.createUser({
user: "foo",
pwd: "foo",
roles: [
{
role: "readWrite",
db: "docker",
},
],
});
// 先作ったdocker dbに切り替え
db = db.getSiblingDB("docker");
// コレクションを自動作成、データinsert
db.createCollection("tests");
db.tests.insertMany([{ id: 1 }, { id: 2 }]);
データの準備は完了
まとめ
ここまでのフォルダ構造
これからは以下のフォルダをコンテンツ化します
backend
├──node_modules
├── index.ts
├── tsconfig.json
├── yarn.lock
└── package.json
frontend
├── node_modules
├── public
├── src
├── vite.config.ts
├── tsconfig.json
├── yarn.lock
└── package.json
// 一部省略
database
└── mongo-init.js
4.フロントエンドのDockerfile
考え方
必要なフロントエンドファイルをコンテンツにコピー,コンテンツで必要な環境を用意,コピーした後でファイルをビルド、Nginxでビルドしたファイルをデプロイ
Step1 imageインストール
nodeとnginxのdocker imageをpull
pcで既にnodeとnginxのdocker imageがインストールされたらこのStepを無視
docker pull node
docker pull nginx
Step2 Nginx設定
frontendフォルダでnginxの設定ファイルdefault.confを新規作成
フロントエンドはport7021
を使います\
server {
listen 7021;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /test {
proxy_pass http://backend:7022;
}
}
ご注意
proxy_pass
のはバックエンドのdockeコンテンツ内アドレスです(後で説明)\
Step3 Dockerfile作成
frontendフォルダでDockerfileを新規作成、以下のコードを使ってください\
# イメージ指定
FROM node:16.3.0
# 作者指定
LABEL maintainer="kensoz"
# ワークスペース指定
WORKDIR /usr/src/frontend
# package.jsonとyarn.lockコピー
COPY ["package.json", "yarn.lock", "./"]
# インストール
RUN yarn
# ファイルコピー
COPY . .
# ビルド
RUN yarn build
# イメージ指定
FROM nginx:latest
# コンテナ内のビルドしたdistフォルダをnginxへコピー
COPY --from=0 /usr/src/frontend/dist/ /usr/share/nginx/html/
# nginxコンフィグファイルコピー
COPY default.conf /etc/nginx/conf.d/default.conf
簡単に説明:
FROM node:16.3.0
コンテンツで使うnode環境とそのバージョン指定
WORKDIR /usr/src/frontend
コンテンツ内のフロントエンドのフォルダ(ワークスペース)
COPY ["package.json", "yarn.lock", "./"]
ローカルのpackage.jsonやソースコードをコンテンツ内にコピー
RUN yarn
コンテンツ内でフロントエンドをインストール
COPY . .
インストールしたものを全部コンテンツ内にコピー
RUN yarn build
コンテンツ内でビルド
FROM nginx:latest
コンテンツで使うnginx環境とそのバージョン指定
COPY --from=0 /usr/src/frontend/dist/ /usr/share/nginx/html/
コンテンツ内で先ビルドしたdistファイルをコンテンツ内のnginxフォルダの中のhtmlフォルダにコピー(nginxの使い方はローカルと同じ)
COPY default.conf /etc/nginx/conf.d/default.conf
ローカルのnginx設定ファイルをコンテンツ内にコピー\
フロントエンドDockerfile設定完了
5.バックエンドのDockerfile
考え方
必要なフロントエンドファイルをコンテンツにコピー,コンテンツで必要な環境を用意,コピーした後でファイルをビルド、その後サーバーを起動
Step1 Dockerfile
バックエンドはport7022
を使います
すでにnodeのimageをインストールしましたので、imageのpullはいらないです
backendフォルダでDockerfileを新規作成、以下のコードを使ってください\
# イメージ指定
FROM node:16.3.0
# 作者指定
LABEL maintainer="kensoz"
# ワークスペース指定
WORKDIR /usr/src/backend
# package.jsonとyarn.lockコピー
COPY ["package.json", "yarn.lock", "./"]
# インストール
RUN yarn
# ファイルコピー
COPY . .
# ビルド
RUN yarn build
# ポートの解放
EXPOSE 7022
# コンテナ実行
ENTRYPOINT [ "yarn", "start" ]
簡単に説明:
FROM node:16.3.0
コンテンツで使うnode環境とそのバージョン指定
WORKDIR /usr/src/backend
コンテンツ内のバックエンドのフォルダ(ワークスペース)
COPY ["package.json", "yarn.lock", "./"]
ローカルのpackage.jsonやソースコードをコンテンツ内にコピー
RUN yarn
コンテンツ内でフロントエンドをインストール
COPY . .
インストールしたものを全部コンテンツ内にコピー
RUN yarn build
コンテンツ内でビルド
EXPOSE 7022
port7022を公開
ENTRYPOINT [ "yarn", "start" ]
サーバーを起動
バックエンドDockerfile設定完了
6.データのDockerfile
Step1 imageインストール
データはport27017
を使います
MongoDBのdocker imageをpull
pcで既にMongoDBのdocker imageがインストールされたらこのStepを無視
docker pull mongo
Step2 Dockerfile
databaseフォルダでDockerfileを新規作成、以下のコードを使ってください
# イメージ指定
FROM mongo:latest
# 作者指定
LABEL maintainer="kensoz"
# 管理者アカウント作成
ENV MONGO_INITDB_ROOT_USERNAME root
# 管理者パスワード作成
ENV MONGO_INITDB_ROOT_PASSWORD root
# 使う予定のデータベース名称
ENV MONGO_INITDB_DATABASE docker
# コンテナ起動の時、データベース管理者スクリプト実行
ADD mongo-init.js /docker-entrypoint-initdb.d/
簡単に説明:
FROM mongo:latest
コンテンツで使うMongoDB環境とそのバージョン指定
ENV MONGO_INITDB_ROOT_USERNAM
和ENV MONGO_INITDB_ROOT_PASSWORD
コンテンツを起動すると、root管理員のIDとパスワードを指定
ADD mongo-init.js /docker-entrypoint-initdb.d/
コンテンツを起動すると、先作ったスクリプトを自動で実行
データDockerfile設定完了
Tip
それぞれのフォルダで.dockerignore
ファイルを作成して、不要なファイルとフォルダを無視にしましょう
node_modules;
dist.vscode;
logs;
coverage;
npm - debug.log;
yarn - debug.log;
7.docker-compose.yml
Step1 rootフォルダでdocker-compose.ymlを新規作成
version: "3.8"
# network
# コンテンツ内ネットワーク名称
networks:
dockertest-network:
driver: bridge
services:
### frontend #################
# フロントエンド,ここの名称 frontend はコンテンツ内ネットワークでportとして使う
frontend:
container_name: depoly-frontend
build:
context: ./frontend
ports:
- 127.0.0.1:7021:7021
restart: always
depends_on:
- backend
networks:
- dockertest-network
### backend #################
# バックエンド,ここの名称 backend はコンテンツ内ネットワークでportとして使う
backend:
container_name: depoly-backend
build:
context: ./backend
ports:
- 127.0.0.1:7022:7022
restart: always
depends_on:
- database
networks:
- dockertest-network
### database #################
# データベース,ここの名称 database はコンテンツ内ネットワークでportとして使う
database:
container_name: depoly-database
build:
context: ./database
ports:
- "127.0.0.1:27017:27017"
restart: always
networks:
- dockertest-network
簡単に説明:\
docker-compose.yml
を使うと、各プロジェクト(フロントエンド、バックエンド、データ)を連携して、コンテンツ内ネットワークを構築、このネットワークによってコンテンツ同士がアクセスできます。
本来データベースにアクセスする時、localhost:27017/
みたいなurlを使いますが、コンテンツ内ではlocalhost
がなくて、動的なportとなります。コンテンツ内の場合はdocker-compose.yml
で定義したコンテン名称をportとして使います。本記事はdatabaseを定義して、database:27017
をデータベースのport urlとして使っています。
docker-compose.yml設定完了
8.dockerコンテンツ実行
rootフォルダで実行
docker-compose up -d
問題がなければ、dockerのGUIで以下のものが確認できます
9.検証
フロントエンド検証
http://localhost:7021/
を起動すると、データが確認できます
バックエンド検証
データ検証
MongoDBのGUIで,dockerデータベースなどが確認できます
10.最後
-
volumes
は使っていないので、好きに追加してください -
CD/CI
は使っていないので、好きに追加してください.docker-compose up -d
を実行すれば自動でデプロイできると思います。