Go言語を使用したプロジェクトでは、Dockerを活用することで環境構築やデプロイを効率化できます。ただし、プロジェクトのディレクトリ構成に応じてDockerfileやdocker-compose.ymlを適切に配置しないと、管理が煩雑になり、エラーやトラブルの原因となることがあります。本記事では、Goプロジェクトの標準的なディレクトリ構成を踏まえ、Dockerfileとdocker-compose.ymlを効果的に配置し、実践的に運用する方法を解説します。これにより、環境構築をシンプルにし、プロジェクトのスケーラビリティを向上させるための基礎知識を習得できます。
Go言語プロジェクトの標準的なディレクトリ構成
Go言語では、プロジェクトのディレクトリ構成を適切に設計することが開発の効率化と保守性の向上に繋がります。以下に、一般的なGoプロジェクトのディレクトリ構造とその役割を説明します。
標準的なディレクトリ構成
Go言語プロジェクトでよく採用される構造は次のようになります。
project/
├── cmd/ # メインアプリケーションのエントリーポイント
│ └── app/
│ └── main.go
├── pkg/ # 外部や内部で再利用可能なコード
│ └── utils/
├── internal/ # プロジェクト内部専用のコード
│ └── service/
├── configs/ # 設定ファイル
├── scripts/ # スクリプトファイル (デプロイやビルド用)
├── build/ # コンテナやパッケージ化に必要なビルド関連ファイル
├── vendor/ # 依存ライブラリ
├── Dockerfile # Dockerイメージの定義ファイル
├── docker-compose.yml # Docker Composeの設定ファイル
└── README.md # プロジェクトの概要説明
ディレクトリの詳細な説明
cmd/
アプリケーションのエントリーポイントを配置するディレクトリです。main.go
は通常ここに置かれ、Goアプリケーションのスタート地点となります。
pkg/
再利用可能なコードやライブラリを配置します。他のプロジェクトからも使用可能な機能はここに格納するのが一般的です。
internal/
プロジェクト内でのみ使用するコードを配置します。このディレクトリ内のコードはGoのコンパイラによって他のプロジェクトからの利用が禁止されます。
configs/
設定ファイルを格納するディレクトリで、環境変数やYAML形式の設定ファイルが含まれることが多いです。
scripts/
デプロイやビルドプロセスを自動化するスクリプトを配置します。CI/CDパイプラインでも活用されます。
Docker関連ファイルの配置
- Dockerfile: プロジェクトのルートディレクトリに配置します。
- docker-compose.yml: プロジェクトのルートディレクトリか、
build/
ディレクトリに配置するのが一般的です。
これらの構成を採用することで、開発チーム全体で統一された環境を維持しやすくなります。
Dockerfileの役割と基本構造
Dockerfileは、Dockerコンテナの環境を定義するための設定ファイルです。これを使用することで、Go言語プロジェクトに必要な依存関係や構築手順を自動化し、どの環境でも一貫した動作を保証できます。
Dockerfileの役割
Dockerfileは以下のような役割を果たします:
- 環境の自動構築: 必要なライブラリやツールを自動でインストールするため、手動設定が不要になります。
- 移植性の向上: 開発環境と本番環境で同じ構成を再現可能です。
- 依存関係の管理: コンテナ内に必要なものだけを含めることで、軽量かつセキュアな環境を提供します。
Dockerfileの基本構造
以下に、Goプロジェクトに特化したシンプルなDockerfileの例を示します:
# ベースイメージを指定
FROM golang:1.20-alpine
# 作業ディレクトリを設定
WORKDIR /app
# Goモジュールを利用する場合、依存関係を先にコピー
COPY go.mod go.sum ./
RUN go mod download
# プロジェクトのソースコードをコピー
COPY . .
# アプリケーションをビルド
RUN go build -o main .
# コンテナ起動時に実行するコマンドを指定
CMD ["./main"]
構成要素の説明
FROM
使用するベースイメージを指定します。golang:1.20-alpine
は軽量で人気のあるGoの公式イメージです。
WORKDIR
コンテナ内の作業ディレクトリを設定します。このディレクトリにソースコードをコピーし、ビルドや実行を行います。
RUN
指定したコマンドを実行します。上記ではGoモジュールの依存関係をダウンロードし、アプリケーションをビルドしています。
COPY
ホストマシン上のファイルをコンテナ内にコピーします。必要なファイルだけを効率的にコピーすることでビルドの効率が向上します。
CMD
コンテナ起動時に実行されるデフォルトのコマンドを設定します。この例では、ビルドされたGoアプリケーションを実行します。
ベストプラクティス
- マルチステージビルドの活用: ビルド環境と実行環境を分離することで、軽量なイメージを作成できます。
- キャッシュを効率的に活用:
go.mod
やgo.sum
を先にコピーして依存関係を先にダウンロードすることで、再ビルドの時間を短縮できます。 - セキュリティ考慮: 必要最低限のツールだけをイメージに含めることで、セキュリティリスクを低減します。
Dockerfileを適切に設計することで、Goプロジェクトの開発からデプロイまでのワークフローを効率化できます。
docker-composeの役割と基本構造
docker-compose
は、複数のDockerコンテナを簡単に管理・オーケストレーションするためのツールです。Go言語プロジェクトにおいても、アプリケーションやデータベース、キャッシュサービスなどを統合的に管理する際に活用できます。
docker-composeの役割
- 複数コンテナの管理: アプリケーションとその依存サービス(例: データベースやメッセージキュー)を一括管理できます。
- 設定の一元化: サービスの設定やネットワークを一つの
docker-compose.yml
ファイルで管理できます。 - 開発と本番環境の統一: 開発と本番で同じ設定を使用できるため、環境差による問題を軽減します。
docker-compose.ymlの基本構造
以下にGo言語プロジェクトを例にした基本的なdocker-compose.yml
の例を示します:
version: '3.9'
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
volumes:
- .:/app
depends_on:
- db
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: exampledb
ports:
- "5432:5432"
構成要素の説明
version
Composeファイルのバージョンを指定します。最新の3.9
を使用することで、最新機能を活用できます。
services
管理する各コンテナを定義します。この例ではapp
(Goアプリケーション)とdb
(PostgreSQLデータベース)の2つのサービスが含まれます。
app
- build: アプリケーション用のDockerfileを指定します。
context
はビルドの対象ディレクトリ、dockerfile
は使用するDockerfileを指定します。 - ports: ホストとコンテナのポートをマッピングします。例では8080ポートを公開しています。
- volumes: ホストディレクトリとコンテナディレクトリを共有します。これにより、コード変更が即座に反映されます。
- depends_on: 他のサービス(ここでは
db
)が起動済みであることを保証します。
db
- image: 使用するDockerイメージ(PostgreSQL 15)を指定します。
- environment: 環境変数を設定します。この例ではデータベースのユーザー名、パスワード、データベース名を指定しています。
- ports: PostgreSQLのデフォルトポート5432を公開します。
ベストプラクティス
- 環境変数ファイルの使用: センシティブな情報は
.env
ファイルに保存し、Composeファイルで参照する形にすることでセキュリティを向上させます。 - ネットワーク設定の活用: カスタムネットワークを設定し、セキュアな通信を確保します。
- ボリュームの適切な設定: 開発用と本番用で異なるボリュームを利用することで、適切なファイル管理が可能になります。
docker-composeを活用することで、Go言語プロジェクトの依存サービスを統一的に管理でき、効率的な開発環境が構築できます。
Dockerfileの適切な配置方法
Dockerfileをプロジェクトのディレクトリ構成に適切に配置することは、開発効率やメンテナンス性を高めるために重要です。Go言語プロジェクトでは、プロジェクトの規模や用途に応じて配置方法を工夫する必要があります。
プロジェクトルートへの配置
小規模なプロジェクトや単一アプリケーションの場合、Dockerfileはプロジェクトルートに配置するのが一般的です。
例:
project/
├── cmd/
│ └── main.go
├── pkg/
├── Dockerfile
├── go.mod
└── go.sum
この構成では、Dockerfileがルートにあるため、簡単にビルドコマンドを実行できます。
docker build -t my-go-app .
buildディレクトリへの配置
中規模以上のプロジェクトや、複数のDockerfileを使用する場合は、build/
ディレクトリを作成し、そこにDockerfileを配置します。
例:
project/
├── build/
│ └── Dockerfile
├── cmd/
├── pkg/
├── go.mod
└── go.sum
この方法のメリットは、プロジェクトのソースコードとビルド設定を分離することで、ディレクトリ構造が整然とすることです。ビルドコマンドでは-f
オプションを指定します。
docker build -f build/Dockerfile -t my-go-app .
サービスごとの配置
マイクロサービスアーキテクチャを採用するプロジェクトでは、各サービスのディレクトリ内に個別のDockerfileを配置します。
例:
project/
├── service1/
│ ├── cmd/
│ ├── Dockerfile
│ ├── go.mod
│ └── go.sum
├── service2/
│ ├── cmd/
│ ├── Dockerfile
│ ├── go.mod
│ └── go.sum
└── docker-compose.yml
この構成では、各サービスが独立してビルドおよび実行可能です。
docker build -t service1-app ./service1
docker build -t service2-app ./service2
ベストプラクティス
プロジェクトの規模に応じた配置
- 小規模プロジェクト:Dockerfileはルートディレクトリに配置する。
- 中規模以上:
build/
ディレクトリを作成し、Dockerfileをそこに配置する。 - マイクロサービス:各サービスごとにDockerfileを分けて管理する。
モジュールの分離
複数のプロジェクトやモジュールがある場合、個別のDockerfileを作成し、適切な場所に配置することで再利用性を高めます。
配置の自動化
CI/CDパイプラインを利用して、特定の場所にDockerfileを自動で展開する方法も検討すると効率的です。
Dockerfileの配置を適切に行うことで、プロジェクトの拡張性や管理の効率性が向上します。プロジェクト規模や用途に応じて最適な配置戦略を採用してください。
docker-compose.ymlの適切な配置方法
docker-compose.yml
は、複数のコンテナをまとめて管理するための設定ファイルです。Go言語プロジェクトにおけるその配置場所を適切に選ぶことで、プロジェクト全体の管理が容易になります。
プロジェクトルートへの配置
小規模から中規模のプロジェクトでは、docker-compose.yml
をプロジェクトルートに配置するのが一般的です。
例:
project/
├── cmd/
├── pkg/
├── Dockerfile
├── docker-compose.yml
├── go.mod
└── go.sum
この配置では、docker-compose
コマンドを簡単に実行できます。
docker-compose up
ルートに配置することで、プロジェクト全体を一元的に管理できる利点があります。
buildディレクトリへの配置
中規模以上のプロジェクトでは、build/
ディレクトリを作成し、その中にdocker-compose.yml
を配置する方法があります。
例:
project/
├── build/
│ ├── Dockerfile
│ └── docker-compose.yml
├── cmd/
├── pkg/
├── go.mod
└── go.sum
この構成では、開発環境や本番環境の構築に必要なファイルをbuild/
ディレクトリにまとめることで、プロジェクトのディレクトリ構造を整理できます。コマンド実行時はディレクトリを指定します。
docker-compose -f build/docker-compose.yml up
環境別のディレクトリ配置
本番環境、開発環境、テスト環境など、複数の環境をサポートする場合、環境ごとにdocker-compose.yml
を分けて配置します。
例:
project/
├── docker/
│ ├── docker-compose.dev.yml
│ ├── docker-compose.prod.yml
│ └── docker-compose.test.yml
├── cmd/
├── pkg/
├── go.mod
└── go.sum
各環境用のComposeファイルを用意することで、設定を柔軟に変更できます。使用時には-f
オプションで指定します。
docker-compose -f docker/docker-compose.dev.yml up
ベストプラクティス
用途に応じた配置
- 単純なプロジェクト:プロジェクトルートに配置。
- 中規模以上のプロジェクト:
build/
ディレクトリを作成して管理。 - 複数環境に対応:環境ごとにComposeファイルを作成し、
docker/
ディレクトリなどで管理。
環境変数の活用
.env
ファイルを用意して、docker-compose.yml
内で環境変数を使用することで、設定の重複を防ぎつつ環境に応じた値を動的に変更できます。
version: '3.9'
services:
app:
image: ${APP_IMAGE}
ports:
- "${APP_PORT}:8080"
モジュール化の推奨
Composeファイルを分割して複数のファイルに分け、docker-compose.override.yml
などを使うことで拡張性を高めます。
docker-compose -f docker-compose.yml -f docker-compose.override.yml up
まとめ
docker-compose.yml
の配置場所はプロジェクト規模や使用環境に応じて適切に選択することが重要です。ルートディレクトリや専用ディレクトリへの配置、環境別の設定ファイル管理を活用することで、効率的かつ柔軟なコンテナ管理が実現します。
実践例:Go言語プロジェクトでの構築手順
ここでは、Go言語プロジェクトにおけるDockerfile
とdocker-compose.yml
を使った実際の構築手順を説明します。データベースとしてPostgreSQLを使用する例で解説します。
ディレクトリ構成
以下の構造を前提とします:
project/
├── cmd/
│ └── main.go
├── Dockerfile
├── docker-compose.yml
├── go.mod
└── go.sum
main.go
: 簡単なHTTPサーバーを実装します。Dockerfile
: Goアプリケーションをビルドするための設定ファイル。docker-compose.yml
: GoアプリケーションとPostgreSQLを一緒に起動する設定。
ステップ1: Goアプリケーションの作成
cmd/main.go
に以下の内容を記述します:
package main
import (
"database/sql"
"fmt"
"log"
"net/http"
_ "github.com/lib/pq"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, Dockerized Go!"))
})
http.HandleFunc("/db", func(w http.ResponseWriter, r *http.Request) {
connStr := "postgres://user:password@db:5432/exampledb?sslmode=disable"
db, err := sql.Open("postgres", connStr)
if err != nil {
http.Error(w, "Database connection failed", http.StatusInternalServerError)
return
}
defer db.Close()
err = db.Ping()
if err != nil {
http.Error(w, "Database ping failed", http.StatusInternalServerError)
return
}
w.Write([]byte("Database connected successfully!"))
})
fmt.Println("Server is running on port 8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
ステップ2: Dockerfileの作成
Dockerfile
に以下を記述します:
FROM golang:1.20-alpine
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o main ./cmd
CMD ["./main"]
ステップ3: docker-compose.ymlの作成
docker-compose.yml
に以下を記述します:
version: '3.9'
services:
app:
build:
context: .
ports:
- "8080:8080"
depends_on:
- db
environment:
- DB_HOST=db
- DB_PORT=5432
- DB_USER=user
- DB_PASSWORD=password
- DB_NAME=exampledb
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: exampledb
ports:
- "5432:5432"
ステップ4: 構築と実行
以下のコマンドを実行して、コンテナを構築・起動します:
docker-compose up --build
起動後、次のURLでアプリケーションにアクセスできます:
- http://localhost:8080/: HTTPサーバーの応答を確認。
- http://localhost:8080/db: データベース接続の動作確認。
ステップ5: 動作確認
- ブラウザで確認: 上記URLにアクセスして適切な応答が得られることを確認します。
- ログの確認:
docker-compose
のログ出力にエラーがないか確認します。 - データベースの確認: 任意のツール(例:
psql
)でPostgreSQLに接続し、データベースが動作しているかを確認します。
まとめ
この手順を通じて、GoアプリケーションとPostgreSQLのコンテナを連携させる環境を構築しました。この方法を応用すれば、他のサービスや設定を加えて、より複雑なシステムを構築することも可能です。Dockerfileとdocker-compose.ymlの活用により、開発とデプロイが一貫した効率的なプロセスに改善されます。
よくあるミスとその対処方法
Dockerを使ってGoプロジェクトを構築する際には、いくつかのよくあるミスがあります。これらの問題を把握し、適切に対処することで、スムーズな開発プロセスを実現できます。
1. Dockerfileの設定ミス
問題
- 必要な依存関係が正しくインストールされていない。
- 作業ディレクトリの設定忘れ。
COPY
やRUN
コマンドの順序によるキャッシュの非効率利用。
解決策
- Dockerfileを適切に構成する。以下のように依存関係のインストールを先に行うとキャッシュを有効活用できます。
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o main ./cmd
- 作業ディレクトリを明確に指定する。
WORKDIR /app
で、コード配置やビルドを統一的に管理します。
2. docker-compose.ymlの依存関係の設定ミス
問題
depends_on
でサービスの起動順序を設定しても、完全な起動を待たない。- 環境変数の設定漏れやミス。
解決策
healthcheck
を使って、サービスの起動状態を確認してからアプリケーションが起動するように設定します。
db:
image: postgres:15-alpine
healthcheck:
test: ["CMD", "pg_isready", "-U", "user"]
interval: 10s
retries: 5
.env
ファイルを利用して環境変数を明示的に定義します。
DB_USER=user
DB_PASSWORD=password
DB_NAME=exampledb
DB_HOST=db
Composeファイルで参照:
environment:
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
3. ポートの競合
問題
複数のコンテナやサービスが同じポートを使用している場合、ポート競合が発生します。
解決策
docker-compose.yml
で明確なポートマッピングを設定します。例えば、複数のアプリケーションが8080ポートを使う場合:
services:
app1:
ports:
- "8081:8080"
app2:
ports:
- "8082:8080"
4. ボリュームの適切な管理ができていない
問題
ホストの変更がコンテナに即時反映されない、またはボリュームのデータが誤って削除される。
解決策
volumes
を適切に設定し、コードの即時反映を確保します。
volumes:
- .:/app
- 必要に応じて、永続的なデータ保存には名前付きボリュームを利用します。
volumes:
db_data:
5. ネットワーク設定の不足
問題
サービス間でネットワーク通信ができない。
解決策
Composeファイルでカスタムネットワークを定義し、サービス間の通信を有効化します。
networks:
app_net:
services:
app:
networks:
- app_net
db:
networks:
- app_net
6. イメージサイズが大きくなりすぎる
問題
Dockerイメージに不要なファイルやツールが含まれており、サイズが肥大化する。
解決策
- マルチステージビルドを活用して不要なファイルを排除します。
FROM golang:1.20-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o main ./cmd
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/main .
CMD ["./main"]
7. ログやエラーメッセージの不足
問題
エラー発生時に原因を特定できる情報が得られない。
解決策
- ログ出力を追加し、エラー原因を把握しやすくする。Goアプリケーションでは次のようにログを設定します:
log.Println("Server is starting...")
log.Fatal(http.ListenAndServe(":8080", nil))
まとめ
Dockerを活用したGoプロジェクト構築では、細かい設定ミスが原因でトラブルが発生することがあります。本記事で紹介したミスと対策を参考に、効率的かつ安定した開発環境を構築してください。
応用例:複数サービス構成での活用
Go言語プロジェクトを大規模に展開する際には、複数のサービス(アプリケーション、データベース、キャッシュ、メッセージキューなど)を連携させるケースが増えます。このような複数サービス構成では、Dockerfileとdocker-composeを活用して効率的な管理を行うことが重要です。
事例: Goアプリケーション + PostgreSQL + Redis
ここでは、Goアプリケーションがデータベース(PostgreSQL)とキャッシュ(Redis)を利用する例を示します。
ディレクトリ構成
以下の構造を仮定します:
project/
├── cmd/
│ └── main.go
├── Dockerfile
├── docker-compose.yml
├── go.mod
├── go.sum
└── configs/
└── app.env
Goアプリケーションのコード例
以下は、データベース(PostgreSQL)とキャッシュ(Redis)を利用するGoアプリケーションの例です。
package main
import (
"database/sql"
"fmt"
"log"
"net/http"
"github.com/go-redis/redis/v8"
_ "github.com/lib/pq"
"golang.org/x/net/context"
)
var ctx = context.Background()
func main() {
// Redisクライアント
rdb := redis.NewClient(&redis.Options{
Addr: "redis:6379",
})
_, err := rdb.Ping(ctx).Result()
if err != nil {
log.Fatalf("Failed to connect to Redis: %v", err)
}
// PostgreSQLクライアント
connStr := "postgres://user:password@db:5432/exampledb?sslmode=disable"
db, err := sql.Open("postgres", connStr)
if err != nil {
log.Fatalf("Failed to connect to PostgreSQL: %v", err)
}
defer db.Close()
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, Dockerized Multi-Service Go!"))
})
http.HandleFunc("/db", func(w http.ResponseWriter, r *http.Request) {
err := db.Ping()
if err != nil {
http.Error(w, "Database connection failed", http.StatusInternalServerError)
return
}
w.Write([]byte("Database connected successfully!"))
})
http.HandleFunc("/cache", func(w http.ResponseWriter, r *http.Request) {
err := rdb.Set(ctx, "key", "value", 0).Err()
if err != nil {
http.Error(w, "Redis set failed", http.StatusInternalServerError)
return
}
val, err := rdb.Get(ctx, "key").Result()
if err != nil {
http.Error(w, "Redis get failed", http.StatusInternalServerError)
return
}
w.Write([]byte(fmt.Sprintf("Cache value: %s", val)))
})
fmt.Println("Server is running on port 8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
docker-compose.ymlの設定例
以下は、Goアプリケーション、PostgreSQL、Redisを連携するdocker-compose.yml
の例です。
version: '3.9'
services:
app:
build:
context: .
ports:
- "8080:8080"
depends_on:
- db
- redis
environment:
- DB_HOST=db
- DB_PORT=5432
- DB_USER=user
- DB_PASSWORD=password
- DB_NAME=exampledb
- REDIS_HOST=redis
- REDIS_PORT=6379
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: exampledb
ports:
- "5432:5432"
healthcheck:
test: ["CMD", "pg_isready", "-U", "user"]
interval: 10s
retries: 5
redis:
image: redis:7-alpine
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
retries: 5
ステップ1: コンテナの起動
以下のコマンドを実行して、すべてのサービスを起動します:
docker-compose up --build
ステップ2: 動作確認
- アプリケーションの確認
ブラウザでhttp://localhost:8080
にアクセスし、レスポンスが得られることを確認します。 - データベースの確認
http://localhost:8080/db
にアクセスし、PostgreSQLへの接続が成功していることを確認します。 - キャッシュの確認
http://localhost:8080/cache
にアクセスし、Redisへの接続が成功していることを確認します。
応用例
1. メッセージキューの追加
RabbitMQやKafkaをComposeファイルに追加し、イベント駆動型のアーキテクチャを構築します。
2. サードパーティAPIとの統合
Goアプリケーションで外部APIを呼び出し、レスポンスをキャッシュやデータベースに保存する機能を追加します。
3. ロードバランサーの導入
Nginxを追加し、複数のアプリケーションコンテナに対してロードバランシングを行う構成を構築します。
まとめ
複数サービス構成を活用することで、Go言語プロジェクトをスケーラブルかつモジュール化されたシステムとして設計できます。Dockerfileとdocker-composeを適切に組み合わせて、効率的な開発環境と本番環境を構築しましょう。
まとめ
本記事では、Go言語プロジェクトにおけるDockerfile
とdocker-compose.yml
の配置方法と活用事例について詳しく解説しました。プロジェクトの規模や用途に応じたファイル配置、効率的なビルド構成、複数サービス連携の実践例を通じて、Dockerを利用した開発とデプロイの基礎から応用までを網羅しました。
適切なディレクトリ構成とファイル管理により、開発効率やメンテナンス性が向上し、環境差によるトラブルも最小化できます。さらに、複数サービスの連携や応用例を実践することで、スケーラブルで柔軟なシステム構築が可能となります。
Dockerの仕組みを正しく理解し、Go言語プロジェクトに応用することで、強力かつ効率的な開発体験を手に入れましょう。
コメント