Using Wing with Docker

Index of All Documentation » How-Tos » How-Tos for Containers »


Wing Pro Screenshot

Wing Pro is a Python IDE that can be used to develop, test, and debug Python code running on Docker containers.

This document describes how to configure Wing Pro for Docker. To get started using Wing Pro as your Python IDE, please refer to the tutorial in Wing's Help menu or read the Quickstart Guide.

Getting Started

Before you can work with Docker you will need to download and install it.

On Windows and macOS, downloading Docker Desktop from the Docker website is the easiest way to install it. Be sure to launch the Docker Desktop after you install it, so the daemon is started.

On most Linux distributions, Docker CE (the free community edition) can be installed with the docker-engine package as described here.

You should also install Wing Pro if you don't already have it.

Create a Working Example

This guide uses a small real world example to illustrate the necessary configuration steps. If you want to try out the configuration without altering your existing Docker containers, start by creating a directory docker and placing the following files into it.

Dockerfile:

FROM python:3.7
WORKDIR /app
RUN pip install --trusted-host pypi.python.org Flask
EXPOSE 80
CMD ["python", "app.py"]

app.py:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "<h3>Hello World!</h3>Your app is working.<br/></br/>"

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80, use_reloader=True)

Then build the Docker container by typing the following in the docker directory:

docker build --tag=myapp .

You can now run your container like this:

docker run -v "/path/to/docker":/app -p 4000:80 myapp

You will need to substitute /path/to/docker with the path to the docker directory you created above; the quotes make it work if the path has spaces in it.

You can now try this tiny Flask- web app by pointing a browser running on your host system at it:

If you are using Docker Desktop, then use http://localhost:4000/

If you are using Docker CE, you will need to determine the IP address of your container and use that instead of localhost. One way to do this is to type docker ps to find the Container ID for your container and then use it in the following in place of c052478b0f8a:

docker inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" c052478b0f8a

Notice that if you make a change to app.py in Wing, then the change will be reflected in your browser when you reload the page. This is due to using both the -v argument for docker run to mount a volume in the container, and the fact that app.run() for Flask is being passed use_reloader=True.

Working with Docker through Local Files

In most cases you will want to use Wing with the local (host-side) copy of files that are mapped into the container, with some additional configuration so that processes running on the container can be debugged.

(1) Map host files to the container

As in the above example, you will need to make local (host-side) files available in the container, either at build time or by mapping a volume into the container at runtime.

This can be done at build time in the Dockerfile with COPY. If you use this form, you will need to stop, rebuild, and restart your container every time you make a change:

COPY C:/Users/test/docker /app

Alternatively, you can map the directories at runtime, which allows you to keep working with changed files without restarting the container (although this also depends on the ability of the hosted app to reload your changes):

docker run -v C:/Users/test/docker:/app myapp

Both of these also work on Linux and macOS, with the appropriate paths substituted.

(2) Install the debugger

To access Wing's debugger on the container, add another -v mapping to your docker run command line, so the Wing installation on the host is made available to the container. For example on Windows:

docker run -v "C:/Program Files (x86)/Wing Pro 7.2":/wingpro7 -v C:/Users/test/docker:/app myapp

Or on Linux:

docker run -v /usr/lib/wingpro7:/wingpro7 -v /home/test/docker:/app myapp

Or for macOS:

docker run -v /Applications/WingPro.app/Contents/Resources:/wingpro7 -v /Users/test/docker:/app myapp

You will need to substitute the correct installation location for Wing on your host, which can be seen in Wing's About box, and the full path to the docker directory you created earlier.

Mapping the Wing installation across OSes (for example from Windows host to Linux container) works because Wing's installation has all the files necessary files for debugging on every supported OS.

(2) Copy and configure wingdbstub.py

Debugging is initiated on the Docker side by importing Wing's wingdbstub module. To use this, copy wingdbstub.py from your Wing installation to your mapped directory on the host. For example on a Windows host:

copy "C:/Program Files (x86)/Wing Pro 7.2/wingdbstub.py" C:/Users/test/docker

Or on a Linux host:

cp /usr/lib/wingpro7/wingdbstub.py /home/test/docker

Or a macOS host:

cp /Applications/WingPro.app/Contents/Resources/wingdbstub.py /Users/test/docker

After copying, you will need to edit the file to change kWingHostPost from localhost:50005 to a value that uses the IP address or name of the host computer, for example if your host's IP address is 192.168.1.50:

kWingHostPort = '192.168.1.50:50005'

With Docker version 18.03 or later you on Windows or macOS, you can use the special name host.docker.internal instead of the IP address (this does not work on Linux):

kWingHostPort = 'host.docker.internal:5005'

You will also need to set WINGHOME to the location where you have mapped your Wing installation on the container:

WINGHOME = '/wingpro7'

(3) Enable access

Before Wing will accept any debug connections initiated from outside of the IDE, you need to click on the bug icon in the lower left of Wing's window and enabling Accept Debug Connections.

Then copy the file wingdebugpw from the Settings Directory shown in Wing's About box into the same directory as wingdbstub.py. This is the security token that Wing uses to authenticate the debug connection. Copying this file into place manually is required because the debugger cannot write a persistent security token in most Docker configurations.

(4) Establish a file mapping

In order for Wing's debugger to be able to find files running in the container on the hosts's file system, you must tell Wing about the relationship between the directories you mapped from the host to the container with COPY or the -v option for docker run.

The easiest way to do this is to be sure that you add all your source directories to your project in Wing. This allows Wing to discover all the files that will be used on Docker and to build a mapping between the location of the files on the two systems. See Location Maps for details.

Manually specifying a file mapping

In rare cases where you need to establish a file mapping by hand as described in Manually Configured File Location Maps, you will need to determine the IP address to use in the mapping.

For Docker Desktop, the IP address to use is the one for the host system. This is because Docker Desktop configures networking in a way that makes the container's IP address appear to be the same as the host's.

For Docker CE, you can obtain the container's IP address by determining the container id with docker ps and then use it to inspect the container as in the following example for container id c052478b0f8a:

docker inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" c052478b0f8a

(5) Initiate debug

Once these steps are complete, you can initiate debug from Python code running in the container by importing the module wingdbstub.py as follows:

import wingdbstub

Your copy of wingdbstub.py must be in the same directory as the source code that imports it, or somewhere on the PYTHONPATH (aka sys.path).

The first time you try to debug, Wing will reject the debug connection and prompt you to accept the debug security token being used in the container. After accepting the token, future debug connections will be accepted.

To preauthorize the debug connection, you can copy the file wingdebugpw from the Settings Directory on the host into the same directory as wingdbstub.py on the container.

Once you successfully start debugging and the IDE accepts the connection, the bug icon in the lower left of Wing's Window turns green and the toolbar changes to its debug configuration. The debug process keeps running until it reaches any exceptions or breakpoints.

If you are using the small auto-reloading Flask container example from Create a Working Example above, you can add import wingdbstub as the first line of app.py. When you save the file, Flask should auto-reload it, which will initiate debug. You can set a breakpoint by clicking in the leftmost margin to the left of the return statement in app.py and then trigger it by reloading the page in your browser.

To learn more about Wing's debugger, take a look at the Tutorial in Wing's Help menu or the Debugging Code section of the Quick Start Guide.

Trouble-shooting

If your configuration does not work, try setting kLogFile in your copy of wingdbstub.py to see whether the debugger is reporting errors. Also, looking at the end of ide.log in the Settings Directory listed in Wing's About box may reveal why a connection is failing, if it is being refused by the IDE.

Setting kExitOnFailure in your copy of wingdbstub.py is another way to see why debug or the connection to the IDE is failing. In this case, when you restart the container it will fail to start and print a message indicating the error encountered during import wingdbstub.

If the debug connection is established but breakpoints are not reached, you may need to add your source directories to the project in Wing so a mapping can be established to the location of files on Docker. One way to diagnose this is to add assert 0 to your code. Wing will always stop on that and will report the file it thinks it should be opening in the Exceptions tool. Those can be used to manually configure a file location map, as described above.

Remote Development to Docker with SSH

Docker CE (but not Docker Desktop) is sometimes used to host a more complete installation of Linux, acting more like a stand-alone system that includes the ability to ssh from the host system into the container. In this case, Wing Pro's Remote Development capability can be used instead, to work directly with files and processes running under Docker.

For more information, see Remote Python Development (if the debug process can be launched from the IDE) or Remote Web Development (if the debug process is launched from outside of the IDE).

Related Documents

For more information see: