在Windows下使用远程开发是当下非常流行的开发方式,它带来了许多好处:
- 原生Linux开发环境
- 无缝跨平台开发
- 统一的开发体验
远程服务器系统,我通常是选择 虚拟机虚拟Debian12 ,但虚拟机的不足之处:
- 文件与网络被隔离:由于虚拟系统与宿主系统是完全隔离的,这就导致在部分开发场景需要反复下载上传文件(如配置文件),涉及调试web时也要更改
0.0.0.0
才能访问 - 硬件资源切割:虚拟机需要规划好性能,提前划出硬盘、CPU、网络等资源作为独立的虚拟资源,尤其涉及到显卡训练等场景非常不便捷
而Docker的轻量级虚拟可以很好的弥补这2个缺点,与宿主机实现统一网络环境与文件系统
下面是实践一个 Debian 容器作为开发容器的实践
1. Debian 容器
开发容器实现的目标如下
- Host网络:采用
host
网络,无需映射端口方便web应用调试 - 持久化存储:对代码目录做持久化存储,和宿主机双向绑定,方便更改文件
为了方便迁移容器,此次采用 docker-compose.yaml
来构建
1.1. 镜像构建
Docker设计理念与虚拟机不同,一个容器是生命进程等于一个应用的生命进程,而不是虚拟机这种完全独立的操作系统
所以要给容器一个永久运行的应用,这里选用 SSH 服务,构建一个 Dockerfile
文件如下:
FROM debian:12.7
ENV TZ=Asia/Shanghai
# 更改apt源为清华源
RUN sed -i.bak 's|http://deb.debian.org|http://mirrors.tuna.tsinghua.edu.cn|g' /etc/apt/sources.list.d/debian.sources && \
sed -i.bak 's|http://security.debian.org|http://mirrors.tuna.tsinghua.edu.cn|g' /etc/apt/sources.list.d/debian.sources
# Software install
RUN apt-get update && \
apt-get install -y openssh-server vim wget git zsh curl unzip gcc make openssl && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# SSH configuration
RUN mkdir -p /run/sshd && \
ssh-keygen -A && \
echo 'root:root' | chpasswd && \
sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config && \
sed -i 's/#Port 22/Port 30022/' /etc/ssh/sshd_config
CMD ["/usr/sbin/sshd", "-D"]
容器说明:
- 更换到清华源并安装的基础服务如ssh、git等
- 初始化 root 用户的密码为 root
- 更改ssh服务的端口为
30022
测试构建镜像:
sudo docker build -t debian:develop . --no-cache
1.2. 代码目录
为了方便宿主机器与容器共享代码目录,创建一个目录 codes
用于存放容器的代码文件
再将上面的 Dockerfile
也放入到目录中,再创建一个docker-compose.yaml
文件,目录如下:
$ tree -L 2
.
├── codes
│ ├── golang
│ ├── nodejs
│ ├── python
│ └── web
├── Dockerfile
└── docker-compose.yaml
5 directories, 2 files
docker-compose.yaml
文件的内容如下:
¥
启动容器
sudo docker-compose up
1.3. 连接
运行成功后,在宿主机使用ssh容器连接
ssh root@127.0.0.1 -p 30022
连接后可以根据需要自行进行系统设置了
1.4. 备份
容器比起虚拟机而言,更容易被删除,所以定时做冷备也是保持开发环境稳定重要的一环
以上面的容器为例,这里在做完初步的系统设置后,创建一个新的备份镜像
sudo docker commit debian12 debian_develop_backup_image
如果需要迁移,或者考虑冷备的话还可以将这个新的备份镜像保存为 tar 文件
sudo docker save -o debian_develop_backup_image.tar debian_develop_backup_image
迁移到其他具备 docker 环境的服务器上,使用load就可以将这个镜像重新导入
docker load -i debian_develop_backup_image.tar
1.5. GUI开发
实际开发时,会有一些程序需要显示 GUI 图形界面,这就需要借助 VcXsrv 或 Xming 等 X Server 程序
X Server 实现了远程服务器上运行GUI程序,并在本地计算机中显示其内容的功能
其工作原理如下:
借助这个技术,可以在远程开发时使用开发一些GUI程序,非常方便
实现步骤如下
- 安装运行 VcXsrv 程序,并依次检查
Multiple Windows
-Start no client
-Disable access control
三个选项都勾选了 - 使用任意SSH客户端连接远程服务器,要设置 启用X11转发 选项(如:
ssh -x username@hostname
) - 运行任意GUI程序即可在本地看到GUI内容
首先在本地Windows中安装 VcXsrv 程序
- 下载地址:https://github.com/ArcticaProject/vcxsrv/releases
安装后打开,记得勾选下面这个选项免去访问控制,之后根据需要自行启用
接着使用任何ssh客户端,我用的是 tabby,打开具体ssh服务器设置,并勾选 X11转发 ,如下
登录服务器后,运行用于测试的 X11-apps GUI程序,如下:
sudo apt install x11-apps
# 执行 xclock 程序
xclock
接着运行xclock,效果如下
2. 一些实际问题
由于 Docker 镜像并非完整操作系统,在日常使用会出现不少小问题,以下是一些记录与修复
2.1. 光标输入错位
这是缺失中文编码的问题,输入 locale
可以检查,如下:
$ locale
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC=zh_CN.UTF-8
LC_TIME=zh_CN.UTF-8
LC_COLLATE="en_US.UTF-8"
LC_MONETARY=zh_CN.UTF-8
LC_MESSAGES="en_US.UTF-8"
LC_PAPER=zh_CN.UTF-8
LC_NAME=zh_CN.UTF-8
LC_ADDRESS=zh_CN.UTF-8
LC_TELEPHONE=zh_CN.UTF-8
LC_MEASUREMENT=zh_CN.UTF-8
LC_IDENTIFICATION=zh_CN.UTF-8
LC_ALL=
修复需要安装locales
,如下:”
apt install -y locales
运行选择默认的语言编码
dpkg-reconfigure locales
在弹出的所有语言编码中选择你需要的默认语言编码,我这里选择的是120. en_US.UTF-8 UTF-8