yasuです。
先日、ChromeBookやWindows PCに構築したJavaの開発環境で使うために、Proxmox VEのLXCコンテナにPostgreSQLをインストールしました。
どうせならChromeBookやWindows PCに構築したJavaの開発環境をLXCコンテナに作成して、iPadやChromeBookのブラウザからでも開発できるようにしてみようというのが今回のお話です。
目次(クリックで開閉)
LXCコンテナ テンプレートダウンロード
LXCコンテナのテンプレートをダウンロードします。
前回PostgreSQLの時はAlmaLinux10のテンプレートを使いましたが、今回はUbuntu 24.04のテンプレートを使います。
まずProxmoxの左メニューからノード(proxmox01)の下にあるディスク(本例ではnfs0)を選択して、右隣のメニューにある[CTテンプレート]を選択し、上部にある[テンプレート]ボタンをクリックします。

テンプレート一覧が表示されるので、[ubuntu-24.04-standard]を選択して、[ダウンロード]ボタンをクリックします。

テンプレートのダウンロードが終わったら、ダイアログ右上のバツボタンをクリックしてダイアログを閉じます。

LXCコンテナ作成
続いて右上にある[CTを作成]ボタンをクリックします。

LXCコンテナのノード、CT ID、ホスト名、パスワードを選択・入力します。
非特権コンテナとネストにチェックを付けて、[次へ]ボタンをクリックします。

(テンプレートが格納されている)ストレージと対象のテンプレートを選択して、[次へ]ボタンをクリックします。

LXCコンテナを作成するストレージとディスクサイズを選択・入力して、[次へ]ボタンをクリックします。

CPUコア数を設定して、[次へ]ボタンをクリックします。

メモリサイズとスワップサイズを入力して、[次へ]ボタンをクリックします。

ネットワーク名、ブリッジ、IPv4/CIDR、ゲートウェイ(IPv4)、IPv6を設定して、[次へ]ボタンをクリックします。

DNSドメイン名とDNSサーバーを入力して、[次へ]ボタンをクリックします。

[完了]ボタンをクリックします。

LXCコンテナが出来てダイアログ内に「TASK OK」が表示されたら、ダイアログ右上のバツボタンをクリックしてダイアログを閉じます。

Proxmox VEの左メニューに今作成したLXCコンテナを選択して、右隣のメニューの[オプション]を選択。
機能を選択して、[編集]ボタンをクリックします。

[keyctl]にチェックを付けて、[OK]ボタンをクリックします。

機能に「keyctl=1,nesting=1」と表示されていればOKです。

LXCコンテナを起動する前にLXCコンテナの設定ファイルに下記設定を追加します。
LXCコンテナを作成した側のサーバー(本例ではproxmox01.sa-sa-ki.jp)にSSHで接続します。
C:\Users\yasu>ssh root@proxmox01.sa-sa-ki.jp
root@proxmox01.sa-sa-ki.jp's password:
# vi /etc/pve/lxc/502.conf
arch: amd64
cores: 2
features: keyctl=1,nesting=1
hostname: javadev
memory: 2048
nameserver: 10.31.17.13 10.31.17.14
net0: name=eth0,bridge=vmbr0,firewall=1,gw=192.168.0.254,hwaddr=BC:24:11:BA:0D:03,ip=192.168.0.62/24,ip6=auto,type=veth
ostype: ubuntu
rootfs: nfs0:502/vm-502-disk-0.raw,size=10G
searchdomain: sa-sa-ki.jp
swap: 2048
unprivileged: 1
# 下記を追記
lxc.apparmor.profile: unconfined
lxc.cgroup2.devices.allow: a
lxc.cap.drop:
追加した設定の意味は以下のとおりです。
apparmor: unconfined
OS保護(AppArmor)の無効化
特権モードと同等。コンテナ内からホストの /sys や /proc への危険な操作が防げなくなります。
cgroup2.devices.allow: a
全てのデバイスへのアクセス許可
特権モードと同等。コンテナからホストの物理ディスクやデバイスに直接触れるようになります。
lxc.cap.drop:
権限(ケーパビリティ)の全保持
特権モードと同等。本来制限されるはずの「RAWソケット作成」や「マウント」が自由になります。
ほとんど特権コンテナ同等なのですが、コンテナ内の root (UID 0) は、ホスト側では 100000 などの一般ユーザーとして扱われるのが、特権コンテナと違うところです。
LXCコンテナにSSHで接続する
作成したLXCコンテナにSSHで接続できたほうが作業効率がいいので、設定を行います。
LXCコンテナのコンソールへrootユーザーでログインして、sedコマンドでrootユーザーがssh接続可能なようにsshdの設定ファルを変更してsshdを再起動します。

実際に打ち込んでいるコマンドは下記のとおりです。
javadev login: root
Password:
root@javadev:~# sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
root@javadev:~# systemctl restart sshd
開発に必要なアプリのインストール
ここからはLXCコンテナに開発に必要なアプリをインストール、設定していきます。
パッケージリストの更新
LXCコンテナのUbuntuのパッケージを最新化します。
# apt update && apt upgrade -y
パッケージ更新の途中で先程更新した/etc/ssh/sshd_configをどうするか確認があるので、ひとまず[keep the local version currently installed]を選択して[OK]をクリックします。

Java 21(OpenJDK)、Nginx、Podmanのインストール
# apt install -y curl git gnupg software-properties-common uidmap nginx openjdk-21-jdk podman podman-compose
code-server のインストール
# curl -fsSL https://code-server.dev/install.sh | sh
CloudBeaver のデプロイ (Podman)
# mkdir -p /opt/cloudbeaver
# cd /opt/cloudbeaver
# 設定ファイルの作成
# cat <<EOF > docker-compose.yml
services:
cloudbeaver:
image: dbeaver/cloudbeaver:latest
container_name: cloudbeaver
ports:
- "8978:8978"
volumes:
- ./cloudbeaver-data:/opt/cloudbeaver/workspace
EOF
# レジストリの設定を追加する
# vi /etc/containers/registries.conf
[registries.search]
registries = ['docker.io', 'quay.io']
# コンテナ起動
# podman-compose up -d
#コンテナ初回起動の途中どちらのイメージをダウンロードするか聞かれるので[docker.io]側を選択して[Enter]キー押下
? Please select an image:
▸ docker.io/dbeaver/cloudbeaver:latest
quay.io/dbeaver/cloudbeaver:latest
自己署名証明書(SSL)の作成
# sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/ssl/private/server.key -out /etc/ssl/certs/server.crt -subj "/C=JP/ST=Chiba/L=Ichikawa/O=Development/CN=$(hostname -I | awk '{print $1}')"
Nginxのリバースプロキシ設定
# vi /etc/nginx/sites-available/server
server {
listen 443 ssl;
server_name _;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400;
}
}
server {
listen 8443 ssl;
server_name _;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://192.168.0.62:8978/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400;
}
}
Nginxの設定有効化
# ln -s /etc/nginx/sites-available/server /etc/nginx/sites-enabled/
# rm -f /etc/nginx/sites-enabled/default
# nginx -t && systemctl restart nginx
code-serverのサービス化
# vi /etc/systemd/system/code-server.service
[Unit]
Description=code-server
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/root
ExecStart=/usr/bin/code-server --bind-addr 127.0.0.1:8080 --auth none
[Install]
WantedBy=multi-user.target
# 自動起動の有効化と開始
# systemctl daemon-reload
# systemctl enable --now code-server
cloudbeaver用podmanコンテナ自動起動の有効化
# vi /etc/containers/systemd/cloudbeaver.container
[Unit]
Description=cloudbeaver
[Container]
Image=docker.io/dbeaver/cloudbeaver:latest
PublishPort=192.168.0.62:8978:8978
Volume=/opt/cloudbeaver/cloudbeaver-data:/opt/cloudbeaver/workspace
[Install]
WantedBy=multi-user.target
# 自動起動の有効化と開始
# systemctl daemon-reload
# systemctl enable --now cloudbeaver
これでLXCコンテナにNginxをプロキシしてcode-serverとcloudbeaverにアクセスできるようになりました。
iPadからcode-serverとcloudbeaverにブラウザでアクセス
iPadのSafariからLXCコンテナに構築したcode-serverに接続します。
自己証明書なので警告が出ますが、[Webサイトを閲覧]を選択します。
まず最初にテーマ選択画面が表示されますが、無視して画面左の拡張機能(四角が4つ上下左右に並んでいるアイコン)をタップします。

EXTENSIONSの下のテキストボックスに「japanese」を入力して、日本語パックを検索します。

「Japanese Language Pack for Visual Studio Code」の[Install]ボタンをタップしたあと、[Trust Publisher & Install]ボタンをタップして、日本語パックをインストールします。

インストールが終わったら、画面上部のテキストボックスをタップして[Show and Run Commands >]を選択します。

[Configure Display Language]を選択します。

[日本語(ja)]を選択します。

Restart code-server to switch to 日本語?ダイアログが表示されたら、[Restart]ボタンをタップします。

これでcode-serverの日本語化は完了です。

続いてCloudBeaberにアクセスしてみます。
CloudBeaverはポート番号8443でアクセスします。
Welcome画面が出てくるので、画面上部の[NEXT]ボタンをタップします。

「ADMINISTRATOR CREDENTIALS」セクションにあるPasswordとRepeat Passwordを入力して、[NEXT]ボタンをタップします。

[FINISH]ボタンをタップします。

「ADMINISTRATOR CREDENTIALS」セクションで設定したアカウント情報を入力して、[LOGIN]ボタンをタップします。

ログインできたら左メニューの[Settings]をタップします。

[Interface]セクションの一番上にあるLanguageを「日本語」に変更して、[SAVE]をタップします。

右上の歯車ボタンの[Logout]をタップします。

再度、右上の歯車ボタンの[Login]をタップします。

「ADMINISTRATOR CREDENTIALS」セクションで設定したアカウント情報を入力して、[LOGIN]ボタンをタップします。

ログインできたら、[New Connection]をタップします。

[PostgreSQL]をタップします。

先日構築したLXCコンテナのPostgreSQLの接続情報を入力して、右上の[CREATE]ボタンをタップします。

左メニューに設定したPostgreSQLが表示されたら、「>」をタップします。

PostgreSQLに作成したDB用のアカウント情報を入力して、[LOGIN]ボタンをタップします。

データベース、管理者、システム情報が出てきたら無事接続できています。

ということで、code-serverとCloudBeaverは初期設定だけですがiPadのSafariから接続可能です。
code-serverには開発に必要な拡張機能を追加していけば、VSCodeで開発しているのとほとんど同じ感じで作業できると思いますし、DBはCloudBeaver経由で操作可能です。
iPad Pro 10.5とキーボードを購入した2017年当時にiPadでも開発できる環境を作りたかったのですが、当時はcode-serverとかCloudBeaverといった製品がまだなく諦めてしまっていましたが、ようやくiPadで開発できる環境が整いました。