🐳

Dockerよくわからん!から 環境構築が少しできるようになった話

2023/07/14に公開

Dockerってよくわかんない

私はプログラミングを始めてから1年ほどの頃にDockerの勉強を行ったのですが、いまいちよく理解できなくて途中で勉強を辞めてしまったことがあります。
仮想化?コンテナって何?
自分の中でなかなかイメージが固められていないまま、フロントエンドの勉強ばかりしていました。

しかし最近、Go言語とMySQLの勉強を始め、本格的なWebアプリケーションの制作をしてみたいと思いました。なので、ついでにDockerも使えるようになりたい! とリベンジをしようと思い、再度勉強し始めました。

今回は、自分が行ったDockerの勉強方法と環境構築を紹介します。

Dockerの教材本を読んだ

手始めに、Dockerでできることは何なのか、コンテナやイメージなど、基礎の基礎から学びたいと思いました。
理解が曖昧なまま、ある程度構築できるようになっても応用が利かないですし、自分が今何をしているのかハッキリさせながら構築できるようになるべきだと感じています。

Dockerの仕組みを一から学べるような本を探していると、こちらを見つけました。

https://zenn.dev/suzuki_hoge/books/2022-03-docker-practice-8ae36c33424b59

こちらの本を読んで勉強させてもらいましたが、とてもわかりやすく説明されていました。
おかげでDockerへの知識が付き、イメージも固まりました。
Dockerの勉強をこれから始める方にはとてもオススメです。
以下は読んでいて感じた良さです。

  1. 無料で読める
  2. 基礎知識がしっかり身に付く
  3. 図をたくさん使った説明でわかりやすい
  4. Docker composeも学べる

さっそく環境構築を行った

インプットしたらアウトプットをしようということで、たくさんの記事を参考にしながら、今回はReact + Go + MySQLの環境構築を行いました。
手を動かして実際に作ってみるのが1番身に付くと思います。
以下実際に作ったファイルです。なるべくシンプルに書いてあります。
汚いですが、よければ参考程度に見てくれると嬉しいです。

ホスト環境

  • Apple M2 / macOS Ventura

ディレクトリ構成

.
├── frontend
├── backend
│   ├── .ari.toml
├── database
│   ├── my.cnf
├── docker
│   ├── frontend.dockerfile
│   ├── backend.dockerfile
└── compose.yml

Dockerなどの設定

docker-compose.yml
services:
  frontend:
    container_name: frontend
    build:
      context: .
      dockerfile: ./docker/frontend.dockerfile
    tty: true
    volumes:
      - ./frontend:/home/frontend
    command: sh -c "npm run start"
    ports:
      - 3000:3000
    depends_on:
      - backend

  backend:
    container_name: backend
    build:
      context: .
      dockerfile: ./docker/backend.dockerfile
    volumes:
      - ./backend:/go/src/app
    tty: true
    ports:
      - "127.0.0.1:8080:8080"
    depends_on:
      database:
        condition: service_healthy

  database:
    container_name: database
    image: mysql:8.0
    volumes:
      - ./database/my.cnf:/etc/mysql/conf.d/my.cnf
    environment:
      MYSQL_DATABASE: main
      MYSQL_USER: docker
      MYSQL_PASSWORD: docker
      MYSQL_ROOT_PASSWORD: MYSQL_ROOT_PASSWORD
      TZ: "Asia/Tokyo"
    ports:
      - 3306:3306
    healthcheck:
      test: [ "CMD", "mysqladmin", "ping", "-u", "root" ]
      interval: 6s
      timeout: 1s
      retries: 5
    platform: linux/amd64
docker/frontend.dockerfile
FROM node:lts
WORKDIR /home/frontend
docker/backend.dockerfile
FROM golang:1.19.1-alpine

COPY ./backend/go.mod /go/src/app/go.mod
COPY ./backend/go.sum /go/src/app/go.sum

RUN apk update &&  apk add git
RUN go install github.com/cosmtrek/air@v1.29.0

WORKDIR /go/src/app

CMD ["air"]

Airを使用しているため、.air.tomlを作成

backend/.ari.toml
root = "."
tmp_dir = "tmp"

[build]
# Just plain old shell command. You could use `make` as well.
cmd = "go build -o ./tmp/main ."
# Binary file yields from `cmd`.
bin = "tmp/main"
# Customize binary, can setup environment variables when run your app.
full_bin = "APP_ENV=dev APP_USER=air ./tmp/main"
# Watch these filename extensions.
include_ext = ["go", "tpl", "tmpl", "html"]
# Ignore these filename extensions or directories.
exclude_dir = ["assets", "tmp", "vendor", "frontend/node_modules"]
# Watch these directories if you specified.
include_dir = []
# Exclude files.
exclude_file = []
# Exclude specific regular expressions.
exclude_regex = ["_test.go"]
# Exclude unchanged files.
exclude_unchanged = true
# Follow symlink for directories
follow_symlink = true
# This log file places in your tmp_dir.
log = "air.log"
# It's not necessary to trigger build each time file changes if it's too frequent.
delay = 1000 # ms
# Stop running old binary when build errors occur.
stop_on_error = true
# Send Interrupt signal before killing process (windows does not support this feature)
send_interrupt = false
# Delay after sending Interrupt signal
kill_delay = 500 # ms

[log]
# Show log time
time = false

[color]
# Customize each part's color. If no color found, use the raw app log.
main = "magenta"
watcher = "cyan"
build = "yellow"
runner = "green"

[misc]
# Delete tmp directory on exit
clean_on_exit = true

DB用の設定

my.cnf
[mysqld]
character-set-server=utf8

[client]
default-character-set=utf8

buildしてReactとgo.modを導入

docker-compose build
docker-compose run --rm client sh -c 'npx create-react-app . --template typescript'
docker-compose run --rm server sh -c 'go mod init'

main.goを作成

server/main.go
package main

import "fmt"

func main() {
  fmt.Println("Hello World")
}

起動する

docker-compose up

localhost:3000に接続して以下の画面とターミナルにHello Worldが出力されていれば完了です。お疲れ様でした。

react_img

最後に

Dockerは意外と理解しやすいものだと勉強してから感じました。まだまだ奥が深いDockerですが、何度も繰り返しDockerを用いたWebアプリケーションを作成して、より知識を身につけていきたいなと思っています。後はもっと綺麗に書けるようになりたい!

Discussion