エンジニア

docker-composeで「Go+Node+MySQL」のWEBサービス開発環境構築!

2022年9月20日

docker-composeで「Go+Node+MySQL」のWEBサービス開発環境構築!

WEBサービスの開発では、バックエンドの1つの言語だけでなくて、データベースやフロントのビルド環境も必要だと思うんだけど、dockerで全部環境構築できるのかな?

 

こんにちは、古賀です!

 

本記事では、docker-composeを使用して、

はてな

バックエンド:「Go言語」

フロントエンド:「Node」

データベース:「MySQL」

の開発環境の構築について、お話します。

 

以前の記事では、dockerの概要やPython実行環境の構築についてお話しました。

dockerをインストールしていることを前提でお話していくので、

まだインストールしていない方はこちらをご確認ください。

docker簡単解説&インストール
dockerとは?dockerをわかりやすく簡単に説明&インストールする!

最近dockerってよく聞くけど、dockerって何をしてくれるものなんだろう? ネットで調べてみたけど、難しい用語ばっかで全然わからない。。   こんにちは、古賀です!   本記 ...

続きを見る

dockerでPython環境構築
dockerでPythonの環境構築をする!データ分析環境「Jupyter Lab」を起動するまで!

dockerでプログラミングの環境を作れることはわかったけど、どんな感じで作るんだろう? 実際に作る流れを見たいな。。   こんにちは、古賀です!   本記事では、 はてな 「do ...

続きを見る

dockerfileを使ってPython環境構築
dockerfileの基礎!dockerfileを使ってPython実行環境を構築!

dockerの環境構築はdockerfileを使わなくてもできるけど、 dockerfileを使って環境構築した方が良いんだよね? dockerfileを使った環境構築方法を知りたいな。。 &nbsp ...

続きを見る

 

今回は1つの言語の環境ではなく、

WEBサービス開発で使う3つの環境をdocker-composeを使用して作成します。

dockerを使用すると、自分のPCに直接色々とインストールせずに開発を行うことができます。

WEBサービス開発もdockerを利用して、環境構築できるようになりましょう!

 

1点注意ですが、プロジェクトによってはdockerコンテナをそのまま本番環境にデプロイする場合もあると思いますが、

今回はローカル開発環境の場合のみになります。

 

実際にわたしはこの構成で、WEBサービスを作成しました。

詳細はこちらです。気になる方はチェックしてみてください!

eSportsプラットフォームSPFans
個人開発WEBサービス!eSportsプラットフォーム「SPFans」をリリース!概要と使用技術はこちら!

  こんにちは、古賀です!   本記事では、わたしが個人開発したWEBサービス はてな eSportsプラットフォーム「SPFans」 の紹介をします。   以前に紹介し ...

続きを見る

 

簡単な自己紹介ですが、

わたしは上場IT企業に新卒入社し、プログラマー、システムエンジニアとして約10年間働いた後、

現在フリーランスとして活動しております。

プロフィールの詳細はこちらです。

野球
プロフィール

こんにちは、古賀正雄です。現在36歳です。 簡単ではありますが、こちらのページで自己紹介とこのブログについてお話します。 高校時代 学生時代は主に野球をしていました。 進学先の高校も野球で選びました。 ...

続きを見る

 

※YouTubeに同内容を公開しております。

docker-composeとは?

docker-compose

まず、今回使用するdocker-composeについてですが、docker-composeは、

複数のコンテナを扱う時に使用する

ものです。

 

前回のPython実行環境を構築した時は、1つのコンテナのみ作成したので特別必要なかったのですが、

今回のようにWEBサービスを開発する場合、

「バックエンド」、「フロントエンド」、「データベース」のコンテナがそれぞれ必要になります。

 

1つのコンテナに、この3つの役割をすべて詰め込むことも可能ではありますが、

それぞれのコンテナを作成するのが一般的です。

 

なので今回は、

  • バックエンドコンテナに「Go」
  • フロントエンドコンテナに「Node.js」
  • データベースコンテナに「MySQL」

をそれぞれ入れます。

docker-compose.ymlとdockerfileを作成する

docker-composeを使用して各コンテナを作成するためには、

  • docker-compose.yml
  • 各コンテナのdockerfile

が必要です。

 

docker-compose.ymlは各コンテナの取りまとめ役のようなものです。

各コンテナのdockerfileとそのまとめ役のファイルを用意することで、各コンテナを作成することができます。

フォルダ構成は好きなようにしても問題ありませんが、今回は以下のような構成にします。

docker-compose-folder1

 

docker-compose.ymlを一番上の階層に配置して、

各dockerfileは専用のフォルダを用意して、その中にdockerfileを配置します。

Goのdockerfileを作成

Golang

はじめにGoのdockerfileを作成します。

作りたい環境によってはもっと複雑になると思いますが、今回はシンプルに以下のようにしました。

FROM golang:1.16-alpine

RUN mkdir /work \
  && apk update

WORKDIR /work

# COPY go.mod go.sum ./
# RUN go mod download

 

dockerfileを作成する上で最初にやることは大元のdockerimageを選択することです。

Goに限ったことではありませんが、各言語には大体公式のdockerimageが用意されています。

Goの場合はこちらに用意されています。

 

言語のバージョンとOSをタグで選択することになるのですが、

言語のバージョンは本番にデプロイする環境と同じにしておきましょう。

なんでもかんでも最新にしてしまうと、いざデプロイする時に最新バージョンが対応されていない場合もあるので注意です。

OSはお好みで良いですが、今回は軽量なalpineを選択しています。

 

その後は「work」という名前で作業フォルダを作成しておきます。

後ほどローカルのファイルとこの作業フォルダをリンクさせます。

 

「apk update」はおまじないです。

ubuntuの「apt-get」と同じで、

「これからインストールするものを最新の場所から取ってくるようにします。」

という作業をします。

 

「WORKDIR /work」で作業フォルダに移動しています。

コンテナに入った時のデフォルトカレントディレクトリにもなります。

 

以下の2行をコメントにしていますが、実際にGoの開発を始めた後に書いておくと良いです。

# COPY go.mod go.sum ./
# RUN go mod download

go.modとgo.sumはGoのプログラムで使用するモジュールや依存関係を管理しているファイルです。

この2つのファイルがローカルのフォルダに既にある場合は、コンテナの中にファイルをコピーをして、

使用するモジュールをあらかじめダウンロードしておこうという処理がこの2行になります。

今はローカルにそんなファイルは存在しないので、コメントにしています。

 

dockerfileは最初に完成させるのではなく、開発しながらも少しずつ変わっていくものだと思います。

自分や後でメンバーが追加になっても開発しやすいように、適宜変更していきましょう。

Nodeのdockerfileを作成

Node

続いてNodeのdockerfileを作成します。

このNodeコンテナが必要な理由についてですが、生のJavaScriptやCssを書く人は特に必要ありませんが、

TypeScriptやTailwindCssを利用したりして、実行前にビルドが必要な人は必須になります。

※あまりわたしはフロント知識に強くないので、細かいことは墓穴を掘る前に割愛させてください!

 

作成するdockerfileは次のようにします。

FROM node:16.13.0-alpine3.14

RUN mkdir /work \
    mkdir /work/front \
  && apk update \
  && npm install -g npm

WORKDIR /work/front

# COPY ./front/package*.json ./
# RUN npm install

Nodeのdockerimageはこちらから選択できます。

 

Goと似たような感じです。

ちょっとだけ変えているのは、作業フォルダの下にfrontフォルダを作成していること(あとで理由はお話します)と、

あらかじめnpmをインストールしているところです。

 

最後のコメントにしている2行もGoと同じ理由です。

「package.json」には使用するパッケージ情報が記載されているので、

実際に開発を始めて「package.json」を作成したら、

dockerビルド時に開発で使用するパッケージを自動でインストールしてくれるように、

ローカルから「package.json」ファイルを渡して「npm install」を実行するようにしておきます。

MySQLのdockerfileを作成

MySQL

最後3つ目、MySQLのdockerfileです。

FROM mysql:8

とりあえずこれだけでOKです。

dockerimageはこちらから選択できます。

開発中MySQLのコンテナの中に入って、インストールしたりビルドしたりしないので、

作業フォルダを作ったりはしません。

 

必要な設定ファイルやデータの受け渡しは、

どちらに書いても良いと思いますが、この後に作成するdocker-compose.ymlファイルに記述したいと思います。

 

以上でdockerfile3つを作成が完了です!

docker-compose.ymlを作成

dockerfileを作成したら、とりまとめ役のdocker-compose.ymlを作成します。

その前にいくつかローカルの方にフォルダとファイルを追加します。

docker-compose-folder2

「db」フォルダを新しく追加して、その中にMySQL用のコンフィグファイル「my.cnf」を追加します。

ファイルの中身は必要に応じて変更して欲しいのですが、以下のようにしています。

[mysqld]
# character set / collation
character_set_server = utf8mb4
collation-server = utf8mb4_general_ci
default-authentication-plugin = mysql_native_password

# timezone
default-time-zone = SYSTEM
log_timestamps = SYSTEM

[mysql]
default-character-set = utf8mb4

[client]
default-character-set = utf8mb4

 

もう1つ「front」フォルダを追加しています。

このフォルダの中にフロント開発で作成するjsやCssのファイルを入れていきます。

フロントとバックエンドを完全に分ける場合は、それぞれ独立して並列にするかもしれませんが、

今回はフロントとバックを一緒にしたいので、バックエンドの中に一部フロントがあるフォルダ構成にします。

この「front」フォルダと、先程Nodeコンテナを作成した「front」フォルダをリンクさせるようにします。

 

 

それを踏まえてdocker-compose.ymlファイルを作成します。

今回は以下のようにします。

version: "3.8"
services:
  go:
    build:
      context: .
      dockerfile: ./docker/go/dockerfile
    stdin_open: true
    tty: true
    volumes:
      - .:/work
    ports:
      - 8080:8080
    depends_on:
      - "db"
  db:
    build:
      context: .
      dockerfile: ./docker/db/dockerfile
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: web_dev_database
      MYSQL_USER: web_dev_user
      MYSQL_PASSWORD: web_dev_password
      TZ: "Asia/Tokyo"
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
    volumes:
      - web-dev-data:/var/lib/mysql
      - ./db/my.cnf:/etc/mysql/conf.d/my.cnf
    ports:
      - 3306:3306
  node:
    build:
      context: .
      dockerfile: ./docker/node/dockerfile
    stdin_open: true
    tty: true
    volumes:
      - .:/work
volumes:
  web-dev-data:
    driver: local

内容が多いので、細かい内容は公式ドキュメントを確認してみてください。

今回はざっくり説明します。

 

バージョンを記載した後、「services」キーに対して各コンテナを記載して、

その中にコンテナに対する記述を追加していきます。

version: "3.8"
services:
  go:
    ※goコンテナに対する記述
  db:
    ※mysqlコンテナに対する記述
  node:
    ※nodeコンテナに対する記述

 

各コンテナの中にある記述をいくつか説明します。

「build」キーでは、紐づけるdockerfileを記載します。

build:
      context: .
      dockerfile: ./docker/go/dockerfile

 

「volumes」キーでは、ローカルとコンテナの中のフォルダを紐づけします。

volumes:
      - web-dev-data:/var/lib/mysql
      - ./db/my.cnf:/etc/mysql/conf.d/my.cnf

MySQLのデータを保持するためには、上記の記述に加えてdocker-compose.ymlの一番下にある「volumes」キーの記述が必要です。

これでローカルにデータを保持して、コンテナの中に送ることができます。

volumes:
  web-dev-data:
    driver: local

 

「ports」ではローカルとコンテナを繋ぐportを指定します。

Goで作成したWEBサービスをブラウザから接続したり、MySQLに接続したりする時に使用します。

ports: - 8080:8080

 

「environment」では環境変数を設定します。

environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: web_dev_database
      MYSQL_USER: web_dev_user
      MYSQL_PASSWORD: web_dev_password
      TZ: "Asia/Tokyo"

MySQLのコンテナでは、ユーザやパスワード情報を設定します。

 

その他は割愛します!

わたしもすべて把握しているわけではなく、作成した時はところどころ調べています。

都度確認して、理解を深めていきましょう!

docker-composeでコンテナを使用する

コード

これで必要なファイルが揃ったので、実際にコンテナを作成して起動してみましょう。

docker-compose buildでコンテナを作成

まずはbuildが必要です。

ターミナルやPowerShellでdocker-compose.ymlファイルがある階層に移動して、

docker-compose build

を実行しましょう。

dockerfileやdocker-compose.ymlのどこかに記述ミスがあると、エラーが発生してしまいます。

 

エラーが発生しなければ、これで各コンテナが作成されます。

docker-compose upでコンテナを起動する

ビルドが完了したら、

docker-compose up -d

で各コンテナを起動します。

「-d」は「このコマンド後も、コマンドを入力します」という意味のオプションです。

「-d」を使わずにコマンド入力すると意味が分かると思いますが、おまじないと思って頂いて大丈夫です。

 

これで各コンテナが利用可能になりました。

docker-compose execでコンテナへコマンド実行する

各コンテナが利用可能になったので、実際にGoのコンテナの中に入ってみましょう。

「docker-compose exec コンテナ名 ash」でコンテナの中に入れます。

「ash(アルムクィスト シェル)」は「bash」のようなもので、今回OSにalpineを利用しているので「ash」となります。

他のOSを利用している場合は、また別のものになるので注意です。

docker-compose exec go ash

 

これでコンテナの中に入り、開発に必要なものをインストールしたり、Goのプログラムを実行できるようになります。

試しに以下のようなmain.goファイルを用意して、実行してみます。

package main

import (
	"fmt"
)

func main() {
	fmt.Print("Golang from docker")
}

Goのプログラム実行は、main.goファイルがあるディレクトリで、

go run main.go

で実行できます。

これを実行すると、

Golang from docker

が表示されて、Goのプログラムの実行が確認できると思います。

 

同じようにしてNodeコンテナの中に入って、必要なパッケージをインストールしたり、

フロントで使用するjsやCssをビルドしたりすることができます。

 

MySQLコンテナへの接続はdocker-compose.ymlに記述した接続情報を使用して、接続が確認できます。

MySQLのGUIツールのWorkbenchで接続する場合は、指定したポートとrootパスワードを使用して接続確認することができます。

docker-compose-mysql1

接続すると記述したdocker-compose.ymlに記述したデータベースが作成されていることも確認できます。

docker-compose-mysql2

GoからMySQLへの接続はまた別の記事でお話したいと思います。

docker-compose downでコンテナを停止する

最後にコンテナの停止方法です。

docker-compose down

で各コンテナが停止します。

 

以上がdocker-composeの使用方法です。

大まかな内容だけでしたが、実際にわたしが開発を行ったときも、これくらいのコマンドしか使っていません。

細かい内容はもっとありますが、公式ドキュメントを確認したりして、少しずつ使い方を覚えていきましょう!

まとめ:docker-composeで「Go+Node+MySQL」のWEBサービス開発環境構築

ここまでの話をまとめます。

まとめ

docker-composeとは、

複数のコンテナを扱う時に使用する

もので、今回は

  • バックエンドコンテナに「Go」
  • フロントエンドコンテナに「Node.js」
  • データベースコンテナに「MySQL」

として環境構築した

docker-composeを使用してコンテナを作成するためには、

  • docker-compose.yml
  • 各コンテナのdockerfile

の2つが必要

ファイルを用意したら、

  1. docker-compose buildでコンテナを作成
  2. docker-compose upでコンテナを起動
  3. docker-compose execでコンテナへコマンド実行
  4. docker-compose downでコンテナを停止

することができる

 

dockerで環境構築しておけば、PCを買い替えた時や、他の人に開発を頼む時でも、

すぐに同じ環境ができるので非常に便利です。

 

「Macではスムーズに環境構築できたけど、WIndowsではうまくいかない。。」

といったこともほぼなくなります。

 

dockerの環境をそのまま本番環境へ適用するケースも増えてきています。

とは言っても、コマンドやオプション、ymlファイルのキーの内容など、

細かい内容はとても多いです。

わたしも細かい内容はほとんど頭に入っていません。

 

なので、開発環境だけでもdockerを利用して少しずつ使えるようにしていきましょう!

おすすめ記事

eSportsプラットフォームSPFans 1

  こんにちは、古賀です!   本記事では、わたしが個人開発したWEBサービス はてな eSportsプラットフォーム「SPFans」 の紹介をします。   以前に紹介し ...

成長するエンジニア 2

  エンジニアになったけど、いまいち成長を感じられないなぁ。。 作業スピードも品質も平凡。 この先成長していけるんだろうか。。   こんにちは、古賀です!   エンジニア ...

道のり 3

※本記事は、各記事のまとめ記事です。   こんにちは、古賀です!   本記事では、 「プログラミング未経験者がエンジニアとして働き、 年収1000万に到達するまでの道のり」 をご説 ...

プログラミングスクール 4

  プログラミングを本格的に勉強して仕事に繋げていきたいけど、 プログラミングスクール多すぎる。。 どういう目線で選べばいいんだ。。   こんにちは、古賀です。   プロ ...

-エンジニア
-, , , , ,

Copyright© Koga Masao's LifeBlog , 2024 All Rights Reserved.