インターン(KLab Server Side Camp #2)で使用されていた環境構築法について調べてみる

2022/03/17に公開

目的

先日,KLab(クラブ)様のServer Side Campインターンに参加させていただきました.この際,環境構築をすべてGithub上のCodespacesで完結させており,とても参考になりました.そこで今回はこれらの環境構築で使用されていたテクニックなどを調べていき,自分自身の今後の開発に役立てることを目的とします.

Fast APIとかMySQL周りは他の参加者の方々が書いてくださるであろうので・・・(この記事も去年散々流行ったことの焼き直しなのですが2022年版ということで...)

KLab(クラブ) Server Side Campについて

実際の音ゲーに近いクライアントアプリを用意していただき(!!),そのクライアントからのリクエストを処理するバックエンド側(Python・FastAPI・MySQL)を書いていくことをメインとするインターンでした.今回で2回目の開催となるようです.春休み中平日の5日間で開催され,ずぼらな大学生・高専生でも参加しやすいタイムスケジュールとなっていてとてもやりやすかったです.私は犬の朝散歩から帰ってきてから参加していましたが余裕をもって取り組むことができました.

講義を受けて実装に移るスタイルだったので,初めて使うライブラリや,DB周りのこともしっかりと理解しながら進めることができました.趣味でPythonを使ったことがある程度の私でもついていくことができたので,このページをご覧になっているみなさんならおそらく大丈夫でしょう.

今年(2022年)の夏にも開催するとのことなので興味がある方はいかがでしょうか.
私はTwitterでの募集を見て参加しましたが,公式サイトや逆求人サイトでの募集も活発に行っているそうです.

参加した後に気づいたのですが,私はTCP/IPスタックを自作するExpert Campについてのスライドを昨年見ており不思議なこともあるものだなと感じました.

1. Dev Container

lets you use a Docker container as a full-featured development environment. It allows you to open any folder inside (or mounted into) a container and take advantage of Visual Studio Code's full feature set.

Developing inside a Container

Dockerコンテナ内を開発環境として使うことができます.

これまでのDockerと共通の書き方でセットアップすることができるので多人数で同時に開発したいときに,ライブラリやインタプリタ・コンパイラのバージョン合わせをする手間が省けますね.

VSCode側はRemote Containerという拡張機能をインストールする必要があります.

Remote - Containers

2. 環境構築をVSCodeにやらせる

今回のインターンで使用した開発リポジトリにはルートディレクトリに.devcontainerディレクトリが配置されており,その内部は以下のような構成になっていました.

.
├─.devcontainer
│      devcontainer.json
│      docker-compose.yml
│      Dockerfile
│      postCreate.sh

最初に見るのはdevcontainer.jsonです.

{
    // 名前.適当に設定する.
	"name": "FastAPI tutorial",

	// docker-compose.ymlへのファイルパス..devcontainerの位置が基準だと理解した.
	"dockerComposeFile": "docker-compose.yml",
	// VS Codeが使用(接続)するdocker-compose.yml上に記載したサービスの名前.
	"service": "app",
	// コンテナ内のどこにプロジェクトファイルを配置するか設定する.
	"workspaceFolder": "/workspace",
    // コンテナを立ち上げたのちに実行するコマンドを実行する.
	"postCreateCommand": ".devcontainer/postCreate.sh",

	// コンテナ内のVSCodeプロジェクトの設定をする.settings.jsonに書くこととと同じ効果を発揮する.
	"settings": { 
		"python.pythonPath": "/usr/local/bin/python",
		"python.languageServer": "Pylance",
		"python.linting.enabled": true,
		"python.linting.flake8Enabled": true,
		"python.linting.pylintEnabled": false,
		"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8",
		"python.formatting.blackPath": "/usr/local/py-utils/bin/black",
		"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf",
		"python.linting.banditPath": "/usr/local/py-utils/bin/bandit",
		"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
		"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy",
		"python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle",
		"python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
		"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint",
		"python.terminal.activateEnvironment": true
	},

    // コンテナが作成されたあと,インストールされるVSCodeの拡張機能
	"extensions": [
		"ms-python.python",
		"ms-python.vscode-pylance",
		"MS-vsliveshare.vsliveshare-pack"
	],

    // コンテナ外部に引き出すポート番号を指定する
	"forwardPorts": [2222],

	// Use 'postCreateCommand' to run commands after the container is created.
	// "postCreateCommand": "pip3 install --user -r requirements.txt",

	// コンテナ内のユーザー名を指定する.
	"remoteUser": "vscode"
}

nameに設定した名前は以下の画像のように表示されます.

これはVSCodeがContainerを扱う上での設定を書いているファイルで,docker-composeとの連携や,開発するうえで必要な拡張機能を設定し自動でインストールさせることができます.
コンテナが立ち上がったあとに自動でスクリプトを実行することもできるのでPythonの場合はpipコマンドを発行したりvenvしたりすることもできるでしょう.
今回の講習で配布された環境ではここでvenvの立ち上げと必要なPythonライブラリのインストールを行っていました.

次にdocker-compose.ymlを見ていきます.

version: '3'

services:
  app:
    build:
      # docker-compose.ymlファイルの存在するディレクトリをカレントディレクトリに設定する.
      context: .
      dockerfile: Dockerfile

    volumes:
      #ホスト:コンテナ
      # .devcontainer.jsonでworkspaceFolderとして設定したディレクトリと同じものを設定する.
      # cachedをつけると読み込み性能が改善するが,ホスト側での変更が反映されるのに時間がかかるようになる.
      - ..:/workspace:cached

      # Uncomment the next line to use Docker from inside the container. See https://aka.ms/vscode-remote/samples/docker-from-docker-compose for details.
      # - /var/run/docker.sock:/var/run/docker.sock 

    # なにもプロセスを立ち上げてないときに勝手にコンテナがシャットダウン(タイムアウト)しないようにする.Dockerの仕様がよくわかっていないので詳しく理解していない.
    command: /bin/sh -c "while sleep 1000; do :; done"  

    # 指定したサービスコンテナと同じネットワークで起動する..devcontainer.jsonで指定したforwardPortsで指定したポートで通信する.
    network_mode: service:db
    
    # Use "forwardPorts" in **devcontainer.json** to forward an app port locally. 
    # (Adding the "ports" property to this file will not forward from a Codespace.)

    # Uncomment the next line to use a non-root user for all processes - See https://aka.ms/vscode-remote/containers/non-root for details.
    # user: vscode

    # Uncomment the next four lines if you will use a ptrace-based debugger like C++, Go, and Rust.
    # cap_add:
    #   - SYS_PTRACE
    # security_opt:
    #   - seccomp:unconfined
    
  # You can include other services not opened by VS Code as well
  db:
    image: mysql:latest
    environment:
      MYSQL_ROOT_PASSWORD: root_no_password
      MYSQL_DATABASE: webapp
      MYSQL_USER: webapp
      MYSQL_PASSWORD: webapp_no_password
      TZ: Asia/Tokyo
    command: --innodb_flush_log_at_trx_commit=2

ここではappという名前のサーバーサイドプログラムを実行するためのコンテナとdbという名前のMySQLを実行するためのコンテナの2つの設定を行っていることが分かりました.

appコンテナは独自のDockerfileを指定して起動させていますが,dbコンテナは既存のイメージを指定しています.

最後にDockerfileについて見て見ます.

~~中略~~
ARG VARIANT="3.10"
# 使用する既存イメージの選択
FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT}

# [Optional] Uncomment this section to install additional OS packages.
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
    && apt-get -y install --no-install-recommends bash-completion \
        default-libmysqlclient-dev default-mysql-client default-mysql-server \
        vim

ここではappコンテナ内で使う各種のライブラリ,コマンドのインストールを行っています.
DEBIAN_FRONTEND=noninteractiveというオプションを指定することで,インストール中の設定画面を入力待ちでブロックしなくなります.

3. venv周り

今回の配布されたリポジトリではコンテナ内でもPython標準のvenvでPython仮想環境を作成していました.
devcontainer.jsonのpostCreateCommandで設定されていたシェルスクリプトの中身がこちらとなっています.

#!/bin/bash

# venvでvenvという名前の仮想環境を作成する.
python -m venv --prompt . venv
# pipの更新インストール
venv/bin/pip install -U pip
# requirements.txt内に記載されているパッケージのインストール
venv/bin/pip install -r requirements.txt

#コンソールの色付け設定(未調査)
cp conf/.my.cnf conf/.dircolors ~/

venvの--prompt .はプロンプトの文字列を現在のフォルダ名にするためのコマンドです.こうすることで以下の画像のようになります.頭が(workspace)となっており,これは現在のディレクトリ名と同じですね.

なお,このスクリプトが実行し終わった後,VSCodeが勝手にvenv環境を認識してくれるというわけではなく,自分で画面下部からインタプリタの選択を行う必要があります.(VSCode再起動では直らなかったような気がする.)

まとめ

以上で今回参加したインターンで用いられていた環境構築法についての調査を終わります.
VSCodeとDocker,docker-composeさえ入れていればどこでも仮想環境を作れて開発できちゃうの強すぎますね.今後の研究生活でも取り入れたいと思います.

今回のインターンではCodespacesというgithubのサービスを使って,github上のサーバーでコンテナが実行されていて,それに手元のVSCodeで接続するというすごい環境でやらせていただきました.

ここまでくるとChromeBookとかiPad,ARM Windowsでプログラミングすることへのハードルがものすごい低くなると思いました.やっぱりコマンドライン一発で全部揃っちゃうのは強すぎる.

最後に,今回のインターンに参加するにあたってお世話になりましたメンターの方々,人事部のAさん,ありがとうございました.

Discussion