🚀 Welcome to the Development Container Environment project!
This repository provides a highly customizable development container environment with Podman-first defaults, Docker compatibility, and convenient scripts for building and managing development containers.
We welcome everyone to contribute, improve, and keep this project up to date together!
🚀 欢迎来到开发用容器环境项目!
本仓库提供了高度可定制的开发容器环境,默认优先使用 Podman,同时兼容 Docker,并内置了便捷脚本用于构建和管理开发容器。
欢迎大家共同参与、完善和持续更新本项目!
A customized development container environment with pre-installed tools, designed to be resilient, easy to set up, and friendly to both Podman and Docker workflows.
📚 Documentation:
- Quick Start Guide - Get started in 3 steps
- Configuration Examples - Detailed configuration examples
- Podman is the default preferred runtime
- Docker is also supported as a fallback or explicit runtime choice
- For Podman: working Podman rootless setup or Podman machine
- For Docker: user added to the docker group or root privileges
- Default runtime priority:
podman→docker - Default workspace mount:
- Docker:
/home/$(whoami)/workspace - Podman:
/var/lib/podman/$(whoami)/mounts/workspace
- Docker:
- You can override with
WORKSPACE_DIRor-pto select the runtime explicitly
| Runtime | Default behavior | Typical use |
|---|---|---|
| Podman | Preferred by default | Rootless container development, modern Linux workflows |
| Docker | Supported fallback | Traditional Docker-based development setups |
The easiest way to set up the environment is to use the provided setup script:
# Make the script executable
chmod +x setup.sh
# Run the setup script with default settings (Ubuntu 22.04, full mode)
# Podman is preferred by default
./setup.sh
# Force Podman explicitly
CONTAINER_RUNTIME=podman ./setup.sh
# Explicitly use Docker when needed
CONTAINER_RUNTIME=docker ./setup.sh
# Or specify OS version and build mode
./setup.sh -o ubuntu2404 -m full # Ubuntu 24.04, full mode
./setup.sh -o ubuntu2004 -m minimal # Ubuntu 20.04, minimal mode
./setup.sh -o centos8 -m full # CentOS Stream 8, full mode
./setup.sh -p podman -o ubuntu2204 -bThe project supports two build modes:
-
full (default): Includes all development tools
- LLVM/Clang toolchain (version 18)
- ZSH with Oh My Zsh and plugins
- Miniconda Python distribution
- Complete development environment
-
minimal: Lightweight installation
- Essential tools only (gcc, git, vim, etc.)
- Bash shell (no ZSH)
- No LLVM/Clang
- No Miniconda
- Faster build time and smaller image size
| OS Version | Base Image | Description |
|---|---|---|
ubuntu2004 |
Ubuntu 20.04 | Focal Fossa (LTS) |
ubuntu2204 |
Ubuntu 22.04 | Jammy Jellyfish (LTS) - Default |
ubuntu2404 |
Ubuntu 24.04 | Noble Numbat (LTS) |
centos7 |
CentOS 7 | CentOS 7 |
centos8 |
CentOS Stream 8 | CentOS Stream 8 |
You can use the following options with setup.sh:
| Option | Description |
|---|---|
-o OS_VERSION |
Specify OS version (see table above) |
-m MODE |
Build mode: minimal or full (default: full) |
-b |
Build image, run container, and show IP |
-r |
Run container and show IP (skip build) |
-i |
Show container IP only |
-s |
Stop and remove the container |
-c |
Show current configuration |
-p RUNTIME |
Select runtime: docker or podman |
-l |
List available OS versions |
-h |
Display help message |
Example:
# List available OS versions
./setup.sh -l
# Build Ubuntu 24.04 with full mode (default)
./setup.sh -o ubuntu2404 -b
# Build CentOS 8 with minimal mode
./setup.sh -o centos8 -m minimal -b
# Build and run with default settings
./setup.sh
# Stop and remove container
./setup.sh -sHTTP_PROXYandHTTPS_PROXYcan be set to configure proxy for build and runtime.CONTAINER_RUNTIMEcan be set todockerorpodmanto override auto-detection.WORKSPACE_DIRcan be set to override the default host workspace mount location.SSH_BIND_ADDRESSsets the host bind address for forwarded SSH port (default:127.0.0.1).SSH_HOST_PORTsets the host forwarded SSH port (default:2222, set0for random free port).
Default container password is
123456.
You can customize the container username, password, image name, and container name by editing the variables at the top ofsetup.shbefore building/running the container.
SSH Access via Jump Host (Bastion Host):
For Podman, the recommended SSH pattern is to proxy through the bastion host using the Podman rootless-netns tunnel. The required SSH proxy command is:
Example SSH config:
Host dev-container HostName <container_ip> User sheen Port 2222 ProxyCommand cyclab-server Host cyclab-server HostName <jump_host_ip> User <your_jump_host_user> Port 22
- Replace
<container_ip>with the IP address of your container.- Replace
<jump_host_ip>and<your_jump_host_user>with your bastion host details.- After saving, you can connect with:
ssh dev-containerDocker still works with a normal direct or
ProxyJumpapproach when required, but Podman is the default recommended method in this project.
- Default container user:
sheen - Default password:
123456 - Workspace mount: Host's
~/workspace/dev_<os_version>_<mode>_<username>is mounted to/home/sheen/workspacein the container- Example:
~/workspace/dev_ubuntu2204_full_sheenfor Ubuntu 22.04 in full mode
- Example:
- Container naming: Containers are named based on OS version and build mode
- Format:
dev_<os_version>_<mode>_<username> - Example:
dev_ubuntu2204_full_sheen
- Format:
- SSH enabled: Port 22 is exposed for SSH access
- GPU support: Automatically enabled if NVIDIA runtime is available
- Shell: ZSH (full mode) or Bash (minimal mode)
# Podman flow (default)
podman ps --filter "label=user=$container_user_name"
podman start $container_name
podman stop $container_name
podman exec -it $container_name zsh
podman logs $container_name
podman rm -f $container_name
# Docker flow (optional, explicit runtime)
docker ps --filter "label=user=$container_user_name"
docker start $container_name
docker stop $container_name
docker exec -it $container_name zsh
docker logs $container_name
docker rm -f $container_name# Query connectivity info (IP if available + forwarded SSH port)
./setup.sh -i
# Podman direct-IP SSH example (when IP is available)
container_ip=$(podman inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $container_name)
echo "Container IP: $container_ip"
echo "SSH command: ssh -o ProxyCommand='ssh cyclab-server \"podman unshare --rootless-netns nc %h %p\"' $container_user_name@$container_ip"
# Podman port-forward SSH example (recommended fallback when IP is not available)
forwarded_port=$(podman port $container_name 22/tcp | head -n1 | awk -F: '{print $NF}')
echo "SSH command: ssh -p $forwarded_port $container_user_name@127.0.0.1"
# Docker SSH example
container_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $container_name)
echo "SSH command: ssh $container_user_name@$container_ip"In many rootless Podman environments, direct container IP may be unavailable. In that case, use forwarded SSH port access.
# Copy files from host to container
docker cp /path/to/local/file $container_name:/home/$container_user_name/
# Copy files from container to host
docker cp $container_name:/home/$container_user_name/file /path/to/local/A helper script is provided for proxy management:
cd scripts
./set_proxy.sh -s [PROXY_URL] # Set proxy (use default if not provided)
./set_proxy.sh -u # Unset proxy
./set_proxy.sh -t # Test proxy connection
./set_proxy.sh -st # Show current proxy status
./set_proxy.sh -h # Show help- The script will also configure proxy for
git,npm,pip, andcondaif available.
| Feature | Full Mode | Minimal Mode |
|---|---|---|
| Shell | ZSH with Oh My Zsh | Bash |
| LLVM/Clang | ✅ Version 18 | ❌ |
| Python Distribution | Miniconda | System Python 3 |
| Development Tools | Complete set | Essential only (gcc, git, cmake) |
| Image Size | Larger (~2-3GB) | Smaller (~800MB-1GB) |
| Build Time | Longer (~10-15 min) | Faster (~5-8 min) |
The full mode container includes:
- Oh My Zsh: Pre-installed with useful plugins (if installation succeeds)
- Fallback Configuration: Basic ZSH setup works even if Oh My Zsh installation fails
- Helper Functions: Manual installation commands available
- LLVM/Clang: Complete toolchain (version 18) with clangd, lld, lldb
- Python: Miniconda distribution with conda package manager
- Build Tools: gcc, cmake, ninja, make, autotools
- Additional Tools: ripgrep, tmux, jq, and more
If Oh My Zsh didn't install (you'll see a message when you log in), you can use these commands:
# Install Oh My Zsh manually
install_omz
# Install ZSH plugins (after Oh My Zsh is installed)
install_zsh_pluginsThe minimal mode is designed for:
- Quick development environments
- CI/CD pipelines
- Resource-constrained environments
- Basic compilation and testing tasks
Includes:
- Essential build tools (gcc, make, cmake)
- Version control (git)
- Text editors (vim)
- Basic utilities (curl, wget, ssh)
-
Docker permission issues
- Ensure your user is in the docker group:
sudo usermod -aG docker $USER - Log out and log back in for changes to take effect
- Ensure your user is in the docker group:
-
Network connectivity issues
- If the container can't access the internet, try setting HTTP/HTTPS proxies
- Use the proxy helper script or set environment variables
- Oh My Zsh and plugins may not install if there's no internet connection, but the container will still work
-
Container startup failures
- Check container logs:
docker logs $container_name - Verify GPU support if attempting to use it:
docker info | grep -i runtime
- Check container logs:
-
SSH permission issues
- If you encounter permission problems after SSH login:
- First login to the container via terminal:
docker exec -it $container_name zsh - Then use sudo to modify home directory permissions:
sudo chmod -R 700 /home/$container_user_name/.ssh
- First login to the container via terminal:
- If you encounter permission problems after SSH login:
-
ZSH configuration issues
- If Oh My Zsh didn't install properly, use the
install_omzhelper function - If plugins aren't working, use the
install_zsh_pluginsfunction - Make sure to restart your shell after installing plugins
- If Oh My Zsh didn't install properly, use the
- You can customize the
Dockerfileto add additional packages or configurations based on your development needs. - Scripts in the
scripts/directory can be extended for more automation.
- 2026-01-29: (V0.2.0) Added multi-OS support and build modes
- Support for Ubuntu 20.04, 22.04, 24.04
- Support for CentOS 7, Stream 8
- Two build modes: minimal and full
- Flexible configuration via command-line options
- 2025-05-30: (V0.1.1) Fixed workspace mounting and added resilient ZSH configuration
- 2025-05-29: (V0.1.0) Initial release