Skip to content

Commit b1cc17e

Browse files
committed
Dev Containiers
1 parent 623cbf5 commit b1cc17e

3 files changed

Lines changed: 224 additions & 0 deletions

File tree

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
---
2+
title: "2026年2月版: Dev Containersでプチはまり(Node.js 24とPostgreSQL 18とプロキシ)"
3+
date: 2026/02/13 00:00:00
4+
postid: a
5+
tag:
6+
- Dev Containers
7+
- Node.js
8+
- PostgreSQL
9+
- プロキシ
10+
category:
11+
- Programming
12+
thumbnail: /images/2026/20260213a/thumbnail.png
13+
author: 澁川喜規
14+
lede: "Dev Containers便利ですよね?使っていますか?便利なのですが、久々に新しい環境を作ろうとしてちょっとはまったので解決のメモを書いておきます。"
15+
---
16+
Dev Containers便利ですよね?使っていますか?便利なのですが、久々に新しい環境を作ろうとしてちょっとはまったので解決のメモを書いておきます。書いておけばそのうち生成AIが拾って簡単に解決できるようになると思うので。
17+
18+
# Node.jsのイメージがおかしい
19+
20+
Node.js + PostgreSQLのベース設定をもとに環境を作ると、いきなり起動時に失敗します。Node.js 22であれば問題ないのですが、現在アクティブなサポートバージョンの24だとエラーになります。コンテナイメージのタグの命名規則が変わったようです。
21+
22+
ついでにdebianも最新のtrixieに変えましょう。
23+
24+
```diff Dockerfile
25+
- FROM mcr.microsoft.com/devcontainers/javascript-node:1-24-bookworm
26+
+ FROM mcr.microsoft.com/devcontainers/javascript-node:dev-24-trixie
27+
```
28+
29+
# 同一のWSLで複数のPostgreSQLを使うDev Containersを利用するとエラー
30+
31+
これ、わかりにくかったのですが、DBに依存しているアプリケーション開発環境の方が起動できない(参加したいネットワーク service.dbがない)という感じのエラーなのですが、よくよく見てみると、DBがエラーで再起動を続けています。
32+
33+
以前はPostgreSQL 17を使っていたのですが、今回18にしてみたら(docker-compose.ymlのタグを書き換えた)らエラーが発生しました。どうも17と18はデータの配置のルールが変わり、なおかつデータの置き場(ボリュームのマウントポイント)も`/var/lib/postgresql/data`から、`/var/lib/postgresql`に変わったようです。
34+
35+
```diff docker-compose.yml
36+
- version: 3.8
37+
service:
38+
:
39+
db:
40+
- image: postgres:17
41+
+ image: postgres:18
42+
restart: unless-stopped
43+
volumes:
44+
- - postgres-data:/var/lib/postgresql/data
45+
+ - postgres-data:/var/lib/postgresql
46+
environment:
47+
POSTGRES_PASSWORD: postgres
48+
POSTGRES_USER: postgres
49+
POSTGRES_DB: postgres
50+
```
51+
52+
# サービス名も重複しない名前にしておく
53+
54+
アプリ名がぶつかるのもよくないということを聞きましたので、そうなるとサービス名とかも変えておく方が良いですね
55+
56+
```diff
57+
services:
58+
- app:
59+
+ myproj-app:
60+
build:
61+
context: .
62+
dockerfile: Dockerfile
63+
- network_mode: service:db
64+
+ network_mode: service:myproj-db
65+
66+
- db:
67+
+ myproj-db:
68+
image: postgres:18
69+
restart: unless-stopped
70+
```
71+
72+
# プロキシ
73+
74+
プロキシ突破はコツがわからないと苦労しがちです。一般的なDockerのプロキシ設定であれば、以下の当ブログの記事で書かれたGUIの設定の内容で十分でしょう。
75+
76+
* [ProxyとDockerと新人社員と時々わたし](https://future-architect.github.io/articles/20201020/)
77+
78+
しかし、特にDockerをDev Containersで使う場合は、通常のイメージ作成で使う
79+
80+
* イメージ取得
81+
* ビルド時
82+
83+
に加えて、
84+
85+
* 通常ユーザーの実行時(npm installやgo get)
86+
* sudoの実行時(apt-get)
87+
88+
と4パターンの通信を扱う必要があり、それぞれ別に設定が必要だったりするためにさらにややこしいです。以前、[当ブログで紹介した記事](https://future-architect.github.io/articles/20231206a/#NG-%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7%E8%A8%AD%E5%AE%9A)ではあっさり紹介しましたが、今回、まっさらな環境からDev Containersを作るスクリプトを書いてみて、いろいろ試行錯誤したのでその知見も紹介します。
89+
90+
Dev Containersは、.devcontainer/devcontainer.jsonが設定の大本です。ここで開発環境のDockerfile、もしくは既成のイメージを選択します。PostgreSQLなどのDBも併用する場合はcompose.yamlを間に挟むこともあります。プロキシを通過する場合はさまざまなこれらの設定ファイルに記述していく必要があります。その相関関係を記したのが以下の図です。
91+
92+
<img src="/images/2026/20260213a/image.png" alt="image.png" width="484" height="488" loading="lazy">
93+
94+
以下の3つのレイヤーの設定について紹介していきます。
95+
96+
* ホスト環境(イメージ取得、ビルド時のapt-getなどの通信)
97+
* devcontainer.json(実行環境の通信)
98+
* Dockerfile(sudoの通信)
99+
100+
## ホスト環境(イメージ取得、ビルド時のapt-getなどの通信)
101+
102+
まず、Dockerが動くホスト環境でDockerのプロキシ設定および、環境変数を指定します。条件によって組み合わせが複雑なので要注意です。
103+
104+
| 環境 | イメージ取得 | ビルド内通信 | 環境変数 |
105+
|:-|:-:|:-:|:-:|
106+
| Windows版Dockerデスクトップ | (1) | (1) | (5) |
107+
| Linux単独 | (2) | (4) | (6) |
108+
| WSL2+Linux版Docker | (3) | (4) | (5) |
109+
110+
個々の設定が終わったあとの確認方法としては、これらを設定すれば、ホスト環境の中でdocker pullやcurlコマンドで外につなぎにいけるはずなので、Dev Containersの起動前に試してみましょう。また、Dockerfileの中の外部通信(apt-getなど)もいけるはず。
111+
112+
### (1): Dockerデスクトップのプロキシ設定
113+
114+
Dockerデスクトップの場合はGUIで設定ができます。これを設定することで、イメージ取得やビルド内の通信の両方でプロキシが取った状態で通信ができます。
115+
116+
### (2): Linuxのイメージ取得用の設定
117+
118+
Dockerコマンド自体はデーモンへのリクエストだけを行い、実際のビルドやイメージ取得はデーモンが行います。そのデーモンに対しては専用の設定ファイルがあります。
119+
120+
```toml /etc/systemd/system/docker.service.d/http-proxy.conf
121+
[Service]
122+
Environment="HTTP_PROXY=http://proxy.example.com:8080/"
123+
Environment="HTTPS_PROXY=http://proxy.example.com:8080/"
124+
Environment="NO_PROXY=localhost,127.0.0.1,docker-registry.somecorporation.com"
125+
```
126+
127+
修正したらデーモンを再起動します。
128+
129+
```shell
130+
sudo system docker restart
131+
```
132+
133+
### (3): WSL2+Linuxのイメージ取得の設定
134+
135+
WSL2の中でLinux版のDockerを使っている場合、現行のWSL2であればは自動でWindowsのプロキシを設定する機能(autoProxy)があります。Windows側設定が適切であればイメージ取得は通るようになります。裏のネットワークインタフェース側で解決してくれるようです。デフォルトでtrueになっていますが、明示的に書きたい場合は次のように設定します。
136+
137+
```toml $HOME/.wslconfig
138+
[wsl2]
139+
dnsTunneling=true
140+
autoProxy=true
141+
```
142+
143+
### (4): LinuxのDockerの設定
144+
145+
ビルド時にプロキシ情報の環境変数を渡す方法には、--build-argでコマンドで渡す方法と設定ファイルで渡す方法があります。VSCodeのDev Containersのビルドの中の触れない場所で呼ばれてオプションが追加できないため、ファイルで渡す方法しかないでしょう。
146+
147+
```json $HOME/.docker/config.json
148+
{
149+
"proxies": {
150+
"default": {
151+
"httpProxy": "http://proxy.example.com:8080",
152+
"httpsProxy": "http://proxy.example.com:8080",
153+
"noProxy": "*.test.com,localhost,127.0.0.1"
154+
}
155+
}
156+
}
157+
```
158+
159+
Dockerfile内で直接書いてしまう方法もありますが、ポータビリティも下がりますし、認証情報が入る可能性があるため、お勧めしません。
160+
161+
### (5): 環境変数の設定(WSL2の場合)
162+
163+
デスクトップ版はWSL2を使います。また、WSL2+Linux版の組み合わせでもWSL2になります。Dev Containerに渡すにはWSL2の中のLinuxの環境変数にプロキシ設定がある状態にしておく必要があります。
164+
165+
設定方法としては、2つあり、まずはWindowsの環境変数にhttp_proxy, https_proxy, no_proxyなどを設定するとともに、次の環境変数も一緒に設定する方法です。
166+
167+
`WSLENV="http_proxy/u:https_proxy/u:no_proxy/u"`
168+
169+
これらで指定した環境変数がWSL2の中にも取り込まれます。それ以外としては次のLinux単独の環境変数設定方法も使えます。
170+
171+
### (6): 環境変数の設定(Linuxの場合)
172+
173+
WSL2ではないLinuxの場合は、いつも通り、ユーザーの.profileとか.bashrcといったところに環境変数でプロキシ設定を書きます。
174+
175+
```shell .bashrc
176+
export http_proxy="http://proxy.example.com:8080"
177+
export https_proxy="http://proxy.example.com:8080"
178+
export no_proxy="localhost,127.0.0.1,host.docker.internal"
179+
```
180+
181+
## devcontainer.json(実行環境の通信)
182+
183+
devcontainer.jsonの中でホスト側の環境変数を実行時に展開してくれる機能があるのでこれを利用します。`docker run -e 環境変数=値`で渡すのと同じですが、元の変数も参照として書けるため、設定ファイルをプロジェクトで共有する場合にもハードコード不要で安全です。
184+
185+
```json
186+
{
187+
"remoteEnv": {
188+
"HTTPS_PROXY": "${localEnv:https_proxy}",
189+
"https_proxy": "${localEnv:https_proxy}",
190+
"HTTP_PROXY": "${localEnv:http_proxy}",
191+
"http_proxy": "${localEnv:http_proxy}",
192+
"NO_PROXY": "${localEnv:no_proxy}",
193+
"no_proxy": "${localEnv:no_proxy}"
194+
}
195+
}
196+
```
197+
198+
これで、`https_proxy`環境変数などを参照するnpmやgo getなどは正しく動きます。
199+
200+
なお、証明書のエラーが出る場合は証明書の検証をやめるオプションを定義して回避もできますが、可能であれば証明書を入れる方がましです。Dockerfileに以下の行を追加しましょう。
201+
202+
```Dockerfile Dockerfile
203+
COPY my-company-ca.crt /usr/local/share/ca-certificates/my-company-ca.crt
204+
```
205+
206+
## Dockerfile(sudoの通信)
207+
208+
これまでのところでほぼ問題ありませんが、開発環境の中でapt-getで追加のツールなどを入れようとするとエラーになります。devcontainer.jsonは、作業ユーザーの環境変数には設定してくれますが、sudo apt-getとすると、一時的に環境変数が設定されていない別ユーザーに代わってしまい、設定が見えなくなってしまうからです。
209+
210+
sudoしても必要な環境変数を引き継ぐような設定をDockerfileに足してあげることで、自由にapt-getできるようになります。
211+
212+
```Dockerfile Dockerfile
213+
RUN echo 'Defaults env_keep += "http_proxy https_proxy HTTP_PROXY HTTPS_PROXY no_proxy NO_PROXY"' >> /etc/sudoers
214+
```
215+
216+
## macOSの場合
217+
218+
macOSの場合はWSL2のレイヤーを意識する必要性がないのでシンプルです。Linux VMは確かにありますが、Windowsと違ってパフォーマンスのためにWSL2の中のファイルシステムに環境を作ってWSL2の中からVSCodeを起動するということがないからです。
219+
220+
Docker Desktop版を使うなら、そちらのプロキシ設定とmacOSの一般の環境変数にhttp_proxyなどを設定すればおしまいです。Linux VMの中にわざわざ作るのであれば同じように設定は必要になると思いますが。
221+
222+
# まとめ
223+
224+
Dev Containersは便利ですが、若さにあふれているというか、安定性よりも新しいものを、という気概を感じます。そこそこ小さい苦労があったので、メモ代わりに書いてみました。もし、ほかにもこんな問題もあったぞとかがあれば、Xなどでお知らせいただければと思います。
31.8 KB
Loading
49.6 KB
Loading

0 commit comments

Comments
 (0)