古いLinuxのDocker containerにVSCodeのDev Containersで接続する

# はじめに

2025/3にリリースされた v1.99 以降の VSCode では、v2.28 以降の glibc が必要になったため、Ubuntu 20.04 などの古い Linux にリモート接続できなくなりました。このため、古い Linux の Docker container に Dev Containers で接続することもできなくなりました。その対処方法を以下で紹介します。

# 対処方法

基本的には以下のサイトに書いてある通りなのですが、色々と面倒なので一括で準備できる Docker image を作ります。

https://code.visualstudio.com/docs/remote/faq#_can-i-run-vs-code-server-on-older-linux-distributions

https://hep.techwp.net/2025/04/16/remote-ssh-to-old-linux-servers-with-latest-vscode/

```Dockerfile
FROM ubuntu:latest AS builder

RUN apt update \
 && apt install -y \
      gcc g++ gperf bison flex texinfo help2man make libncurses5-dev \
      python3-dev autoconf automake libtool libtool-bin gawk wget bzip2 xz-utils unzip \
      patch rsync meson ninja-build \
 && apt clean \
 && rm -rf /var/lib/apt/lists/*

# Install crosstool-ng
RUN wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.26.0.tar.bz2 \
 && tar -xjf crosstool-ng-1.26.0.tar.bz2 && rm crosstool-ng-1.26.0.tar.bz2

WORKDIR /crosstool-ng-1.26.0
RUN  ./configure --prefix=/crosstool-ng-1.26.0/out && make && make install

ENV PATH=$PATH:/crosstool-ng-1.26.0/out/bin

# Build libc2.28
WORKDIR /toolchain-dir
RUN wget https://raw.githubusercontent.com/microsoft/vscode-linux-build-agent/refs/heads/main/x86_64-gcc-8.5.0-glibc-2.28.config -O .config \
  && echo "CT_EXPERIMENTAL=y" >> .config \
  && echo "CT_ALLOW_BUILD_AS_ROOT=y" >> .config \
  && echo "CT_ALLOW_BUILD_AS_ROOT_SURE=y" >> .config \
  && ct-ng build

### 1. 必要に応じて CT_JOBS を設定
### 2. ct-ng build 時に isl などのダウンロードに失敗する場合は、
###    /toolchain-dir/downloads
###    に、そのファイルを別途ダウンロードして置いておく
### 3. "x86_64"の部分は必要に応じて変更

# Get patchelf
RUN wget https://github.com/NixOS/patchelf/releases/download/0.18.0/patchelf-0.18.0-x86_64.tar.gz \
 && tar -xzf patchelf-0.18.0-x86_64.tar.gz && rm patchelf-0.18.0-x86_64.tar.gz

# Copy only the necessary files
FROM ubuntu:latest
WORKDIR /vscode_glibc
COPY --from=builder /toolchain-dir/x86_64-linux-gnu/x86_64-linux-gnu/sysroot ./sysroot
COPY --from=builder /toolchain-dir/bin/patchelf .
```

上記 `Dockerfile` を使い、以下のコマンドを実行して、必要なファイルが揃った Docker volume を作成します。volume が作成されたら build 用の Docker image は不要なので、削除しても構いません。

```sh
#!/bin/sh
docker build -t vscode_glibc .
docker run --rm -v vscode_glibc:/vscode_glibc vscode_glibc
```

これで準備完了です。後は環境変数を設定して、動かしたい Docker image を起動するだけです。この方法ならば、Dev Containers で接続する時だけこの volume をマウントすれば良いので、元の Docker image に手を加えずに済みます。

```sh
docker run \
  -v vscode_glibc:/vscode_glibc \
  -e VSCODE_SERVER_CUSTOM_GLIBC_LINKER=/vscode_glibc/sysroot/lib/ld-2.28.so \
  -e VSCODE_SERVER_CUSTOM_GLIBC_PATH=/vscode_glibc/sysroot/lib \
  -e VSCODE_SERVER_PATCHELF_PATH=/vscode_glibc/patchelf \
  OTHER_OPTIONS IMAGE_NAME COMMAND
```

# 参考情報

<https://code.visualstudio.com/docs/remote/faq#_can-i-run-vs-code-server-on-older-linux-distributions>
<https://hep.techwp.net/2025/04/16/remote-ssh-to-old-linux-servers-with-latest-vscode/>
<https://github.com/crosstool-ng/crosstool-ng/issues/1625>

# 余談

苦労して最新の VSCode で接続できるようにしたのは、少し古いPyTorchを使うソフトのデバッグをしたかったからなのですが…

![error](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791334/cd1dcb28-0ca9-4df6-ad3f-b1056ddb9c93.png)

大人しく古いVSCodeを Portable mode で使えば良かったのか？