はじめに
上野です!
以前に「VSCodeでGolang✖︎Next.jsの開発環境を構築してみた」という記事を投稿したのですが、記事の内容通りの環境だと色々と不便なことが出てきたので、改めて開発環境を見直してみました。
特に不便だと感じたのが、GolangとNext.jsのコンテナが別々になっていることによって、VSCodeのWindowを二つ開かないといけないのが特に不便に感じました。どうせなら、一つのWindowでソースコードの編集できれば楽だということに気づきました…
ということで、今回は一つのコンテナ上でGolangとNode.jsが動作する環境を作成し、そのコンテナにVSCodeで接続して開発ができるようにしていきたいと思います!
GolangとNode.jsが動作するDockerfileを作成
フォルダ構成は以前のを使用します。
以前の「VSCodeでGolang✖︎Next.jsの開発環境を構築してみた」の記事を参考にGolang✖︎Next.jsのフォルダを作成してください。
新しく追加したファイルに関しては「(New)」と記載しています。
go-next
|_.devcontainer
| |_devcontainer.json (New)
|
|_.vscode
| |_launch.json (New)
|
|_server
| |_.devcontainer
| | |_devcontainer.json
| |_.vscode
| | |_launch.json
| |_Dockerfile
| |_.air.toml
| |_main.go
|
|_client
| |_.devcontainer
| | |_devcontainer.json
| |_Dockerfile
|
|_docker-compose.yml
|
|_Dockerfile.dev (New)
では、最初にDockerfile.devのファイルを作成します。
# ------------------------ Golang ---------------------------
FROM golang:1.17-alpine AS golang
# 環境変数設定
ENV ROOT=/go/src/app
WORKDIR ${ROOT}
RUN apk update && apk add git
RUN go install golang.org/x/tools/cmd/goimports@latest \
&& go install golang.org/x/tools/gopls@latest \
&& go install golang.org/x/tools/cmd/godoc@latest \
&& go install golang.org/x/lint/golint@latest \
&& go install github.com/rogpeppe/godef@latest \
&& go install github.com/nsf/gocode@latest \
# hot relord
&& go install github.com/cosmtrek/air@latest \
# debug
&& go install github.com/go-delve/delve/cmd/dlv@latest
ADD ./server/shell/mysqldef.sh ${ROOT}/shell/mysqldef.sh
RUN sh ${ROOT}/shell/mysqldef.sh
# GO MODULEインストール
COPY ./server/go.mod .
COPY ./server/go.sum .
RUN go mod download
# # ------------------------ Node ---------------------------
FROM node:17-alpine as node
# # ------------------------ Develop ---------------------------
FROM alpine as dev
# 環境変数設定(GO)
ENV GOPATH=/root/go
ENV PATH $PATH:/usr/local/go/bin/:/usr/local/go/bin/go:/go/bin
ENV GO111MODULE=on
WORKDIR /app
RUN apk update && \
apk add --no-cache && \
apk add curl && \
apk add tzdata && \
apk add git && \
apk add openssh && \
apk add make
# Golang用
COPY --from=golang /usr/local/bin /usr/local/bin
COPY --from=golang /usr/local/go /usr/local/go
COPY --from=golang /go/bin /go/bin
COPY --from=golang /go/pkg ${GOPATH}/pkg
# Node.js用
COPY --from=node /usr/local/bin /usr/local/bin
COPY --from=node /usr/local/lib/node_modules/npm /usr/local/lib/node_modules/npm
COPY --from=node /opt/yarn* /opt/yarn
RUN ln -fs /opt/yarn/bin/yarn /usr/local/bin/yarn && \
ln -fs /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg
# Gin Port
EXPOSE 8080
# Next.js Port
EXPOSE 3000
こちらのDockerifleでは、マルチステージビルドを利用しています。
GolangとNode.jsのステージから必要なフォルダ抽出しalpineステージにコピーしています。
次に.devcontainer/devcontainer.jsonを作成します。
{
"name": "Go devcontainer",
"build": {
"dockerfile": "../Dockerfile.dev",
"target": "dev"
},
"mounts": [
"source=${localWorkspaceFolder},target=/app,type=bind,consistency=cached"
],
"workspaceFolder": "/app",
"appPort": ["7777:8080", "3434:3000"],
"settings": {
"editor.tabSize": 2,
"editor.formatOnPaste": true,
"editor.formatOnType": true,
"editor.renderWhitespace": "all",
"editor.bracketPairColorization.enabled": true,
"editor.guides.bracketPairs": "active",
"files.trimTrailingWhitespace": true,
"files.trimFinalNewlines": true,
"go.toolsManagement.checkForUpdates": "off",
"go.inferGopath": true,
"go.useLanguageServer": true,
"eslint.packageManager": "yarn",
"eslint.run": "onSave",
"eslint.nodePath": "/app/client",
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"[go]": {
"editor.defaultFormatter": "golang.go",
"editor.insertSpaces": true,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true
},
"editor.suggest.snippetsPreventQuickSuggestions": false
},
"[javascript]": {
"editor.formatOnSave": true
},
"[typescript]": {
"editor.formatOnSave": true
},
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact"
]
},
"extensions": [
"golang.go",
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
],
"shutdownAction": "none"
}
devcontainerファイルは以前のGolangとNode.jsのdevcontainerファイルを合体させたものになります。
異なっている点としては、docker-composeファイルの指定からDockerfileの指定になっている点です。
Golangでデバックができるよう.vscode/launch.jsonファイルを作成します。
{
"version": "0.2.0",
"configurations": [
{
"name": "Go",
"type": "go",
"debugAdapter": "dlv-dap",
"request": "attach",
"mode": "remote",
"cwd": "${workspaceFolder}/server",
"port": 2345,
"host": "0.0.0.0",
"showLog": true,
}
]
}
以上でコンテナ一つで開発ができる環境ができました。
開発する際は、VSCodeの一番左下のボタンから「Reopen in Container」を選択し接続してみてください。
まとめ
以前の開発環境だとわざわざ二つのwindowを開かないといけず、gitの操作も以前の環境だとできませんでした。ただ、今回の一つのコンテナに接続して開発する方法だと一つのwindowを開くだけで済み、かつgitの操作もコンテナ内で行えるようになりました。今後はこの開発環境をベースにGolangとNext.jsのアプリを作ってみたいと思います。
今回は以上となります。ありがとうございました!