Skip to content

About

This repository provides a highly customizable development container environment with pre-installed tools and convenient scripts.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Latest commit

 

History

36 Commits

Folders and files

Repository files navigation

🚀 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,并内置了便捷脚本用于构建和管理开发容器。
欢迎大家共同参与、完善和持续更新本项目!

🇬🇧 English | 🇨🇳 中文


🐳 Development Container Environment

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:


📦 Prerequisites

  • 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

Runtime behavior

  • Default runtime priority: podman → docker
  • Default workspace mount:
    • Docker: /home/$(whoami)/workspace
    • Podman: /var/lib/podman/$(whoami)/mounts/workspace
  • You can override with WORKSPACE_DIR or -p to select the runtime explicitly

Docker vs Podman

Runtime Default behavior Typical use
Podman Preferred by default Rootless container development, modern Linux workflows
Docker Supported fallback Traditional Docker-based development setups

🚀 Quick Start

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 -b

Build Modes

The 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

Supported OS Versions

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

Script Options

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 -s

Environment Variables

  • HTTP_PROXY and HTTPS_PROXY can be set to configure proxy for build and runtime.
  • CONTAINER_RUNTIME can be set to docker or podman to override auto-detection.
  • WORKSPACE_DIR can be set to override the default host workspace mount location.
  • SSH_BIND_ADDRESS sets the host bind address for forwarded SSH port (default: 127.0.0.1).
  • SSH_HOST_PORT sets the host forwarded SSH port (default: 2222, set 0 for random free port).

⚠️ Note

Default container password is 123456.
You can customize the container username, password, image name, and container name by editing the variables at the top of setup.sh before 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-container

Docker still works with a normal direct or ProxyJump approach when required, but Podman is the default recommended method in this project.


🏗️ Container Details

  • Default container user: sheen
  • Default password: 123456
  • Workspace mount: Host's ~/workspace/dev_<os_version>_<mode>_<username> is mounted to /home/sheen/workspace in the container
    • Example: ~/workspace/dev_ubuntu2204_full_sheen for Ubuntu 22.04 in full mode
  • Container naming: Containers are named based on OS version and build mode
    • Format: dev_<os_version>_<mode>_<username>
    • Example: dev_ubuntu2204_full_sheen
  • 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)

🛠️ Common Commands

Container Management

# 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

SSH Connection

# 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.

File Transfer

# 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/

🌐 Proxy Configuration

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, and conda if available.

🧩 ZSH and Development Tools

Build Mode Comparison

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)

Full Mode Features

The full mode container includes:

ZSH Configuration

  • 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

Development Tools

  • 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

Helper Commands (Full Mode Only)

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_plugins

Minimal Mode Features

The 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)

🧩 Troubleshooting

Common Issues

  1. 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
  2. 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
  3. Container startup failures

    • Check container logs: docker logs $container_name
    • Verify GPU support if attempting to use it: docker info | grep -i runtime
  4. SSH permission issues

    • If you encounter permission problems after SSH login:
      1. First login to the container via terminal: docker exec -it $container_name zsh
      2. Then use sudo to modify home directory permissions: sudo chmod -R 700 /home/$container_user_name/.ssh
  5. ZSH configuration issues

    • If Oh My Zsh didn't install properly, use the install_omz helper function
    • If plugins aren't working, use the install_zsh_plugins function
    • Make sure to restart your shell after installing plugins

🎨 Customization

  • You can customize the Dockerfile to add additional packages or configurations based on your development needs.
  • Scripts in the scripts/ directory can be extended for more automation.

📚 Reference Links


📝 Changelog

  • 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

About

This repository provides a highly customizable development container environment with pre-installed tools and convenient scripts.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages