cover

使用 Container Station 在 Qnap NAS 上部署 VSCode

本文介绍了如何在 Qnap NAS 上使用 Container Station 部署网页版的 VSCode。

2023-12-19

为了能在 iPad 上使用 VSCode 完成一些简单的编程任务,打算在威联通 Qnap 的 NAS 上部署 VSCode 编辑器服务,对这个在线服务的基本要有:

  1. 能够直接编辑 NAS 上文件;
  2. 能够使用 Qnap Container Station 应用的容器实例;
  3. 能够进行 Python、Node.js 及 Rust 应用开发。

在网上进行检索之后发现两种部署方案:

  1. 使用
    linuxserver/code-server
    部署基于浏览器的 VScode 服务;
  2. 使用
    linuxserver/vscodium
    部署基于浏览器的 VSCode 服务;

是一个开源的项目,使用
code-server
可以在浏览器中访问
VSCode
编辑器。它提供了一个基于 Web 的集成开发环境(IDE),使开发者能够通过浏览器远程访问和使用
VSCode
的功能,而无需在本地安装
VSCode

code-server
的工作原理是在服务器上运行一个
VSCode
实例,然后通过
WebSocket
VSCode
的用户界面传输到客户端浏览器中。

是一个开源版本的
VSCode
。与
VSCode
相比,其主要区别在于
VSCodium
不包含 Microsoft 的 Logo、构建标识和 Telemetry 数据收集相关的代码。

heading

vscodium
code-server
的对比

在体验时使用的均为 LinuxServer 提供的镜像,两者之间的体验差异如下:

差异/镜像
linuxserver/vscodium
linuxserver/code-server
基础镜像体积2.41G570MB
客户端Web 浏览器Web 浏览器
流畅程度卡顿感明显与桌面版无异
界面显示默认配置锯齿明显,需要调整缩放(iPad 上看还算正常)正常
中文显示需要手动安装中文字体可正常显示
中文输入无法使用快捷键切换可正常切换
插件无限制无法使用桌面版应用的插件(如
Dev Containers
Docker in Docker支持,需要手动配置支持,需要手动配置
是否账号支持同步不支持不支持

从流畅程度上看

linuxserver/code-server
的体验时明显优于
linuxserver/vscodium
linuxserver/vscodium
是基于 KasmVNC 将桌面端应用转换为 Web 应用,因此其基础镜像相比
code-server
会大上不少,而且在使用时需要传输的数据量也更多。
linuxserver/code-server
是原生的 Web 应用,在渲染的时候不会像
linuxserver/vscodium
一样需要传输那么多的数据量,使用的流畅度基本和在本机上使用
VSCode
没有什么区别。

在显示上,

linuxserver/vscodium
的分辨率如果和本机不同,则锯齿会非常明显。并且
linuxserver/vscodium
默认情况下不支持中文的显示,需要在基础镜像的基础上安装中文字体包并进行相应的调整。因为
linuxserver/code-server
是 Web 应用,所以显示效果完全取决于本机,并不需要额外的配置。

但是两者在中文输入上都有不好的地方。

linuxserver/vscodium
可以使用本机的输入法,但是必须通过左侧的控制栏进行设置,在体验的时候并没有发现能够通过快捷键进行调整的方法。而
linuxserver/code-server
的问题在于 vim 插件无法在 normal mode 时自动切换到英文输入法,如果在本机上使用的话可以通过配置 im-select 解决这个问题,但是作为 Web 应用似乎没有很好的解决办法。

从对插件的支持程度上来看,

linuxserver/vscodium
linuxserver/code-server
具备更好的普适性。由于
linuxserver/vscodium
其实就是一个桌面版的 VSCode 应用,因此只要基础镜像操作系统中安装了必备的依赖,那么基本上所有的插件都可以使用。由于
linuxserver/code-server
是 Web 应用,并非所有的插件都能够安装(比如 Dev Containers)。

两者都不能使用 VSCode 自带的同步服务,但是如果在 NAS 上使用的话,这一项功能的有无其实并不重要。

heading

部署 code-server 服务

在对比

linuxserver/vscodium
linuserver/code-server
后,从个人的角度上看
linuxserver/code-server
更能满足我的需求。下面对
linuxserver/code-server
进行一些调整以使其更符合个人的使用场景。

heading

配置 Docker in Docker

为了启用 Docker in Docker,需要在容器启动时将 Container Station 的

docker.socker
文件映射到容器内,并且在容器内安装
docker-cli
使用宿主机 docker 服务。

要注意的是,

linuxserver/code-server
中使用的默认账户是
abc
,该账户无法直接使用
docker.sock
文件,而 VSCode 中的 Docker 插件要求 rootless docker,因此需要将用户
abc
添加到
root
用户组中。

调整后的 Dockerfile 如下:

# 引入基础镜像 FROM lscr.io/linuxserver/code-server:latest # 更换 apt 源 RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list && \ apt update -y && apt upgrade -y # 安装 docker cli RUN apt install -y ca-certificates curl gnupg && \ install -m 0755 -d /etc/apt/keyrings && \ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg && \ chmod a+r /etc/apt/keyrings/docker.gpg && \ echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null && \ apt update -y && \ apt install -y docker-ce-cli docker-buildx-plugin docker-compose-plugin # 将 abc 用户添加到 root 用户组 RUN usermod -aG root abc
coder.Dockerfile
heading

配置 Python 开发环境

基础镜像中已经安装了 Python3.10,因此不再重复安装,如果有多版本的需求,可以通过安装 Pyenv 实现。

# 安装 pip、pipx 和 poetry RUN apt install -y python3-pip pipx && \ pipx install poetry
coder.Dokerfile
heading

配置 Node.js 开发环境

安装 Node.js@20 以及 yarn,如果有多版本的需求,可以通过安装 nvm 实现。

# 安装 nodejs@20 ENV NODE_MAJOR=20 RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \ echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list && \ apt -y update && \ apt install nodejs -y && \ npm install --global yarn
coder.Dockerfile
heading

配置 Rust 开发环境

直接通过 rustup 配置 Rust 开发环境,在 Dockerfile 中需要添加

-y
参数以使用默认配置直接安装。

# 安装 Rust 和依赖 RUN apt install -y libssl-dev pkg-config RUN curl --proto '=https' --tlsv1.3 https://sh.rustup.rs -sSf | sh -s -- -y
heading

使用 docker-compose 启动服务

完成镜像的配置后,在 NAS 上使用下面的指令创建镜像:

docker build . -f coder.Dockerfile -t local/coder:latest

在 docker-compose 文件中添加如下配置:

version: "3.9" services: code-server: image: local/coder:latest container_name: code-server extra_hosts: - "host.docker.internal:host-gateway" # 将主机地址映射到容器内 secrets: - hashed_password # 应用密码(使用 argon2-cli 生成) - hashed_sudo_password # 系统 sudo 密码(使用 argon2-cli 生成) environment: - DEFAULT_WORKSPACE=/workspace # 启动目录 - FILE__HASHED_PASSWORD=/run/secrets/hashed_password # 使用 secret 文件指定应用密码 - FILE__SUDO_PASSWORD_HASH=/run/secrets/hashed_sudo_password # 使用 secret 文件制定系统 sudo 密码 - PROXY_DOMAIN=coder.example.com # 代理域名 - PGID=100 # 用户组 id(使用 `id` 指令查看,应当和 NAS 用户一致,否则可能会出现文件权限的问题) - PUID=1000 # 用户 id(使用 `id` 指令查看,应当和 NAS 用户一致,否则可能会出现文件权限的问题) - TZ=Asia/Shanghai # 时区 volumes: - /path/to/WORKSPACE:/workspace # 工作区目录 - /path/to/coder/config:/config # code-server 配置目录 - /var/run/docker.sock:/var/run/docker.sock # Docker in Docker 配置,Container Station 的 `docker.sock` 文件 ports: - 3000:3000 # 暴露 3000、3001 用于开发调试 - 3001:3001 - 8443:8443 # code-server 服务端口 restart: unless-stopped secrets: # 指定 password 路径 hashed_password: file: /path/to/code-server/_secrets/hashed_password.txt hashed_sudo_password: file: /path/to/code-server/_secrets/hashed_sudo_password.txt
docker-compose.yaml

在 Container Station 中运行或者通过下面的指令运行:

cd /path/to/docker-compose.yaml docker compose up -d

启动成功后在浏览器中访问 http://<nas ip address>:8443,输入设置的密码即可。

注意,如果不使用

https
访问的话某些依赖 Service Workers 的服务将无法使用(比如 Markdown 预览)。