LoginSignup
3
6

devcontainerを使った自分のPython開発環境

Posted at

:hatching_chick: はじめに

Qiita初記事として自分のPython開発環境の備忘録を書いていきます! 1.

前まではコードエディターとしてVSCode、仮想環境構築にAnacondaを使っていたんですが、Dockerの勉強を兼ねてdevcontainerを使った開発環境構築を試みました。
その間に調べたことをまとめていきます!

少しでも参考になる箇所があればうれしいです!!

:thumbsup: 本記事の要点

:no_good: 本記事では扱わない内容

  • VSCodeのインストール
  • DockerやWSLのインストール
  • Remote-containerの追加
  • devcontainerの起動
  • DockerやDocker Composeの説明や仕組み

:whale2: devcontainerの(自分なり)ベストプラクティス

ディレクトリ構造

.
├─ .devcontainer
|  ├─ compose.yaml
|  └─ devcontainer.json
├─ Dockerfile
├─ requirements.txt
└─ ... (使うスクリプトなどを置く)

構成ファイル

compose.yaml
version: '3'

services:
    app:
        command: sleep infinity
        build:
            context: ../
            dockerfile: Dockerfile
        volumes:
            - ../:/workspace
devcotainer.json
{
    "dockerComposeFile": ["compose.yaml"],
    "service": "app",
	"workspaceFolder": "/workspace",
	"extensions": [
        "coenraads.bracket-pair-colorizer",
        "dongli.python-preview",
		"esbenp.prettier-vscode",
		"ionutvmi.path-autocomplete",
		"kevinrose.vsc-python-indent",
		"mechatroner.rainbow-csv",
		"mhutchie.git-graph",
		"mosapride.zenkaku",
		"ms-python.python",
		"oderwat.indent-rainbow",
		"shardulm94.trailing-spaces",
		"streetsidesoftware.code-spell-checker"
	]
}
Dockerfile
FROM ubuntu:22.04

ENV TZ=Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

RUN apt-get update && apt-get install -y \
    python3.10\
    python3-pip\

RUN echo -n '\n\
    alias python="python3"\n\
    alias pip="pip3"\n\
    \n\
    ' >> /root/.bashrc

COPY ./requierments.txt /tmp/

RUN python3 -m pip install -r /tmp/requierments.txt

WORKDIR /workspace/
requirements.txt
numpy
opencv-python
pandas

:notepad_spiral: 構成ファイルの詳細解説メモ

compose.yaml

services

1つのコンテナを1つのserviceとして記述する
今回の場合はappと命名

複数のコンテナを定義し実行することができる(そのために使われることが多いが今回は1つ)

Remote-containerで開くためには、devcontainer.jsonのserviceで指定したservice(今回の場合app)にcommand: sleep infinityを入れる必要がある 2.

docker-compose.ymlではcontextで上位ディレクトリを参照可能
.devcontainer下に置いて親ディレクトリにあるDockerfileを参照させた 3.

build

contextで指定したパスにあるdockerfileで指定したDockerfileをビルドする

volumes

マウントするファイルやディレクトリを指定する。

マウントしたファイル、ディレクトリがコンテナ内で受けた編集はホストの同ファイル、ディレクトリにも反映される

コンテナ内で作成したファイルに関して 4.

  • Linux版Dockerの場合
    オーナーがroot(UID=0)となりホスト側からはsudoをつけないと編集できない
  • Docker Desktop for Macの場合
    コンテ内ではUID=0、ホスト側ではmacOS側のUIDとなるためそのまま編集可能

後述のDockerfileのADD, COPYのみで追加されたファイル等への編集はホストの同ファイルに反映されない

🛤️脱線メモ compose.yamlとdocker-compose.ymlの違い

Docker Compose V2がリリースされて以降compose.yamlが推奨

--fileオプションを指定せずにdocker compose upを実行したときに作業ディレクトリにあるcompose.yamlが読み込まれる
後方互換を維持するためdocker-compose.ymlもサポートされてはいる 5.

🛤️脱線メモ VolumesとBind mounts

Dockerコンテナで扱うデータを永続化する方法には、Volumes(ボリューム)とBind mounts(バインドマウント)がある 6.

違いはDockerによって管理されるか否か → Volumes: 管理される Bind mounts: 管理されない

Volumesには、Named volume(名前付きボリューム)とAnonymous volume(匿名ボリューム)がある

Anonymous volumeは、volumeの名前を指定しなかった場合にユニークなハッシュ値が割り振られる

Docker公式ではVolumesの使用を推奨 7.

何のためのvolumeかがわかるようにNamed volumeの使用を推奨 8.

今回のベストプラクティスではBind mountsを使用している

将来的にgithubで開発環境とプロジェクトのソースコードを共有、管理したいため
(本番環境を用意した開発までは想定していない)

ただ、上記想定においてもNamed volumeを使える方法があれば変更したい! 【情報求む】

devcotainer.json

dockerComposeFile

使用するcompose.yamlのパスを指定する

service

compose.yamlで作成したservicesのうちdevcontainerので使用するserviceを指定する

workspaceFolder

devcontainer起動時に開かれるパスを指定する

extensions

使用したいVSCodeの拡張機能を追加する

入れたい拡張機能を検索、該当のものを右クリックしCopy Extension Idを選択し、devcotainer.jsonextensionsにカンマ区切りで追記する

おすすめの拡張機能は下記サイト等を参照

Dockerfile

FROM

ベース・イメージを指定する

  • ubuntuを使うのが良いそう

よく使われるalpineは軽量のOSのため、vim入っていない、互換性、速度が遅くなる等の問題がある 9.

ENV TZ=Asia/Tokyo

タイムゾーンを指定する

ベース・イメージにubuntuを選択するとDocker build中にタイムゾーンの設定でハングアップするエラーを回避するため設定が必要 10.

RUN

コマンドを実行する

python3.10pip3をインストールする

RUN apt-get update && apt-get install -y \
    python3.10\
    python3-pip\

コマンドでpythonと打った際にpython3を、pipと打った際にpip3実行するように設定する

RUN echo -n '\n\
    alias python="python3"\n\
    alias pip="pip3"\n\
    \n\
    ' >> /root/.bashrc

requierments.txtに書かれたライブラリをインストールする

RUN python -m pip install -r /tmp/requierments.txt

ADD, COPY

ホスト(ローカル)環境のファイルをコンテナ環境内に追加する

ADDとCOPYの違いは? 11.

  • リモートからのファイル追加ができるか否か → ADD: できる COPY: できない
  • 圧縮ファイルが自動解凍されるか否か    → ADD: される COPY: されない

Imageサイズとセキュリティの観点からCOPYが良いそう 12.

Docker Desktop for Macは、ADD, COPY時に上位ディレクトリを参照する相対パス..../を消してしまうので注意 13.

WORKDIR

Docker runでコンテナを立ち上げた際に開かれるパスを指定するが、devcontainer起動時はdevcontainer.jsonworkspaceFolderで指定したパスのどちらが優先されるかは不明

🛤️脱線メモ aptとapt-getの違い

aptはapt-getの持っていた設計上のミスを克服している
→Ubuntuではatpの使用を推奨 14.

コマンドラインで打つときはaptを使うが、スクリプトで使うときは下位互換性を保ってapt-getやapt-cacheを使うことを推奨
→Dockerfileではapt-getの使用を推奨 15.

apt-getのオプション-y問い合わせがあった場合はすべて「y」と答える 16.

🛤️脱線メモ pipとpip3の違い

pipはPython2, Python3で使用可能、pip3はPython3でのみ使用可能
→Python3環境へのパッケージインストールであれば明示的にpip3コマンドを利用することを推奨 17.

requirements.txt

pip installでインストールしたいライブラリを書く

バージョン指定も可能 18.

Mac環境ではDockerfileで上位ディレクトリを参照できないため、
requierments.txtはDockerfileと同じ階層に置く必要がある 13.

:checkered_flag: さいごに

ここまでお読みいただきありがとうございます。
本記事では、devcontainerを使ったPython開発環境の自分なりベストプラクティスを紹介させていただきました。

初めて記事を書いてみて改めて実感したのは、様々な記事を書かれてきた方々の偉大さとありがたさです!

少しでもその感謝をお返ししたい気持ちを込め、『引用・参考文献』には参照したサイトはもちろんのこと、作者さまの他の記事を参照できるホーム画面へのリンクも掲載させていただきました。
番号は本記事内の参考箇所へのリンク、記事タイトルは参照したサイトへのリンク、@以降は作者さまのハンドルネームで作者さまの他の記事を参照できるホーム画面へのリンクを埋め込んでいます。

本記事の内容をより詳しくみられたい方は参考記事を、新しい発見をされたい方は参考作者さまの他の記事を見に行ってみてください!

さいごに、本記事の単語や表現に誤用があればコメントいただけると嬉しいです!
そういうの気になる人種なんでw

:pray: 引用・参考文献

1. Markdown記法 チートシート @Qiita
2. Docker Compose な開発環境にちょい足し3分で作るVSCode devcontainer @saboyutaka
3. Dockerで上位の階層をCOPYしたい時はビルドコンテキストの設定を変更する @ましろ
4. DockerのUID/GIDあれこれ: Linux版通常モード & Docker Desktop for Mac編 @yuyakato
5. Docker Compose V2で変わったdocker-compose.ymlの書き方 @kagamirror
6. Docker の Volume がよくわからないから調べた @aki_55p
7. Good use cases for volumes @Docker
8. dockerコンテナのデータを永続化する方法 @RAKUS Developers Blog | ラクス エンジニアブログ
9. 完璧なPython Dockerfileを作る(前半) @gavin.zhou
10. Docker Buildでタイムゾーン設定で固まる @量子プログラミング入門→量子コンピューティングサービス構築入門
11. Dockerfile の ADD と COPY の違いを結論から書く @YumaInaura
12. DockerfileにてなぜADDよりCOPYが望ましいのか @momotaro98
13. Docker Desktop for Mac は相対パス指定を消している @Takenobu Endo (遠藤 武宣)
14. apt と apt-get の違い @rs-techdev
15. Dockerfileを書いていて【apt】と【apt-get】【apt-cache】の使い分けに悩んだ話 @ぴーや!
16. 【 apt-get 】 パッケージを取得してインストール/アップデートする @日経XTECH
17. pipとpip3の違いを調べた @AoyaHashizu
18. Python, pipでrequirements.txtを使ってパッケージ一括インストール @note.nkmk.me

3
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
6