VScodeでコンテナを使った開発について(自分用メモ)

最近、Djangoの開発環境を整えようとしていて、Visual Stuido Code(以降 VScode)の設定で躓いたのでそのメモを自分の為に残したものです。解決法が見つかったらこのメモは修正します~

対象と環境

対象

  • Ubuntu22.04にVScodeをインストールしてDockerを用いて開発したいが、VScodeのDev Containerのextentionを使ってコンテナの操作をしつつ開発したいがコンテナが見えなくて困っている人
  • pythonについてはこちらここを参考にしてください

環境

  • OSはUbuntu22.04
  • DockerでPostgreSQLとDjangoをdocker-composeを使って立ち上げる
  • VScodeをUbuntuにインストール
  • VScodeのextentionにRemote Developmentをインストール
  • Remote Developmentで一緒にインストールされるRemote SSHでローカルにログインできるようUbuntuでsshdを起動する
  • Dockerを一般アカウント(sakana)で実行できるようにする
  • Djangoのアプリを構築する
  • DjangoをPostgreSQLに接続させる(今回のサンプルアプリでは使わない)
  • 仕上がりのツリー
  • 本記事では、$HOMEは /home/sakana とします。ご自身の環境に読み替えてください
$HOME/work/django_pj
|-- .devcontainer
|   |-- Dockerfile
|   |-- devcontainer.json
|   `-- docker-compose.yml
|-- data/db
|      略
|-- db.sqlite3
|-- django_pj
|   |-- __init__.py
|   |-- __pycache__
|   |   |-- __init__.cpython-310.pyc
|   |   `-- settings.cpython-310.pyc
|   |-- asgi.py
|   |-- settings.py
|   |-- urls.py
|   `-- wsgi.py
|-- manage.py
|-- singlepage
|   |-- __init__.py
|   |-- admin.py
|   |-- apps.py
|   |-- migrations
|   |   `-- __init__.py
|   |-- models.py
|   |-- templates
|   |   `-- index.html
|   |-- tests.py
|   |-- urls.py
|   `-- views.py
|
`-- venv

設定

Ubuntuの設定

VScode(とchrome)のインストール

snapでVScodeと、ついでにchromiumもついでにインストールしておく。

$ sudo snap install code
$ sudo snap install chromium

sshdの設定

ローカルホスト以外の端末からもsshdでログインできるようにしておく。

$ sudo apt install openssh-server
$ sudo vi /etc/ssh/sshd_config
$ diff /etc/ssh/sshd_config /etc/ssh/sshd_config.org
16c16
< ListenAddress 0.0.0.0
---
> #ListenAddress 0.0.0.0

dockerを一般アカウントで実行できるようにする設定

dockerグループに一般アカウント(sakana)を登録することで実行できるようにします。またdockerを一般アカウントで操作した際にpermissionのエラーが出る場合はsocketのパーミションが足りていないかも。

$ grep docker /etc/group 
$ sudo groupadd docker     無ければグループを作る

$ sudo usermod -aG docker sakana
$ grep docker /etc/group
$ groups sakana | grep docker
sakana : sakana  docker
$ id
uid=1000(sakana) gid=1000(sakana) groups=1000(sakana),略,1002(docker)
$ newgrp docker
$ id
uid=1000(sakana) gid=1002(docker) groups=1002(docker),略,1000(sakana)
$ ls -l /var/run/docker.sock
srw-rw---- 1 root docker 0  3 25 10:53 /var/run/docker.sock

djangoの環境構築

プロジェクトの作成

ひとまず、djangoのプロジェクトとアプリの作成。

$ mkdir -p /home/sanaka/work/
$ cd /home/sanaka/work/

$ pip install virtualenv
$ python3 -m venv ./venv
$ source ./venv/bin/activate
(venv)$ pip install django psycopg2-binary

(venv)$ django-admin startproject django_pj
(venv)$ cd $HOME/work/django_pj/
(venv)$ python manage.py startapp singlepage

アプリケーションの設定

以下のサイトの設定をする。以下サイトのmysiteを今回の設定のdjango_pjに読み替えて設定してください。

https://www.pythonstacks.com/blog/post/create-single-page-application

Docker環境構築

djangoアプリのDockerイメージを作成する。

$ mkdir $HOME/work/django_pj/.devcontainer
$ cd $HOME/work/django_pj/.devcontainer
$ vi Dockerfile
---
FROM python:3.10-alpine
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERD=1
WORKDIR /code
ADD ../ /code
RUN pip install django psycopg2-binary
COPY ../ /code/
---

$ docker build . -t django_pj-web:latest
$ docker images | grep django_pj-web
django_pj-web   latest    ce6c763a1748   3 weeks ago     191MB

alpineを使ったpythonのコンテナにdjangoと、今回はPostgreSQLと接続させる設定をする予定なのでpsycopg2のモジュールをインストールしたイメージを作成する。

docker-composeの作成

postgresqlと一緒に起動するように設定する。djangoのプロジェクト配下を/codeとしてマウントして起動させる。

$ cd $HOME/work/django_pj/.devcontainer
$ vi docker-compose.yml
---
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ../data/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=django
      - POSTGRES_USER=django
      - POSTGRES_PASSWORD=django
  web:
    image: django_pj-web
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - ../:/code:cached
    ports:
      - "8000:8000"
    environment:
      - POSTGRES_NAME=django
      - POSTGRES_USER=django
      - POSTGRES_PASSWORD=django
    depends_on:
      - db
---

Dev Container用の設定

VScodeのDev Containerのextentionでコンテナを扱えるように設定ファイルを設置

$ cd $HOME/work/django_pj/.devcontainer
$ vi devcontainer.json
---
{
        "name": "django_pj",
        "service": "web",
        "dockerComposeFile": ["docker-compose.yml"],
        "workspaceFolder": "/code",
        "forwardPorts": [8000]
}
---

serviceは、docker-compose.ymlのserviceの名前を指定する。dockerComposeFileはdocker-compose.ymlのファイルの位置を指定する。配列にして複数のymlファイルを順に検索させることが出来る。workspaceFolderはDockerファイルで指定したWORKDIRでdocker-compose.ymlでdjango_pj以下をマウントさせている。

sshの設定

Dockerのextentionでローカルのコンテナが見えない…この問題が解決できず、今回の苦肉の策を取ったわけです…(誰か助けてw)

で、Remote SSHのextentionで自分自身のホストにsshすることでdockerコンテナの操作が出来るようになったので以下の設定をしていきます。

パス無しログインの為の設定

リモートログインするのですが、接続が必要な都度パスワードの入力をするのは面倒なのでパスワード無しログインをしたいわけです。

で、そのためには、接続元でssh-keygenをパスワード無しで作成して出来た公開鍵(ex. id_rsa.pub)を接続先のauthorized_keysに登録して接続時に秘密鍵(ex. id_rsa)を指定することで実現できます。

$ cd ~/.ssh/
$ ssh-keygen -t rsa -b 4096
  ※パスワードを問われたらエンターキーのみを押す
$ cat id_rsa.pub >> authorized_keys
$ ssh -i ./id_rsa sakana@127.0.0.1 ls

VScodeから接続するために使う設定

Remote SSHのextentionのデフォルトでは、$HOME/.ssh/configが使われるようなので以下の通り設定を作成する。Hostの値は識別用で、HostNameの値が接続に使われる。

$ vi ~/.ssh/config
---
Host 127.0.0.1
  HostName 127.0.0.1
  User sakana
  IdentityFile $HOME/.ssh/id_rsa
---

VScodeでのリモート接続

Remote DevelopmentのExtentionをインストールすると、VScodeのIDEの左下角に、「><」といった記号があるのでそれをクリックすることでリモートホストに接続できるようになる。

  • 「><」をクリックする
  • 「Connect To Host…」を選択する
  • 「127.0.0.1」を選択する (/home/sakana/.ssh/config のHostで指定された文字列)