Docker+Code-server+Anaconda:一站式搭建云端Python开发环境

张开发
2026/4/16 17:53:59 15 分钟阅读

分享文章

Docker+Code-server+Anaconda:一站式搭建云端Python开发环境
1. 为什么你需要一个云端Python开发环境想象一下这个场景你正在用你的笔记本电脑写一个Python数据分析脚本跑得好好的突然老板发来一个更大的数据集你的电脑风扇开始像直升机一样轰鸣内存直接爆满程序卡死。或者你和几个同学想一起做一个机器学习项目但大家的电脑配置、操作系统、Python版本都不一样光是配环境、同步代码就花了两天项目还没开始热情先耗光了。又或者你是个老师想给学生提供一个统一的、开箱即用的编程练习环境难道要给每个学生都装一遍Anaconda和一堆库吗这些痛点我猜很多开发者都遇到过。本地开发环境就像你的私人书房舒服是舒服但一旦需要协作、需要更强的算力、或者需要随时随地工作它就显得有点局促了。而云端开发环境就像是给你在数据中心里租了一个带全套顶级装备的“云书房”。你的代码、环境、运行结果都放在云端服务器上你只需要一个能上网的浏览器就能随时随地打开一个功能完整、性能强劲的开发桌面。那么怎么快速拥有这样一个“云书房”呢今天我要分享的就是我用得最顺手的一套组合拳Docker Code-server Anaconda。Docker负责把整个环境打包成一个轻便、隔离的“集装箱”Code-server让你能在浏览器里用上几乎和本地一模一样的VS Code而Anaconda则是Python数据科学领域的“瑞士军刀”管理虚拟环境和安装库无比方便。把它们仨拧在一起你就能在十分钟内从零搭建一个支持多Python版本、随时切换虚拟环境、并能远程协作的云端开发平台。无论是个人学习、团队项目还是教学培训这套方案都实测非常“稳”。2. 核心工具三剑客它们各自扮演什么角色在开始动手之前我们得先搞清楚手里的三样工具到底是干嘛的这样后面操作起来心里才有底。你可以把它们想象成盖房子的三个关键角色。Docker万能的环境打包匠和搬运工Docker的核心思想是“容器化”。你可以把它理解成一个超级轻量级的虚拟机但它比虚拟机启动更快、占用资源更少。它的价值在于“一次构建处处运行”。我们通过一个叫Dockerfile的文本文件定义好环境里需要什么操作系统、安装哪些软件、配置什么参数。然后Docker就能根据这个“菜谱”生成一个不可变的镜像。这个镜像在任何安装了Docker的机器上无论是你的Mac、Windows PC还是云服务器运行起来的表现都是一模一样的。这就彻底解决了“在我机器上好好的怎么到你那就挂了”这个千古难题。在我们的方案里Docker就是那个负责把Anaconda、Code-server以及所有基础依赖严丝合缝地打包成一个整体“箱子”的工匠。Code-server把VS Code装进浏览器VS Code无疑是当下最受欢迎的代码编辑器之一插件生态丰富用户体验极佳。Code-server就是这个编辑器的开源服务端版本。简单说它把VS Code的后台跑在服务器上然后通过浏览器把操作界面提供给你。你通过浏览器访问一个网址看到、用到的界面和功能和本地安装的VS Code几乎没区别包括文件管理、终端、代码高亮、智能提示、插件安装大部分等等。这意味着你不再需要在本机安装任何开发工具一台平板电脑甚至手机只要能打开现代浏览器就能进行严肃的编码工作。它就是我们“云书房”里的那张桌子和台灯。AnacondaPython项目的环境管理大师Python开发尤其是数据科学和机器学习领域最头疼的就是库的版本管理和环境隔离。项目A需要TensorFlow 2.4项目B需要PyTorch 1.7系统自带的Python还可能被其他软件依赖不能乱动。Anaconda以及其包管理工具conda就是来解决这个问题的。它可以轻松创建多个相互独立的“虚拟环境”每个环境里都可以安装特定版本的Python和任何第三方库彼此互不干扰。就像在你的书房里为不同的项目准备了不同的书架和工具箱需要做哪个项目就切换到对应的环境干净又省心。在我们的云端环境里Anaconda就是那个强大的“书架管理员”。把这三者结合Docker提供了底层的一致性和可移植性Code-server提供了顶层的开发界面和体验Anaconda则在中间层提供了灵活多变的Python环境管理。这个架构既稳固又灵活是我实践下来非常推荐的一种组合。3. 五分钟快速上手使用现成镜像部署如果你只是想最快速度体验一下或者对Docker还不那么熟悉那么最简单粗暴的方法就是直接使用别人已经搭建好的镜像。我在网上也维护了一个集成了Code-server和Anaconda的镜像你可以直接拉下来用。这就像直接买了一个精装修、带家具的“云书房”拎包入住。第一步拉取预构建的镜像首先确保你的机器上已经安装好了Docker。打开终端Linux/macOS或命令提示符/PowerShellWindows执行下面的命令。这个命令会从Docker Hub仓库把我准备好的镜像下载到本地。docker pull landasika/vscode-conda:latest下载时间取决于你的网速镜像大概有几个GB包含了一个比较完整的Python数据科学基础环境。喝杯咖啡等一下就好。第二步一键运行容器镜像拉取成功后我们就可以启动一个容器实例了。下面这条命令看起来有点长但别怕我拆开给你解释。docker run -d \ --name code-server-anaconda \ -p 666:8080 \ -p 777:8888 \ -v $HOME/.config/code-server:/root/.config/code-server \ -v /home/vscode:/root/coder/project \ -u $(id -u):$(id -g) \ -e DOCKER_USER$USER \ landasika/vscode-conda-d让容器在后台运行这样你关了终端它也不会停。--name code-server-anaconda给这个容器起个名字方便后续管理比如停止、重启或者进入容器。-p 666:8080这是端口映射关键它把容器内部的8080端口Code-server服务默认端口映射到你宿主机的666端口。这意味着你通过浏览器访问你服务器的IP:666就能连上Code-server。-p 777:8888同上把容器内部的8888端口Jupyter Lab默认端口映射到宿主机的777端口用来后续运行Jupyter。-v $HOME/.config/code-server:/root/.config/code-server这是目录挂载卷映射。把宿主机上~/.config/code-server目录挂载到容器内的对应路径。这样你对Code-server的配置比如安装的插件、用户设置就会保存在宿主机上即使容器删除重建配置也不会丢失。-v /home/vscode:/root/coder/project同样把宿主机上的/home/vscode目录挂载为容器内的项目目录。你的所有代码项目都应该放在这个目录下保证数据持久化。-u $(id -u):$(id -g)和-e DOCKER_USER$USER这两项是为了解决容器内文件权限问题让容器内创建的文件所有者与宿主机当前用户一致避免出现你无法读写挂载目录文件的情况。landasika/vscode-conda最后指定我们使用的镜像名。命令执行后如果没有报错用docker ps命令应该能看到一个名为code-server-anaconda的容器正在运行。第三步访问你的云端VS Code现在打开你的浏览器输入地址http://你的服务器IP地址:666。第一次访问会要求你输入密码。这个密码在哪里呢它被写在容器内的配置文件里了。我们需要进入容器看一眼。执行命令进入容器docker exec -it code-server-anaconda bash然后查看密码配置文件cat ~/.config/code-server/config.yaml你应该会看到类似这样的内容bind-addr: 0.0.0.0:8080 auth: password password: 你的密码就在这里 cert: false记下这个密码或者你可以按后面手动搭建部分的方法修改它回到浏览器登录页面输入就能进入一个完全在浏览器中运行的VS Code界面了左侧文件管理器里你应该能看到/root/coder/project目录它对应着你宿主机上的/home/vscode你可以在这里创建Python文件开始编码了。第四步启动Jupyter Lab服务有时候你可能想用Jupyter Notebook/Lab做交互式数据分析。在我们的容器里Anaconda已经预装好了。我们需要在容器内部启动Jupyter服务。因为这是一个需要长期运行的后台服务我推荐使用tmux来管理会话这样即使你退出终端服务也不会停止。还是在容器内的终端里执行tmux new -s jupyter_server这会新建一个名为jupyter_server的tmux会话。然后在新的会话中启动Jupyter Labcd ~ jupyter lab --ip* --port8888 --no-browser --allow-root你会看到一串输出其中最关键的是包含token的URL比如http://127.0.0.1:8888/lab?token一串很长的字符现在你可以按Ctrlb然后按d从当前tmux会话中“脱离”出来。Jupyter服务会在后台继续运行。回到你的宿主机打开浏览器访问http://你的服务器IP地址:777并把上面看到的token输入进去就能使用Jupyter Lab了。至此一个功能完整的云端Python开发环境就已经跑起来了。你可以用Code-server写脚本、管理项目用Jupyter做探索性分析并且利用Anaconda随意创建新的虚拟环境。这可以说是最快速的体验路径。4. 从零开始手动搭建深入理解每个环节直接用现成镜像虽然快但就像吃泡面省事却少了点“锅气”。如果你想更深入地控制这个环境比如定制预装的Python包、使用特定版本的Code-server或者单纯想学习一下搭建过程那么手动搭建是更好的选择。这个过程能让你彻底明白这三者是如何协同工作的。别担心我会一步步带你走踩过的坑都给你标出来。4.1 第一步用Docker拉起Anaconda基础环境我们选择从官方的Anaconda镜像开始这是一个干净、标准的起点。docker pull continuumio/anaconda3:latest拉取镜像后我们需要以一种特殊的方式运行它。因为Anaconda镜像默认的启动命令会启动一个交互式shell如果我们直接以-d后台模式运行容器会立刻退出。所以我们需要用一个“永远不结束”的命令来保持容器运行常用的就是tail -f /dev/null。同时我们把后续Code-server需要的目录映射也提前做好。docker run -d \ --name my-anaconda-base \ -p 6666:8080 \ -p 7777:8888 \ -v $HOME/.config/my-code-server:/root/.config/code-server \ -v $HOME/my-projects:/root/coder/project \ -u $(id -u):$(id -g) \ -e DOCKER_USER$USER \ continuumio/anaconda3 \ tail -f /dev/null这里我把外部端口改成了6666和7777只是为了和前面的例子区分目录映射路径也稍作修改。执行后一个包含了完整Anaconda的容器就在后台安静运行了。你可以用docker exec -it my-anaconda-base bash进入容器用conda --version和python --version验证一下。4.2 第二步在容器内安装和配置Code-server现在我们进入这个“毛坯房”容器开始安装和装修Code-server。首先更新系统包管理器并安装一些必要工具如vim用于编辑tmux用于管理后台会话apt-get update apt-get install -y vim tmux wget接着下载Code-server的二进制包。建议去 Code-server的GitHub Release页面 查看最新版本。这里以v4.14.1为例mkdir /opt/code-server cd /opt/code-server wget https://github.com/coder/code-server/releases/download/v4.14.1/code-server-4.14.1-linux-amd64.tar.gz tar -xvf code-server-4.14.1-linux-amd64.tar.gz解压后你会得到一个类似code-server-4.14.1-linux-amd64的目录里面的bin/code-server就是主程序。现在配置Code-server。首先创建配置目录和文件mkdir -p ~/.config/code-server vim ~/.config/code-server/config.yaml在config.yaml文件中输入以下基础配置bind-addr: 0.0.0.0:8080 auth: password password: your_secure_password_here # 请务必修改成一个强密码 cert: falsebind-addr: 服务监听地址0.0.0.0表示监听所有网络接口。auth: 认证方式password是密码认证。password: 登录密码强烈建议修改成你自己的复杂密码。cert: 是否使用HTTPS证书我们暂时设为false后续可以通过反向代理加SSL。4.3 第三步打包自定义镜像并设置启动命令配置好后我们退出容器在容器内输入exit。现在容器里有了Anaconda和Code-server的程序文件但默认启动命令还是tail -f /dev/null。我们需要把它打包成一个新镜像并设置启动容器时自动运行Code-server。首先在宿主机上查看当前容器的ID或名字docker ps然后将这个容器提交为一个新的镜像我们命名为my-custom-vscode-condadocker commit my-anaconda-base my-custom-vscode-conda提交完成后可以删除旧的测试容器因为数据已通过卷映射保存在宿主机所以安全docker rm -f my-anaconda-base现在用我们自定义的镜像并以Code-server作为启动命令重新运行容器docker run -d \ --name my-dev-env \ -p 6666:8080 \ -p 7777:8888 \ -v $HOME/.config/my-code-server:/root/.config/code-server \ -v $HOME/my-projects:/root/coder/project \ -u $(id -u):$(id -g) \ -e DOCKER_USER$USER \ my-custom-vscode-conda \ /opt/code-server/code-server-4.14.1-linux-amd64/bin/code-server注意最后一行我们直接指定了Code-server二进制文件的完整路径作为容器的启动命令。这样容器一启动Code-server服务就会自动运行。现在再次访问http://你的服务器IP:6666用你刚才在config.yaml里设置的密码登录就能看到Code-server界面了。而且因为容器里已经有了Anaconda你可以在Code-server的内置终端里自由使用conda命令创建和管理虚拟环境。4.4 第四步在Code-server中使用Conda虚拟环境这是整个方案最精髓的部分之一在浏览器里的VS Code中无缝使用容器内的Conda环境。打开终端在Code-server界面按Ctrl或者点击菜单栏的“终端”-“新建终端”会打开一个集成终端。这个终端实际上是在容器内部运行的。创建新环境在终端里你可以像在本地一样使用conda。例如创建一个名为my_py39、Python版本为3.9的环境conda create -n my_py39 python3.9激活环境conda activate my_py39安装Python包在激活的环境下用pip或conda install安装项目所需的包比如pip install numpy pandas matplotlib。在Code-server中选择解释器这是让VS Code识别你环境的关键。点击Code-server左下角的齿轮设置图标或者按CtrlShiftP打开命令面板输入并选择 “Python: Select Interpreter”。稍等片刻它会扫描出所有可用的Python解释器其中应该就包含你刚刚创建的my_py39环境下的Python路径通常类似/opt/conda/envs/my_py39/bin/python。选择它。验证新建一个.py文件写一句import numpy如果没有报错并且编辑器能提供该库的代码提示就说明环境切换成功了。你可以在不同项目文件夹下为每个项目选择不同的Conda解释器真正做到环境隔离。手动搭建的过程虽然步骤多一些但给了你完全的控制权。你可以选择更轻量级的Miniconda镜像可以预装特定的科学计算库也可以锁定Code-server的版本。理解了这个过程你就能根据自己的需求随意定制这个“云书房”的装修方案了。5. 进阶配置与优化技巧基础环境搭好了但要想用得顺手还得做一些“精装修”。这里分享几个我实践中总结出来的关键配置和优化技巧能极大提升你的使用体验。5.1 使用反向代理和域名访问更安全、更便捷直接通过IP:端口访问不太美观也不安全HTTP明文传输。更专业的做法是使用Nginx或Apache配置反向代理并绑定域名、启用HTTPS。为什么用反向代理隐藏端口可以用https://code.yourdomain.com直接访问不用记端口号。SSL加密方便配置HTTPS证书比如用Let‘s Encrypt免费证书保证通信安全。负载均衡未来如果你部署多个实例可以通过代理做负载均衡。解决WebSocket问题Code-server和Jupyter都重度依赖WebSocket进行实时通信。一些Web服务器对WebSocket的支持需要特殊配置反向代理可以统一处理。这里以Nginx为例假设你有一个域名dev.yourdomain.com已经解析到了你的服务器IP。首先安装Nginx如果还没安装# Ubuntu/Debian sudo apt update sudo apt install nginx # CentOS/RHEL sudo yum install nginx然后为Code-server创建一个Nginx配置文件例如/etc/nginx/sites-available/code-server没有sites-available目录的话可以直接在nginx.conf的http块里添加server配置server { listen 80; server_name dev.yourdomain.com; # 你的域名 # 将HTTP请求重定向到HTTPS如果你配置了SSL # return 301 https://$server_name$request_uri; location / { proxy_pass http://localhost:6666; # 指向Docker容器映射的端口 proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 增加超时设置避免长连接断开 proxy_read_timeout 86400s; proxy_send_timeout 86400s; } }关键点proxy_set_header Upgrade $http_upgrade;和proxy_set_header Connection upgrade;这两行是必须的它们确保了WebSocket连接能够正确建立。没有这个Code-server的终端、插件市场等功能可能无法正常工作。保存配置后创建一个符号链接启用它如果使用sites-available目录sudo ln -s /etc/nginx/sites-available/code-server /etc/nginx/sites-enabled/测试Nginx配置是否正确sudo nginx -t如果显示syntax is ok和test is successful就重载Nginx使配置生效sudo systemctl reload nginx现在你就可以通过http://dev.yourdomain.com访问你的Code-server了。如果想配置HTTPS可以使用Certbot工具自动获取和配置Let‘s Encrypt证书这里不再赘述。对于Jupyter Lab也可以用同样的方法用另一个子域名如jupyter.yourdomain.com配置一个反向代理指向容器的8888端口映射例如宿主机的7777端口。记得在Jupyter的配置中允许跨域访问或者在Nginx配置中处理好。5.2 优化Code-server使用体验默认的Code-server可能有些地方需要调优。1. 安装必备插件虽然是在浏览器里但Code-server支持安装大部分VS Code插件。不过由于一些插件依赖本地原生模块并非所有插件都能完美运行。以下是一些经测试兼容性很好的核心插件建议安装Python(ms-python.python)提供Python语言支持、调试、测试等。Pylance(ms-python.vscode-pylance)强大的Python语言服务器提供超快的代码补全和类型检查。Jupyter(ms-toolsai.jupyter)在VS Code中直接运行Jupyter Notebook。GitLens(eamodio.gitlens)增强Git功能。Docker(ms-azuretools.vscode-docker)方便管理Docker容器和镜像如果你在宿主机上操作。Remote - SSH(ms-vscode-remote.remote-ssh)虽然我们在用Code-server但这个插件有时在管理其他服务器时仍有奇效。安装方式和在本地VS Code中一样点击左侧活动栏的扩展图标搜索安装即可。2. 修改用户设置有些默认设置可能需要调整。点击左下角齿轮 - 设置或者按Ctrl,打开设置界面。关闭遥测如果你担心速度慢或者隐私问题可以关闭VS Code的遥测数据上报。在设置中搜索telemetry将Telemetry: Enable Crash Reporter和Telemetry: Enable Telemetry都设为false。你也可以直接在用户设置的JSON文件~/.local/share/code-server/User/settings.json里添加telemetry.enableCrashReporter: false, telemetry.enableTelemetry: false调整文件监控如果项目文件很多可能会遇到“文件监视程序”达到系统限制的警告。可以调整设置files.watcherExclude: { **/.git/objects/**: true, **/.git/subtree-cache/**: true, **/node_modules/*/**: true, **/env/**: true, **/venv/**: true, **/.conda/**: true }Python相关设置可以指定默认的Python路径、格式化工具等。3. 管理多个Python解释器如前所述利用Conda创建多个环境后在Code-server中可以灵活切换。你甚至可以为一个工作区Workspace单独指定解释器配置保存在项目目录下的.vscode/settings.json中非常适合团队协作时统一环境。5.3 数据持久化与备份策略我们的方案通过Docker的-v参数将两个关键目录挂载到了宿主机配置目录(~/.config/my-code-server)保存了Code-server的所有用户配置、已安装的插件、快捷键设置等。定期备份这个目录就等于备份了你的开发环境偏好。项目目录(~/my-projects)保存了所有代码。这个目录必须做好版本控制Git和定期备份。进阶建议使用Docker Compose当你的服务变得复杂比如除了开发环境还想挂个数据库、消息队列或者需要清晰定义所有配置时推荐使用docker-compose.yml文件来管理。创建一个docker-compose.yml文件version: 3.8 services: code-server: image: my-custom-vscode-conda # 或直接使用 landasika/vscode-conda container_name: my-dev-env restart: unless-stopped # 容器意外退出时自动重启 ports: - 6666:8080 - 7777:8888 volumes: - $HOME/.config/my-code-server:/root/.config/code-server - $HOME/my-projects:/root/coder/project - $HOME/.ssh:/root/.ssh:ro # 可选挂载SSH密钥方便Git操作 user: 1000:1000 # 直接指定UID和GID避免权限问题 environment: - DOCKER_USER${USER} - TZAsia/Shanghai # 设置容器时区 command: /opt/code-server/code-server-4.14.1-linux-amd64/bin/code-server然后只需要在文件所在目录运行docker-compose up -d所有服务就会按照定义启动。配置一目了然管理起来也方便docker-compose down停止docker-compose logs查看日志等。6. 常见问题与故障排除即使按照步骤来也可能会遇到一些小问题。这里把我遇到过的一些典型问题和解决方法列出来希望能帮你快速排雷。1. 无法通过浏览器访问Code-server连接被拒绝检查容器状态运行docker ps确认你的容器正在运行STATUS 为 Up。如果没有用docker logs 容器名查看启动日志通常能发现错误原因比如端口冲突、命令错误。检查防火墙确保你云服务器的安全组/防火墙规则放行了你映射的宿主机端口如6666, 7777。对于本地机器检查系统防火墙设置。检查端口映射确认docker run命令中的-p参数是否正确格式是宿主机端口:容器内端口。容器内Code-server默认监听8080Jupyter默认监听8888。2. 登录Code-server时密码错误确认密码文件进入容器 (docker exec -it 容器名 bash)查看~/.config/code-server/config.yaml文件中的password字段。注意YAML格式对缩进敏感。修改密码你可以直接编辑这个文件修改密码后需要重启Code-server进程或整个容器才能生效。在容器内可以pkill code-server然后重新启动它如果启动命令在Docker中已定义则需重启容器docker restart 容器名。3. Code-server终端无法使用conda命令或conda环境无法激活Shell初始化问题Code-server内置终端默认可能不会加载~/.bashrc。解决方法是在终端里手动执行source ~/.bashrc或者更一劳永逸的在Code-server的用户设置(settings.json)里添加terminal.integrated.shellArgs.linux: [-l]这个-l参数让终端以“登录shell”方式启动会自动加载profile脚本。环境变量未传递确保在创建容器时使用了-u和-e参数来正确设置用户和环境变量。4. Jupyter Lab无法访问或Token无效检查Jupyter是否在运行进入容器用tmux attach -t jupyter_server如果你用了tmux或ps aux | grep jupyter查看进程。检查端口映射和防火墙同问题1确保宿主机7777端口可访问并映射到了容器的8888。获取最新Token如果之前的token丢失可以在运行Jupyter的终端里按CtrlC停止然后重新启动会生成新的token。或者Jupyter的token也记录在~/.local/share/jupyter/runtime/下的某个文件里可以进去查看。5. 插件安装失败或无法使用网络问题Code-server插件市场默认访问的是VS Code官方的市场有时可能因网络问题连接慢或失败。可以尝试在设置中配置其他镜像源但这需要插件本身支持。对于Python、Pylance这类核心插件通常直接安装问题不大。插件兼容性有些插件依赖本地原生组件如某些代码美化、调试器插件在Code-server的Web环境中可能无法工作。如果安装后功能异常可以尝试禁用或寻找替代插件。一般语言支持类LSP和主题类插件兼容性较好。6. 容器内磁盘空间不足清理Docker定期清理无用的镜像、容器和缓存。可以使用命令docker system prune -a谨慎使用这会删除所有未被使用的镜像、容器、网络和卷确保你不需要它们。清理Conda缓存在容器内运行conda clean --all。清理pip缓存在容器内运行pip cache purge。遇到其他问题第一反应是查看日志docker logs 容器名是定位Docker容器问题最直接的工具。其次可以进入容器内部亲自执行命令来复现和调试问题。

更多文章