基于 Code Server 搭建一套 Web IDE

title

最近,冲动消费,斥巨资购入了一台 iPad Pro 2020,为了预防“买前生产力,买后爱奇艺”(爱奇艺打钱!)的囧境,还是打算给它上一个能正儿八经写点代码的环境


最近在我网上冲浪的时候,就发现了有这么一个团队做了一件很可爱的事情

他们把 VSCode 给搬到了 Web 端,可以在浏览器里运行 VSCode,恰巧我又有一台算力还算过得去的服务器,这就很符合我的需求点了嘛,马上用起来


直奔主题,官方仓库的地址:http://github.com/cdr/code-server

官方提供了两种方式来部署,一种是基于 Docker 的方式,一种是直接二进制启动

个人会比较倾向二进制的方式启动,后面我会讲原因,我先介绍一下如何通过 Docker 的方式启动

通过 Docker 启动

通过 Docker 的方式启动比较简单,也可以很好的宿主环境进行隔离,当前最新的版本为 2.1698-vsc1.41.1

步骤

首先需要准备一台已经装好 Docker 的机器(这里就不赘述了)

准备一个目录用于存放 CodeServer 产生的文件,这里我放在 /data/codeserver 下面

1
2
mkdir -p /data/codeserver
chown -R 1000:1000 /data/codeserver

然后通过以下命令启动一个 CodeServer

1
2
3
4
5
docker run -it \
-p 8080:8080 \
-v "/data/codeserver:/home/coder" \
--restart always \
codercom/code-server

这时候在浏览器里访问 http://localhost:8080,输入命令行里打印出来的密码就可以访问到 CodeServer 了

如果想要停下来的话,只需要如下命令就可以了

1
docker ps | grep code-server | awk '{print $1}' | xargs -I {} docker stop {}

是不是很简单呢?但是有小伙伴就要问了,那是不是就要一直开着那个终端呢?

其实可以不用,现在放心大胆的关闭终端就好了,容器已经运行在后台了

当然我们也有办法在启动的时候就放到后台去,只需要稍微变更一下 docker run 的参数就好了

1
2
3
4
5
docker run -d \
-p 8080:8080 \
-v "/data/codeserver:/home/coder" \
--restart always \
codercom/code-server

但是如果要查看密码怎么办呢?

我们只需要这样操作

1
docker ps | grep code-server | awk '{print $1}' | xargs -I {} docker logs {}

就又可以打印出对应容器的日志啦

但是又有小朋友要问了,还要填密码,好麻烦,能不能不要密码

简单,我们再来修改上一步中的启动参数,但如果你是打算让你的服务器能能够从公网访问,我强烈不建议你这么做,这是个非常危险的操作

1
2
3
4
5
docker run -d \
-p 8080:8080 \
-v "/data/codeserver:/home/coder" \
--restart always \
codercom/code-server --auth none

使用二进制常驻进程

我先讲讲为什么我更倾向于使用二进制常驻进程的方式启动

因为我当前的主语言是 Golang,所以我还需要 Golang 的开发环境,因此如果我使用 docker 的方式,我还需要自己去构建一个安装了 Golang 环境的镜像,之后如果官方镜像更新还需要重新构建

而且在因为容器中的文件系统和宿主机是隔离的,作为日常的工作机的话,有诸多不便,所以我还是选择了使用二进制常驻进程的方式来部署

步骤

安装

首先我们来到官方仓库的 release 页面,下载最新的版本,当前最新的版本为 3.1.0

1
2
3
4
5
6
7
8
9
10
# 下载
wget https://github.com/cdr/code-server/releases/download/3.1.0/code-server-3.1.0-linux-x86_64.tar.gz
# 解压
tar -zxf code-server-3.1.0-linux-x86_64.tar.gz
# 移动到目录
mv code-server-3.1.0-linux-x86_64 /var/lib/code-server
# 创建软链
ln -s /var/lib/code-server/code-server /usr/local/bin/
# 查看版本
code-server -v

当最后一步完成,可以看到命令行打出了当前的版本号

1
3.1.0 5aded14b87e017d32d080b686515f6a26be455f1

配置常驻和开机启动

此步骤基于 systemd 要求 Centos >= 7 Ubuntu >= 1.15

这里需要提一下我踩过的一个小坑

在安装完 Golang 环境之后,在 codeserver 中可以使用 go 命令获取到版本,但是会因为各种路径问题构建失败

最后终于发现,使用 systemd 启动的应用,环境变量里只会有 PATHLANG 两个简单的变量

1
2
3
4
5
6
7
● cat-env.service - cat-env
Loaded: loaded (/usr/lib/systemd/system/cat-env.service; static; vendor preset: disabled)
Active: inactive (dead)

4月 11 17:02:37 code.0x233.cn systemd[1]: Started cat-env.
4月 11 17:02:37 code.0x233.cn env[8589]: LANG=en_US.UTF-8
4月 11 17:02:37 code.0x233.cn env[8589]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

所以我们要给 CodeServer 一套很接近机器的环境变量,可以执行 env 命令查看当前 shell 的环境变量,在去掉了一些无用的变量之后,把它放到 /etc/code-server/env

也可以直接使用这个命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mkdir -p /etc/code-server
cat << EOF > /etc/code-server/env
LANG=$LANG
LC_CTYPE=$LC_CTYPE
USER=$USER
LOGNAME=$LOGNAME
HOME=$HOME
PATH=$PATH
SHELL=$SHELL
TERM=$TERM
XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR
HOSTNAME=$HOSTNAME
ZSH=$ZSH
GOPATH=$GOPATH
EOF

创建 code-server.service 配置文件

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
27
28
29
30
31
export PORT=8080 # 修改为自己监听的端口
export AUTH=password # 如果不想设置密码,此处修改为'none'
export WORKDIR=/root # 应用的根目录,code-server 会在这里存放一些配置信息,此处可以更改为自己喜欢的目录

cat << EOF > /usr/lib/systemd/system/code-server.service
[Unit]
Description=Code Server
Wants = network-online.target
After = network.target

[Service]
Type=simple
WorkingDirectory=$WORKDIR
EnvironmentFile=/etc/code-server/env
ExecStart=/usr/local/bin/code-server --host 0.0.0.0 --port $PORT --auth $AUTH
ExecReload=/bin/kill -USR1 \$MAINPID
ExecStop=/bin/kill -SIGTERM \$MAINPID

KillMode=control-group
Restart=on-failure
RestartSec=10s
StandardOutput = syslog

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload

# 设置开机启动,并立即启动
systemctl enbale code-server --now

如果是设置了密码的方式,可以使用 systemctl status code-server 命令查看到

接下来,在浏览器里访问试试吧~

拓展

在我自己的部署中,我没有使用 CodeServer 提供的简单的密码登录,而是使用了基于 OIDC 的登录方式,经由我的 Gitlab 进行授权,以后我会详细讲讲怎么搭建这个授权

0%