devcontainer

Dev Container

所有环境构建均在官方标准之上进行构建

文档参考

官网

模板列表

构建说明

  1. 基于官方基础镜像, 替换源和时区, 并指定代理 HTTP_PROXY/HTTPS_PROXY
  2. 安装 chezmoi 来同步环境设置
  3. chezmoi 需要先创建 dotfiles 仓库及该仓库的只读 PAT, PAT 同时也作为密码来解密用 aes-128-cbc 加密的 gpg 密钥文件
  4. 初始化 chezmoi 时会 clone dotfiles 仓库需要走代理, 而 git 并不会使用 HTTP_PROXYHTTPS_PROXY, 需要手动指定
  5. 首次应用 chezmoi 时会先用 PAT 解密并导入 gpg 的密钥文件, 然后再使用 gpg 来解密 ssh 的公钥和私钥
  6. 使用 ssh 来 clone 仓库, 如果还需要走代理, 则在第 2 步中安装 ncat
1
2
3
4
5
6
# 加密 gpg 密钥文件
openssl enc -aes-128-cbc -pbkdf2 -in ~/.gpg/SECRET.asc -out ~/.gpg/SECRET.asc.enc -pass env:GITHUB_PAT
openssl enc -aes-128-cbc -pbkdf2 -in ~/.gpg/public.asc -out ~/.gpg/public.asc.enc -pass env:GITHUB_PAT
# 解密 gpg 密钥文件
openssl aes-128-cbc -d -pbkdf2 -in ~/.gpg/SECRET.asc.enc -out ~/.gpg/SECRET.asc -pass env:GITHUB_PAT
openssl aes-128-cbc -d -pbkdf2 -in ~/.gpg/public.asc.enc -out ~/.gpg/public.asc -pass env:GITHUB_PAT

环境变量

  • GITHUB_USERNAME: GitHub 的用户名, 用于拉取 dotfiles 仓库
  • GITHUB_PAT: GitHub dotfiles 仓库的 PAT, 用于拉取 dotfiles 仓库及后续解密并导入 gpg 密钥文件
  • HTTP_PROXY/HTTPS_PROXY: 代理, 用于安装和更新 chezmoi
  • TZ=Asia/Shanghai: 上海时区
  • DEBIAN_FRONTEND=noninteractive: 避免交互式提示

构建命令

  1. 修改 APT 源为阿里云并更新
  2. 安装 chezmoi, ncat(可选, 用于 ssh 走代理)
  3. 切换到 vscode 用户并初始化 dotfiles 仓库

后续的软件安装及环境配置均由 dotfiles 中的脚本完成

构建步骤(以 Java 为例)

Dockerfile

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
FROM mcr.microsoft.com/devcontainers/java:8-bookworm
LABEL authors="Simple"
ARG GITHUB_USERNAME
ARG GITHUB_PAT
ENV GITHUB_USERNAME=${GITHUB_USERNAME} GITHUB_PAT=${GITHUB_PAT}
ENV HTTP_PROXY=socks5://host.docker.internal:1080 HTTPS_PROXY=socks5://host.docker.internal:1080
ENV DEBIAN_FRONTEND=noninteractive TZ=Asia/Shanghai

RUN sed -i -e 's@deb.debian.org@mirrors.aliyun.com@;s@http:@https:@' /etc/apt/sources.list.d/debian.sources && \
    apt-get update > /dev/null && apt-get upgrade -y > /dev/null && \
    apt-get install -y ncat > /dev/null && \
    sh -c "$(curl -fsLS get.chezmoi.io)"
USER vscode
RUN git config --global http.https://github.com.proxy $HTTP_PROXY && \
    chezmoi init https://$GITHUB_USERNAME:$GITHUB_PAT@github.com/$GITHUB_USERNAME/dotfiles.git
ENTRYPOINT ["bash"]

如果基础镜像不支持通过环境变量 TZ 来修改时区, 则可以在更新软件包后安装 tzdata 来修改时区

1
apt-get install -y tzdata > /dev/null && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

devcontainer.json

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{
  "name": "thesixonenine/dev-java:8-bookworm",
  "build": {
    "dockerfile": "Dockerfile",
    "args": {
        "GITHUB_USERNAME": "thesixonenine", 
        "GITHUB_PAT": "${localEnv:GITHUB_PAT}"
    }
  },
  "customizations": { "vscode": { "settings": {
        "extensions.allowed": {
            "microsoft": false,
            "github": false
        }
  }}}
}

Build

需要在 GitHub 上申请 PAT, 权限只勾选 dotfiles 仓库的读取权限即可

提前构建

使用 Dev Container CLI 构建镜像

1
npm install -g @devcontainers/cli --registry=https://registry.npmmirror.com

将以上 Dockerfiledevcontainer.json 置于当前目录下的 .devcontainer 目录中, 配置环境变量 GITHUB_PAT 后在当前目录下执行

1
devcontainer build --no-cache --workspace-folder . --image-name thesixonenine/dev-java:8-bookworm

直接构建

直接根据 Dockerfile 进行构建

1
docker build --no-cache --build-arg GITHUB_USERNAME=thesixonenine --build-arg GITHUB_PAT=github_pat_* -t thesixonenine/dev-java:8-bookworm .
1
2
3
docker run --rm -it --user vscode thesixonenine/dev-java:8-bookworm
# update
cd && chezmoi update

构建其他语言的镜像基本相同, 只需要替换基础镜像名称和构建的镜像名称即可.

使用构建

  1. 打开 VSCode 并用 Ctrl + Shift + p 打开命令面板
  2. 输入 Dev Containers: Clone Repository in Named Container Volume... 并选中
  3. 输入仓库地址, 例如: git@github.com:thesixonenine/dotfiles.git
  4. 选择新建命名的卷并输入名称, 与仓库名称相同即可
  5. Enter 确认使用默认的目录名称, 即与仓库名称相同

此时开始构建, 构建过程中需要从指定镜像开始, 例如 /tmp/vsch-simple/bootstrap-image/0.427.0/bootstrap.Dockerfile

在该 Dockerfile 中涉及 alpine 的镜像及软件安装, 可以先关闭 VSCode, 然后在 WSL2 中编辑该文件, 增加镜像源

修改前的 Dockerfile 内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
FROM mcr.microsoft.com/devcontainers/base:0-alpine-3.20

COPY host-ca-certificates.crt /tmp/host-ca-certificates.crt
RUN cat /tmp/host-ca-certificates.crt >> /etc/ssl/certs/ca-certificates.crt
RUN csplit -f /usr/local/share/ca-certificates/host-ca-certificate- -b '%02d.pem' -z -s /tmp/host-ca-certificates.crt '/-----BEGIN CERTIFICATE-----/' '{*}'
ENV NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt

# Avoiding OpenSSH >8.8 for compatibility for now: https://github.com/microsoft/vscode-remote-release/issues/7482
RUN echo "@old https://dl-cdn.alpinelinux.org/alpine/v3.15/main" >> /etc/apk/repositories

RUN apk add --no-cache \
        git-lfs \
        nodejs \
        python3 \
        npm \
        make \
        g++ \
        docker-cli \
        docker-cli-buildx \
        docker-cli-compose \
        openssh-client-default@old \
        ;

RUN npm config set cafile /etc/ssl/certs/ca-certificates.crt && cd && npm i node-pty || echo "Continuing without node-pty."

COPY .vscode-remote-containers /root/.vscode-remote-containers

修改后的 Dockerfile 内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
FROM mcr.microsoft.com/devcontainers/base:0-alpine-3.20

COPY host-ca-certificates.crt /tmp/host-ca-certificates.crt
RUN cat /tmp/host-ca-certificates.crt >> /etc/ssl/certs/ca-certificates.crt
RUN csplit -f /usr/local/share/ca-certificates/host-ca-certificate- -b '%02d.pem' -z -s /tmp/host-ca-certificates.crt '/-----BEGIN CERTIFICATE-----/' '{*}'
ENV NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt

# Avoiding OpenSSH >8.8 for compatibility for now: https://github.com/microsoft/vscode-remote-release/issues/7482
RUN echo "@old https://dl-cdn.alpinelinux.org/alpine/v3.15/main" >> /etc/apk/repositories
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk add --no-cache \
        git-lfs \
        nodejs \
        python3 \
        npm \
        make \
        g++ \
        docker-cli \
        docker-cli-buildx \
        docker-cli-compose \
        openssh-client-default@old \
        ;
RUN npm config set registry https://registry.npmmirror.com
RUN npm config set cafile /etc/ssl/certs/ca-certificates.crt && cd && npm i node-pty || echo "Continuing without node-pty."

COPY .vscode-remote-containers /root/.vscode-remote-containers

修改点如下:

指定 apk 镜像源

1
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories

指定 npm 镜像源

1
RUN npm config set registry https://registry.npmmirror.com

另外, 还可以预先拉取该 Dockerfile 中的基础镜像 mcr.microsoft.com/devcontainers/base:0-alpine-3.20

镜像源替换

debian

1
sudo sed -i -e 's@deb.debian.org@mirrors.aliyun.com@;s@http:@https:@' /etc/apt/sources.list.d/debian.sources

ubuntu

1
sudo sed -i 's@//.*archive.ubuntu.com@//mirrors.aliyun.com@g' /etc/apt/sources.list.d/ubuntu.sources

alpine

1
sudo sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories

npm

1
npm config set registry https://registry.npmmirror.com

MySQL Client

Dockerfile

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
FROM alpine:latest
LABEL authors="Simple"
ENV TZ=Asia/Shanghai
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
    apk add --no-cache tzdata mysql-client && \
    cp /usr/share/zoneinfo/${TZ} /etc/localtime && \
    echo "${TZ}" > /etc/timezone && \
    apk del tzdata && \
    echo -e "[client]\nskip-ssl" > /etc/my.cnf

WORKDIR /work
ENTRYPOINT ["mariadb"]

Build

1
docker build -t mysql-client:latest .

Run SQL

指定 host port user password database 及要执行的 SQL

1
docker run --rm mysql-client --host= --port= --user= --password= --database= -B -e "show tables;"
Licensed under CC BY-NC-SA 4.0
最后更新于 2025-10-15
使用 Hugo 构建
主题 StackJimmy 设计