← Back to DevBytes

Vim Docker Integration: Complete Guide

Vim Docker Integration: Complete Guide

Working with Docker containers often means juggling between terminal sessions, copying files in and out of containers, and struggling with limited tooling inside minimal images. Vim, the ubiquitous text editor, can become your secret weapon for seamless Docker workflows — whether you're editing files inside running containers, developing Dockerfiles efficiently, or running Vim itself inside a containerized environment. This guide walks through everything you need to know.

What Is Vim Docker Integration?

Vim Docker integration refers to the set of techniques, plugins, and workflows that allow Vim (or Neovim) to interact smoothly with Docker containers. This includes editing files that live inside containers, using Vim as your editor for docker commit operations, running Vim inside containers for debugging, and leveraging Vim plugins that understand Dockerfile syntax and container lifecycles.

At its core, the integration is about removing friction. Instead of copying files out of a container, editing them locally, and copying them back, you can edit in place. Instead of fighting with missing editors inside Alpine-based images, you can establish a consistent editing environment.

Why It Matters

Editing Files Inside Running Containers

The simplest form of integration is editing files that exist inside a running container. Docker provides a cp command, but a more elegant approach uses docker exec combined with an editor. However, many minimal images don't include Vim. The workaround is to copy the file out, edit locally, and copy it back — or mount a volume.

Here's a shell function that automates the round-trip editing pattern:

# Add to your ~/.bashrc or ~/.zshrc
docker-vim() {
  if [ -z "$1" ] || [ -z "$2" ]; then
    echo "Usage: docker-vim <container> <file-path>"
    return 1
  fi
  local container="$1"
  local filepath="$2"
  local filename=$(basename "$filepath")
  local tmpfile=$(mktemp "/tmp/docker-vim-${filename}.XXXXXX")
  docker cp "${container}:${filepath}" "$tmpfile"
  vim "$tmpfile"
  docker cp "$tmpfile" "${container}:${filepath}"
  rm -f "$tmpfile"
}

After sourcing your shell configuration, you can run docker-vim my_container /etc/nginx/nginx.conf to edit the file with your local Vim configuration and have changes pushed back automatically.

Using Vim as the Default Editor for Docker Operations

Docker doesn't have a built-in "edit" command, but you can configure your environment so that any tooling that invokes an editor — such as docker commit change messages or compose file generators — uses Vim. Set the EDITOR and VISUAL environment variables:

export EDITOR=vim
export VISUAL=vim

For tools that spawn an editor inside a container, pass the environment variable through:

docker run -it --rm -e EDITOR=vim my-image /bin/sh

Running Vim Inside a Container

Sometimes you need Vim available inside the container itself — for example, when debugging network-isolated environments or when the container filesystem is complex. The challenge is that most production images are minimal. You have two main strategies: install Vim at runtime, or bake it into a development image.

Strategy 1: Install at Runtime

For quick debugging sessions, install Vim on the fly. This is ephemeral and won't persist after the container is removed:

# Alpine-based images
docker exec -it my_container sh -c "apk add --no-cache vim && vim"

# Debian/Ubuntu-based images
docker exec -it my_container sh -c "apt-get update && apt-get install -y vim && vim"

Strategy 2: Build a Development Image

For a more robust setup, create a dedicated development Dockerfile that extends your production image with Vim and your configuration:

FROM my-app:latest

# Install Vim
RUN apt-get update && \
    apt-get install -y --no-install-recommends vim && \
    rm -rf /var/lib/apt/lists/*

# Copy your Vim configuration
COPY .vimrc /root/.vimrc
COPY .vim /root/.vim

# Install plugin manager if needed
RUN vim +PlugInstall +qall || true

WORKDIR /app
CMD ["vim"]

Build and run it:

docker build -t my-app:dev -f Dockerfile.dev .
docker run -it --rm \
  -v $(pwd):/app \
  -v my-app-vim-cache:/root/.vim/cache \
  my-app:dev

Mounting Your Local Vim Configuration Into Containers

If you don't want to bake your config into an image, you can mount your local Vim files as volumes. This keeps your configuration centralized on your host while making it available inside any container:

docker run -it --rm \
  -v $(pwd):/workspace \
  -v ~/.vimrc:/root/.vimrc:ro \
  -v ~/.vim:/root/.vim:ro \
  -v ~/.vim/bundle:/root/.vim/bundle \
  -w /workspace \
  alpine sh -c "apk add --no-cache vim && vim"

Note the :ro flag on the config files — this prevents the container from accidentally modifying your host configuration. The bundle directory is mounted read-write so plugins can update their caches.

Neovim and Docker: A Modern Approach

Neovim offers better integration opportunities thanks to its built-in terminal emulator and remote plugin architecture. You can run Neovim in a container and connect to it, or use Neovim's terminal to manage Docker sessions. A popular pattern is to run Neovim as a containerized development environment:

# Dockerfile.nvim
FROM ubuntu:22.04

RUN apt-get update && apt-get install -y \
    neovim \
    git \
    curl \
    ripgrep \
    nodejs \
    npm \
    && rm -rf /var/lib/apt/lists/*

RUN curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs \
    https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

COPY init.lua /root/.config/nvim/init.lua

WORKDIR /workspace
CMD ["nvim"]

Run it with your project mounted:

docker run -it --rm \
  -v $(pwd):/workspace \
  -v nvim-data:/root/.local/share/nvim \
  my-nvim:latest

Vim Plugins for Docker Development

Several Vim plugins enhance Docker-specific workflows. Here are the most useful ones:

1. vim-dockerfile-syntax

Provides proper syntax highlighting and indentation for Dockerfiles. Most modern Vim distributions include this, but if not:

" .vimrc
Plug 'ekalinin/Dockerfile.vim'

2. vim-docker (Async Commands)

Lets you run Docker commands asynchronously from within Vim, so you can build images without blocking the editor:

Plug 'skanehira/docker.vim'

With this plugin, you can use commands like :DockerImageList, :DockerContainerList, and :DockerImageBuild directly from Vim.

3. ALE (Asynchronous Lint Engine)

ALE can lint Dockerfiles using hadolint, catching common mistakes before you build:

Plug 'dense-analysis/ale'

let g:ale_linters = {
\   'dockerfile': ['hadolint'],
\}

Install hadolint on your host or mount it into your container, and ALE will highlight issues as you type.

Editing Docker Compose Files Efficiently

Compose files are YAML, and Vim handles YAML well out of the box. To improve the experience, add these settings to your .vimrc:

" YAML-specific settings
autocmd FileType yaml setlocal ts=2 sts=2 sw=2 expandtab
autocmd FileType yaml setlocal foldmethod=indent foldlevel=1

" Auto-reload compose file detection
autocmd BufRead,BufNewFile docker-compose*.yml set filetype=yaml.docker-compose

You can also define a custom command to validate compose files from within Vim:

command! ComposeValidate :!docker compose config --quiet
command! ComposeUp :!docker compose up -d
command! ComposeDown :!docker compose down

Remote Editing with Vim and Docker Volumes

A powerful pattern for remote development is running Vim on your host while the application runs in a container, sharing a named volume. This gives you full local Vim performance while the container sees live file changes:

# Create a named volume
docker volume create app-source

# Run the application container with the volume
docker run -d --name my-app \
  -v app-source:/app \
  my-app:latest

# Run a sidecar Vim container that shares the same volume
docker run -it --rm \
  -v app-source:/workspace \
  -v ~/.vimrc:/root/.vimrc:ro \
  my-vim:latest

Now edits made in the Vim container are immediately visible to the application container, enabling true hot-reload development.

Best Practices

A Complete Development Dockerfile Example

Putting it all together, here's a complete development Dockerfile that bundles Vim with a typical web development setup:

FROM node:20-alpine

# Install Vim and useful tools
RUN apk add --no-cache \
    vim \
    git \
    ripgrep \
    bash \
    curl

# Set Vim as default editor
ENV EDITOR=vim
ENV VISUAL=vim

# Copy Vim configuration
COPY vimrc /root/.vimrc

# Install vim-plug
RUN curl -fLo /root/.vim/autoload/plug.vim --create-dirs \
    https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

# Install plugins silently
RUN vim +PlugInstall +qall >/dev/null 2>&1 || true

WORKDIR /app
EXPOSE 3000

CMD ["vim"]

And the accompanying vimrc for the container:

set nocompatible
syntax on
filetype plugin indent on

set number
set tabstop=2
set shiftwidth=2
set expandtab
set autoindent
set smartindent
set hlsearch
set incsearch
set ignorecase
set smartcase

call plug#begin('~/.vim/plugged')
  Plug 'pangloss/vim-javascript'
  Plug 'maxmellon/vim-jsx-pretty'
  Plug 'dense-analysis/ale'
  Plug 'tpope/vim-fugitive'
call plug#end()

let g:ale_linters = {
\   'javascript': ['eslint'],
\   'dockerfile': ['hadolint'],
\}

Conclusion

Vim and Docker are a surprisingly powerful combination. By understanding the various integration points — from editing files inside running containers to running Vim itself in a containerized environment — you can build a development workflow that is fast, consistent, and fully reproducible. Whether you choose to mount your local configuration, bake Vim into a development image, or use async plugins to manage Docker from within the editor, the key is to match the approach to your team's needs. Start with the simple round-trip editing function, graduate to a dedicated development Dockerfile, and layer in plugins as your workflow demands. With these techniques in your toolkit, containerized development with Vim becomes not just viable, but genuinely enjoyable.

— Ad —

Google AdSense will appear here after approval

← Back to all articles