Use Docker + Conda as Your Local Python Dev Environment (with Jupyter)

Want a reproducible Python setup without polluting your laptop? This guide shows how to run a Conda-based environment inside Docker, mount your project folder, persist Conda packages/environments, and (optionally) launch Jupyter Lab on http://localhost:8888.

TL;DROne docker-compose.yml fileYour project is mounted to /workspaceConda env auto-created on first run (e.g., dev with Python 3.11)Works on macOS / Windows / Linux

1) Prerequisites

  • Docker Desktop (macOS/Windows) or Docker Engine (Linux)
  • docker compose CLI
  • A project folder (any directory on your machine)

2) Project Layout

your-project/
├── docker-compose.yml
└── .env                 # optional, to customize image/env/ports

3) docker-compose.yml

Copy this file into the project root.
The code contains a few Chinese comments for clarity.

# docker-compose.yml — Conda-based local dev environment
# -----------------------------------------------------
# Usage:
#   docker compose up -d
#   docker compose exec dev bash
#   conda activate $CONDA_ENV
# 可选:启动 Jupyter Lab -> jupyter lab --ip=0.0.0.0 --port=8888 --no-browser

version: "3.9"

services:
  dev:
    # 默认使用 Miniconda3。需要 Python 2.7 时可换为 conda/miniconda2(不推荐,已停更)
    image: ${CONDA_IMAGE:-conda/miniconda3}
    container_name: conda-dev
    working_dir: /workspace

    # 将当前目录挂载到容器(代码热更新);同时持久化 Conda 缓存与环境,加速后续启动
    volumes:
      - ./:/workspace
      - conda_pkgs:/opt/conda/pkgs
      - conda_envs:/opt/conda/envs

    # 暴露 Jupyter 端口(如不使用可改为注释)
    ports:
      - "${JUPYTER_PORT:-8888}:8888"

    environment:
      - TZ=${TZ:-Europe/Berlin}
      - CONDA_ENV=${CONDA_ENV:-dev}
      - PYTHON_VERSION=${PYTHON_VERSION:-3.11}

    tty: true
    stdin_open: true

    # 首次启动自动创建指定 Python 版本的 Conda 环境,并写入 ~/.bashrc 方便进入即激活
    command: >-
      bash -lc "
      if [ ! -d /opt/conda/envs/${CONDA_ENV} ]; then
        conda update -y -n base -c defaults conda &&
        conda create -y -n ${CONDA_ENV} python=${PYTHON_VERSION};
      fi;
      echo 'source activate ${CONDA_ENV}' >> ~/.bashrc;
      exec bash"

    # Linux 用户可按需开启以匹配宿主机文件权限(Windows/macOS 通常不需要)
    # user: "${UID}:${GID}"

volumes:
  conda_pkgs:
  conda_envs:

4) Optional .env (to customize)

Create a .env file next to the compose file to change defaults:

# .env
CONDA_IMAGE=conda/miniconda3   # or continuumio/miniconda3; conda/miniconda2 for Py2 (EOL)
CONDA_ENV=dev
PYTHON_VERSION=3.11
JUPYTER_PORT=8888
TZ=Europe/Berlin

# Linux only (match host permissions)
# UID=$(id -u)
# GID=$(id -g)
Tip (镜像源/速度): If your network is slow, you can later configure Conda channels inside the container (e.g., add mirrors) and then export your ~/.condarc for reuse.

5) Start and Enter the Environment

From the project root:

# Start container (in the background)
docker compose up -d

# Open a shell inside
docker compose exec dev bash
# Your env is auto-activated (via ~/.bashrc), or run:
conda activate $CONDA_ENV

6) Install Packages (Persisted)

Anything you install in the CONDA_ENV is stored in the named volume and survives container rebuilds:

# Inside the container
conda install -y numpy pandas
# or with mamba if you prefer (after installing it):
# conda install -y -n base -c conda-forge mamba && mamba install -n $CONDA_ENV -y scikit-learn
Note: The conda_pkgs (package cache) and conda_envs volumes speed up subsequent operations and keep your base image clean.

7) (Optional) Launch Jupyter Lab

# Inside the container
jupyter lab --ip=0.0.0.0 --port=8888 --no-browser

Open your browser at: http://localhost:8888 and paste the token from the terminal.
If port 8888 is busy, change JUPYTER_PORT in .env (e.g., 9000) and re-up.


8) Use with VS Code

You can attach VS Code to the running container:

  1. Install the Dev Containers extension.
  2. F1 → “Dev Containers: Attach to Running Container…” → select conda-dev.
  3. Your project appears under /workspace with IntelliSense powered by the container’s Python.

(No extra config is required because we mount your project folder.)


9) Troubleshooting

  • Port already in use
    Change JUPYTER_PORT in .env and run docker compose up -d again.
  • Permissions (Linux only)
    If files created inside the container are owned by root, set your numeric UID/GID in .env and uncomment the user: "${UID}:${GID}" line in docker-compose.yml. Recreate the container.
  • Conda not found / env not activated
    Enter the container with docker compose exec dev bash and run source ~/.bashrc then conda activate $CONDA_ENV.
    (The compose command already appends source activate to ~/.bashrc on first start.)
  • Need Python 2.7 for legacy code
    Switch the image to conda/miniconda2 in .env. Python 2 is end-of-life; consider porting to Python 3.

10) Clean Up

# Stop and remove containers (keeps volumes)
docker compose down

# Remove containers + volumes (deletes environments/caches)
docker compose down -v

11) Why This Setup?

  • Reproducible: Everyone on your team runs the same base image + Conda env name & Python version.
  • Non-invasive: Your host Python remains untouched.
  • Fast iterations: Project is bind-mounted, so edits on your host reflect instantly in the container.
  • Persisted envs: Conda envs and package caches survive docker compose down and speed up rebuilds.

12) Copy-Paste Quickstart

# 1) Create a project folder and add docker-compose.yml (from this post)
# 2) Optional: create .env to customize
docker compose up -d
docker compose exec dev bash
conda activate $CONDA_ENV
# 开发吧!pip/conda 安装的包会被持久化到卷中

That’s it—you now have a clean, portable Conda-inside-Docker workflow for local development, with optional Jupyter and smooth editor integration.