📝

QNAP(QTS)でVS Codeを使いファイル編集する

2024/07/10に公開

とりあえず結果の概要

Docker上でUbuntuを動かしその中でSSHdとVS Codeサーバーを動かしマウントしたVolume上のファイルを編集する。

やりたいこと

QNAPを持っているが、この上でDockerが動くのでちょっとした私家アプリケーションを動かしたい。しかしQNAPのエントリーモデル用OSであるQTSはLinuxであるもののBusyboxベースなので、コマンドオプションが異なっていたり、最小限のコマンドしか入っていないのでなかなか使いにくい(一応viは入っている)。

VS CodeでリモートからQNAPにアクセスしファイル編集でたら良いのになぁ…。

とりあえず動かない理由

VS Code Serverのインストーラーがgrepを使っているが、GNU grepを前提としており、busyboxのgrepはオプションが異なるため、まずそこで引っ掛かる。もし仮にgrepをGNU版に入れ替え、そこは通ったとしてもその先で使用するコマンドオプションやら必要とするライブラリーで苦労するはず。

なお、私の持っているQNAPはTS-231でArm32アークテクチャ。VS Codeは Arm32にも対応しているので、deb系, rpm系なら動くはず…。

Container Station上で動かす

ということでQNAPのアプリケーションContainer Station = Docker EngineでUbuntuを動かし、その上でVS Code Server動かすこととした。

事前条件

  • QNAPにSSH接続するための設定はこちら
  • コマンドラインでDockerを使うための話はこちら
  • SSH公開鍵認証の話はこちら

上記が揃ったところで、

Dockerfile

VS Codeを動かすために必要なもの

SSH Remoteで接続するのでopenssh-serverlibatomic1はVS Codeが必要とするライブラリー、sudoは後述するファイルのパーミッションを合わせるためrootでないユーザーで動かすためsudosshdを起動するため。

RUN apt-get update && apt-get install -y --no-install-recommends \
    openssh-server \
    libatomic1 \
    sudo

SSHdの設定

こちらを参考に

https://docs.docker.jp/engine/examples/running_ssh_service.html

RUN mkdir /var/run/sshd

# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

開発ツール

VS Codeでファイル編集してもそのファイルをgitで管理したりコピーしたりしたい。なので基本的なコマンドはインストールしておく。

# Development tools
RUN apt-get install -y --no-install-recommends \
    git \
    curl \
    vim-tiny \
    less \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

VS Code実行ユーザー

コンテナーをrootユーザーで動かすと、ホストOSのユーザーとUID/GIDがマッチせず、root権限のファイルがホストOS上に作成されてしまう。このため一般ユーザーを作ってそちらに切り替える。UID=500はQNAPで最初に作成したユーザーのUIDになる。基本的におうちサーバーを想定しているので、管理者=最初のユーザーがVS Codeを使うことになるだろう、家族は501,502,…になる。だから、まあ、500ってことで。そうじゃない場合はUIDを変更。

それとユーザーを切り替えて動かすのでsshdが実行できなくなるためsudoを使いたいがパスワードを要求されないようにsudoersに入れておく。

あとはsshの設定を入れるディレクトリーだけ作成しておく。

# Host/container user mapping
ARG USERNAME=vscode     # FIXME
ARG UID=500             # FIXME
ARG GID=100             # FIXME

RUN useradd -m -s /bin/bash -u $UID -g $GID $USERNAME
RUN echo '%users ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/vscode

USER $USERNAME

RUN mkdir /home/$USERNAME/.ssh
RUN chmod 700 /home/$USERNAME/.ssh

SSHd実行

ポート22を公開しsudo経由でsshdをデーモンモードで実行。上記の通りsudoers設定にてパスワードは要求されない。

# SSH daemon
EXPOSE 22
CMD ["sudo", "/usr/sbin/sshd", "-D"]

Dockerfileまとめ

まとめるとこちら、

https://github.com/hkato/qnap-vscode-container/blob/main/Dockerfile

Composeファイル

docker runコマンドで実行しても良いがオプションが長くなるのでcompose.yamlを設定しdocker composeで実行する。

  • user: にてホストOSと同じユーザーで実行(ファイル権限を合わせるため)
  • port: にてSSHdのポートを2022にマッピングして公開
  • volumes:
    • Workspacesを作業用・共有ヴォリュームとした。
    • authorized_keysはQNAP上に置いといてマウント、パスワードなしでログインするためホストOS側の公開鍵を入れておく
    • 秘密鍵はgit+sshでGitサーバーにアクセスしファイル管理したいため
    • .gitconfigはGitの設定
services:
  vscode:
    build: .
    restart: always
    user: 500:100     # FIXME
    ports:
      - 2022:22
    volumes:
      - $HOME/Workspaces:/home/vscode/Workspaces:rw
      - $HOME/.ssh/authorized_keys:/home/vscode/.ssh/authorized_keys:ro
      - $HOME/.ssh/id_ed25519:/home/vscode/.ssh/id_ed25519:ro
      - $HOME/.gitconfig:/home/vscode/.gitconfig:ro

これでdocker compose build && docker compose up -dしておく。

ローカルホスト側設定

ポート2022と固定ユーザーvscodeでログインしたいので.ssh/configに次のエントリーを設定しておく。

Host vscode-on-qnap                # as you like
    HostName my-qnap-host.local    # QNAP local hostname
    User vscode
    Port 2022
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null

HostNameはQNAP本体のホスト名あるいはIPアドレス。Hostは好きな名前で。StrictHostKeyCheckingUserKnownHostsFileはコンテナーをビルドするたびにSSHホスト鍵が変わってしまうのでその回避(あまり良くない)。

接続

あとはVS Codeのリモートエクスプローラーから上記の設定だとvscode-on-qnapに接続すれば、いつも通りにVS Code Serverのインストールが始まり、フォルダー選択とワークスペースが開き、ファイルの編集ができるようになる。

Discussion