Skip to content

Instantly share code, notes, and snippets.

@yarlson
Last active July 22, 2025 08:39
Show Gist options
  • Select an option

  • Save yarlson/8612e3a2ed568be6722ffca792669849 to your computer and use it in GitHub Desktop.

Select an option

Save yarlson/8612e3a2ed568be6722ffca792669849 to your computer and use it in GitHub Desktop.
ds - Docker Shell Helper

ds - Docker Shell Helper

A simple zsh function for easily shelling into running Docker containers with tab completion.

Installation

Add this to your ~/.zshrc:

# Docker shell helper - shell into running containers
ds() {
  local container="${1}"
  local shell_cmd="${2:-}"
  
  if [[ -z "$container" ]]; then
    echo "Usage: ds <container> [shell]"
    echo ""
    echo "Examples:"
    echo "  ds my-container"
    echo "  ds nginx-123 /bin/sh"
    return 1
  fi
  
  # Show which container we're entering
  echo "\033[36m🐳 Entering container:\033[0m \033[1;34m$container\033[0m"
  
  if [[ -n "$shell_cmd" ]]; then
    echo "\033[90m→ Running: $shell_cmd\033[0m"
    docker exec -it "$container" "$shell_cmd"
  else
    if docker exec "$container" command -v /bin/bash &>/dev/null; then
      echo "\033[90m→ Running: /bin/bash\033[0m"
      docker exec -it "$container" /bin/bash
    else
      echo "\033[90m→ Running: /bin/sh\033[0m"
      docker exec -it "$container" /bin/sh
    fi
  fi
}

# Fuzzy completion for ds (inline, no popup)
_ds_complete() {
  if [[ $CURRENT -eq 2 ]]; then
    local containers=($(docker ps --filter "status=running" --format '{{.Names}}' 2>/dev/null))
    local partial="${words[CURRENT]}"
    local matches=()
    
    # Fuzzy matching: find containers that contain the partial string (case insensitive)
    for container in "${containers[@]}"; do
      if [[ -z "$partial" ]] || [[ "${container:l}" == *"${partial:l}"* ]]; then
        matches+=("$container")
      fi
    done
    
    # If no substring matches, try simpler pattern matching
    if [[ ${#matches[@]} -eq 0 && -n "$partial" ]]; then
      for container in "${containers[@]}"; do
        # Simple character sequence check: all chars from partial must appear in order
        local container_lower="${container:l}"
        local remaining="$container_lower"
        local found=1
        
        for (( i=1; i<=${#partial}; i++ )); do
          local char="${partial[i]:l}"
          if [[ "$remaining" == *"$char"* ]]; then
            # Remove everything up to and including this character
            remaining="${remaining#*$char}"
          else
            found=0
            break
          fi
        done
        
        if [[ $found -eq 1 ]]; then
          matches+=("$container")
        fi
      done
    fi
    
    if [[ ${#matches[@]} -gt 0 ]]; then
      _describe 'containers' matches
    fi
  fi
}

compdef _ds_complete ds

Then reload your shell:

source ~/.zshrc

Usage

# Shell into a container (auto-detects bash/sh)
ds my-container

# Use a specific shell
ds nginx-container /bin/zsh

# Fuzzy completion examples:
ds nginx<TAB>  # Shows all containers containing "nginx"
ds dep<TAB>    # Shows deployment-* containers  
ds djg<TAB>    # Shows docker-jenkins-group (character sequence: d-j-g)
ds api<TAB>    # Shows containers containing "api"

Features

  • πŸš€ Simple zsh function - no external scripts
  • πŸ” Fuzzy completion - substring and character sequence matching (case insensitive)
  • ⚑ Inline completion - works like standard tab completion but with fuzzy search
  • 🎯 No dependencies - pure zsh, no fzf or external tools required
  • 🐚 Automatic shell detection (/bin/bash β†’ /bin/sh fallback)
  • βš™οΈ Override shell with second argument
  • πŸ“¦ All-in-one - just add to your zshrc

Requirements

  • Zsh shell
  • Docker installed and accessible
  • Running Docker containers (for completion to work)

How It Works

  1. Function: Creates a ds function in your shell
  2. Fuzzy Completion: Substring matching (case-insensitive) + character sequence matching (e.g., "djg" matches "docker-jenkins-group")
  3. Filtering: Only shows running containers (excludes restarting/stopped containers)
  4. Shell Detection: Tries /bin/bash first, falls back to /bin/sh
  5. Execution: Uses docker exec -it for interactive sessions

That's it! No files to manage, everything in your zshrc. πŸŽ‰

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment