Fossil と SQLite が使える VS Code 開発コンテナーの用意 - Linux 使いになりたい人向け
はじめに
これは、「VS Code 開発コンテナーを使って Fossil 分散バージョン管理システムを試す - Linux 使いになりたい人向け」の続きです。
分散バージョン管理システム Fossil というものがあると知ったので、簡単に調べてみたのですが、そのときに使った VS Code 開発コンテナーについて、使いやすいものにしてみました。
Fossil をインストールして使ってみるにあたって、結局のところ node ユーザーを追加したり、Node.js 環境をインストールしたりしました。既存の VS Code 開発コンテナー用のイメージには、TypeScript が使えるものがあるので、ここではそちらを使う場合について説明します。
Fossil について調べてみると VS Code の拡張機能もあるようですし、SSH を使ったアクセスにも対応しているようです。git
コマンドに近いコマンド体系ですから、VS Code 開発コンテナー内で使えるようにしておくバージョン管理システムとして良いかもしれないと思い始めています。
この記事は VS Code と Docker が使える人で Linux 使いになりたい人向けの内容で書いてあり、対象者は次の人です。
- 分散バージョン管理システム Fossil に興味がある
- VS Code 開発コンテナーに興味がある
- Linux が使えるようになりたい
筆者は Linux 使いで、基本的に Linux 環境で動作確認をしています。ここで紹介しているようなちょっとしたことを少しずつ知ることを毎日続けることで Linux の機能を少しずつ理解することができるようになりました。Linux が使えるようになりたいと思っている人向けに、記事を公開していく予定です。
開発コンテナー devcon-fossil
前回と同様に、今回用意した VS Code 開発コンテナーは下記で公開しています。
ここでは、この devcon-fossil 開発コンテナーについて説明します。
動作に必要な環境 については次の通りです。
- Docker Engine
- Docker Compose Plugin
- VS Code
- Docker 拡張機能
- Dev Containers 拡張機能
次のように ZIP ファイルをダウンロードして展開し、カレントディレクトリーを ZIP ファイルを展開したディレクトリー内にある devcon-fossil
ディレクトリーとします。
curl -o dcfwd.zip -L https://codeload.github.com/hiro345g/dcfwd/zip/refs/heads/main
unzip dcfwd.zip
cd dcfwd-main/devcon-fossil
ここでは、以降、devcon-fossil ディレクトリー(フォルダ)を ${REPO_DIR}
と表記します。
ディレクトリー構造
devcon-fossil 用のディレクトリー構造は次のようになっています。
devcon-fossil/
├── .devcontainer/
│ ├── devcontainer.json
│ └── script/ ... devcon-fossil 開発コンテナー内で使えるスクリプト
│ ├── postCreateCommand-node.sh ... 開発コンテナー作成後に node ユーザーで実行するスクリプト
│ └── postCreateCommand.sh ... 開発コンテナー作成後に root ユーザーで実行するスクリプト
├── README.md ... このファイル
├── docker-compose.yml ... devcon-fossil 開発コンテナー用 Docker Compose 設定ファイル
└── script/ ... Docker ホストで使用するスクリプト
└── fossil-clean.sh
ここでは、dev-fossil 開発コンテナーのときよりも本格的に VS Code 開発コンテナーを使うために、.devcontainer/devcontainer.json
ファイルを用意しています。
VS Code の Dev Containers 拡張機能は、このファイルが置いてあるフォルダを開くと、開発コンテナーとして認識して通知を表示します。
開発コンテナーで再度開く
表示された通知にある「開発コンテナーで再度開く」をクリックすることで、devcon-fossil 開発コンテナーをアタッチした VS Code の画面を自動で開きます。
devcon-fossil 開発コンテナーをアタッチした VS Code の画面
devcontainer.json
devcontainer.json
は次のようにしてあります。
// https://github.com/devcontainers/
{
"name": "devcon-fossil",
"dockerComposeFile": "../docker-compose.yml",
"service": "devcon-fossil",
"postCreateCommand": "sudo sh /script/postCreateCommand.sh",
"shutdownAction": "stopCompose",
"customizations": {
"vscode": {
"settings": {
"sqltools.connections": [
{
"previewLimit": 50,
"driver": "SQLite",
"name": "proj001",
"database": "${workspaceFolder:repo}/proj001.fossil"
}
]
},
"extensions": [
"koog1000.fossil",
"mtxr.sqltools",
"mtxr.sqltools-driver-sqlite"
]
}
},
"remoteUser": "node", // "node" or "root",
"workspaceFolder": "/home/node/repo"
}
"dockerComposeFile":
で使用する docker-compose.yml
ファイルを指定します。また、開発コンテナーとして利用するサービスを "service":
で指定します。
開発コンテナーが用意できた後に実行するスクリプトを "postCreateCommand":
で指定し、開発コンテナーの初期化処理をしています。
"shutdownAction":
は開発コンテナーをアタッチした VS Code の画面を閉じた時の開発コンテナーの挙動を指定するものです。ここでは docker compose stop
コマンドを実行することに相当する "stopCompose"
を指定しました。
"customizations":
には、開発コンテナーをアタッチした VS Code をカスタマイズする設定を指定します。SQLTools を使うので、その設定をしてあります。また、使用する拡張機能を "extensions":
に指定しました。
"remoteUser":
は開発コンテナーをアタッチした VS Code で使用するユーザーを指定します。今回使用する開発コンテナー用のイメージは、これを省略すると node になります。そのため、指定しなくても良いのですが、設定ファイルを見れば使うユーザーがわかる方が便利なので明示的に指定しました。ここを root とすると、管理者で開発コンテナーを利用することになります。
"workspaceFolder":
は使用する docker-compose.yml
に合わせて指定してあります。
開発コンテナーを起動したときに、開発コンテナー内で .devcontainer
にあるファイルを編集できてしまうのはトラブルにつながりやすいのでやらないようにしています。また、バインドマウントしたファイルを操作するよりは、コンテナー内へコピーしてファイル操作した方がトラブルが少ないので、そういう方針にしています。
docker-compose.yml
docker-compose.yml
ファイルは次のようになります。https://github.com/devcontainers/images で公開されている開発コンテナー用の mcr.microsoft.com/devcontainers/typescript-node:20-bookworm
イメージを使っています。
name: devcon-fossil
services:
devcon-fossil:
image: mcr.microsoft.com/devcontainers/typescript-node:20-bookworm
container_name: devcon-fossil
hostname: devcon-fossil
init: true
tty: true
# node なら 1000:1000, root なら 0:0
user: 1000:1000
working_dir: /home/node/repo
volumes:
- repo-data:/home/node/repo
- type: bind
source: ${SCRIPT_DIR:-./.devcontainer/script}
target: /script
read_only: true
volumes:
repo-data:
name: devcon-fossil-home-node-repo-data
ここで使っている Docker イメージは、イメージ名からわかるように Node.js バージョン 20 の環境で TypeScript が使えます。また、Debian の bookworm をベースとしています。
作業で使用するボリュームは Docker ボリュームで用意して、初期化で使用するスクリプトはバインドマウントを使って devcon-fossil:/script
へマウントしています。
user:
と working_dir:
は devcontainers.json
と合わせたものを指定してあります。
devcon-fossil-home-node-repo-data ボリューム
この開発コンテナー用の docker-compose.yml
では、devcon-fossil-home-node-repo-data ボリュームを用意していて、devcon-fossil:/home/node/repo
を永続化しています。そのため、開発コンテナーを破棄しても、ここに作成したリポジトリは残ります。
postCreateCommand.sh
ここでは少し戻って、devcontainers.json
の "postCreateCommand": "sudo sh /script/postCreateCommand.sh",
の指定について説明します。
ここで使っている /script/postCreateCommand.sh
が利用可能なのは、docker-compose.yml
で ${REPO_DIR}/.devcontainer/script
を devcon-fossil:/script
へバインドマウントしているからです。
"postCreateCommand":
の指定されたコマンドは、開発コンテナーが作成された後に、node ユーザーで実行されます。
devcon-fossil 開発コンテナーでは、パッケージのインストールなど root 権限が必要なコマンドを初期化で実行したいので、sudo
を使って管理者権限を付与した状態でのコマンド実行としてあります。
postCreateCommand.sh
の具体的な内容は次のようになっています。
#!/bin/sh
apt update \
&& apt -y upgrade \
&& apt -y install fossil sqlite3 \
&& chown node:node /home/node/repo \
&& sudo -u node /usr/bin/sh /script/postCreateCommand-node.sh
最後に実行している postCreateCommand-node.sh
は node ユーザーで実行するコマンドです。別ファイルにした方が書きやすかったので別にしています。また、"postCreateCommand":
で指定するコマンドは長くしたくなかったので、postCreateCommand.sh
内で実行するようにしてあります。
このスクリプトは、SQLTools で使用する sqlite3 の npm パッケージをインストールする処理を実行し、初期状態の Fossil のリポジトリ proj001.fossil を用意します。具体的な内容は次のようになります。
#!/bin/sh
REPO_FILE=/home/node/repo/proj001.fossil
if [ -e ${HOME}/.local/share/vscode-sqltools/ ]; then
cd ${HOME}/.local/share/vscode-sqltools/
npm install sqlite3@5.1.1
fi
if [ ! -e ${REPO_FILE} ]; then
fossil new ${REPO_FILE}
fi
VS Code 開発コンテナー devcon-fossil の利用
ファイルが用意できたら、VS Code 開発コンテナー devcon-fossil を起動します。手順は次の通りです。
- VS Code の「ファイル」-「フォルダーを開く」で
${REPO_DIR}
を開く - 右下に表示される通知で「開発コンテナーで再度開く」をクリック
- 左下に
開発コンテナー:devcon-fossil
と表示された開発コンテナーが開く
これ以降、開発コンテナーの VS Code は devcon-fossil の VS Code
と表記します。
サンプルリポジトリ
devcon-fossil の VS Code では、すでに説明したように、開発コンテナー起動時に、/home/node/repo/proj001.fossil
というサンプルリポジトリのファイルを自動で作成するようにしてあります。そのため、devcon-fossil の VS Code のエクスプローラーにサンプルリポジトリ proj001.fossil
が表示されているはずです。
devcon-fossil の VS Code のエクスプローラー画面
ターミナルを起動して、/home/node/repo
をカレントディレクトリーとすれば fossil
コマンドを使って proj001.fossil
リポジトリを利用できます。
なお、devcon-fossil の VS Code では Fossil の拡張機能 koog1000.fossil
が最初から使えるようになっています。これを使って Fossil のリポジトリを使うこともできます。
Fossil の拡張機能を使ってみよう
ここでは、Fossil の拡張機能を使ってみましょう。Fossil の拡張機能は VS Code のソース管理の画面を表示すると使えます。少しわかりにくいですが、サイドバーの画面上部に表示されます。なお、サンプルリポジトリは、ここでは使いません。SQLTools の機能を使うときに利用します。
メニューにはリポジトリをクローンするための Clone と、リポジトリから作業用ディレクトリを作成するための Open のメニューが用意されています。
Fossil の拡張機能で Clone と Open が可能
また、Fossil のアイコンをクリックすると、「Initialize Fossil Repository」のメニューが表示されます。これを使うことで Fossil のリポジトリファイルを作成できます。
Fossil の拡張機能でリポジトリの作成が可能
リポジトリの作成
それではリポジトリを作成してみましょう。Fossil のアイコンをクリックしてから「Initialize Fossil Repository」をクリックすると、作成するリポジトリファイル名を指定する入力欄が表示されます。ここでは /home/node/repo/repo.fossil
と指定します。
作成するリポジトリファイル名の指定
「OK」をクリックすると、プロジェクト名を入力する欄が表示されます。ここでは repo
とします。
プロジェクト名の指定
「OK」をクリックすると、プロジェクトの説明を入力する欄が表示されます。ここでは repo プロジェクト
とします。
プロジェクトの説明の指定
「OK」をクリックすると、/home/node/repo/repo.fossil
というリポジトリのファイルが作成されます。通知にリポジトリをオープンするためのボタンが表示されます。ここでは、このリポジトリのファイルを直接使うことはしないので、そのままにしておきます。
リポジトリのクローン
Fossil は分散バージョン管理システムとして使えるので、リポジトリのクローンを作成することができます。普通は HTTPS や SSH といったネットワーク・プロトコル経由でリモートにあるリポジトリをクローンするときに使うのですが、ここでは機能の確認なので、同じローカルにあるファイルシステムのリポジトリをリモートにあるものと見立てて使ってみます。
単純にファイルコピーをすれば良いと思うかもしれませんが、クローンをした場合は、クローンにより作成されたローカルのリポジトリには、リモートのリポジトリの情報を持つようになります。そのため、単純にファイルコピーで別ファイルを作成した場合とはリポジトリに含まれる情報が変わります。
さて、リポジトリのクローンをするには URL を指定します。ファイルの場合は次のようになります。
file://<絶対パス>
ここでクローンするファイルは /home/node/repo/repo.fossil
なので、URL は file:///home/node/repo/repo.fossil
となります。
devcon-fossil の VS Code のソース管理の画面で Fossil のメニューを表示して、Clone Fossil Repository
をクリックします。
Fossil の拡張機能で Clone (図では Open が反転しているが、Clone の方をクリックすること)
すると、クローンする URL を入力する画面になるので、file:///home/node/repo/repo.fossil
を指定して「OK」をクリックします。
クローンする URL の指定
次に、ローカルに作成するリポジトリファイル名を入力する画面になるので、/home/node/repo/repo-clone.fossil
を指定して「OK」をクリックします。
ローカルに作成するリポジトリファイル名の指定
これでリモートリポジトリから、ローカルのリポジトリをクローンできます。ここまでのリポジトリ作成とクローンでローカルリポジトリ作成を見てわかるように、Fossil ではリポジトリは1つのファイルになっています。
バージョン管理の情報はこのファイルに全部含まれるので、このファイルを複数のマシンで管理しておけば、分散バージョン管理ができるようになります。
このファイルの実体は SQLite という組み込み型リレーショナル・データベースの DB ファイルなので、後で中身を少し調べてみます。
作業用ディレクトリーの用意
さて、リポジトリファイルはバージョン管理をしたいファイルとは別のものです。バージョン管理対象としたいファイルを置くためのディレクトリーは作業用ディレクトリーとして別途用意する必要があります。ここでは、作業用に repo-clone
ディレクトリーを用意することにします。
devcon-fossil の VS Code のエクスプローラーの画面で用意するなら、「新しいフォルダー」のアイコンをクリックすると用意されるエクスプローラー内の入力欄でrepo-clone
と指定して Enter キーを入力します。すると、/home/node/repo/repo-clone
フォルダーが作成されます。
/home/node/repo/repo-clone
フォルダーの作成
ターミナルで作成することもできます。その場合は mkdir
コマンドを使います。
mkdir /home/node/repo/repo-clone
作業用ディレクトリーの用意が出来たら devcon-fossil の VS Code のソース管理の画面で Fossil のメニューを表示して、Open Fossil Repository
をクリックします。
Fossil の拡張機能で Open
すると、リポジトリーファイルのパスを入力する画面が表示されるので、そこへローカルのリポジトリーファイルである /home/node/repo/repo-clone.fossil
を指定して「OK」をクリックします。
repo-clone.fossil
リポジトリーファイルの指定
今度は、作業用ディレクトリーのパスを入力する画面が表示されるので、用意した /home/node/repo/repo-clone
を指定して「OK」をクリックします。
作業用ディレクトリー /home/node/repo/repo-clone
の指定
これで devcon-fossil の VS Code のソース管理画面で Fossil リポジトリを開いた状態になります。見た目としては Git のリポジトリ作成を促す画面が消えているはずです。
Fossil リポジトリを開いた直後の VS Code のソース管理画面
なお、ソース管理画面でサイドバーの中のメニューを開くと、Fossil 用のものが表示されていることがわかります。また、画面下にブランチ情報に trunk
が表示されます。
ソース管理画面でサイドバーの中の Fossil 用メニュー
devcon-fossil の VS Code 画面でエクスプローラーをサイドバーに表示すると、/home/node/repo/repo-clone/
には .fslckout
という特別なファイルが作成されいます。このことから、Fossil のリポジトリの内容を作業用ディレクトリーへ取り出せたことがわかります。といっても、まだバージョン管理をする対象ファイルがないので、他にはファイルがなくて空の状態です。
Fossil リポジトリを開いた後の VS Code 画面でエクスプローラー画面
バージョン管理をするファイルの追加方法については、ここでは省略して、次にリポジトリファイルの方を調べてみます。
SQLTools
fossil のリポジトリファイルの実体は SQLite の DB です。VS Code では、SQLite の DB を参照するには、SQLTools という拡張機能が使えます。この devcon-fossil 開発コンテナーでは最初から使えるようになっています。
初期状態のリポジトリファイル
devcon-fossil の VS Code の画面でアクティビティーバーにある SQLTools のアイコンをクリックすると、サイドバーに SQLTools の画面が表示されます。proj001
という接続設定名で proj001.fossil
を SQLite の DB ファイルとして接続できる設定がすでにされているので、それが表示されるはずです。
ここで、proj001.fossil
は、fossil
コマンドで作成した初期状態のリポジトリファイルです。これを DB として開いて中を見てみましょう。proj001
のコンセントのアイコンをクリックすると、DB 接続ができます。それをクリックして proj001.fossil に接続すると、テーブルやビューの情報を確認することができます。
VS Code の SQLTools の画面
DB 接続をするとわかりますが、proj001.fossil
にはリポジトリの情報を保存するためのテーブルが複数あります。その中に user
テーブルがあるので、確認してみます。
SQLTools の画面でテーブル一覧を展開して user
を表示し、それをマウス右クリックするとメニューが表示されます。その中にある Show Table Records
をクリックすると、user
テーブルのレコードが VS Code の画面に表示されて確認できます。
user テーブルのレコード表示
接続を閉じるには、マウスポインタを重ねると Disconnect
と表示されるアイコンをクリックします。
接続を閉じる
DB 接続をすると用意される proj001.session.sql
には、実行したい SQL 文を記述して、ファイルの上部にある再生ボタン(▶)をクリックすると実行できます。
例えば、user
テーブルの uid
と login
カラムを抽出する SELECT
文を実行してみましょう。
SELECT uid, login FROM user;
これを proj001.session.sql
に保存して実行すると次のような画面になります。
proj001.session.sql の利用
このファイルは残しておけば次に DB 接続するときにも使えます。
クローンしたリポジトリファイル
クローンしたリポジトリファイルについても調べてみましょう。新規に接続情報を作成するには SQLTools の画面でマウスを重ねるとAdd New Connection
と表示されるアイコンをクリックします。すると、Connection Assistant
の画面が表示されます。
Connection Assistant
の画面
画面内にある SQLite(Node)
をクリックすると SQLite の DB 接続設定用の画面になります。
ここでは、repo-clone
という接続名で repo-clone.fossil
リポジトリファイルへ接続する指定をします。ファイルは SELECT FILE
で選択しようとしたところ開発コンテナー内のパスが表示されなかったので、手入力で /home/node/repo/repo-clone.fossil
を指定しました。
入力できたら TEST CONNECTION
をクリックするとテスト接続がされます。これが成功すると Successfully connected!
というメッセージが画面に表示されます。
DB 接続の情報を指定し、接続テストが成功したときの画面
DB 接続が成功したら、SAVE CONNECTION
をクリックして接続情報を保存します。すると、DB 接続情報の保存画面になります。
DB 接続情報の保存画面
この情報は、VS Code の setting.json
に保存されます。devcon-fossil の VS Code のエクスプローラーの画面から .vscode/setting.json
を開いて確認することができます。
.vscode/setting.json
の確認
ここでは、元から用意されていた proj001
の接続情報も追加されています。proj001
の接続情報については、.devcontainer/devcontainer.json
で指定されていたものが自動で追加されたということになります。.vscode/setting.json
が開いたフォルダーにあると、そちらが優先されますし、SQLTools の画面で接続情報を更新すると、このファイルに反映されるので、このままにしておきます。
さて、repo-clone.fossil
については、config
テーブルを確認してみましょう。repo-clone.sessin.sql
ファイルに次の SQL 文を保存して実行してみます。
SELECT name, value FROM config
WHERE name in (
'project-name',
'project-description',
'last-sync-url',
'ckout:/home/node/repo/repo-clone/'
);
実行結果は次のようになります。リモートリポジトリの情報と、クローンして作成されたファイルの情報が含まれていることがわかります。
config
テーブルの確認
こういった実装情報は知らなくても良いのですが、こうやって確認ができると実際の動作についても推測できることが増えます。ということで個人的にはこうやって興味があって、わかる範囲で調べてみています。
おわりに
devcon-fossil 開発コンテナーを使うと fossil
コマンドを実行したり、リポジトリの実体である SQLite DB ファイルを調べたりすることができるようになります。また、Fossil 用の VS Code の拡張機能についても、使い勝手を確認することが簡単にできます。
終了するときは、devcon-fossil の VS Code 画面を閉じます。次回使うときは、最初に devcon-fossil の VS Code 画面を開いた時と同じようにします。
開発コンテナーを破棄するには、devcon-fossil の VS Code 画面を閉じた後に、Docker ホストの VS Code の画面で Docker 拡張機能の画面にして、CONTAINERS
にある devcon-fossil をマウス右ボタンでクリックします。それから、メニューに表示される Compose Down
をクリックすると、開発コンテナーが破棄されます。
devcon-fossil 開発コンテナーのクリーニング
devcon-fossil 開発コンテナーのクリーニングをするには、次のように Docker ホストで fossil-clean.sh
スクリプトを実行します。シェルスクリプトが実行できない OS を Docker ホストで使っている場合は、相当する処理を手作業で実行してください。基本的にスクリプト内にある docker
コマンドの部分を実行すれば大丈夫です。なお、クリーニングしても良い状態にしてから、実行するようにしてください。
cd ${REPO_DIR}
sh script/fossil-clean.sh
このスクリプトは、devcon-fossil 開発コンテナーが使っていた Docker ボリュームと Docker ネットワークといったリソースについて、完全に破棄します。実行すると、開発コンテナーを破棄してから、Docker ボリュームと Docker ネットワークも破棄します。
Discussion