【超便利】DevContainerでサクッと開発環境を構築しよう!
はじめに
Dev Container
の拡張機能はコンテナ(docker)を利用して開発環境を構築できる機能です。
この記事では、新規構築だけではなく既存のDockerfileやdocker-compose.ymlを使ったパターンについても紹介していきます。
Dev Containerとは
VSCodeは定番のコードエディタで、様々な「拡張機能」を追加して機能拡張できる点が特徴の1つです。他にも主要なプラットフォームで使えるなど様々な特徴を持っています。
Dockerを利用して環境構築可能な拡張機能がDev Container
です。
特徴
- VSCodeとDockerがインストールされていれば、開発構築が簡単に構築できます
- Dockerfileやdocker-composeにも対応している
- コード(ファイル)化されるので、構築時の差異が発生しづらい
- VSCodeの拡張機能も指定できる(拡張機能を統一もできる)
zennの執筆環境(新規構築)
zennの執筆環境としても活用しているので、例として紹介します。
zennの記事以外にもmarkdownを使っている設計書などにも活用できます。
構築手順は後述しますが、最終的にできた設定ファイルdevcontainer.json
は以下になります。
{
"name": "zenn",
// dockerイメージ
"image": "mcr.microsoft.com/devcontainers/base:jammy",
// nodeやpythonなどのインストール設定
"features": {
"ghcr.io/devcontainers/features/node:1": {}
},
"customizations": {
// カスタマイズ
"vscode": {
"extensions": [
"taichi.vscode-textlint", // 文章校正として、textlintの拡張機能
"DavidAnson.vscode-markdownlint", // Markdownの構文とスタイルをチェックの拡張機能
"hediet.vscode-drawio", // 図を記載する際に使うdrawioの拡張機能
"bierner.markdown-mermaid" // mermaidの記載もプレビューできるようにする拡張機能
],
"settings": {}
}
},
// 起動時の実行コマンド
// 今回はnodejsのパッケージをインストール
"postCreateCommand": "yarn install"
}
zennの執筆環境_構築完了後
構築完了後、以下のことができる環境になります。
-
Zenn CLI
がターミナルで実行できる - 校正がVSCode上でできる
- 図などを編集・プレビューできる
zennの執筆環境_新規構築の流れ
GUIで指定した方法を記載しますが、慣れてきたら.devcontainer/devcontainer.json
を書いた方が個人的には速いです。
- VSCodeの左下「><」を選択します。
-
Open Container Configuration File
を選択します。
- イメージを選択します。今回は"Ubuntu"のイメージを選びます。
- "jammy"のタグを選びます。
- 元のイメージにはないツールとして"Nodejs"を入れるように選択します。
- "OK"⇒"Keep Defaults"で選択すると、設定ファイルが作成されます。
.devcontainer/devcontainer.json
- 右下に表示される
Reopen in Container
をクリックして環境を立ち上げます。 - nodejsがインストールされた環境(コンテナ)が立ち上がるので、お好きなパッケージ管理でパッケージをダウンロードします。
- zenn-cli (例:
yarn add zenn-cli
) - markdownlint-cli2 (例:
yarn add --dev markdownlint-cli2
) - textlint (例:
yarn add --dev textlint
)- textlint-rule-xxxも同時に追加します。
- zenn-cli (例:
- ここまでの設定だとdevcontainer起動してすぐはパッケージがインストールされないので、
devcontainer.json
のpostCreateCommand
にインストールコマンドを記載します。-
postCreateCommand
は環境(コンテナ)起動時に毎回呼ばれるコマンドです。 - 例:
yarn install
-
- 続いて拡張機能を
devcontainer.json
のcustomizations.vscode.extensions
に指定します。- 拡張機能のIDの確認方法は以下になります。
- 拡張機能のIDの確認方法は以下になります。
-
devcontainer.json
を保存すると、右下にReBuild
が表示されるのでクリックします。
※ フロントエンド(VueやReactなど)の開発環境も同じように構築ができます。
既存のDockerfileを利用した構築
すでにDockerfileを使って環境を構築してる場合でもdevcontainerを活用できます。
基本は同じで、devcontainer.json
の一部を変えるのみです。
{
- "image": "mcr.microsoft.com/devcontainers/base:jammy",
- "features": {
- "ghcr.io/devcontainers/features/node:1": {}
- }
+ "build": {
+ "dockerfile": "../Dockerfile"
+ },
}
想定フォルダ構成は以下です。
- .devcontainer
- devcontainer.json
- Dockerfile (すでにあったファイル)
既存のdocker-compose.ymlを利用した構築
同じくすでにdocker-composeを使って環境(WEB+DB)を構築してる場合でもdevcontainerを活用できます。
基本は同じで、devcontainer.json
の一部を変えるのみです。
{
- "image": "mcr.microsoft.com/devcontainers/base:jammy",
- "features": {
- "ghcr.io/devcontainers/features/node:1": {}
- }
+ "dockerComposeFile": [
+ "../docker-compose.yml"
+ ],
+ "service": "サービス名",
+ "workspaceFolder": "フォルダパス",
}
想定フォルダ構成は以下です。
- .devcontainer
- devcontainer.json
- docker-compose.yml (すでにあったファイル)
その他サンプル
Pythonの開発環境として使いたい場合
Python+poetry
- .devcontainer
- devcontainer.json
- Dockerfile
{
"name": "poetry3-poetry-pyenv",
"build": {
"dockerfile": "Dockerfile"
},
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"njpwerner.autodocstring"
]
}
}
}
FROM mcr.microsoft.com/devcontainers/base:jammy
# FROM mcr.microsoft.com/devcontainers/base:jammy
ARG DEBIAN_FRONTEND=noninteractive
ARG USER=vscode
RUN DEBIAN_FRONTEND=noninteractive \
&& apt-get update \
&& apt-get install -y build-essential --no-install-recommends make \
ca-certificates \
git \
libssl-dev \
zlib1g-dev \
libbz2-dev \
libreadline-dev \
libsqlite3-dev \
wget \
curl \
llvm \
libncurses5-dev \
xz-utils \
tk-dev \
libxml2-dev \
libxmlsec1-dev \
libffi-dev \
liblzma-dev
# Python and poetry installation
USER $USER
ARG HOME="/home/$USER"
ARG PYTHON_VERSION=3.10
# ARG PYTHON_VERSION=3.10
ENV PYENV_ROOT="${HOME}/.pyenv"
ENV PATH="${PYENV_ROOT}/shims:${PYENV_ROOT}/bin:${HOME}/.local/bin:$PATH"
RUN echo "done 0" \
&& curl https://pyenv.run | bash \
&& echo "done 1" \
&& pyenv install ${PYTHON_VERSION} \
&& echo "done 2" \
&& pyenv global ${PYTHON_VERSION} \
&& echo "done 3" \
&& curl -sSL https://install.python-poetry.org | python3 - \
&& poetry config virtualenvs.in-project true
Laravel(DBコンテナ含む)の開発環境として使いたい場合
Laravel+MySQL
- .devcontainer
- devcontainer.json
- docker
- Dockerfile
- docker-compose.yml
{
"name": "PHP",
"dockerComposeFile": [
"../docker-compose.yml"
],
"service": "webapp",
"workspaceFolder": "/var/www/html"
}
version: '3'
services:
webapp:
build:
context: ./docker
dockerfile: Dockerfile
args:
WWWGROUP: '${WWWGROUP}'
extra_hosts:
- 'host.docker.internal:host-gateway'
ports:
- '${APP_PORT:-80}:80'
environment:
WWWUSER: '${WWWUSER}'
LARAVEL_SAIL: 1
XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
volumes:
- './:/var/www/html'
- vol_vendor:/var/www/html/vendor
- vol_node_modules:/var/www/html/node_modules
depends_on:
- mysql
mysql:
image: 'mysql/mysql-server:8.0'
ports:
- '${FORWARD_DB_PORT:-3306}:3306'
environment:
MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
MYSQL_ROOT_HOST: '%'
MYSQL_DATABASE: '${DB_DATABASE}'
MYSQL_USER: '${DB_USERNAME}'
MYSQL_PASSWORD: '${DB_PASSWORD}'
MYSQL_ALLOW_EMPTY_PASSWORD: 1
volumes:
- 'vol_mysql:/var/lib/mysql'
healthcheck:
test:
- CMD
- mysqladmin
- ping
- '-p${DB_PASSWORD}'
retries: 3
timeout: 5s
volumes:
vol_mysql:
driver: local
vol_node_modules:
driver: local
vol_vendor:
driver: local
FROM ubuntu:22.04
ARG WWWGROUP
ARG NODE_VERSION=18
ARG POSTGRES_VERSION=15
WORKDIR /var/www/html
ENV DEBIAN_FRONTEND noninteractive
ENV TZ=UTC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get update \
&& apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python2 dnsutils \
&& curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c' | gpg --dearmor | tee /etc/apt/keyrings/ppa_ondrej_php.gpg > /dev/null \
&& echo "deb [signed-by=/etc/apt/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu jammy main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \
&& apt-get update \
&& apt-get install -y php8.3-cli php8.3-dev \
php8.3-pgsql php8.3-sqlite3 php8.3-gd php8.3-imagick \
php8.3-curl \
php8.3-imap php8.3-mysql php8.3-mbstring \
php8.3-xml php8.3-zip php8.3-bcmath php8.3-soap \
php8.3-intl php8.3-readline \
php8.3-ldap \
php8.3-msgpack php8.3-igbinary php8.3-redis php8.3-swoole \
php8.3-memcached php8.3-pcov php8.3-xdebug \
libapache2-mod-php8.3 apache2 \
&& php -r "readfile('https://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer \
&& curl -sLS https://deb.nodesource.com/setup_$NODE_VERSION.x | bash - \
&& apt-get install -y nodejs \
&& npm install -g npm \
&& curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /etc/apt/keyrings/yarn.gpg >/dev/null \
&& echo "deb [signed-by=/etc/apt/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \
&& curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/keyrings/pgdg.gpg >/dev/null \
&& echo "deb [signed-by=/etc/apt/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt jammy-pgdg main" > /etc/apt/sources.list.d/pgdg.list \
&& apt-get update \
&& apt-get install -y yarn \
&& apt-get install -y mysql-client \
&& apt-get install -y postgresql-client-$POSTGRES_VERSION \
&& apt-get -y autoremove \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.3
RUN groupadd --force -g $WWWGROUP sail
RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail
COPY php.ini /etc/php/8.3/apache2/php.ini
RUN cp -R /etc/php/8.3/cli/conf.d /etc/php/8.3/apache2/conf.d
COPY apache/default.conf /etc/apache2/sites-enabled/000-default.conf
RUN a2enmod rewrite
EXPOSE 80
CMD ["apachectl", "-D", "FOREGROUND"]
おわりに
Dev Container
の拡張機能を使った環境構築について改めてまとめました。
常々思っていますが、コンテナでの環境構築はかなり便利です。また、Dev Container
を使うことで開発環境でのlintなどの拡張機能をチームで統一ができます。
すでにDockerfileやdocker-composeを使っていれば、簡単に利用できる点でも好きな拡張機能です。
最後にDev Container
を使うメリットをまとめておきます。
- ローカル環境を汚さない
- 環境構築をコード化できる
- lintなどの拡張機能をチームで統一ができる
- dockerを使っているプロジェクトであれば、容易に使える
Dockerfileの書き方は以下の記事にまとめていますので、こちらもご参照ください。
参考
Discussion