Xdebug with Vim for Docker for Mac with Ubuntu 16.04

Integrated Development Environments (IDEs) are nice for debugging problems but with Docker containers they have to be set up to work remotely. Vim may not be as nice an interface but has an advantage of being able to run in the container making it easier to get set up and running quickly. This is especially true for new releases where there is not much information yet on configuration.

I will be using Vdebug which is compatible with Python 2.4+. Ubuntu 16.04 can be installed with either Python 2.7 or Python 3. There may be different versions of Ubuntu 16.04 that have either Python 2.7 or Pythn 3 pre-installed but the version I am using does not have either installed. Vim can come in variants that do not have any Python support compiled in or Python 2 or Python 3. I will also be using PHP 7.0 and Drupal 8. In the Dockerfile we need to add

RUN apt-get install -y \
  php-xdebug \
  python \

COPY conf/20-xdebug.ini /etc/php/7.0/apache2/conf.d/
COPY conf/vimrc /root/.vimrc

COPY conf/xdebug.sh /root/
RUN /root/xdebug.sh

I will discuss the files later. First notice that I have specified a variant of Vim with Python 2. A shell in the container can be run using

docker exec -it <ID> /bin/bash

where is the container ID or name. At the prompt type

# python --version
Python 2.7.11+

Make sure that Python 2 is installed for Vdebug. If not then the python 2.7 package may need to be installed. The file 20-xdebug.ini is pretty straightforward.


; Set to 0 if using "?XDEBUG_SESSION_START=1" to start xdebug.
; For debugging connection issues.
; xdebug.remote_log=/tmp/xdebug.log

Vdebug uses the dbgp protocol. I turn on auto start so the special string in the URL is not required but this may need to be changed it other browser sessions are causing confusion. I have commented out the connection logging but this should be uncommented when trying to get Vim and Xdebug communicating. The script installs Vdebug. I do not use Vundle or Pathogen just to simplify the install. The script looks like


git clone https://github.com/joonty/vdebug.git
mkdir -p .vim
cp -r vdebug/* .vim/
rm -r vdebug

This just simply uses Git to grab the files and then copies the stuff that is needed into the proper location. So far installing this in a container is similar to a native install but now we get to a slight twist. Since Vim and the application are together in the container there has been no configuration with ports and such. But it turns out that the keys used to control Vdebug do not get passed into the container. So we have to supply a key mapping to keys that do get passed to the container. I am using the leader key to define a key combination. The default for the leader key is the backslash. These are placed in .vimrc.

let g:vdebug_keymap = {
\ 'run' : '5',
\ 'run_to_cursor' : '9',
\ 'step_over' : '2',
\ 'step_into' : '3',
\ 'step_out' : '4',
\ 'close' : '6',
\ 'detach' : '7',
\ 'set_breakpoint' : 's',
\ 'get_context' : 'c',
\ 'eval_under_cursor' : 'u',
\ 'eval_visual' : 'v',
" For debugging connection issues.
"let g:vdebug_options = {
"\    "debug_file_level" : 2,
"\    "debug_file" : '~/vdebug.log',

With the default for the leader key then starting the debugger in Vim will use "\5" as the key combination instead of the function key F5 which does not get passed into the container. I tried to use the same integer where possible in my key mapping. I also have commented out connection logging but this should be enabled when working on getting the connection working.

In the shell in the container start Vim. Typing :scriptnames in Vim will show whether Vdebug is getting loaded and .vimrc is getting read. Then press "\5" and at the bottom of the window should appear the message

Waiting for a connection (Ctrl-C to cancel, this message will self-destruct in 20 seconds...)

Now go to a browser that is accessing a website in the container and load a page. Then in Vim press return to enter the debugger. If the connection does not work go to the log files /tmp/vdebug.log and /tmp/xdebug.log to figure out the connection problem. Potential problems are using a version of Vim that does not have support for Python2 or Python 2.4+ is not installed.  Once the connection is made the debugger is completely running in the Docker container which has less potential problems then trying to run with one part on the host and the other in the container.