在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程序,并在本地计算机中显示其内容的功能
其工作原理如下:
@startuml
title X11 Forwarding to VcXsrv Sequence Diagram
actor User
participant "Local Computer\n(Windows)" as Local
participant "SSH Client\n(OpenSSH)" as SSHClient
participant "Remote Server\n(Linux)" as Remote
participant "VcXsrv\nX Server" as VcXsrv
User -> Local: Run VcXsrv \nSetup Display
User -> Local: SSH Remote Server
Local -> SSHClient++: Establish SSH Connection\nEnable X11 Forwarding
SSHClient -> Remote++: X11 Channel Request
Remote -> SSHClient--: Accept Request
alt Application Uses GUI
SSHClient -> VcXsrv++: Forward X11 Traffic
VcXsrv -> SSHClient--: Display Output
end
SSHClient -> Remote--: Send Input
Remote -> Local: Application Output
Local -> User: Display Application GUI
@enduml
借助这个技术,可以在远程开发时使用开发一些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