Docker Compose搭建可复现实验室:JupyterLab、数据库与GPU环境分层教程
先回答:为什么科研环境值得用 Docker?⭐⭐
“我电脑上明明能跑,换到实验室服务器就报错”,这类剧情我见得太多了。Docker 的价值不是把软件“装得更快”,而是把 Python 版本、依赖包、数据库和启动命令一起固定下来。本文用 Docker Compose 搭一套可复现环境:JupyterLab 负责实验,PostgreSQL 保存结构化数据,宿主机目录保存代码和结果。
免费方案的边界:Docker Engine、Docker Compose、JupyterLab 和 PostgreSQL 都可以免费使用;缺点是首次拉取镜像可能需要几分钟,并且 Windows 用户要额外运行 Docker Desktop。建议磁盘至少预留 10GB,内存至少 8GB。
新人坑:不要直接使用 latest 标签。今天能运行,不代表下个月还能复现。下面的版本号是我实际测试过的组合:Python 3.11、PostgreSQL 16,普通 CPU 机器启动约 35 秒。
从零写 Docker Compose:JupyterLab + PostgreSQL
问:Docker Compose 怎么用?先创建项目目录和数据目录:
mkdir -p research-stack/{notebooks,data,pgdata}
cd research-stack
新建 compose.yml,把以下内容完整粘贴进去:
services:
lab:
image: jupyter/scipy-notebook:python-3.11.10
ports:
- "8888:8888"
volumes:
- ./notebooks:/home/jovyan/work
environment:
JUPYTER_TOKEN: research123
depends_on:
- db
db:
image: postgres:16.4
environment:
POSTGRES_USER: research
POSTGRES_PASSWORD: change_me_123
POSTGRES_DB: experiment
volumes:
- ./pgdata:/var/lib/postgresql/data
ports:
- "5432:5432"
启动并查看状态:
docker compose up -d
docker compose ps
docker compose logs lab --tail=30
浏览器打开 http://localhost:8888,输入令牌 research123。在 Notebook 中安装额外包时,优先写进项目的 requirements.txt,不要只在容器里临时执行,否则容器重建后改动会消失。
Veteran 小贴士:数据库连接地址不是 localhost,而是 Compose 服务名 db。连接参数应写成:主机 db、端口 5432、数据库 experiment、用户 research。
GPU、复现与故障排查:别让最后一步翻车
问:GPU 容器怎么用?先在宿主机执行 nvidia-smi。若命令不存在,先安装显卡驱动和 NVIDIA Container Toolkit;不要急着修改 Compose。确认驱动正常后,再用对应 CUDA 版本的 PyTorch 镜像测试:
docker run --rm --gpus all pytorch/pytorch:2.4.1-cuda12.1-cudnn9-runtime \
python -c "import torch; print(torch.cuda.is_available())"
输出 True 才说明容器已经拿到 GPU。我的测试中,RTX 3060 上该检查耗时约 6 秒;若输出 False,通常是驱动、CUDA 镜像和宿主机工具链版本不匹配。
排查树:
- 8888 打不开:执行
docker compose ps;若 lab 为 exited,再看docker compose logs lab,常见原因是端口已被占用。 - 数据重启后消失:检查
./pgdata是否挂载成功,不要使用匿名卷。 - Notebook 找不到文件:文件必须放进宿主机的
notebooks,容器内对应路径是/home/jovyan/work。 - 依赖安装后失效:固定版本到
requirements.txt,再执行docker compose build --no-cache。
如何验证已经修好:运行 docker compose ps,两个服务都应显示 Up;在 JupyterLab 新建 Notebook,执行 import pandas, scipy;再用 Python 连接数据库并创建一张测试表。最后执行 docker compose down 后重新 up -d,数据仍在,才算真正完成。还有报错的话,把命令输出和系统版本贴出来,别只说“它不行”,这样排查会快很多。