需求整理
微软在19年的build大会上公开了Visual Studio Online,相当于把Visual Studio Code和我们需要的开发相关文件装进了浏览器,随时访问。不过目前的公共预览版还没有提供在国内的服务器,定价上最基本的配置4核/8GB RAM/64GB HDD每活跃一小时需3.15元人民币,待机一小时0.05元人民币。自建服务器也必须跑在Azure上,也并不算便宜:Visual Studio Online 定价
社区也开发了相同功能的开源软件:code-server。不过如果我们专程为这个需求分配一个开发机,即使是2核/4GB RAM/40GB SSD的基本机型,不打折时包年的费用也接近2000元人民币。所以使用code-server,我们也必然需要实现按需分配。接下来我们就在阿里云上实现这个需求。
code-server用到了service worker,在不通过localhost访问时,必须使用https协议。所以我们为了实现整个需求,必须用到阿里云的如下服务:
- 一个已经备案的域名,如果用境外服务器的话域名可以不备案
- 一个弹性公网IP,需要的时候申请下来,将一个二级域名http://code.example.com解析到该IP上
- 容器镜像服务,方便我们快速地使用打包好的code-server docker镜像
- 弹性容器实例ECI,这是最为经济的算力资源,2核/4GB RAM每小时0.44元人民币,4核/8GB RAM每小时0.88元人民币,而且计价是精确到秒的。
- 文件存储服务NAS,我们之后需要将它作为NFS Volume挂载在ECI上,存储开发常用资料。这部分需要长期运行,价格0.30元/GB/月。
实现我们想要的按需分配code-server的“算法”描述起来如下:
- 准备阶段
- 准备code-server的镜像上传到阿里云容器镜像仓库,镜像里需要有SSL证书相关服务
- 申请好NAS实例
- 需要真正使用时
- 申请一个弹性公网IP x.x.x.x
- 更新二级域名http://code.example.com的解析到x.x.x.x
- 申请弹性容器实例,以准备好的docker image启动,绑定弹性IP x.x.x.x
- 启动时执行代码,给二级域名http://code.example.com获取SSL证书后,之后便可以启动code-server了
- 挂载NAS,阿里云这里应该是有些bug,启动时挂载NAS容易使ECI无法正常启动
docker镜像准备
我们首先要准备一个帮助我们处理SSL证书的增强版code-server docker image。
一个思路是,code-server为我们提供了它的Dockerfile,我们可以对这个Dockerfile稍加修改,以满足我们所要的功能。可惜的是,我自己试了多次,即使不更改这个Dockerfile,也无法正确地生成docker image。会遇到这个问题:Failed to build docker image · Issue #1380 · cdr/code-server
于是我转换了另一个解决方案,基于centos镜像,在这个基础上,下载code-server的Binary Release,布置好SSL证书相关软件,这里选择Let's Encrypt的Certbot。
基于此,准备好的Dockerfile如下(注意这个Dockerfile后面有更新):
FROM
更改工作目录到这个文件夹后,制作docker image:
docker image build -t my-code-server:0.1 .
成功之后查看本地images,找到需要的ID
docker images
登录阿里云的容器镜像服务,这里我选择离我最近的成都节点:
sudo docker login --username=mayundaddy registry.cn-chengdu.aliyuncs.com
tag并推送这个容器镜像:
sudo docker tag [imageID] registry.cn-chengdu.aliyuncs.com/mayundaddy/code-server:0.1
sudo docker push registry.cn-chengdu.aliyuncs.com/mayundaddy/code-server:0.1
测试一下,我们手动做好其他部分的工作,启动这个容器的时候,运行以下指令,成功之后就可以在任意设备上访问了:
&&
不过这个方法相当于是每次启动时都申请了一个新的SSL证书,Let's Encrypt对此是有频率限制的,整个一级域名每周50个。如果启动次数没有那么频繁,这个也能将就用了。我这边后来为了解决这个问题,其实用了一个常在线的服务器不断维系一个通用*.example.com的SSL证书并且在启动时拷贝过来。
由此我更改了Dockerfile如下:
FROM
这个版本的Dockerfile不再需要处理certbot相关的SSL/HTTPS逻辑,构建起来也轻松许多。转而在`run.sh`中处理一些简单逻辑:
#!/bin/bash
阿里云API操作
既然Docker image已经构造好了,那么只需要调用阿里云的API,把其他步骤做好就是。由于我们改进了思路,所以到这一步还需要完成的任务就是:
- 申请一个弹性公网IP x.x.x.x
- 更新二级域名http://code.example.com的解析到x.x.x.x
- 申请弹性容器实例,绑定弹性IP x.x.x.x,以准备好的docker image启动,绑定弹性IP x.x.x.x
可以说比较简单了,node.js实现如下:
const
执行一下`node this.js`,很快一切都配置好了。不过域名解析还需要至多10分钟生效。这段时间如果急着用,可以通过不安全的方式访问https://IP开始使用。
云盘挂载
这一部分暂时还没来得及测试,等搞定了回来补充