Keyboard shortcuts

Press ← or β†’ to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

Welcome to Dockim The Book - your comprehensive guide to mastering Dockim, a modern CLI tool that revolutionizes how you manage Dev Containers.

What is Dockim?

Dockim is a powerful command-line tool designed to simplify and streamline your development workflow by providing intuitive commands for Dev Container management and seamless Neovim integration. It bridges the gap between containerized development environments and productive coding experiences.

Why Use Dockim?

Modern software development increasingly relies on containerized environments to ensure consistency across different development setups. However, managing these containers can often be cumbersome and time-consuming. Dockim addresses these pain points by offering:

πŸš€ Simplified Container Management

  • One-command container initialization with dockim init
  • Effortless building and starting with dockim build and dockim up
  • Intuitive stop and cleanup commands

πŸ“ Seamless Neovim Integration

  • Launch Neovim with remote UI support directly in your container
  • Automatic port management for remote connections
  • Clipboard synchronization between host and container

πŸ›  Developer-Friendly Workflow

  • Project template generation for quick start
  • Flexible configuration options
  • Custom build support including source compilation

πŸ”§ Production-Ready Features

  • Support for complex multi-service setups
  • Integration with existing Docker workflows
  • Comprehensive configuration management

Key Features

Dockim provides a rich set of features designed to enhance your development experience:

  • Quick Container Management - Start, stop, and build dev containers effortlessly
  • Neovim Integration - Launch Neovim with remote UI support and automatic port forwarding
  • Project Initialization - Generate dev container templates instantly with sensible defaults
  • Flexible Configuration - Support for custom builds, dotfiles integration, and source compilation
  • Port Management - Easy port forwarding setup and management
  • Multi-language Support - Works with any development stack that runs in containers

How Dockim Compares

Unlike traditional Docker management tools or basic dev container CLIs, Dockim focuses specifically on the developer experience. It combines the power of Dev Containers with the productivity of modern editors like Neovim, creating a unified workflow that just works.

FeatureTraditional DockerDev Container CLIDockim
Container Managementβœ… Complexβœ… Goodβœ… Simplified
Editor Integration❌ Manual setup❌ Limitedβœ… Built-in
Project Templates❌ None⚠️ Basicβœ… Comprehensive
Configuration⚠️ Verbose⚠️ JSON-heavyβœ… User-friendly
Port Management⚠️ Manual⚠️ Limitedβœ… Automatic

Who Should Use This Book?

This book is designed for:

  • Developers who want to adopt containerized development workflows
  • Teams looking to standardize their development environments
  • Neovim users seeking seamless container integration
  • DevOps engineers implementing developer tooling
  • Anyone interested in modern development practices

How to Use This Book

The book is structured to take you from complete beginner to advanced user:

  1. Getting Started - Installation and your first project
  2. User Guide - Core workflows and everyday usage
  3. Integration Guides - Neovim setup and advanced configurations
  4. Reference - Complete command documentation
  5. Advanced Topics - Custom setups and troubleshooting

Each chapter builds upon the previous ones, but experienced users can jump to specific sections as needed.

Prerequisites

Before diving into Dockim, you should have:

  • Basic familiarity with command-line tools
  • Docker installed and running
  • Understanding of development containers (helpful but not required)
  • Neovim installed (for integration features)

Ready to streamline your development workflow? Let's get started with Dockim!

Getting Started

This chapter will guide you through installing Dockim and creating your first development environment. By the end of this chapter, you'll have a working Dockim setup and understand the basic workflow.

Prerequisites

Before installing Dockim, ensure you have the following prerequisites installed on your system:

Required Dependencies

Docker or Docker Desktop

  • Purpose: Dockim relies on Docker to create and manage development containers
  • Installation: Visit Docker's official installation guide
  • Verification: Run docker --version to confirm installation

Dev Container CLI

  • Purpose: Provides the underlying container management functionality
  • Installation: npm install -g @devcontainers/cli
  • Verification: Run devcontainer --version to confirm installation

Neovim

  • Purpose: Required for Dockim's advanced editor integration features
  • Installation: Visit Neovim's installation guide
  • Verification: Run nvim --version to confirm installation

Installation

Dockim can be installed in several ways. Choose the method that best fits your setup:

This method installs the latest stable version directly from the repository:

cargo install --git https://github.com/statiolake/dockim

Advantages:

  • Always gets the latest stable version
  • Automatically handles Rust dependencies
  • Easy to update with the same command

Method 2: Build from Source

If you want to contribute to development or need the absolute latest changes:

# Clone the repository
git clone https://github.com/statiolake/dockim
cd dockim

# Build and install
cargo install --path .

Advantages:

  • Access to the latest development features
  • Ability to modify the source code
  • Full control over the build process

Method 3: Using Pre-built Binaries (Future)

Note: Pre-built binaries are planned for future releases and will be available on the GitHub releases page.

Verification

After installation, verify that Dockim is working correctly:

# Check if dockim is installed and accessible
dockim --version

# View available commands
dockim --help

You should see output similar to:

dockim 0.1.0
A modern CLI tool for managing Dev Containers with ease

Your First Project

Let's create your first project with Dockim to understand the basic workflow:

Step 1: Create a New Directory

mkdir my-first-dockim-project
cd my-first-dockim-project

Step 2: Initialize the Project

dockim init

This command creates the following structure:

.devcontainer/
β”œβ”€β”€ devcontainer.json    # Dev container configuration
β”œβ”€β”€ compose.yml          # Docker Compose configuration
└── Dockerfile          # Custom Docker image definition

Step 3: Examine the Generated Files

devcontainer.json - The main configuration file:

{
    "name": "Development Container",
    "dockerComposeFile": "compose.yml",
    "service": "dev",
    "workspaceFolder": "/workspace",
    "features": {},
    "customizations": {
        "vscode": {
            "extensions": []
        }
    }
}

compose.yml - Docker Compose setup:

services:
  dev:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ..:/workspace:cached
    command: sleep infinity

Dockerfile - Custom image definition:

FROM mcr.microsoft.com/devcontainers/base:ubuntu

# Install additional tools as needed
RUN apt-get update && apt-get install -y \
    git \
    curl \
    && rm -rf /var/lib/apt/lists/*

Step 4: Build Your Container

dockim build

This command:

  • Builds the Docker image defined in your Dockerfile
  • Downloads and prepares all necessary dependencies
  • Sets up the development environment

You'll see output similar to:

πŸ”¨ Building development container...
[+] Building 45.2s (8/8) FINISHED
βœ… Container built successfully!

Step 5: Start Your Development Environment

dockim up

This command:

  • Starts the development container
  • Mounts your project directory
  • Prepares the environment for development

Step 6: Access Your Container

Open a shell in your running container:

dockim shell

You're now inside your development container! You can run commands, install packages, and develop your project in this isolated environment.

Understanding the Workflow

The basic Dockim workflow follows this pattern:

  1. Initialize (dockim init) - Set up project structure
  2. Build (dockim build) - Create the development environment
  3. Start (dockim up) - Launch the container
  4. Develop (dockim shell, dockim exec, dockim neovim) - Work in the environment
  5. Stop (dockim stop or dockim down) - Clean up when done

Configuration Basics

Global Configuration

Create a global configuration file for your preferences:

dockim init-config

This creates ~/.config/dockim/config.toml with default settings:

shell = "/bin/zsh"
neovim_version = "v0.11.0"
dotfiles_repository_name = "dotfiles"
dotfiles_install_command = "echo 'no dotfiles install command configured'"

[remote]
background = false
use_clipboard_server = true
args = ["nvim", "--server", "{server}", "--remote-ui"]

Project-Specific Settings

Each project's .devcontainer/devcontainer.json can be customized for specific needs:

  • Add development tools
  • Configure environment variables
  • Set up port forwarding
  • Install VS Code extensions

Next Steps

Now that you have a basic understanding of Dockim, you can:

Common Issues

Docker Permission Issues

If you encounter permission errors with Docker:

# Add your user to the docker group (Linux)
sudo usermod -aG docker $USER
# Log out and back in for changes to take effect

Port Already in Use

If you see "port already in use" errors:

# Stop all containers
dockim stop

# Or remove them completely
dockim down

Build Failures

If container builds fail:

# Rebuild from scratch
dockim build --rebuild

# Build without Docker cache
dockim build --no-cache

Congratulations! You've successfully set up Dockim and created your first development environment. Ready to dive deeper? Let's explore the User Guide to master everyday workflows.

User Guide

This user guide covers the everyday workflows and core functionality of Dockim. Once you've completed the Getting Started chapter, this guide will help you master the daily development workflows and become productive with Dockim.

Overview

The user guide is divided into three main sections:

Core Concepts

Before diving into specific workflows, let's establish some core concepts that will help you understand how Dockim works:

Development Containers

A development container (or "dev container") is a running Docker container that serves as a fully-featured development environment. It includes:

  • Runtime Environment: The programming languages, frameworks, and tools you need
  • Source Code Access: Your project files are mounted into the container
  • Isolation: Dependencies don't conflict with your host system
  • Reproducibility: Every team member gets the same environment

Dockim's Role

Dockim acts as a friendly interface between you and the underlying container technologies:

You β†’ Dockim β†’ Dev Container CLI β†’ Docker β†’ Your Development Environment

This abstraction means you can focus on development rather than container management details.

Project Structure

Every Dockim project follows this structure:

your-project/
β”œβ”€β”€ .devcontainer/          # Container configuration
β”‚   β”œβ”€β”€ devcontainer.json  # Main configuration file
β”‚   β”œβ”€β”€ compose.yml         # Docker Compose setup
β”‚   └── Dockerfile          # Custom image definition
β”œβ”€β”€ src/                    # Your application code
└── ... (other project files)

Configuration Hierarchy

Dockim uses a configuration hierarchy that allows for both global preferences and project-specific settings:

  1. Global Config (~/.config/dockim/config.toml) - Your personal defaults
  2. Project Config (.devcontainer/devcontainer.json) - Project-specific settings
  3. Command Options - Runtime overrides for specific operations

Common Workflows

Here are the most common workflows you'll use with Dockim:

Starting a New Day

# Navigate to your project
cd my-project

# Start your development environment
dockim up

# Launch your editor
dockim neovim

Making Changes to Container Setup

# Edit your container configuration
vim .devcontainer/Dockerfile

# Rebuild with changes
dockim build --rebuild

# Restart with new container
dockim up

Switching Between Projects

# Stop current project
dockim stop

# Switch to another project
cd ../other-project

# Start the other project
dockim up

End of Day Cleanup

# Stop containers (keeps them for quick restart)
dockim stop

# Or remove containers completely (frees up disk space)
dockim down

Understanding Container States

Your development containers can be in several states:

  • Not Created: No container exists yet (initial state)
  • Built: Container image exists but no running container
  • Running: Container is actively running and ready for development
  • Stopped: Container exists but is not running
  • Removed: Container has been deleted (but image may remain)

Here's how Dockim commands affect these states:

Not Created β†’ dockim build β†’ Built
Built β†’ dockim up β†’ Running
Running β†’ dockim stop β†’ Stopped
Stopped β†’ dockim up β†’ Running
Stopped β†’ dockim down β†’ Removed (back to Built)

Best Practices

Project Organization

  • Keep all project-specific configuration in .devcontainer/
  • Use version control to track container configuration changes
  • Document any manual setup steps in your project README

Container Maintenance

  • Regularly rebuild containers to get security updates: dockim build --rebuild
  • Use dockim down periodically to clean up unused containers
  • Monitor disk usage, especially when working with multiple projects

Development Workflow

  • Start containers before beginning work: dockim up
  • Use dockim shell for quick command-line tasks
  • Use dockim neovim for extended editing sessions
  • Stop containers when switching projects: dockim stop

Team Collaboration

  • Share .devcontainer/ configuration through version control
  • Document any required environment variables or secrets
  • Use consistent base images and tool versions across the team
  • Consider using a shared container registry for custom images

Next Steps

Now that you understand the core concepts, dive into the specific aspects of using Dockim:

  1. Project Initialization - Learn how to set up new projects effectively
  2. Container Management - Master building and managing your containers
  3. Development Workflow - Optimize your daily development routines

Each section builds on these core concepts while providing practical, actionable guidance for specific scenarios.

Project Initialization

This section covers how to initialize new projects with Dockim, understand the generated configuration files, and customize them for your specific needs.

Basic Initialization

Creating a New Project

The simplest way to start a new Dockim project:

# Create and navigate to project directory
mkdir my-new-project
cd my-new-project

# Initialize Dockim configuration
dockim init

This creates the essential .devcontainer/ directory structure with sensible defaults.

Initializing in Existing Projects

You can add Dockim to existing projects:

# Navigate to existing project
cd existing-project

# Initialize Dockim (won't overwrite existing files)
dockim init

# Your existing files remain untouched
ls -la

Dockim will not overwrite existing files, making it safe to run in projects that already have some containerization setup.

Understanding Generated Files

Let's examine each file created by dockim init:

devcontainer.json

The main configuration file that defines your development environment:

{
    "name": "Development Container",
    "dockerComposeFile": "compose.yml",
    "service": "dev",
    "workspaceFolder": "/workspace",
    "features": {},
    "customizations": {
        "vscode": {
            "extensions": []
        }
    }
}

Key Properties:

  • name: Display name for your container
  • dockerComposeFile: Points to the Docker Compose configuration
  • service: Which service from compose.yml to use as the dev container
  • workspaceFolder: Where your code is mounted inside the container
  • features: Pre-built development tools to install
  • customizations: Editor-specific settings

compose.yml

Docker Compose configuration that defines the container services:

services:
  dev:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ..:/workspace:cached
    command: sleep infinity

Key Elements:

  • services.dev: The main development container
  • build: Specifies how to build the container image
  • volumes: Mounts your project code into the container
  • command: Keeps container running (required for dev containers)

Dockerfile

Custom image definition with development tools:

FROM mcr.microsoft.com/devcontainers/base:ubuntu

# Install additional tools as needed
RUN apt-get update && apt-get install -y \
    git \
    curl \
    && rm -rf /var/lib/apt/lists/*

Structure:

  • FROM: Base image (Ubuntu with dev container features)
  • RUN: Commands to install additional tools
  • Clean package lists to reduce image size

Customizing Your Setup

Choosing a Base Image

Dockim uses sensible defaults, but you can customize the base image for your project needs:

For Node.js projects:

FROM mcr.microsoft.com/devcontainers/javascript-node:18

For Python projects:

FROM mcr.microsoft.com/devcontainers/python:3.11

For Rust projects:

FROM mcr.microsoft.com/devcontainers/rust:latest

For multi-language projects:

FROM mcr.microsoft.com/devcontainers/base:ubuntu

# Install multiple runtimes
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
    && apt-get install -y nodejs python3 python3-pip

Adding Development Tools

Customize the Dockerfile to include tools your project needs:

FROM mcr.microsoft.com/devcontainers/base:ubuntu

# System utilities
RUN apt-get update && apt-get install -y \
    git \
    curl \
    wget \
    unzip \
    jq \
    && rm -rf /var/lib/apt/lists/*

# Programming language tools
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - && apt-get install -y nodejs

# Development tools
RUN npm install -g yarn pnpm
RUN pip3 install black flake8 mypy

# Set up dotfiles (optional)
RUN git clone https://github.com/yourusername/dotfiles.git /tmp/dotfiles \
    && /tmp/dotfiles/install.sh \
    && rm -rf /tmp/dotfiles

Configuring Features

Dev Container Features are pre-built tools you can enable easily:

{
    "name": "Development Container",
    "dockerComposeFile": "compose.yml",
    "service": "dev",
    "workspaceFolder": "/workspace",
    "features": {
        "ghcr.io/devcontainers/features/docker-in-docker:2": {},
        "ghcr.io/devcontainers/features/github-cli:1": {},
        "ghcr.io/devcontainers/features/node:1": {
            "version": "18"
        }
    }
}

Popular Features:

  • docker-in-docker: Docker inside your dev container
  • github-cli: GitHub CLI tool
  • node: Node.js runtime
  • python: Python runtime
  • go: Go runtime

Environment Variables

Set environment variables for your development environment:

# compose.yml
services:
  dev:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ..:/workspace:cached
    environment:
      - NODE_ENV=development
      - API_URL=http://localhost:3000
      - DEBUG=true
    command: sleep infinity

Or in devcontainer.json:

{
    "remoteEnv": {
        "NODE_ENV": "development",
        "API_URL": "http://localhost:3000",
        "DEBUG": "true"
    }
}

Port Forwarding

Configure automatic port forwarding for your services:

{
    "forwardPorts": [3000, 8080, 5432],
    "portsAttributes": {
        "3000": {
            "label": "Application",
            "onAutoForward": "notify"
        },
        "8080": {
            "label": "API Server",
            "onAutoForward": "openPreview"
        }
    }
}

Project Templates

Web Application Template

For a typical web application with frontend and backend:

FROM mcr.microsoft.com/devcontainers/javascript-node:18

# Install additional tools
RUN apt-get update && apt-get install -y \
    postgresql-client \
    redis-tools \
    && rm -rf /var/lib/apt/lists/*

# Install global npm packages
RUN npm install -g @vue/cli create-react-app
# compose.yml
services:
  dev:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ..:/workspace:cached
    environment:
      - NODE_ENV=development
    command: sleep infinity
    
  database:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: dev
      POSTGRES_DB: myapp
    ports:
      - "5432:5432"
    
  redis:
    image: redis:alpine
    ports:
      - "6379:6379"

Data Science Template

For Python-based data science projects:

FROM mcr.microsoft.com/devcontainers/python:3.11

# Install system dependencies
RUN apt-get update && apt-get install -y \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

# Install Python packages
RUN pip install \
    jupyter \
    pandas \
    numpy \
    matplotlib \
    seaborn \
    scikit-learn \
    plotly
{
    "forwardPorts": [8888],
    "portsAttributes": {
        "8888": {
            "label": "Jupyter Lab",
            "onAutoForward": "openBrowser"
        }
    }
}

Microservices Template

For projects with multiple services:

# compose.yml
services:
  dev:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ..:/workspace:cached
    depends_on:
      - api
      - database
    command: sleep infinity
    
  api:
    build:
      context: ./api
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://user:pass@database:5432/myapp
      
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
      
  database:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: dev
      POSTGRES_DB: myapp

Best Practices

File Organization

Keep your configuration organized:

.devcontainer/
β”œβ”€β”€ devcontainer.json      # Main configuration
β”œβ”€β”€ compose.yml           # Container orchestration
β”œβ”€β”€ Dockerfile           # Custom image
β”œβ”€β”€ docker-compose.override.yml  # Local overrides (gitignored)
└── scripts/
    β”œβ”€β”€ postCreateCommand.sh    # Setup scripts
    └── postStartCommand.sh     # Startup scripts

Version Control

Include in version control:

  • .devcontainer/devcontainer.json
  • .devcontainer/compose.yml
  • .devcontainer/Dockerfile
  • Setup scripts

Exclude from version control:

  • .devcontainer/docker-compose.override.yml
  • Sensitive environment files

Documentation

Document your setup for team members:

# Development Setup

## Prerequisites
- Docker Desktop
- Dockim CLI

## Getting Started
1. `dockim init` (if not done already)
2. `dockim build`
3. `dockim up`
4. `dockim neovim`

## Services
- App: http://localhost:3000
- API: http://localhost:8080
- Database: localhost:5432

Troubleshooting

Common Issues

Build failures:

# Clear build cache and rebuild
dockim build --no-cache

Permission issues:

# Add to Dockerfile
ARG USERNAME=vscode
RUN usermod -aG sudo $USERNAME

Slow file sync:

# Use cached volumes for better performance
volumes:
  - ..:/workspace:cached

Next: Learn about Container Management to master building and maintaining your development containers.

Container Management

This section covers the lifecycle of your development containers: building, starting, stopping, rebuilding, and maintaining them for optimal performance.

Container Lifecycle

Understanding the container lifecycle helps you choose the right commands for different situations:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    dockim build    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    dockim up      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚             β”‚ ───────────────────▢│             β”‚ ─────────────────▢│             β”‚
β”‚ Not Created β”‚                    β”‚    Built    β”‚                  β”‚   Running   β”‚
β”‚             β”‚                    β”‚             β”‚                  β”‚             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                           β–²                                β”‚
                                           β”‚                                β”‚
                                           β”‚ dockim down                    β”‚ dockim stop
                                           β”‚                                β”‚
                                           β”‚                                β–Ό
                                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    dockim up      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                    β”‚             β”‚ ◀─────────────────│             β”‚
                                    β”‚   Removed   β”‚                  β”‚   Stopped   β”‚
                                    β”‚             β”‚                  β”‚             β”‚
                                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Building Containers

Basic Building

The dockim build command creates your container image:

# Build with current configuration
dockim build

This process:

  1. Reads your .devcontainer/Dockerfile
  2. Downloads the base image
  3. Installs your specified tools and dependencies
  4. Creates a reusable container image

Build Options

Rebuild from scratch:

# Ignore existing image and rebuild completely
dockim build --rebuild

Clear Docker cache:

# Build without using Docker's layer cache
dockim build --no-cache

Build Neovim from source:

# Compile Neovim instead of using binaries
dockim build --neovim-from-source

When to Rebuild

Rebuild your container when:

  • You modify the Dockerfile
  • You change the base image
  • You want to get security updates
  • Dependencies aren't working correctly
  • You've added new development tools

Build Performance Tips

Use multi-stage builds:

# Build stage
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

# Development stage
FROM mcr.microsoft.com/devcontainers/javascript-node:18
COPY --from=builder /app/node_modules /app/node_modules

Order operations by change frequency:

FROM mcr.microsoft.com/devcontainers/base:ubuntu

# System packages (change rarely)
RUN apt-get update && apt-get install -y \
    git curl wget \
    && rm -rf /var/lib/apt/lists/*

# Language runtimes (change occasionally)
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
    && apt-get install -y nodejs

# Project-specific tools (change frequently)
COPY requirements.txt /tmp/
RUN pip install -r /tmp/requirements.txt

Use .dockerignore:

# .dockerignore
node_modules/
.git/
*.log
.env.local

Starting Containers

Basic Start

Start your development environment:

# Start container (builds if necessary)
dockim up

Start Options

Force rebuild and start:

# Rebuild container image, then start
dockim up --rebuild

Background vs Foreground

Dockim containers run in the background by default, allowing you to:

  • Use multiple terminal sessions
  • Run the container without keeping a terminal open
  • Start multiple services simultaneously

Stopping Containers

Graceful Stop

# Stop container but keep it for quick restart
dockim stop

The container preserves:

  • Installed packages
  • Configuration changes
  • Temporary files
  • Process states (where possible)

Complete Removal

# Remove container completely (keeps image)
dockim down

This frees up:

  • Disk space used by the container
  • Memory allocated to the container
  • Network resources

Container Inspection

View Running Containers

# List active containers
docker ps

# View Dockim-related containers only
docker ps --filter "label=dockim"

Container Logs

# View container startup logs
docker logs <container_name>

# Follow logs in real-time
docker logs -f <container_name>

Resource Usage

# View resource usage
docker stats

# One-time resource snapshot
docker stats --no-stream

Advanced Management

Multiple Projects

When working with multiple projects:

# Project A
cd project-a
dockim up

# Switch to Project B (keep A running)
cd ../project-b  
dockim up

# Stop all containers when done
cd ../project-a && dockim stop
cd ../project-b && dockim stop

Container Cleanup

Remove unused containers:

# Remove stopped containers
docker container prune

# Remove unused images
docker image prune

# Remove everything unused (be careful!)
docker system prune

Clean up Dockim specifically:

# Stop and remove all Dockim containers
dockim down

# In each project directory, or:
find . -name ".devcontainer" -type d | while read dir; do
    cd "$(dirname "$dir")" && dockim down 2>/dev/null || true
done

Disk Space Management

Monitor disk usage:

# Check Docker disk usage
docker system df

# Detailed breakdown
docker system df -v

Regular maintenance:

# Weekly cleanup routine
docker container prune -f
docker image prune -f
docker volume prune -f
docker network prune -f

Networking

Port Forwarding

Automatic forwarding:

// devcontainer.json
{
    "forwardPorts": [3000, 8080],
    "portsAttributes": {
        "3000": {
            "label": "Web App",
            "onAutoForward": "notify"
        }
    }
}

Manual forwarding:

# Forward specific ports using Dockim
dockim port add 3000
dockim port add 8080:3000  # host:container

# View active forwards
dockim port ls

# Remove forwards
dockim port rm 3000

Service Communication

When using multiple services in compose.yml:

services:
  dev:
    # ... dev container config
    depends_on:
      - database
      - redis
      
  database:
    image: postgres:15
    environment:
      POSTGRES_DB: myapp
      POSTGRES_PASSWORD: dev
      
  redis:
    image: redis:alpine

Access services by name:

# Inside the dev container
psql -h database -U postgres myapp
redis-cli -h redis

Performance Optimization

Volume Performance

Use cached volumes:

volumes:
  - ..:/workspace:cached  # macOS/Windows
  - ..:/workspace:z       # Linux with SELinux

Separate node_modules:

volumes:
  - ..:/workspace:cached
  - /workspace/node_modules  # Anonymous volume for better performance

Memory and CPU Limits

services:
  dev:
    # ... other config
    deploy:
      resources:
        limits:
          memory: 2G
          cpus: '1.5'
        reservations:
          memory: 1G
          cpus: '0.5'

Build Context Optimization

Keep build context small:

# Copy only what you need
COPY package*.json ./
RUN npm ci

# Copy source code last (changes most frequently)
COPY . .

Troubleshooting

Container Won't Start

Check container logs:

docker logs $(docker ps -aq --filter "label=dockim")

Verify configuration:

# Validate compose file
docker-compose -f .devcontainer/compose.yml config

Check resource availability:

# Ensure Docker has enough resources
docker info | grep -E "(Memory|CPUs)"

Build Failures

Network issues:

# Use specific DNS servers
FROM mcr.microsoft.com/devcontainers/base:ubuntu
RUN echo 'nameserver 8.8.8.8' > /etc/resolv.conf

Permission issues:

# Fix permissions during build
RUN chown -R vscode:vscode /workspace

Cache issues:

# Clear all caches and rebuild
docker builder prune -a
dockim build --no-cache

Performance Issues

Slow file sync:

  • Use cached volume mounts
  • Exclude node_modules with anonymous volumes
  • Consider using Docker Desktop's file sharing optimizations

High memory usage:

  • Set memory limits in compose.yml
  • Monitor with docker stats
  • Regularly clean unused containers and images

Slow builds:

  • Optimize Dockerfile layer order
  • Use multi-stage builds
  • Implement proper .dockerignore

Next: Learn about Development Workflow to optimize your daily development routines within containers.

Development Workflow

This section covers the day-to-day development activities within your Dockim containers, from running commands to editing code and managing your development environment.

Daily Development Routine

Starting Your Day

A typical day with Dockim begins with:

# Navigate to your project
cd my-project

# Start your development environment
dockim up

# Open your editor
dockim neovim
# or use the short alias
dockim v

During Development

Throughout your day, you'll use various commands:

# Run tests
dockim exec npm test

# Install new dependencies
dockim exec npm install lodash

# Check git status
dockim exec git status

# Run database migrations
dockim exec python manage.py migrate

End of Day

Clean shutdown:

# Save your work first!
# Then stop the container
dockim stop

# Or for a full cleanup
dockim down

Working with Shells

Interactive Shell Access

The most common way to work inside your container:

# Default shell (usually zsh)
dockim shell
# Short alias
dockim sh

# Specific shell
dockim bash

Inside the shell, you have access to:

  • All your project files mounted at /workspace
  • Installed development tools and languages
  • Network access for downloading dependencies
  • Environment variables from your configuration

Shell Customization

Configure your preferred shell:

# ~/.config/dockim/config.toml
shell = "/bin/zsh"  # or "/bin/bash", "/bin/fish", etc.

Set up your shell environment:

# In your Dockerfile
RUN apt-get update && apt-get install -y zsh
RUN chsh -s /bin/zsh vscode

# Install oh-my-zsh
RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

Executing Commands

One-off Commands

Execute commands without opening an interactive shell:

# Single commands
dockim exec ls -la
dockim exec python --version
dockim exec npm run build

# Commands with arguments
dockim exec git commit -m "Add new feature"
dockim exec curl -X POST http://localhost:3000/api/test

Running Scripts

Execute project scripts:

# Package.json scripts
dockim exec npm run dev
dockim exec npm run test:watch
dockim exec npm run lint

# Custom scripts
dockim exec ./scripts/setup.sh
dockim exec python scripts/seed_database.py

Background Processes

Some processes need to run in the background:

# Start a development server (blocks terminal)
dockim exec npm run dev

# Or run in background (in a new terminal)
dockim exec npm run dev &

# Check running processes
dockim exec ps aux

File Operations

File Editing Patterns

Quick edits:

# Small config changes
dockim exec nano .env
dockim exec vim package.json

Extended editing sessions:

# Launch full Neovim with remote UI
dockim neovim

# Or directly in container (no remote UI)
dockim neovim --no-remote-ui

File Synchronization

Your files are automatically synchronized between host and container:

# Edit on host
echo "console.log('hello');" > app.js

# Immediately available in container
dockim exec node app.js  # outputs: hello

File Permissions

Handle permission issues:

# In Dockerfile, ensure correct ownership
ARG USERNAME=vscode
RUN chown -R $USERNAME:$USERNAME /workspace
# Fix permissions from inside container
dockim exec sudo chown -R vscode:vscode /workspace

Development Server Management

Running Development Servers

Node.js applications:

# Start development server
dockim exec npm run dev

# With specific port
dockim exec PORT=3000 npm start

Python applications:

# Django
dockim exec python manage.py runserver 0.0.0.0:8000

# Flask
dockim exec FLASK_ENV=development flask run --host=0.0.0.0

Multiple services:

# Terminal 1: Backend
dockim exec npm run server

# Terminal 2: Frontend  
dockim exec npm run client

# Terminal 3: Additional services
dockim exec npm run workers

Port Access

Access your running services:

# Add port forwarding
dockim port add 3000
dockim port add 8080:80  # host:container

# View active forwards
dockim port ls

# Access from host browser
# http://localhost:3000
# http://localhost:8080

Database and Service Interaction

Database Operations

PostgreSQL:

# Connect to database
dockim exec psql -h database -U postgres myapp

# Run migrations
dockim exec python manage.py migrate

# Seed data
dockim exec python manage.py loaddata fixtures/initial_data.json

MongoDB:

# Connect to MongoDB
dockim exec mongo mongodb://database:27017/myapp

# Import data
dockim exec mongoimport --host database --db myapp --collection users --file users.json

Redis Operations

# Connect to Redis
dockim exec redis-cli -h redis

# Check Redis status
dockim exec redis-cli -h redis ping

Service Health Checks

# Check all services are running
dockim exec curl http://localhost:3000/health
dockim exec curl http://api:8080/status
dockim exec pg_isready -h database

Environment Management

Environment Variables

Set for single commands:

dockim exec NODE_ENV=production npm run build
dockim exec DEBUG=app:* npm start

Set in configuration:

# compose.yml
services:
  dev:
    environment:
      - NODE_ENV=development
      - API_URL=http://localhost:3000
      - DEBUG=true

Load from files:

# compose.yml
services:
  dev:
    env_file:
      - .env
      - .env.local

Secrets Management

For development secrets:

# Create .env.local (add to .gitignore)
echo "DATABASE_PASSWORD=dev_secret" > .env.local
echo "API_KEY=dev_api_key" >> .env.local

For production-like testing:

# Use Docker secrets
dockim exec docker secret ls

Testing Workflows

Running Tests

Unit tests:

# Run all tests
dockim exec npm test

# Run specific test file
dockim exec npm test -- user.test.js

# Watch mode
dockim exec npm run test:watch

Integration tests:

# With test database
dockim exec TEST_DB_URL=postgres://test:test@database:5432/test_db npm test

# Run e2e tests
dockim exec npm run test:e2e

Test Environment Setup

Isolated test database:

# compose.yml
services:
  test-db:
    image: postgres:15
    environment:
      POSTGRES_DB: test_db
      POSTGRES_PASSWORD: test
    ports:
      - "5433:5432"  # Different port

Test-specific configuration:

# Run tests with test config
dockim exec NODE_ENV=test npm test

Debugging

Debug Configuration

Node.js debugging:

# Start with debugger
dockim exec node --inspect=0.0.0.0:9229 app.js

# Add port forward for debugger
dockim port add 9229

Python debugging:

# Install pdb
dockim exec pip install pdb

# Debug with pdb
dockim exec python -m pdb app.py

Log Access

Application logs:

# View logs in real-time
dockim exec tail -f logs/app.log

# Search logs
dockim exec grep "ERROR" logs/app.log

Container logs:

# View container startup logs
docker logs <container_name>

# Follow container logs
docker logs -f <container_name>

Performance Monitoring

Resource Usage

Inside container:

# CPU and memory usage
dockim exec htop

# Disk usage
dockim exec df -h
dockim exec du -sh /workspace/*

# Network activity
dockim exec netstat -tuln

From host:

# Container resource usage
docker stats

# Docker system info
docker system df

Application Performance

Node.js profiling:

# CPU profiling
dockim exec node --prof app.js

# Memory usage
dockim exec node --inspect --max-old-space-size=4096 app.js

Database performance:

# PostgreSQL queries
dockim exec psql -h database -c "SELECT * FROM pg_stat_activity;"

# MongoDB operations
dockim exec mongo --eval "db.currentOp()"

Best Practices

Command Organization

Create project-specific aliases:

# Add to your shell rc file
alias dtest="dockim exec npm test"
alias ddev="dockim exec npm run dev"  
alias dlint="dockim exec npm run lint"
alias dfix="dockim exec npm run lint:fix"

Use npm scripts for complex commands:

{
  "scripts": {
    "dev": "concurrently \"npm run server\" \"npm run client\"",
    "test:full": "npm run lint && npm run test && npm run test:e2e",
    "setup": "./scripts/setup.sh"
  }
}

Workflow Optimization

Terminal management:

# Terminal 1: Main development
dockim neovim

# Terminal 2: Server/services
dockim exec npm run dev

# Terminal 3: Testing/commands
dockim shell

# Terminal 4: Monitoring
docker stats

Hot reloading setup:

# Enable hot reloading in Dockerfile
ENV CHOKIDAR_USEPOLLING=true
ENV WATCHPACK_POLLING=true

Error Handling

Graceful failure recovery:

# If container becomes unresponsive
dockim stop
dockim up

# If build fails
dockim build --no-cache
dockim up --rebuild

# If services conflict
dockim down
docker system prune
dockim up

Integration with External Tools

Git Workflow

# Git operations in container
dockim exec git status
dockim exec git add .
dockim exec git commit -m "Update feature"
dockim exec git push

# Or use git on host (recommended)
git status  # Uses host git with container files

CI/CD Integration

Test in container:

# Simulate CI environment
dockim exec NODE_ENV=test npm ci
dockim exec npm run test:ci
dockim exec npm run build

Export artifacts:

# Build and extract artifacts
dockim exec npm run build
docker cp container_name:/workspace/dist ./dist

This completes the User Guide section. You now have comprehensive knowledge of Dockim's core workflows. Next, explore Neovim Integration for advanced editing capabilities.

Neovim Integration

One of Dockim's standout features is its seamless integration with Neovim. This chapter covers how to set up, configure, and optimize Neovim for use with your development containers.

Overview

Dockim's Neovim integration provides two main modes of operation:

  1. Remote UI Mode (default) - Neovim runs in the container while the UI runs on your host
  2. Direct Mode - Neovim runs entirely within the container

The remote UI mode is recommended as it provides the best of both worlds: your familiar host environment with access to the containerized development tools.

Quick Start

Basic Usage

Launch Neovim with automatic setup:

# Start Neovim with remote UI (recommended)
dockim neovim
# Short alias
dockim v

# Start directly in container (no remote UI)
dockim neovim --no-remote-ui

First Launch

On your first launch, Dockim will:

  1. Start the container if it's not running
  2. Launch Neovim server inside the container
  3. Find an available port for the connection
  4. Start your local Neovim client
  5. Establish the remote connection

Remote UI Mode

How It Works

Remote UI mode creates a client-server architecture:

Host Machine                    Container
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Neovim Client  β”‚ ◀────────▢ β”‚  Neovim Server  β”‚
β”‚  (Your UI)      β”‚  Network   β”‚  (LSP, Tools)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  Connectionβ””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Benefits:

  • Native performance on your host system
  • Access to all container tools and LSPs
  • Seamless file synchronization
  • Clipboard integration
  • Port forwarding handled automatically

Port Management

Dockim automatically manages ports for Neovim connections:

# View active Neovim connections
dockim port ls

# Specify a custom host port
dockim neovim --host-port 8080

Port Selection:

  • Dockim automatically finds available ports
  • Default range: 52000-53000
  • You can specify a custom port if needed
  • Multiple projects can run simultaneously

Client Configuration

Configure your Neovim client behavior:

# ~/.config/dockim/config.toml
[remote]
# Run client in background (don't block terminal)
background = false

# Enable clipboard synchronization
use_clipboard_server = true

# Custom client command
args = ["nvim", "--server", "{server}", "--remote-ui"]

Configuration Options:

  • background: Whether to run client in background
  • use_clipboard_server: Enable clipboard sync between host/container
  • args: Command template for launching the client

Server Configuration

Container Neovim Setup

Install and configure Neovim in your container:

# In your Dockerfile
FROM mcr.microsoft.com/devcontainers/base:ubuntu

# Install Neovim (latest stable)
RUN apt-get update && apt-get install -y software-properties-common \
    && add-apt-repository ppa:neovim-ppa/stable \
    && apt-get update && apt-get install -y neovim \
    && rm -rf /var/lib/apt/lists/*

# Or install from source for latest features
RUN curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim-linux64.tar.gz \
    && tar -C /opt -xzf nvim-linux64.tar.gz \
    && ln -s /opt/nvim-linux64/bin/nvim /usr/local/bin/nvim

Building from Source

For the absolute latest Neovim features:

# Build with Neovim from source
dockim build --neovim-from-source

This option:

  • Downloads and compiles the latest Neovim
  • Takes longer but provides cutting-edge features
  • Useful for plugin development or beta testing

Neovim Version Management

Configure the Neovim version to install:

# ~/.config/dockim/config.toml
neovim_version = "v0.11.0"  # Specific version
# or
neovim_version = "stable"   # Latest stable
# or  
neovim_version = "nightly"  # Latest nightly

Configuration Management

Dotfiles Integration

Automatically set up your Neovim configuration:

# ~/.config/dockim/config.toml
dotfiles_repository_name = "dotfiles"
dotfiles_install_command = "./install.sh nvim"

Dotfiles Workflow:

  1. Dockim clones your dotfiles repository
  2. Runs the specified install command
  3. Your Neovim configuration is available immediately

Configuration Mounting

Alternative approaches for configuration:

Mount local config:

# compose.yml
services:
  dev:
    volumes:
      - ..:/workspace:cached
      - ~/.config/nvim:/home/vscode/.config/nvim:ro

Copy during build:

# Dockerfile
COPY .config/nvim /home/vscode/.config/nvim
RUN chown -R vscode:vscode /home/vscode/.config

Language Server Protocol (LSP)

LSP in Containers

One major advantage of container-based development is consistent LSP setup:

Node.js/TypeScript:

# Install language servers in container
RUN npm install -g typescript-language-server typescript
RUN npm install -g @volar/vue-language-server

Python:

RUN pip install python-lsp-server[all] pylsp-mypy pylsp-rope
RUN pip install black isort flake8

Rust:

RUN rustup component add rust-analyzer

Go:

RUN go install golang.org/x/tools/gopls@latest

LSP Configuration

Example Neovim LSP setup for containers:

-- ~/.config/nvim/lua/lsp-config.lua
local lspconfig = require('lspconfig')

-- TypeScript
lspconfig.tsserver.setup({
    root_dir = lspconfig.util.root_pattern("package.json", ".git"),
})

-- Python
lspconfig.pylsp.setup({
    settings = {
        pylsp = {
            plugins = {
                black = { enabled = true },
                isort = { enabled = true },
            }
        }
    }
})

-- Rust
lspconfig.rust_analyzer.setup({
    settings = {
        ["rust-analyzer"] = {
            cargo = { allFeatures = true },
            checkOnSave = { command = "clippy" },
        }
    }
})

Debugging Integration

Debug Adapter Protocol (DAP)

Set up debugging within containers:

-- Debug configuration
local dap = require('dap')

-- Node.js debugging
dap.adapters.node2 = {
    type = 'executable',
    command = 'node',
    args = {'/path/to/vscode-node-debug2/out/src/nodeDebug.js'},
}

dap.configurations.javascript = {
    {
        name = 'Launch',
        type = 'node2',
        request = 'launch',
        program = '${workspaceFolder}/${file}',
        cwd = vim.fn.getcwd(),
        sourceMaps = true,
        protocol = 'inspector',
        console = 'integratedTerminal',
    },
}

Port Forwarding for Debugging

# Forward debugger ports
dockim port add 9229  # Node.js debugger
dockim port add 5678  # Python debugger

# Launch with debugging
dockim exec node --inspect=0.0.0.0:9229 app.js
dockim exec python -m debugpy --listen 0.0.0.0:5678 --wait-for-client app.py

Plugin Management

Container-Specific Plugins

Useful plugins for container development:

-- Plugin configuration (using packer.nvim example)
return require('packer').startup(function(use)
    -- Essential plugins for container dev
    use 'neovim/nvim-lspconfig'         -- LSP configuration
    use 'hrsh7th/nvim-cmp'              -- Completion
    use 'nvim-treesitter/nvim-treesitter' -- Syntax highlighting
    
    -- Container-specific utilities
    use 'akinsho/toggleterm.nvim'       -- Terminal integration
    use 'nvim-telescope/telescope.nvim' -- File finding
    use 'lewis6991/gitsigns.nvim'       -- Git integration
    
    -- Remote development helpers
    use 'folke/which-key.nvim'          -- Key binding help
    use 'windwp/nvim-autopairs'         -- Auto pairs
    use 'numToStr/Comment.nvim'         -- Easy commenting
end)

Plugin Synchronization

Ensure plugins work across host and container:

-- Conditional plugin loading
local in_container = vim.fn.getenv("CONTAINER") == "1"

if in_container then
    -- Container-specific plugin config
    require('lspconfig').tsserver.setup({})
else
    -- Host-specific config (if needed)
end

Clipboard Integration

Automatic Clipboard Sync

Enable seamless clipboard sharing:

# ~/.config/dockim/config.toml
[remote]
use_clipboard_server = true

Manual Clipboard Setup

If automatic sync doesn't work:

-- Neovim clipboard configuration
if vim.fn.getenv("SSH_TTY") then
    -- SSH/Remote environment
    vim.g.clipboard = {
        name = 'OSC 52',
        copy = {
            ['+'] = require('vim.ui.clipboard.osc52').copy('+'),
            ['*'] = require('vim.ui.clipboard.osc52').copy('*'),
        },
        paste = {
            ['+'] = require('vim.ui.clipboard.osc52').paste('+'),
            ['*'] = require('vim.ui.clipboard.osc52').paste('*'),
        },
    }
end

Performance Optimization

Startup Time

Optimize Neovim startup in containers:

-- Lazy loading configuration
vim.loader.enable()  -- Enable faster Lua module loading

-- Lazy load plugins
require('lazy').setup({
    -- Plugin specifications with lazy loading
    {
        'nvim-treesitter/nvim-treesitter',
        event = 'BufRead',
    },
    {
        'hrsh7th/nvim-cmp',
        event = 'InsertEnter',
    },
})

File Watching

Configure file watching for better performance:

-- Optimize file watching in containers
vim.opt.updatetime = 100
vim.opt.timeoutlen = 500

-- Use polling for file changes (if needed)
if vim.fn.getenv("CONTAINER") == "1" then
    vim.opt.backup = false
    vim.opt.writebackup = false
    vim.opt.swapfile = false
end

Troubleshooting

Connection Issues

Server won't start:

# Check if Neovim is installed in container
dockim exec nvim --version

# Check container is running
docker ps --filter "label=dockim"

# Restart container
dockim stop && dockim up

Client can't connect:

# Check port forwarding
dockim port ls

# Check if port is available on host
netstat -tuln | grep :52000

# Try with specific port
dockim neovim --host-port 8080

Performance Issues

Slow startup:

  • Use lazy loading for plugins
  • Minimize startup scripts
  • Consider using Neovim nightly for performance improvements

Laggy editing:

  • Check network latency between host and container
  • Disable heavy plugins temporarily
  • Use local file editing for large files

High memory usage:

  • Monitor container resource limits
  • Disable unnecessary language servers
  • Use treesitter instead of regex-based syntax highlighting

Plugin Issues

LSP not working:

# Check if language server is installed
dockim exec which typescript-language-server
dockim exec which pylsp

# Check LSP status in Neovim
:LspInfo

Debugging not connecting:

# Verify debugger ports are forwarded
dockim port ls

# Check debugger is listening
dockim exec netstat -tuln | grep :9229

Advanced Workflows

Multiple Projects

Working with multiple projects simultaneously:

# Terminal 1: Project A
cd project-a
dockim neovim --host-port 8001

# Terminal 2: Project B  
cd ../project-b
dockim neovim --host-port 8002

Session Management

Save and restore Neovim sessions:

-- Session management configuration
vim.opt.sessionoptions = 'blank,buffers,curdir,folds,help,tabpages,winsize,winpos,terminal'

-- Auto-save session on exit
vim.api.nvim_create_autocmd('VimLeavePre', {
    callback = function()
        vim.cmd('mksession! ~/.config/nvim/session.vim')
    end,
})

Custom Keybindings

Container-specific keybindings:

-- Container development keybindings
local keymap = vim.keymap.set

-- Quick container commands
keymap('n', '<leader>ct', ':term dockim exec npm test<CR>')
keymap('n', '<leader>cb', ':term dockim exec npm run build<CR>')
keymap('n', '<leader>cs', ':term dockim shell<CR>')

-- Port management
keymap('n', '<leader>cp', ':term dockim port ls<CR>')

Next: Learn about Port Management for advanced networking configuration with your development containers.

Port Management

Port management is a crucial aspect of containerized development. This chapter covers how to effectively manage network ports for accessing your applications, services, and development tools running inside containers.

Overview

When developing in containers, your applications run on the container's internal network. To access these services from your host machine or share them with others, you need to set up port forwarding. Dockim provides intuitive commands to manage this seamlessly.

Basic Concepts

Port Forwarding Basics

Port forwarding creates a mapping between your host machine and container:

Host Machine        Container
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ localhost   β”‚    β”‚             β”‚
β”‚ :3000       │◀──▢│ :3000       β”‚
β”‚             β”‚    β”‚ Your App    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Port Types

Understanding different port scenarios:

  • Same Port: Host port 3000 β†’ Container port 3000 (3000:3000)
  • Different Ports: Host port 8080 β†’ Container port 3000 (8080:3000)
  • Dynamic Ports: Dockim automatically assigns available ports
  • Service Ports: Database, cache, and other service ports

Port Commands

Adding Port Forwards

Basic port forwarding:

# Forward host port 3000 to container port 3000
dockim port add 3000

# Forward host port 8080 to container port 3000
dockim port add 8080:3000

Multiple ports:

# Add multiple ports at once
dockim port add 3000 8080 5432
dockim port add 8001:3000 8002:3001 8003:5432

Viewing Active Ports

# List all active port forwards
dockim port ls

# Example output:
# HOST PORT    CONTAINER PORT    SERVICE
# 3000         3000             web-app
# 8080         8080             api-server  
# 5432         5432             database

Removing Port Forwards

Remove specific ports:

# Remove single port forward
dockim port rm 3000

# Remove multiple port forwards
dockim port rm 3000 8080

Remove all ports:

# Remove all active port forwards
dockim port rm --all

Automatic Port Detection

DevContainer Configuration

Configure automatic port forwarding in your project:

// .devcontainer/devcontainer.json
{
    "forwardPorts": [3000, 8080, 5432],
    "portsAttributes": {
        "3000": {
            "label": "Web Application",
            "onAutoForward": "notify"
        },
        "8080": {
            "label": "API Server", 
            "onAutoForward": "openPreview"
        },
        "5432": {
            "label": "PostgreSQL Database",
            "onAutoForward": "silent"
        }
    }
}

Port Attributes:

  • label: Human-readable description
  • onAutoForward: Action when port is detected
    • notify: Show notification
    • openPreview: Open in browser
    • silent: Forward without notification

Dynamic Port Assignment

Dockim can automatically detect and forward ports:

# Start container with automatic port detection
dockim up --auto-ports

# Dockim will scan for listening ports and forward them

Application-Specific Scenarios

Web Development

Frontend applications:

# React development server
dockim exec npm start  # Usually runs on port 3000
dockim port add 3000

# Vue CLI
dockim exec npm run serve  # Usually runs on port 8080
dockim port add 8080

# Next.js
dockim exec npm run dev  # Usually runs on port 3000
dockim port add 3000

Backend services:

# Node.js Express server
dockim port add 3000:3000

# Python Flask
dockim port add 5000:5000

# Python Django
dockim port add 8000:8000

# Go HTTP server
dockim port add 8080:8080

Database Access

PostgreSQL:

# Standard PostgreSQL port
dockim port add 5432:5432

# Access from host
psql -h localhost -p 5432 -U postgres

MySQL:

# Standard MySQL port  
dockim port add 3306:3306

# Access from host
mysql -h localhost -P 3306 -u root

MongoDB:

# Standard MongoDB port
dockim port add 27017:27017

# Access from host
mongo mongodb://localhost:27017

Redis:

# Standard Redis port
dockim port add 6379:6379

# Access from host
redis-cli -h localhost -p 6379

Development Tools

Jupyter Notebook:

# Forward Jupyter port
dockim port add 8888:8888

# Start Jupyter in container
dockim exec jupyter lab --ip=0.0.0.0 --port=8888 --no-browser

Debugger Ports:

# Node.js inspector
dockim port add 9229:9229
dockim exec node --inspect=0.0.0.0:9229 app.js

# Python debugger
dockim port add 5678:5678
dockim exec python -m debugpy --listen 0.0.0.0:5678 app.py

Advanced Port Management

Port Conflicts Resolution

When ports are already in use:

# Check what's using a port
netstat -tuln | grep :3000
lsof -i :3000

# Use different host port
dockim port add 3001:3000

# Or find available port automatically
dockim port add :3000  # Auto-assigns host port

Multiple Services

Microservices architecture:

# Service mapping
dockim port add 3001:3000  # Frontend
dockim port add 3002:8080  # API Gateway
dockim port add 3003:8081  # User Service
dockim port add 3004:8082  # Order Service
dockim port add 5432:5432  # Database

Docker Compose services:

# compose.yml
services:
  frontend:
    build: ./frontend
    ports:
      - "3000:3000"
      
  api:
    build: ./api  
    ports:
      - "8080:8080"
      
  database:
    image: postgres:15
    ports:
      - "5432:5432"

Load Balancing

Multiple instances:

# Run multiple instances on different ports
dockim port add 3001:3000  # Instance 1
dockim port add 3002:3000  # Instance 2
dockim port add 3003:3000  # Instance 3

# Use nginx for load balancing
dockim port add 80:80     # Load balancer

Security Considerations

Port Binding

Secure binding:

# Bind only to localhost (more secure)
dockim port add 127.0.0.1:3000:3000

# Bind to all interfaces (less secure)
dockim port add 0.0.0.0:3000:3000

Firewall Configuration

Host firewall rules:

# Allow specific ports through firewall
sudo ufw allow 3000
sudo ufw allow 8080

# Check firewall status
sudo ufw status

Environment Separation

Different environments:

# Development (permissive)
dockim port add 3000:3000

# Staging (restricted)
dockim port add 127.0.0.1:3000:3000

# Production (use reverse proxy)
# No direct port exposure

Monitoring and Debugging

Port Status Checking

Verify port forwarding:

# Test if port is accessible
curl http://localhost:3000

# Check container listening ports
dockim exec netstat -tuln

# Check from host
netstat -tuln | grep :3000

Port scanning:

# Scan container ports
dockim exec nmap localhost

# Scan host ports
nmap localhost

Traffic Monitoring

Monitor network traffic:

# View active connections
dockim exec ss -tuln

# Monitor network usage
docker stats --format "table {{.Container}}\t{{.NetIO}}"

# Log network activity
tcpdump -i any port 3000

Performance Optimization

Port Range Selection

Optimize port ranges:

# Use high port numbers to avoid conflicts
dockim port add 8000:3000  # Instead of 3000:3000

# Group related services
dockim port add 8001:3001  # Frontend
dockim port add 8002:3002  # API
dockim port add 8003:3003  # Admin

Connection Pooling

Database connections:

# Use connection pooling for databases
dockim port add 5432:5432

# Configure connection limits in application
# Example: max_connections=100 in PostgreSQL

Troubleshooting

Common Issues

Port already in use:

# Find what's using the port
lsof -i :3000

# Kill the process if safe
kill -9 <PID>

# Or use different port
dockim port add 3001:3000

Connection refused:

# Check if service is running in container
dockim exec ps aux | grep node

# Check if service is binding to correct interface
dockim exec netstat -tuln | grep :3000

# Ensure service binds to 0.0.0.0, not 127.0.0.1

Slow connections:

# Check Docker network performance
docker network ls
docker network inspect <network_name>

# Monitor container network stats
docker stats --format "table {{.Container}}\t{{.NetIO}}"

Diagnostic Commands

Network debugging:

# Test container connectivity
dockim exec ping google.com

# Test inter-container communication
dockim exec ping other-container-name

# Check DNS resolution
dockim exec nslookup database

Port accessibility:

# From inside container
dockim exec curl http://localhost:3000

# From host
curl http://localhost:3000

# From other machines (if needed)
curl http://your-host-ip:3000

Best Practices

Port Organization

Consistent port mapping:

# Use predictable patterns
3000-3099: Frontend applications
8000-8099: Backend APIs  
5400-5499: Databases
6000-6099: Cache/Queue systems
9000-9099: Monitoring/Debugging

Documentation

Document your ports:

# Port Mapping

| Service | Host Port | Container Port | Description |
|---------|-----------|----------------|-------------|
| Web App | 3000      | 3000           | React frontend |
| API     | 8080      | 8080           | Express backend |
| DB      | 5432      | 5432           | PostgreSQL |
| Redis   | 6379      | 6379           | Cache |

Automation

Automate common setups:

#!/bin/bash
# setup-ports.sh
dockim port add 3000:3000  # Frontend
dockim port add 8080:8080  # API
dockim port add 5432:5432  # Database
dockim port add 6379:6379  # Redis

echo "All ports configured for development"

Next: Learn about Configuration to customize Dockim for your specific development needs and preferences.

Configuration

Dockim provides extensive configuration options to customize your development environment. This chapter covers all configuration aspects, from global settings to project-specific customizations.

Configuration Overview

Dockim uses a hierarchical configuration system:

  1. Global Configuration (~/.config/dockim/config.toml) - Your personal defaults
  2. Project Configuration (.devcontainer/devcontainer.json) - Project-specific settings
  3. Environment Variables - Runtime overrides
  4. Command-line Options - Temporary overrides

Global Configuration

Creating Global Config

Generate your default configuration:

# Create global config file
dockim init-config

This creates ~/.config/dockim/config.toml with default settings you can customize.

Global Config Structure

# ~/.config/dockim/config.toml

# Shell Configuration
shell = "/bin/zsh"                    # Default shell to use
neovim_version = "v0.11.0"           # Neovim version for source builds

# Dotfiles Integration
dotfiles_repository_name = "dotfiles"
dotfiles_install_command = "echo 'no dotfiles install command configured'"

# Container Neovim launch settings
[neovim]
launch_with_shell = true              # Run Neovim through the configured shell by default
shell_args = ["-lc"]                  # Shell flags; use ["-lic"] to source .zshrc

# Remote Neovim Settings
[remote]
background = false                    # Run client in background
use_clipboard_server = true          # Enable clipboard sync
args = ["nvim", "--server", "{server}", "--remote-ui"]

Shell Configuration

Default Shell:

shell = "/bin/zsh"           # Use zsh by default
# or
shell = "/bin/bash"          # Use bash
# or  
shell = "/usr/bin/fish"      # Use fish shell

Custom Shell Path:

# Custom shell installation
shell = "/opt/homebrew/bin/zsh"
# or with specific version
shell = "/usr/local/bin/bash-5.1"

Neovim Configuration

Version Management:

neovim_version = "v0.11.0"    # Specific version
# or
neovim_version = "stable"     # Latest stable release  
# or
neovim_version = "nightly"    # Latest nightly build

Build Options:

[neovim]
launch_with_shell = true     # Start with `<shell> -lc 'exec env ... nvim ...'`
shell_args = ["-lc"]         # Run as `<shell> -lc 'exec env ... nvim ...'`

Run Neovim through zsh to inherit shell-initialized PATH:

shell = "/bin/zsh"

[neovim]
launch_with_shell = true
shell_args = ["-lic"]        # interactive + login; useful when PATH comes from zsh startup files

Dotfiles Integration

Repository Configuration:

dotfiles_repository_name = "dotfiles"
dotfiles_install_command = "./install.sh"

Advanced Dotfiles Setup:

[dotfiles]
repository_name = "dotfiles"
branch = "main"                      # Specific branch
install_command = "./install.sh nvim zsh"
post_install_command = "source ~/.zshrc"

Remote Configuration

Neovim Remote UI:

[remote]
background = false                   # Don't run in background
use_clipboard_server = true         # Enable clipboard sync
port_range = [52000, 53000]        # Port range for connections
client_timeout = 30                  # Connection timeout in seconds
args = ["nvim", "--server", "{server}", "--remote-ui"]

Custom Client Commands:

[remote]
# Use different Neovim client
args = ["nvim-qt", "--server", "{server}"]
# or with specific options
args = ["nvim", "--server", "{server}", "--remote-ui", "--headless"]

Project Configuration

DevContainer Configuration

The main project configuration file:

// .devcontainer/devcontainer.json
{
    "name": "My Development Container",
    "dockerComposeFile": "compose.yml",
    "service": "dev",
    "workspaceFolder": "/workspace",
    
    // Container Features
    "features": {
        "ghcr.io/devcontainers/features/node:1": {
            "version": "18"
        },
        "ghcr.io/devcontainers/features/docker-in-docker:2": {}
    },
    
    // Port Forwarding
    "forwardPorts": [3000, 8080],
    "portsAttributes": {
        "3000": {
            "label": "Web App",
            "onAutoForward": "notify"
        }
    },
    
    // Environment Variables
    "remoteEnv": {
        "NODE_ENV": "development",
        "DEBUG": "app:*"
    },
    
    // Customizations
    "customizations": {
        "vscode": {
            "extensions": [
                "ms-vscode.vscode-typescript-next",
                "bradlc.vscode-tailwindcss"
            ],
            "settings": {
                "terminal.integrated.defaultProfile.linux": "zsh"
            }
        }
    }
}

Docker Compose Configuration

# .devcontainer/compose.yml
services:
  dev:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        - USER_UID=${LOCAL_UID:-1000}
        - USER_GID=${LOCAL_GID:-1000}
    volumes:
      - ..:/workspace:cached
      - ~/.gitconfig:/home/vscode/.gitconfig:ro
      - ~/.ssh:/home/vscode/.ssh:ro
    environment:
      - SHELL=/bin/zsh
      - NODE_ENV=development
    ports:
      - "3000:3000"
      - "8080:8080"
    command: sleep infinity
    
  database:
    image: postgres:15
    environment:
      POSTGRES_DB: myapp
      POSTGRES_PASSWORD: dev
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Dockerfile Configuration

# .devcontainer/Dockerfile
FROM mcr.microsoft.com/devcontainers/base:ubuntu

# Arguments
ARG USER_UID=1000
ARG USER_GID=1000
ARG USERNAME=vscode

# Update system and install packages
RUN apt-get update && apt-get install -y \
    curl \
    git \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

# Install Node.js
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
    && apt-get install -y nodejs

# Set up user permissions
RUN groupmod --gid $USER_GID $USERNAME \
    && usermod --uid $USER_UID --gid $USER_GID $USERNAME \
    && chown -R $USERNAME:$USERNAME /home/$USERNAME

# Switch to user
USER $USERNAME

# Install user-specific tools
RUN npm install -g @vue/cli create-react-app

# Set up shell
SHELL ["/bin/bash", "-c"]

Environment Variables

System Environment Variables

Docker Configuration:

export DOCKER_HOST=unix:///var/run/docker.sock
export DOCKER_BUILDKIT=1
export COMPOSE_DOCKER_CLI_BUILD=1

Dockim Configuration:

export DOCKIM_CONFIG_DIR=~/.config/dockim
export DOCKIM_DEFAULT_SHELL=/bin/zsh
export DOCKIM_NEOVIM_VERSION=stable

Container Environment Variables

In compose.yml:

services:
  dev:
    environment:
      - NODE_ENV=development
      - API_URL=http://localhost:8080
      - DATABASE_URL=postgres://postgres:dev@database:5432/myapp
      - REDIS_URL=redis://redis:6379

In devcontainer.json:

{
    "remoteEnv": {
        "PATH": "/usr/local/bin:${containerEnv:PATH}",
        "NODE_ENV": "development",
        "DEBUG": "app:*"
    }
}

Environment Files

Create .env files:

# .env (committed to repo - safe values only)
NODE_ENV=development
API_PORT=8080
DB_HOST=database

# .env.local (gitignored - sensitive values)
DATABASE_PASSWORD=dev_secret_123
JWT_SECRET=your-jwt-secret
API_KEY=your-api-key

Load in compose.yml:

services:
  dev:
    env_file:
      - .env
      - .env.local

Language-Specific Configuration

Node.js Projects

// .devcontainer/devcontainer.json
{
    "name": "Node.js Development",
    "features": {
        "ghcr.io/devcontainers/features/node:1": {
            "version": "18",
            "npmGlobal": "yarn,pnpm,@vue/cli"
        }
    },
    "postCreateCommand": "npm install",
    "remoteEnv": {
        "NODE_ENV": "development",
        "NPM_CONFIG_PREFIX": "/home/vscode/.npm-global"
    }
}

Python Projects

{
    "name": "Python Development",
    "features": {
        "ghcr.io/devcontainers/features/python:1": {
            "version": "3.11",
            "installTools": true
        }
    },
    "postCreateCommand": "pip install -r requirements.txt",
    "remoteEnv": {
        "PYTHONPATH": "/workspace",
        "PYTHONDONTWRITEBYTECODE": "1"
    }
}

Rust Projects

{
    "name": "Rust Development", 
    "features": {
        "ghcr.io/devcontainers/features/rust:1": {
            "version": "latest",
            "profile": "default"
        }
    },
    "postCreateCommand": "cargo build",
    "remoteEnv": {
        "RUST_BACKTRACE": "1",
        "CARGO_TARGET_DIR": "/workspace/target"
    }
}

Go Projects

{
    "name": "Go Development",
    "features": {
        "ghcr.io/devcontainers/features/go:1": {
            "version": "1.21"
        }
    },
    "postCreateCommand": "go mod download",
    "remoteEnv": {
        "CGO_ENABLED": "0",
        "GOPROXY": "https://proxy.golang.org,direct"
    }
}

Advanced Configuration

Multi-Stage Configuration

Development vs Production:

# Development stage
FROM mcr.microsoft.com/devcontainers/base:ubuntu as development
RUN apt-get update && apt-get install -y \
    curl git build-essential \
    && rm -rf /var/lib/apt/lists/*

# Production stage  
FROM node:18-alpine as production
COPY --from=development /usr/bin/git /usr/bin/git
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

Conditional Configuration

Environment-based config:

{
    "name": "Multi-Environment Container",
    "build": {
        "dockerfile": "Dockerfile",
        "target": "${localEnv:NODE_ENV:-development}"
    },
    "remoteEnv": {
        "NODE_ENV": "${localEnv:NODE_ENV:-development}",
        "LOG_LEVEL": "${localEnv:LOG_LEVEL:-debug}"
    }
}

Custom Scripts

Post-create commands:

{
    "postCreateCommand": [
        "bash",
        "-c", 
        "npm install && npm run setup && echo 'Setup complete!'"
    ]
}

Custom script files:

#!/bin/bash
# .devcontainer/postCreateCommand.sh

echo "Setting up development environment..."

# Install dependencies
npm install

# Set up git hooks
npm run prepare

# Create necessary directories
mkdir -p logs tmp

# Set permissions
chmod +x scripts/*.sh

echo "βœ… Development environment ready!"

Performance Configuration

Build Performance

Docker BuildKit:

# syntax=docker/dockerfile:1
FROM mcr.microsoft.com/devcontainers/base:ubuntu

# Use BuildKit features
RUN --mount=type=cache,target=/var/lib/apt \
    apt-get update && apt-get install -y git curl

Build Arguments:

# compose.yml
services:
  dev:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        - BUILDKIT_INLINE_CACHE=1
      cache_from:
        - myregistry/my-app:cache

Runtime Performance

Resource Limits:

services:
  dev:
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 4G
        reservations:
          cpus: '1'
          memory: 2G

Volume Optimization:

volumes:
  # Cached volume for better file sync
  - ..:/workspace:cached
  # Anonymous volume for node_modules
  - /workspace/node_modules
  # Named volume for persistent data
  - node_cache:/home/vscode/.npm

Security Configuration

User Configuration

# Create non-root user
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID

RUN groupadd --gid $USER_GID $USERNAME \
    && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
    && apt-get update \
    && apt-get install -y sudo \
    && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
    && chmod 0440 /etc/sudoers.d/$USERNAME

USER $USERNAME

Secret Management

Using Docker secrets:

# compose.yml
services:
  dev:
    secrets:
      - db_password
      - api_key

secrets:
  db_password:
    file: ./secrets/db_password.txt
  api_key:
    file: ./secrets/api_key.txt

Environment-based secrets:

# .env.local (never commit!)
DATABASE_PASSWORD=super_secret_password
API_KEY=your_secret_api_key

Configuration Validation

Schema Validation

Validate devcontainer.json:

# Using VS Code Dev Containers CLI
devcontainer build --workspace-folder .

JSON Schema:

{
    "$schema": "https://aka.ms/vscode-remote/devcontainer.json",
    "name": "My Container"
}

Testing Configuration

Test container build:

# Test build
dockim build --no-cache

# Test startup
dockim up

# Test services
dockim exec curl http://localhost:3000

Configuration Templates

Web Application Template

{
    "name": "Web Application",
    "dockerComposeFile": "compose.yml",
    "service": "dev",
    "features": {
        "ghcr.io/devcontainers/features/node:1": {"version": "18"},
        "ghcr.io/devcontainers/features/docker-in-docker:2": {}
    },
    "forwardPorts": [3000, 8080],
    "postCreateCommand": "npm install && npm run setup"
}

Full-Stack Template

{
    "name": "Full-Stack Application",
    "dockerComposeFile": "compose.yml",
    "service": "dev",
    "features": {
        "ghcr.io/devcontainers/features/node:1": {"version": "18"},
        "ghcr.io/devcontainers/features/python:1": {"version": "3.11"}
    },
    "forwardPorts": [3000, 8080, 5432, 6379],
    "postCreateCommand": "npm install && pip install -r requirements.txt"
}

Data Science Template

{
    "name": "Data Science Environment",
    "features": {
        "ghcr.io/devcontainers/features/python:1": {
            "version": "3.11",
            "installTools": true
        },
        "ghcr.io/devcontainers/features/jupyter:1": {}
    },
    "forwardPorts": [8888],
    "postCreateCommand": "pip install pandas numpy matplotlib seaborn scikit-learn"
}

Best Practices

Configuration Management

Version control:

# Include in repository
.devcontainer/
β”œβ”€β”€ devcontainer.json
β”œβ”€β”€ compose.yml
β”œβ”€β”€ Dockerfile
└── postCreateCommand.sh

# Exclude sensitive files
.devcontainer/
β”œβ”€β”€ .env.local          # Gitignored
└── secrets/            # Gitignored

Documentation:

# Development Setup

## Configuration

- Node.js 18 with npm/yarn
- PostgreSQL 15 on port 5432
- Redis on port 6379
- Hot reload on port 3000

## Environment Variables

Copy `.env.example` to `.env.local` and set:
- DATABASE_PASSWORD
- JWT_SECRET

Team Consistency

Shared configuration:

{
    "name": "Team Development Environment",
    "features": {
        "ghcr.io/devcontainers/features/node:1": {"version": "18.16.0"}
    },
    "postCreateCommand": "./scripts/team-setup.sh"
}

Lock versions:

# ~/.config/dockim/config.toml
neovim_version = "v0.9.0"  # Specific version for team consistency

Next: Explore the complete Commands Reference for detailed documentation of all Dockim commands and options.

Commands Reference

This chapter provides comprehensive documentation for all Dockim commands, their options, and usage examples.

Command Overview

Dockim provides a cohesive set of commands organized by functionality:

  • Project Management: init, init-config
  • Container Lifecycle: build, up, stop, down
  • Development Tools: neovim, shell, exec
  • Network Management: port

Global Options

These options are available for all commands:

--help, -h          Show help information
--version, -V       Show version information
--verbose, -v       Enable verbose output
--quiet, -q         Suppress non-error output
--config <PATH>     Use custom config file

Project Management Commands

dockim init

Initialize a new Dockim project with dev container configuration.

Usage:

dockim init [OPTIONS]

Options:

--force, -f         Overwrite existing files
--template <NAME>   Use specific project template
--name <NAME>       Set container name

Examples:

# Initialize with default settings
dockim init

# Initialize with custom name
dockim init --name "my-web-app"

# Force overwrite existing configuration
dockim init --force

# Use a specific template
dockim init --template nodejs

Generated Files:

  • .devcontainer/devcontainer.json - Main container configuration
  • .devcontainer/compose.yml - Docker Compose setup
  • .devcontainer/Dockerfile - Custom image definition

Templates:

  • default - Basic Ubuntu container
  • nodejs - Node.js development environment
  • python - Python development environment
  • rust - Rust development environment
  • go - Go development environment

dockim init-config

Create a global configuration file with default settings.

Usage:

dockim init-config [OPTIONS]

Options:

--force, -f         Overwrite existing config
--editor            Open config in default editor after creation

Examples:

# Create default config
dockim init-config

# Overwrite existing config
dockim init-config --force

# Create and open in editor
dockim init-config --editor

Configuration Location:

  • Linux/macOS: ~/.config/dockim/config.toml
  • Windows: %APPDATA%\dockim\config.toml

Container Lifecycle Commands

dockim build

Build the development container image.

Usage:

dockim build [OPTIONS]

Options:

--rebuild           Force complete rebuild (ignore cache)
--no-cache          Build without using Docker cache
--neovim-from-source    Build Neovim from source instead of binaries
--progress <TYPE>   Progress output type: auto, plain, tty

Examples:

# Standard build
dockim build

# Force rebuild from scratch
dockim build --rebuild

# Build without Docker cache
dockim build --no-cache

# Build with Neovim from source
dockim build --neovim-from-source

# Build with plain progress output
dockim build --progress plain

Build Process:

  1. Read .devcontainer/Dockerfile
  2. Process build arguments and context
  3. Execute Docker build with appropriate options
  4. Tag image for container usage

dockim up

Start the development container.

Usage:

dockim up [OPTIONS]

Options:

--rebuild           Rebuild image before starting
--detach, -d        Run container in background
--remove-orphans    Remove containers for services not in compose file

Examples:

# Start container (build if needed)
dockim up

# Rebuild and start
dockim up --rebuild

# Start in background
dockim up --detach

# Clean up orphaned containers
dockim up --remove-orphans

Startup Process:

  1. Check if image exists (build if needed)
  2. Start Docker Compose services
  3. Wait for container readiness
  4. Set up port forwarding

dockim stop

Stop the running development container.

Usage:

dockim stop [OPTIONS]

Options:

--timeout <SECONDS> Wait timeout before force stopping (default: 10)
--all               Stop all Dockim containers

Examples:

# Stop current project container
dockim stop

# Stop with custom timeout
dockim stop --timeout 30

# Stop all Dockim containers
dockim stop --all

Stop Process:

  1. Send SIGTERM to container processes
  2. Wait for graceful shutdown
  3. Force stop if timeout exceeded
  4. Clean up port forwards

dockim down

Stop and remove the development container.

Usage:

dockim down [OPTIONS]

Options:

--volumes, -v       Remove associated volumes
--images            Remove associated images
--timeout <SECONDS> Wait timeout before force removal

Examples:

# Remove container (keep volumes and images)
dockim down

# Remove container and volumes
dockim down --volumes

# Remove container, volumes, and images
dockim down --volumes --images

# Remove with custom timeout
dockim down --timeout 30

Removal Process:

  1. Stop container if running
  2. Remove container
  3. Remove volumes (if specified)
  4. Remove images (if specified)
  5. Clean up port forwards

Development Tools Commands

dockim neovim

Launch Neovim with remote UI support.

Usage:

dockim neovim [OPTIONS] [FILES...]
dockim v [OPTIONS] [FILES...]  # Short alias

Options:

--no-remote-ui      Run Neovim directly in container (no remote UI)
--host-port <PORT>  Specify host port for remote connection
--server-port <PORT> Specify container port for Neovim server
--wait              Wait for editor to close before returning

Examples:

# Launch with remote UI
dockim neovim
dockim v

# Open specific files
dockim neovim src/main.rs README.md

# Launch without remote UI
dockim neovim --no-remote-ui

# Use custom host port
dockim neovim --host-port 8080

# Wait for editor to close
dockim neovim --wait config.toml

Remote UI Process:

  1. Start container if not running
  2. Launch Neovim server in container
  3. Set up port forwarding
  4. Start local Neovim client
  5. Establish remote connection

dockim shell

Open an interactive shell in the container.

Usage:

dockim shell [OPTIONS]
dockim sh [OPTIONS]  # Short alias

Options:

--shell <SHELL>     Use specific shell (overrides config)
--user <USER>       Run as specific user
--workdir <PATH>    Set working directory

Examples:

# Open default shell
dockim shell
dockim sh

# Use specific shell
dockim shell --shell /bin/bash

# Run as root user
dockim shell --user root

# Start in specific directory
dockim shell --workdir /workspace/src

Shell Selection Priority:

  1. --shell command option
  2. Global config shell setting
  3. Container default shell
  4. /bin/sh as fallback

dockim bash

Open a Bash shell in the container.

Usage:

dockim bash [OPTIONS]

Options:

--user <USER>       Run as specific user
--workdir <PATH>    Set working directory

Examples:

# Open bash shell
dockim bash

# Run as root
dockim bash --user root

# Start in specific directory
dockim bash --workdir /tmp

dockim exec

Execute a command in the running container.

Usage:

dockim exec [OPTIONS] COMMAND [ARGS...]

Options:

--interactive, -i   Keep STDIN open
--tty, -t          Allocate pseudo-TTY
--user <USER>       Run as specific user
--workdir <PATH>    Set working directory
--env <KEY=VALUE>   Set environment variables

Examples:

# Execute simple command
dockim exec ls -la

# Interactive command with TTY
dockim exec -it python

# Run as specific user
dockim exec --user root apt update

# Set working directory
dockim exec --workdir /workspace npm test

# Set environment variables
dockim exec --env DEBUG=1 npm start

# Complex command with arguments
dockim exec git commit -m "Add new feature"

Network Management Commands

dockim port

Manage port forwarding between host and container.

Usage:

dockim port <SUBCOMMAND> [OPTIONS]

dockim port add

Add port forwarding rules.

Usage:

dockim port add [OPTIONS] <PORT_SPEC>...

Port Specifications:

3000                Host port 3000 β†’ Container port 3000
8080:3000          Host port 8080 β†’ Container port 3000
:3000              Auto-assign host port β†’ Container port 3000
localhost:3000:3000 Bind to localhost only

Options:

--protocol <PROTO>  Port protocol: tcp (default), udp
--bind <IP>         Bind to specific IP address

Examples:

# Forward same ports
dockim port add 3000 8080 5432

# Forward different ports
dockim port add 8080:3000 8081:3001

# Auto-assign host ports
dockim port add :3000 :8080

# Bind to localhost only
dockim port add localhost:3000:3000

# UDP port forwarding
dockim port add 1234 --protocol udp

# Bind to specific IP
dockim port add 3000:3000 --bind 192.168.1.100

dockim port ls

List active port forwarding rules.

Usage:

dockim port ls [OPTIONS]

Options:

--format <FORMAT>   Output format: table (default), json, yaml
--filter <FILTER>   Filter ports by criteria

Examples:

# List all active ports
dockim port ls

# JSON output
dockim port ls --format json

# Filter by port number
dockim port ls --filter port=3000

# Filter by protocol
dockim port ls --filter protocol=tcp

Output Format:

HOST PORT    CONTAINER PORT    PROTOCOL    STATUS
3000         3000             tcp         active
8080         3000             tcp         active
5432         5432             tcp         active

dockim port rm

Remove port forwarding rules.

Usage:

dockim port rm [OPTIONS] <PORT>...

Options:

--all, -a           Remove all port forwards
--protocol <PROTO>  Remove only specified protocol ports

Examples:

# Remove specific ports
dockim port rm 3000 8080

# Remove all port forwards
dockim port rm --all

# Remove only TCP ports
dockim port rm --all --protocol tcp

Command Exit Codes

Dockim commands use standard exit codes:

  • 0 - Success
  • 1 - General error
  • 2 - Misuse of command (invalid arguments)
  • 125 - Docker daemon error
  • 126 - Container command not executable
  • 127 - Container command not found
  • 130 - Process terminated by user (Ctrl+C)

Environment Variables

Commands respect these environment variables:

DOCKIM_CONFIG_DIR      # Override config directory
DOCKIM_LOG_LEVEL       # Set log level (debug, info, warn, error)
DOCKIM_NO_COLOR        # Disable colored output
DOCKER_HOST            # Docker daemon connection
COMPOSE_PROJECT_NAME   # Docker Compose project name

Configuration Files

Commands may read configuration from:

  1. Command-line options (highest priority)
  2. Environment variables
  3. Project config (.devcontainer/devcontainer.json)
  4. Global config (~/.config/dockim/config.toml)
  5. Built-in defaults (lowest priority)

Examples by Workflow

Starting a New Project

# Initialize project
dockim init --template nodejs

# Build and start
dockim build
dockim up

# Open editor
dockim neovim

# Set up port forwarding
dockim port add 3000 8080

Daily Development

# Start development environment
dockim up

# Run tests
dockim exec npm test

# Open editor if not running
dockim neovim src/app.js

# Check running services
dockim port ls

# Execute build
dockim exec npm run build

Container Maintenance

# Update container image
dockim build --rebuild

# Clean restart
dockim down
dockim up

# Clean up everything
dockim down --volumes --images

Debugging and Inspection

# Check container status
dockim exec ps aux

# View logs
dockim exec journalctl --follow

# Network diagnostics
dockim exec netstat -tuln
dockim port ls

# Interactive debugging
dockim shell --user root

Shell Completion

Dockim supports shell completion for bash, zsh, and fish:

# Bash
dockim completion bash > /etc/bash_completion.d/dockim

# Zsh
dockim completion zsh > "${fpath[1]}/_dockim"

# Fish
dockim completion fish > ~/.config/fish/completions/dockim.fish

Next: Explore Advanced Usage for complex scenarios, custom setups, and integration patterns.

Advanced Usage

This chapter explores advanced scenarios, custom configurations, and integration patterns for power users and complex development environments.

Multi-Container Architectures

Microservices Development

Setting up multiple interconnected services:

# .devcontainer/compose.yml
services:
  dev:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ..:/workspace:cached
    depends_on:
      - api-gateway
      - user-service
      - order-service
      - database
      - redis
    command: sleep infinity
    
  api-gateway:
    build: ./services/gateway
    ports:
      - "8080:8080"
    environment:
      - USER_SERVICE_URL=http://user-service:3001
      - ORDER_SERVICE_URL=http://order-service:3002
    depends_on:
      - user-service
      - order-service
      
  user-service:
    build: ./services/user
    ports:
      - "3001:3001"
    environment:
      - DATABASE_URL=postgres://postgres:dev@database:5432/users
    depends_on:
      - database
      
  order-service:
    build: ./services/order
    ports:
      - "3002:3002"
    environment:
      - DATABASE_URL=postgres://postgres:dev@database:5432/orders
      - REDIS_URL=redis://redis:6379
    depends_on:
      - database
      - redis
      
  database:
    image: postgres:15
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: dev
      POSTGRES_MULTIPLE_DATABASES: users,orders
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./scripts/init-databases.sh:/docker-entrypoint-initdb.d/init-databases.sh
      
  redis:
    image: redis:alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
  redis_data:

Service Mesh Integration

Integrating with service mesh technologies:

# .devcontainer/compose.yml with Istio sidecar
services:
  dev:
    build: .
    volumes:
      - ..:/workspace:cached
    network_mode: "service:istio-proxy"
    depends_on:
      - istio-proxy
      
  istio-proxy:
    image: istio/proxyv2:latest
    environment:
      - PILOT_CERT_PROVIDER=istiod
    volumes:
      - ./istio-config:/etc/istio/config
    ports:
      - "15000:15000"  # Envoy admin
      - "15001:15001"  # Envoy outbound

Custom Base Images

Creating Optimized Images

# .devcontainer/Dockerfile.base
FROM ubuntu:22.04 as base

# Install system dependencies
RUN apt-get update && apt-get install -y \
    curl \
    git \
    build-essential \
    sudo \
    && rm -rf /var/lib/apt/lists/*

# Create development user
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID

RUN groupadd --gid $USER_GID $USERNAME \
    && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
    && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
    && chmod 0440 /etc/sudoers.d/$USERNAME

# Development stage
FROM base as development
USER $USERNAME

# Install development tools
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - \
    && sudo apt-get install -y nodejs

# Install global packages
RUN npm install -g @vue/cli create-react-app typescript
RUN cargo install ripgrep fd-find

# Production stage
FROM base as production
COPY --from=development /home/vscode/.cargo/bin /usr/local/bin
COPY --from=development /usr/bin/node /usr/bin/node
COPY --from=development /usr/bin/npm /usr/bin/npm

Language-Specific Optimizations

Rust Development Container:

FROM mcr.microsoft.com/devcontainers/rust:latest

# Install additional Rust tools
RUN rustup component add clippy rustfmt rust-analyzer
RUN cargo install cargo-watch cargo-edit cargo-audit

# Configure Rust environment
ENV RUST_BACKTRACE=1
ENV CARGO_NET_GIT_FETCH_WITH_CLI=true

# Pre-compile common dependencies
RUN cargo install --list > /tmp/installed.txt

Node.js with Performance Optimizations:

FROM node:18-bullseye

# Install performance monitoring tools
RUN npm install -g clinic autocannon

# Configure Node.js for development
ENV NODE_ENV=development
ENV NODE_OPTIONS="--max-old-space-size=4096"

# Setup pnpm and yarn
RUN npm install -g pnpm yarn

# Optimize npm settings
RUN npm config set fund false
RUN npm config set audit-level moderate

CI/CD Integration

GitHub Actions

# .github/workflows/dev-container.yml
name: Dev Container CI

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  test-dev-container:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@v4

    - name: Build and test in Dev Container
      uses: devcontainers/ci@v0.3
      with:
        imageName: ghcr.io/${{ github.repository }}/devcontainer
        cacheFrom: ghcr.io/${{ github.repository }}/devcontainer
        push: always
        runCmd: |
          # Install dependencies
          npm ci
          
          # Run tests
          npm run test:ci
          
          # Run linting
          npm run lint
          
          # Build application
          npm run build

  integration-tests:
    runs-on: ubuntu-latest
    needs: test-dev-container
    steps:
    - name: Checkout
      uses: actions/checkout@v4
      
    - name: Run integration tests
      uses: devcontainers/ci@v0.3
      with:
        imageName: ghcr.io/${{ github.repository }}/devcontainer
        runCmd: |
          # Start services
          docker-compose -f .devcontainer/compose.yml up -d database redis
          
          # Wait for services
          sleep 10
          
          # Run integration tests
          npm run test:integration

GitLab CI

# .gitlab-ci.yml
stages:
  - build
  - test
  - deploy

variables:
  CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/devcontainer:$CI_COMMIT_SHA

build-dev-container:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - cd .devcontainer
    - docker build -t $CONTAINER_IMAGE .
    - docker push $CONTAINER_IMAGE

test-in-container:
  stage: test
  image: $CONTAINER_IMAGE
  services:
    - postgres:15
    - redis:alpine
  variables:
    DATABASE_URL: postgres://postgres:postgres@postgres:5432/test
    REDIS_URL: redis://redis:6379
  script:
    - npm ci
    - npm run test
    - npm run lint
    - npm run build

Jenkins Pipeline

// Jenkinsfile
pipeline {
    agent {
        docker {
            image 'docker:latest'
            args '-v /var/run/docker.sock:/var/run/docker.sock'
        }
    }
    
    environment {
        REGISTRY = credentials('docker-registry')
        IMAGE_NAME = "devcontainer-${env.BUILD_ID}"
    }
    
    stages {
        stage('Build Dev Container') {
            steps {
                script {
                    def image = docker.build(
                        "${IMAGE_NAME}",
                        "-f .devcontainer/Dockerfile .devcontainer"
                    )
                }
            }
        }
        
        stage('Test in Container') {
            steps {
                script {
                    docker.image("${IMAGE_NAME}").inside('-u root') {
                        sh 'npm ci'
                        sh 'npm run test'
                        sh 'npm run lint'
                        sh 'npm run build'
                    }
                }
            }
        }
        
        stage('Integration Tests') {
            steps {
                script {
                    docker.image("${IMAGE_NAME}").inside(
                        '--link postgres:database --link redis:cache'
                    ) {
                        sh 'npm run test:integration'
                    }
                }
            }
        }
    }
    
    post {
        cleanup {
            sh "docker rmi ${IMAGE_NAME} || true"
        }
    }
}

Custom Toolchains

Multi-Language Development

FROM mcr.microsoft.com/devcontainers/base:ubuntu

# Install multiple language runtimes
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
    && apt-get install -y nodejs

RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
ENV PATH="/root/.cargo/bin:${PATH}"

RUN curl -fsSL https://golang.org/dl/go1.21.0.linux-amd64.tar.gz | tar -C /usr/local -xzf -
ENV PATH="/usr/local/go/bin:${PATH}"

# Python (already included in base image, but ensure latest)
RUN apt-get update && apt-get install -y \
    python3 \
    python3-pip \
    python3-venv

# Install cross-language tools
RUN npm install -g @microsoft/rush
RUN pip3 install poetry
RUN cargo install cargo-make

Custom Build Systems

# .devcontainer/compose.yml with build orchestration
services:
  dev:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ..:/workspace:cached
      - build_cache:/workspace/target
      - node_modules:/workspace/node_modules
    environment:
      - BUILD_ENV=development
    command: sleep infinity
    
  build-server:
    image: buildkite/agent:latest
    volumes:
      - ..:/workspace
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - BUILDKITE_AGENT_TOKEN=${BUILDKITE_TOKEN}
    
volumes:
  build_cache:
  node_modules:

Performance Optimization

Build Caching Strategies

# Multi-stage build with caching
FROM node:18 as dependencies
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force

FROM node:18 as dev-dependencies  
WORKDIR /app
COPY package*.json ./
RUN npm ci && npm cache clean --force

FROM mcr.microsoft.com/devcontainers/javascript-node:18
WORKDIR /workspace

# Copy production dependencies
COPY --from=dependencies /app/node_modules ./node_modules

# Copy development dependencies for dev containers
COPY --from=dev-dependencies /app/node_modules ./dev_node_modules
ENV NODE_PATH=/workspace/dev_node_modules

Volume Optimization

# compose.yml with optimized volumes
services:
  dev:
    volumes:
      # Source code with optimized sync
      - ..:/workspace:cached
      
      # Separate volumes for generated content
      - node_modules:/workspace/node_modules
      - target:/workspace/target
      - .next:/workspace/.next
      
      # Cache directories
      - ~/.npm:/root/.npm
      - ~/.cargo:/root/.cargo
      
      # Temporary directories
      - /workspace/tmp
      
volumes:
  node_modules:
  target:
  .next:

Resource Management

services:
  dev:
    deploy:
      resources:
        limits:
          cpus: '4'
          memory: 8G
        reservations:
          cpus: '2'
          memory: 4G
    
    # Optimize for development
    environment:
      - NODE_OPTIONS=--max-old-space-size=6144
      - RUST_BACKTRACE=1
      - CARGO_TARGET_DIR=/workspace/target

Security Hardening

User Management

# Secure user setup
ARG USERNAME=devuser
ARG USER_UID=1001
ARG USER_GID=1001

# Create user with specific UID/GID
RUN groupadd --gid $USER_GID $USERNAME \
    && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
    && mkdir -p /etc/sudoers.d \
    && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
    && chmod 0440 /etc/sudoers.d/$USERNAME

# Set up home directory permissions
RUN chown -R $USER_UID:$USER_GID /home/$USERNAME

USER $USERNAME

Secret Management

# compose.yml with secrets
services:
  dev:
    secrets:
      - source: app_secret
        target: /run/secrets/app_secret
        uid: '1001'
        gid: '1001'
        mode: 0400
      - source: db_password
        target: /run/secrets/db_password
        uid: '1001'
        gid: '1001'
        mode: 0400

secrets:
  app_secret:
    file: ./secrets/app_secret.txt
  db_password:
    external: true

Network Security

services:
  dev:
    networks:
      - development
      
  database:
    networks:
      - development
    # Expose only to internal network
    expose:
      - "5432"

networks:
  development:
    driver: bridge
    internal: true

Monitoring and Observability

Container Metrics

# compose.yml with monitoring
services:
  dev:
    # Your main development container
    
  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
      
  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana_data:/var/lib/grafana

  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    ports:
      - "8080:8080"
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:rw
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro

volumes:
  grafana_data:

Application Tracing

# Add tracing capabilities
FROM mcr.microsoft.com/devcontainers/javascript-node:18

# Install tracing tools
RUN npm install -g @opentelemetry/cli
RUN apt-get update && apt-get install -y \
    curl \
    netcat \
    && rm -rf /var/lib/apt/lists/*

# Configure tracing
ENV OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:14268/api/traces
ENV OTEL_SERVICE_NAME=dev-container

Database Development

Multiple Database Support

services:
  dev:
    depends_on:
      - postgres
      - mysql
      - mongodb
      - redis
      
  postgres:
    image: postgres:15
    environment:
      POSTGRES_USER: dev
      POSTGRES_PASSWORD: dev
      POSTGRES_DB: app_development
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./db/postgres:/docker-entrypoint-initdb.d
      
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: dev
      MYSQL_DATABASE: app_development
      MYSQL_USER: dev
      MYSQL_PASSWORD: dev
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql
      - ./db/mysql:/docker-entrypoint-initdb.d
      
  mongodb:
    image: mongo:6
    environment:
      MONGO_INITDB_ROOT_USERNAME: dev
      MONGO_INITDB_ROOT_PASSWORD: dev
      MONGO_INITDB_DATABASE: app_development
    ports:
      - "27017:27017"
    volumes:
      - mongo_data:/data/db
      - ./db/mongodb:/docker-entrypoint-initdb.d
      
  redis:
    image: redis:alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
  mysql_data:
  mongo_data:
  redis_data:

Database Migration Tools

FROM mcr.microsoft.com/devcontainers/base:ubuntu

# Install database clients
RUN apt-get update && apt-get install -y \
    postgresql-client \
    mysql-client \
    mongodb-clients \
    redis-tools \
    && rm -rf /var/lib/apt/lists/*

# Install migration tools
RUN npm install -g db-migrate
RUN pip3 install alembic
RUN cargo install diesel_cli

Testing Environments

Test Isolation

# compose.test.yml
services:
  test:
    build:
      context: .
      dockerfile: Dockerfile
      target: test
    depends_on:
      - test-db
      - test-redis
    environment:
      - NODE_ENV=test
      - DATABASE_URL=postgres://test:test@test-db:5432/test
      - REDIS_URL=redis://test-redis:6379
    command: npm run test:ci
    
  test-db:
    image: postgres:15
    environment:
      POSTGRES_USER: test
      POSTGRES_PASSWORD: test
      POSTGRES_DB: test
    tmpfs:
      - /var/lib/postgresql/data
      
  test-redis:
    image: redis:alpine
    command: redis-server --save ""

Load Testing Environment

services:
  dev:
    # Your application
    
  load-tester:
    image: loadimpact/k6:latest
    volumes:
      - ./tests/load:/scripts
    command: run /scripts/load-test.js
    depends_on:
      - dev
      
  monitoring:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin

Best Practices Summary

Development Workflow

  1. Use multi-stage builds for optimized images
  2. Implement proper caching strategies
  3. Separate concerns between development and production
  4. Version lock your dependencies and tools
  5. Document your setup thoroughly

Security

  1. Run as non-root user whenever possible
  2. Use secrets management for sensitive data
  3. Implement network isolation for services
  4. Regular security updates of base images
  5. Audit dependencies regularly

Performance

  1. Optimize Docker layers and build context
  2. Use appropriate volume types for different data
  3. Implement resource limits to prevent resource exhaustion
  4. Monitor container metrics for optimization opportunities
  5. Use build caches effectively

Next: Learn how to diagnose and resolve common issues in Troubleshooting.

Troubleshooting

This chapter provides comprehensive solutions for common issues, diagnostic techniques, and recovery procedures for Dockim users.

General Diagnostic Approach

When encountering issues with Dockim, follow this systematic approach:

  1. Check System Status - Verify Docker and prerequisites
  2. Review Logs - Examine container and application logs
  3. Test Connectivity - Verify network and port configuration
  4. Check Resources - Monitor CPU, memory, and disk usage
  5. Validate Configuration - Review settings and file contents

Installation Issues

Docker Not Found

Symptoms:

Error: docker command not found

Solutions:

# Check if Docker is installed
which docker

# Install Docker (Ubuntu/Debian)
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Start Docker service
sudo systemctl start docker
sudo systemctl enable docker

# Add user to docker group
sudo usermod -aG docker $USER
# Log out and back in

Docker Permission Issues

Symptoms:

Error: permission denied while trying to connect to Docker daemon

Solutions:

# Add user to docker group
sudo usermod -aG docker $USER

# Apply group changes immediately
newgrp docker

# Verify Docker access
docker version

Dev Container CLI Missing

Symptoms:

Error: devcontainer command not found

Solutions:

# Install Dev Container CLI
npm install -g @devcontainers/cli

# Verify installation
devcontainer --version

# Alternative installation with yarn
yarn global add @devcontainers/cli

Container Build Issues

Build Fails with Network Errors

Symptoms:

Error: failed to solve: failed to fetch

Solutions:

# Configure Docker to use different DNS
sudo tee /etc/docker/daemon.json <<EOF
{
  "dns": ["8.8.8.8", "8.8.4.4"]
}
EOF

# Restart Docker
sudo systemctl restart docker

# Retry build
dockim build --no-cache

Build Hangs or Times Out

Symptoms:

  • Build process appears stuck
  • No progress for extended periods

Solutions:

# Increase Docker build timeout
export DOCKER_BUILDKIT_TIMEOUT=600

# Use plain progress output for debugging
dockim build --progress plain

# Build with more verbose output
dockim build --verbose

# Clear build cache
docker builder prune -a

Dockerfile Syntax Errors

Symptoms:

Error: failed to solve: failed to read dockerfile

Solutions:

# Validate Dockerfile syntax
docker build -f .devcontainer/Dockerfile --dry-run .devcontainer

# Check for common issues:
# - Missing space after instructions (RUN, COPY, etc.)
# - Incorrect file paths
# - Invalid escape sequences

Common Dockerfile Issues:

# Wrong - missing space
RUN apt-get update &&apt-get install -y git

# Correct
RUN apt-get update && apt-get install -y git

# Wrong - incorrect path
COPY ./src /app/source

# Check that ./src actually exists relative to build context

Container Runtime Issues

Container Won't Start

Symptoms:

Error: container exited with code 125

Diagnostic Steps:

# Check container logs
docker logs $(docker ps -aq --filter "label=dockim")

# Check Docker daemon logs
sudo journalctl -u docker.service -f

# Verify container configuration
docker inspect <container_name>

# Try starting with basic command
docker run -it <image_name> /bin/bash

Container Starts but Exits Immediately

Symptoms:

  • Container starts then immediately stops
  • Exit code 0 or other

Solutions:

# Check if main process is running
dockim exec ps aux

# Verify the container command
# In compose.yml, ensure:
command: sleep infinity

# Check for missing dependencies
dockim exec which bash
dockim exec which zsh

Port Binding Failures

Symptoms:

Error: port is already allocated
Error: bind: address already in use

Solutions:

# Find what's using the port
lsof -i :3000
netstat -tuln | grep 3000

# Kill the process using the port
kill -9 <PID>

# Use different port
dockim port add 3001:3000

# Check all port forwards
dockim port ls

Network Connectivity Issues

Cannot Access Application from Host

Symptoms:

  • Application runs in container but not accessible from host
  • Connection refused errors

Diagnostic Steps:

# Check if application is listening on correct interface
dockim exec netstat -tuln | grep :3000

# Application should bind to 0.0.0.0, not 127.0.0.1
# Wrong: app.listen(3000, '127.0.0.1')
# Correct: app.listen(3000, '0.0.0.0')

# Verify port forwarding is active
dockim port ls

# Test connectivity from inside container
dockim exec curl http://localhost:3000

# Test from host
curl http://localhost:3000

Inter-Container Communication Issues

Symptoms:

  • Services can't communicate with each other
  • DNS resolution fails

Solutions:

# Check container network
docker network ls
docker network inspect <network_name>

# Test DNS resolution between containers
dockim exec nslookup database
dockim exec ping database

# Verify services are on same network
docker inspect <container_name> | grep NetworkMode

# Check service dependencies in compose.yml
depends_on:
  - database
  - redis

DNS Resolution Problems

Symptoms:

Error: could not resolve hostname

Solutions:

# Check DNS configuration in container
dockim exec cat /etc/resolv.conf

# Configure custom DNS in compose.yml
services:
  dev:
    dns:
      - 8.8.8.8
      - 8.8.4.4

# Test DNS resolution
dockim exec nslookup google.com
dockim exec dig google.com

Neovim Integration Issues

Remote UI Won't Connect

Symptoms:

  • Neovim server starts but client can't connect
  • Connection timeouts

Diagnostic Steps:

# Check if Neovim server is running
dockim exec ps aux | grep nvim

# Verify port forwarding
dockim port ls | grep nvim

# Check if port is accessible
telnet localhost <port>

# Test with specific port
dockim neovim --host-port 8080

# Check firewall settings
sudo ufw status

Neovim Server Crashes

Symptoms:

  • Server starts then immediately exits
  • Error messages about plugins or configuration

Solutions:

# Run Neovim directly to see error messages
dockim exec nvim --headless

# Check Neovim version
dockim exec nvim --version

# Reset Neovim configuration temporarily
dockim exec mv ~/.config/nvim ~/.config/nvim.bak
dockim exec mkdir ~/.config/nvim

# Test with minimal config
dockim exec nvim --clean

Clipboard Not Working

Symptoms:

  • Copy/paste between host and container fails
  • Clipboard synchronization issues

Solutions:

# Enable clipboard server in config
# ~/.config/dockim/config.toml
[remote]
use_clipboard_server = true

# Check if clipboard tools are installed
dockim exec which xclip
dockim exec which pbcopy  # macOS

# Install clipboard tools (Linux)
dockim exec sudo apt-get install -y xclip

# Test clipboard functionality
echo "test" | dockim exec xclip -selection clipboard

Performance Issues

Slow Build Times

Symptoms:

  • Builds take much longer than expected
  • High CPU/memory usage during builds

Solutions:

# Enable Docker BuildKit
export DOCKER_BUILDKIT=1

# Use build cache
dockim build --cache-from <previous_image>

# Optimize Dockerfile layer ordering
# Put frequently changing files last
COPY package*.json ./
RUN npm ci
COPY . .  # This should be last

# Use .dockerignore
echo "node_modules/" > .dockerignore
echo ".git/" >> .dockerignore
echo "*.log" >> .dockerignore

Slow File Synchronization

Symptoms:

  • File changes not reflected in container
  • High CPU usage during file operations

Solutions:

# Use cached volumes (macOS/Windows)
volumes:
  - ..:/workspace:cached

# Use delegated volumes for write-heavy operations
volumes:
  - ..:/workspace:delegated

# Exclude large directories from sync
volumes:
  - ..:/workspace:cached
  - /workspace/node_modules  # Anonymous volume
  - /workspace/target        # For Rust projects

High Memory Usage

Symptoms:

  • Container uses excessive memory
  • System becomes unresponsive

Solutions:

# Set memory limits
services:
  dev:
    deploy:
      resources:
        limits:
          memory: 4G
        reservations:
          memory: 2G

# Monitor memory usage
docker stats

# Check for memory leaks in applications
dockim exec ps aux --sort=-%mem | head

Storage and Volume Issues

Volume Mount Failures

Symptoms:

Error: invalid mount config
Error: no such file or directory

Solutions:

# Verify source paths exist
ls -la /path/to/source

# Use absolute paths
volumes:
  - $PWD:/workspace:cached  # Instead of .:workspace

# Check permissions
chmod 755 /path/to/source
sudo chown -R $USER:$USER /path/to/source

# Verify Docker has access to the directory
# On macOS: Docker Desktop > Settings > Resources > File Sharing

Disk Space Issues

Symptoms:

Error: no space left on device

Solutions:

# Check disk usage
df -h
docker system df

# Clean up Docker resources
docker system prune -a
docker volume prune
docker image prune -a

# Remove unused containers
docker container prune

# Check for large log files
find /var/lib/docker -name "*.log" -size +100M

Permission Issues with Volumes

Symptoms:

  • Files created in container have wrong ownership
  • Cannot write to mounted volumes

Solutions:

# Set correct user in Dockerfile
ARG USER_UID=1000
ARG USER_GID=1000
RUN usermod --uid $USER_UID --gid $USER_GID vscode

# Fix permissions on host
sudo chown -R $USER:$USER /path/to/project

# Use user namespace remapping
# /etc/docker/daemon.json
{
  "userns-remap": "default"
}

Configuration Issues

Invalid Configuration Files

Symptoms:

Error: invalid devcontainer.json
Error: yaml: invalid syntax

Solutions:

# Validate JSON syntax
cat .devcontainer/devcontainer.json | jq .

# Validate YAML syntax  
yamllint .devcontainer/compose.yml

# Use online validators:
# - jsonlint.com for JSON
# - yamllint.com for YAML

# Check for common issues:
# - Missing commas in JSON
# - Incorrect indentation in YAML
# - Unquoted strings with special characters

Environment Variable Issues

Symptoms:

  • Environment variables not available in container
  • Incorrect values

Solutions:

# Check environment variables in container
dockim exec printenv

# Verify environment file syntax
cat .env
# KEY=value (no spaces around =)
# No quotes unless needed

# Check variable precedence
# 1. Command line options
# 2. Environment variables
# 3. .env files
# 4. compose.yml environment section
# 5. Dockerfile ENV

# Debug specific variables
dockim exec echo $NODE_ENV
dockim exec echo $DATABASE_URL

Recovery Procedures

Complete Environment Reset

When all else fails, start fresh:

# Stop all containers
dockim down --volumes

# Remove all containers and images
docker system prune -a

# Remove all volumes
docker volume prune

# Remove Dockim configuration
rm -rf .devcontainer

# Reinitialize
dockim init
dockim build
dockim up

Backup and Restore

Backup important data:

# Export container data
docker run --volumes-from <container> -v $(pwd):/backup ubuntu tar czf /backup/backup.tar.gz /data

# Backup configuration
tar czf dockim-config-backup.tar.gz .devcontainer ~/.config/dockim

Restore data:

# Restore container data
docker run --volumes-from <container> -v $(pwd):/backup ubuntu bash -c "cd /data && tar xzf /backup/backup.tar.gz --strip 1"

# Restore configuration
tar xzf dockim-config-backup.tar.gz

Emergency Debugging

Access container for manual debugging:

# Get container ID
docker ps

# Access as root for system-level debugging
docker exec -it --user root <container_id> bash

# Check system processes
ps aux

# Check system logs
journalctl -xe

# Check network configuration
ip addr show
cat /etc/hosts

# Check mounted volumes
mount | grep workspace

Getting Help

Collecting Diagnostic Information

When asking for help, collect this information:

# System information
uname -a
docker version
dockim --version

# Container status
docker ps -a
docker images

# Recent logs
docker logs <container_name> --tail 50

# Configuration files
cat .devcontainer/devcontainer.json
cat .devcontainer/compose.yml

# Network information  
docker network ls
dockim port ls

Reporting Issues

When reporting issues:

  1. Describe the problem clearly
  2. Include error messages (full text)
  3. List steps to reproduce the issue
  4. Share configuration files (without secrets)
  5. Provide system information
  6. Mention what you've already tried

Community Resources

  • GitHub Issues: Report bugs and feature requests
  • Discussions: Ask questions and share experiences
  • Documentation: Check latest updates and examples
  • Stack Overflow: Search for similar issues

Next: Learn how to contribute to Dockim development in Contributing.

Contributing

Thank you for your interest in contributing to Dockim! This chapter provides comprehensive guidelines for developers who want to help improve the project.

Ways to Contribute

There are many ways to contribute to Dockim:

  • Report bugs and suggest features through GitHub Issues
  • Improve documentation by fixing errors or adding examples
  • Submit code improvements through pull requests
  • Share your experience in discussions and help other users
  • Test new features and provide feedback
  • Create templates for common development environments

Getting Started

Setting Up the Development Environment

  1. Fork the repository on GitHub
  2. Clone your fork to your local machine:
git clone https://github.com/your-username/dockim.git
cd dockim
  1. Set up the development environment:
# Install Rust (if not already installed)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Install development dependencies
cargo build

# Run tests to ensure everything works
cargo test
  1. Create a new branch for your contribution:
git checkout -b feature/your-feature-name

Project Structure

Understanding the project layout helps you navigate the codebase:

dockim/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ commands/          # Command implementations
β”‚   β”œβ”€β”€ config/            # Configuration management
β”‚   β”œβ”€β”€ container/         # Container operations
β”‚   β”œβ”€β”€ neovim/           # Neovim integration
β”‚   β”œβ”€β”€ port/             # Port forwarding logic
β”‚   └── main.rs           # CLI entry point
β”œβ”€β”€ tests/
β”‚   β”œβ”€β”€ integration/      # Integration tests
β”‚   └── unit/            # Unit tests
β”œβ”€β”€ docs/                # Documentation source
β”œβ”€β”€ templates/           # Project templates
└── examples/           # Usage examples

Development Guidelines

Code Style

Dockim follows standard Rust conventions:

#![allow(unused)]
fn main() {
// Use snake_case for functions and variables
fn handle_container_operation() -> Result<()> {
    let container_name = "dev-container";
    // ...
}

// Use PascalCase for types and structs
struct ContainerConfig {
    name: String,
    ports: Vec<PortMapping>,
}

// Use SCREAMING_SNAKE_CASE for constants
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30);
}

Formatting:

# Format code before committing
cargo fmt

# Check for common issues
cargo clippy

Writing Tests

All new features should include appropriate tests:

Unit Tests:

#![allow(unused)]
fn main() {
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_port_parsing() {
        let result = parse_port_spec("8080:3000").unwrap();
        assert_eq!(result.host_port, 8080);
        assert_eq!(result.container_port, 3000);
    }

    #[test]
    fn test_invalid_port_spec() {
        let result = parse_port_spec("invalid");
        assert!(result.is_err());
    }
}
}

Integration Tests:

#![allow(unused)]
fn main() {
// tests/integration/container_tests.rs
use dockim::commands::container::*;
use tempfile::TempDir;

#[test]
fn test_container_lifecycle() {
    let temp_dir = TempDir::new().unwrap();
    let project_path = temp_dir.path();
    
    // Initialize project
    init_project(project_path, &InitOptions::default()).unwrap();
    
    // Build container
    build_container(project_path, &BuildOptions::default()).unwrap();
    
    // Start container
    start_container(project_path, &StartOptions::default()).unwrap();
    
    // Verify container is running
    assert!(is_container_running(project_path).unwrap());
    
    // Stop container
    stop_container(project_path, &StopOptions::default()).unwrap();
}
}

Error Handling

Use Rust's Result type consistently and provide meaningful error messages:

#![allow(unused)]
fn main() {
use anyhow::{Context, Result};

fn read_config_file(path: &Path) -> Result<Config> {
    let content = std::fs::read_to_string(path)
        .with_context(|| format!("Failed to read config file: {}", path.display()))?;
    
    let config = toml::from_str(&content)
        .with_context(|| "Failed to parse config file as TOML")?;
    
    Ok(config)
}
}

Documentation

Document public APIs with rustdoc:

#![allow(unused)]
fn main() {
/// Manages port forwarding between host and container
pub struct PortManager {
    forwards: Vec<PortForward>,
}

impl PortManager {
    /// Creates a new port manager
    /// 
    /// # Examples
    /// 
    /// ```
    /// use dockim::port::PortManager;
    /// 
    /// let manager = PortManager::new();
    /// ```
    pub fn new() -> Self {
        Self {
            forwards: Vec::new(),
        }
    }
    
    /// Adds a new port forwarding rule
    /// 
    /// # Arguments
    /// 
    /// * `host_port` - Port on the host machine
    /// * `container_port` - Port in the container
    /// 
    /// # Errors
    /// 
    /// Returns an error if the port is already in use
    pub fn add_forward(&mut self, host_port: u16, container_port: u16) -> Result<()> {
        // Implementation
    }
}
}

Submitting Changes

Pull Request Process

  1. Create a focused PR that addresses a single issue or feature
  2. Write a clear title that summarizes the change
  3. Provide a detailed description including:
    • What problem this solves
    • How you tested the changes
    • Any breaking changes
    • Related issues

Example PR Template:

## Summary
Add support for custom port binding addresses in port forwarding.

## Changes
- Added `--bind` option to `dockim port add` command
- Updated port configuration to support IP address specification
- Added tests for IP binding functionality

## Testing
- Unit tests for port parsing with IP addresses
- Integration tests for port forwarding with custom IPs
- Manual testing on macOS and Linux

## Breaking Changes
None - this is a backward compatible addition.

Fixes #123

Commit Guidelines

Use conventional commit format:

# Feature additions
git commit -m "feat: add custom IP binding for port forwards"

# Bug fixes
git commit -m "fix: handle port conflicts when container restarts"

# Documentation updates
git commit -m "docs: add examples for advanced port configuration"

# Code improvements
git commit -m "refactor: simplify port manager error handling"

# Tests
git commit -m "test: add integration tests for port conflicts"

Code Review Process

All contributions go through code review:

  1. Automated checks run on your PR (tests, linting, formatting)

  2. Manual review by maintainers focuses on:

    • Code correctness and safety
    • Performance implications
    • API design consistency
    • Test coverage
    • Documentation completeness
  3. Address feedback by:

    • Making requested changes
    • Explaining your approach if different
    • Adding tests for edge cases
    • Updating documentation

Types of Contributions

Bug Reports

When reporting bugs, include:

Environment Information:

OS: macOS 13.0
Docker: 24.0.5
Dockim: 0.2.1
Rust: 1.70.0

Steps to Reproduce:

1. dockim init --template nodejs
2. dockim build
3. dockim up
4. dockim port add 3000
5. Expected: Port forwards successfully
   Actual: Error: port already in use

Minimal Example: Provide the smallest possible example that demonstrates the bug.

Feature Requests

For new features, describe:

  • Use case: What problem does this solve?
  • Proposed solution: How should it work?
  • Alternatives considered: Other ways to solve this
  • Additional context: Any relevant background

Documentation Improvements

Documentation contributions are always welcome:

  • Fix typos and grammar
  • Add missing examples
  • Clarify confusing sections
  • Translate to other languages
  • Create tutorials and guides

Development Workflow

Local Testing

Run the full test suite before submitting:

# Unit tests
cargo test

# Integration tests
cargo test --test integration

# Documentation tests
cargo test --doc

# Clippy linting
cargo clippy -- -D warnings

# Format check
cargo fmt -- --check

Testing with Real Projects

Test your changes with actual projects:

# Build your changes
cargo build --release

# Use your local build
alias dockim-dev="$PWD/target/release/dockim"

# Test with different project types
cd ~/projects/nodejs-app
dockim-dev init --template nodejs
dockim-dev build
dockim-dev up

Performance Testing

For performance-sensitive changes:

# Benchmark critical paths
cargo bench

# Profile memory usage
valgrind --tool=massif target/release/dockim build

# Time operations
time dockim build --no-cache

Release Process

Understanding the release process helps when timing contributions:

Version Numbering

Dockim uses semantic versioning (SemVer):

  • Major (x.0.0): Breaking changes
  • Minor (0.x.0): New features, backward compatible
  • Patch (0.0.x): Bug fixes, backward compatible

Release Schedule

  • Patch releases: As needed for critical bugs
  • Minor releases: Monthly for new features
  • Major releases: When significant breaking changes accumulate

Pre-release Testing

Before releases, we test:

  • Multiple operating systems (Linux, macOS, Windows)
  • Different Docker versions
  • Various project templates
  • Integration with popular editors

Community Guidelines

Code of Conduct

We are committed to providing a welcoming and inclusive environment:

  • Be respectful in all interactions
  • Be constructive when giving feedback
  • Be patient with new contributors
  • Be collaborative in problem-solving

Communication

GitHub Issues: For bug reports and feature requests GitHub Discussions: For questions and general discussion Pull Requests: For code contributions Documentation: For usage questions

Getting Help

If you need help contributing:

  1. Check existing issues for similar problems
  2. Read the documentation thoroughly
  3. Ask in discussions for guidance
  4. Join community channels for real-time help

Recognition

We appreciate all contributions and recognize contributors:

  • Contributors list in README
  • Changelog acknowledgments for each release
  • Special recognition for significant contributions
  • Maintainer invitation for consistent contributors

Building and Packaging

Local Development Builds

# Debug build (faster compilation)
cargo build

# Release build (optimized)
cargo build --release

# Install locally for testing
cargo install --path .

Cross-Platform Builds

# Add target platforms
rustup target add x86_64-unknown-linux-gnu
rustup target add x86_64-apple-darwin
rustup target add x86_64-pc-windows-gnu

# Build for specific targets
cargo build --release --target x86_64-unknown-linux-gnu

Docker Integration Testing

Test with different Docker configurations:

# Test with different Docker versions
docker --version

# Test with Docker Desktop vs Docker Engine
docker info | grep "Server Engine"

# Test with different base images
dockim init --template nodejs  # Node.js
dockim init --template python  # Python
dockim init --template rust    # Rust

Thank you for contributing to Dockim! Your efforts help make containerized development better for everyone. If you have questions about contributing, don't hesitate to ask in our GitHub Discussions.

Next: Find answers to common questions in FAQ.

Frequently Asked Questions (FAQ)

This chapter answers common questions about Dockim, covering installation, configuration, troubleshooting, and usage scenarios.

General Questions

What is Dockim?

Dockim is a command-line tool that simplifies the creation and management of development containers. It provides an alternative interface to dev containers with enhanced features like built-in Neovim integration, simplified port management, and streamlined container operations.

How does Dockim differ from other dev container tools?

Key differences:

  • Native Neovim integration with remote UI support
  • Simplified command interface compared to VS Code's Dev Containers extension
  • Built-in port management system
  • Direct CLI access without requiring VS Code
  • Template-based project initialization
  • Optimized for terminal-based development

Is Dockim compatible with VS Code Dev Containers?

Yes! Dockim generates standard .devcontainer configuration files that are fully compatible with VS Code's Dev Containers extension. You can:

  • Use Dockim to initialize projects and then open them in VS Code
  • Switch between Dockim CLI and VS Code seamlessly
  • Share projects with team members using either tool

Installation and Setup

What are the system requirements?

Minimum requirements:

  • Docker Engine 20.10+ or Docker Desktop
  • Linux, macOS, or Windows (with WSL2)
  • 4GB RAM (8GB+ recommended)
  • 10GB free disk space

For Neovim integration:

  • Neovim 0.9+ installed on your host system
  • Terminal with true color support

How do I install Dockim?

From releases:

# Linux/macOS
curl -sSL https://github.com/username/dockim/releases/latest/download/dockim-linux | sudo tee /usr/local/bin/dockim > /dev/null
sudo chmod +x /usr/local/bin/dockim

# Or using Homebrew (macOS)
brew install dockim

From source:

git clone https://github.com/username/dockim.git
cd dockim
cargo build --release
sudo cp target/release/dockim /usr/local/bin/

I get "docker command not found" error. What should I do?

This means Docker is not installed or not in your PATH. Install Docker first:

Ubuntu/Debian:

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
# Log out and back in

macOS:

brew install --cask docker
# Or download Docker Desktop from docker.com

Windows: Install Docker Desktop from docker.com and ensure WSL2 integration is enabled.

I get permission denied errors with Docker. How do I fix this?

Add your user to the docker group:

sudo usermod -aG docker $USER
newgrp docker  # Apply immediately

On some systems, you may need to restart the Docker service:

sudo systemctl restart docker

Project Setup

How do I start a new project with Dockim?

# Navigate to your project directory
cd my-project

# Initialize with default template
dockim init

# Or use a specific template
dockim init --template nodejs
dockim init --template python
dockim init --template rust

What templates are available?

Currently available templates:

  • default: Basic Ubuntu container with common tools
  • nodejs: Node.js development environment
  • python: Python development environment
  • rust: Rust development environment
  • go: Go development environment

Can I customize the generated configuration?

Yes! After running dockim init, you can edit:

  • .devcontainer/devcontainer.json - Main container configuration
  • .devcontainer/compose.yml - Docker Compose setup
  • .devcontainer/Dockerfile - Custom image definition

How do I add additional services (database, redis, etc.)?

Edit .devcontainer/compose.yml and add services:

services:
  dev:
    # Your main development container
    depends_on:
      - database
      
  database:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: dev
      POSTGRES_DB: myapp
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Container Management

How do I build and start my development container?

# Build the container image
dockim build

# Start the container
dockim up

# Or combine both steps
dockim up --rebuild

My container fails to build. What should I check?

Common build issues:

  1. Docker daemon not running: sudo systemctl start docker
  2. Network connectivity: Check your internet connection
  3. Dockerfile syntax errors: Validate your .devcontainer/Dockerfile
  4. Insufficient disk space: Run docker system prune to clean up

Enable verbose output for debugging:

dockim build --verbose

How do I update my container after changing the Dockerfile?

# Rebuild the image
dockim build --rebuild

# Restart the container
dockim down
dockim up

How do I access a shell in the running container?

# Open default shell
dockim shell

# Or use the shorter alias
dockim sh

# Open bash specifically
dockim bash

# Run as root user
dockim shell --user root

Neovim Integration

How do I use Neovim with Dockim?

# Start Neovim with remote UI (recommended)
dockim neovim

# Or use the short alias
dockim v

# Open specific files
dockim neovim src/main.rs config.toml

# Run Neovim directly in container (no remote UI)
dockim neovim --no-remote-ui

Neovim won't connect to the container. What's wrong?

Common issues:

  1. Neovim not installed on host: Install Neovim 0.9+
  2. Port conflicts: Check with dockim port ls and free up ports
  3. Firewall blocking connection: Check your firewall settings
  4. Container not running: Ensure container is up with dockim up

Debug steps:

# Check container status
docker ps

# Check port forwarding
dockim port ls

# Test manual connection
telnet localhost <neovim-port>

Can I use my existing Neovim configuration?

Yes! Your host Neovim configuration (~/.config/nvim) is automatically available in the container through volume mounting. The remote UI setup preserves all your plugins and settings.

How do I install additional Neovim plugins in the container?

Your plugins are installed on the host system and work through the remote connection. Simply manage them as usual in your host Neovim configuration.

Port Management

How do I expose ports from my container?

# Forward port 3000 from container to host port 3000
dockim port add 3000

# Forward container port 3000 to host port 8080
dockim port add 8080:3000

# Let Docker assign a free host port
dockim port add :3000

# View active port forwards
dockim port ls

I get "port already in use" errors. How do I fix this?

# Find what's using the port
lsof -i :3000
netstat -tuln | grep 3000

# Kill the process using the port
kill -9 <PID>

# Or use a different port
dockim port add 8080:3000

How do I remove port forwards?

# Remove specific port forwards
dockim port rm 3000 8080

# Remove all port forwards
dockim port rm --all

Configuration

Where are Dockim's configuration files stored?

Global configuration:

  • Linux/macOS: ~/.config/dockim/config.toml
  • Windows: %APPDATA%\dockim\config.toml

Project configuration:

  • .devcontainer/devcontainer.json
  • .devcontainer/compose.yml
  • .devcontainer/Dockerfile

How do I change the default shell?

Globally: Edit ~/.config/dockim/config.toml:

shell = "/bin/zsh"

Per command:

dockim shell --shell /bin/zsh

How do I set environment variables for my container?

In compose.yml:

services:
  dev:
    environment:
      - NODE_ENV=development
      - DATABASE_URL=postgres://localhost:5432/myapp

Using .env file: Create .devcontainer/.env:

NODE_ENV=development
DATABASE_URL=postgres://localhost:5432/myapp

Can I use different configurations for different projects?

Yes! Each project has its own .devcontainer configuration. You can also override global settings per project in devcontainer.json.

Performance

My container builds are very slow. How can I speed them up?

  1. Use .dockerignore to exclude unnecessary files:
node_modules/
.git/
*.log
target/
  1. Enable Docker BuildKit:
export DOCKER_BUILDKIT=1
  1. Optimize Dockerfile layer ordering:
# Copy dependency files first (changes less frequently)
COPY package*.json ./
RUN npm ci

# Copy source code last (changes more frequently)
COPY . .
  1. Use build cache:
dockim build --cache-from previous-image

File changes in my IDE don't appear in the container immediately. Why?

This is usually a file synchronization issue:

  1. Use cached volumes (macOS/Windows):
volumes:
  - ..:/workspace:cached
  1. Exclude large directories:
volumes:
  - ..:/workspace:cached
  - /workspace/node_modules  # Anonymous volume
  1. Check file permissions on Linux:
ls -la .devcontainer

My container uses too much memory. How do I limit it?

Set memory limits in compose.yml:

services:
  dev:
    deploy:
      resources:
        limits:
          memory: 4G
        reservations:
          memory: 2G

Troubleshooting

My container starts but exits immediately. What's wrong?

  1. Check container logs:
docker logs $(docker ps -aq --filter "label=dockim")
  1. Verify the container command:
# In compose.yml, ensure you have:
command: sleep infinity
  1. Check for missing dependencies:
dockim exec which bash
dockim exec which zsh

I can't access my application running in the container from my browser. Why?

  1. Check port forwarding:
dockim port ls
  1. Ensure your application binds to 0.0.0.0, not 127.0.0.1:
// Wrong
app.listen(3000, '127.0.0.1');

// Correct
app.listen(3000, '0.0.0.0');
  1. Test connectivity:
# From inside container
dockim exec curl http://localhost:3000

# From host
curl http://localhost:3000

How do I completely reset my development environment?

# Stop and remove containers, volumes, and images
dockim down --volumes --images

# Remove configuration
rm -rf .devcontainer

# Start fresh
dockim init
dockim build
dockim up

Integration

Can I use Dockim with VS Code?

Yes! Dockim generates standard dev container configurations. You can:

  1. Initialize a project with Dockim
  2. Open it in VS Code
  3. VS Code will detect the dev container configuration automatically

How do I integrate with CI/CD pipelines?

Use the generated dev container configuration with CI services:

GitHub Actions:

- name: Build and test in Dev Container
  uses: devcontainers/ci@v0.3
  with:
    imageName: ghcr.io/${{ github.repository }}/devcontainer
    runCmd: |
      npm ci
      npm test

GitLab CI:

test:
  image: docker:latest
  services:
    - docker:dind
  script:
    - cd .devcontainer && docker build -t test-container .
    - docker run test-container npm test

Does Dockim work with remote development (SSH)?

Yes! You can use Dockim on remote servers via SSH. The Neovim remote UI works particularly well for this scenario as it separates the client and server.

Advanced Usage

Can I use Dockim for microservices development?

Absolutely! Set up multiple services in compose.yml:

services:
  dev:
    # Main development container
    
  api-service:
    build: ./services/api
    ports:
      - "3001:3001"
      
  web-service:
    build: ./services/web
    ports:
      - "3000:3000"
    depends_on:
      - api-service

How do I share volumes between containers?

Use named volumes in compose.yml:

services:
  dev:
    volumes:
      - shared_data:/data
      
  database:
    volumes:
      - shared_data:/var/lib/data

volumes:
  shared_data:

Can I use custom base images?

Yes! Create a custom Dockerfile:

FROM your-custom-base:latest

# Your customizations
RUN apt-get update && apt-get install -y your-tools

USER vscode

Getting Help

Where can I get help with Dockim?

  1. Documentation: Read through this book thoroughly
  2. GitHub Issues: For bug reports and feature requests
  3. GitHub Discussions: For questions and community support
  4. Stack Overflow: Search for similar issues (tag: dockim)

How do I report bugs effectively?

Include the following information:

  1. System information: OS, Docker version, Dockim version
  2. Steps to reproduce the issue
  3. Expected vs actual behavior
  4. Error messages (complete text)
  5. Configuration files (without secrets)
  6. What you've already tried

How can I contribute to Dockim?

See the Contributing chapter for detailed guidelines on:

  • Reporting bugs and suggesting features
  • Contributing code improvements
  • Improving documentation
  • Helping other users

Is there a roadmap for future features?

Check the project's GitHub repository for:

  • Milestones: Planned releases and features
  • Issues: Requested features and their status
  • Discussions: Community ideas and feedback
  • Projects: Development planning boards

If your question isn't answered here, please check the GitHub Discussions or file an issue. We're continuously improving this FAQ based on user feedback!