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.

Prerequisites

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.

Configure Debugging

In order to debug app.py in Wing, you will need to copy in and configure some additional files that allow invocation of Wing's debugger and connection to the IDE.

(1) 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.1":/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.1/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'

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

Next you need to copy the authentication token file wingdebugpw from the Settings Directory listed in Wing's About box to the same directory as your copy of wingdbstub.py, in this case the docker directory on the host system.

Then add to the Debugger > Advanced > Allowed Hosts preference either the host's IP address (if using Docker Desktop) or the container's IP address determined with docker inspect as described above (if using Docker CE). The host IP is used for Docker Desktop because of how it configures networking for containers; there is access from container to host but no access in the other direction, so the host thinks it is receiving a connection from one of its own network interfaces.

You will also need to tell Wing to listen for debug connections initiated from the outside by clicking on the bug icon in the lower left of Wing's window and enabling Accept Debug Connections.

(4) Establish a file mapping

If the docker directory you mapped with the -v option for docker run does not appear on the same path on the host and container then you will need to communicate the mapping to Wing as well, with the Debugger > Advanced > Location Map preference.

For the docker run example above and container IP address of 172.17.0.2 you would add an entry as follows:

Remote IP Address: 172.17.0.2
File Mappings:
    🔘 Specify Mapping
    Remote: /app
    Local: C:/Users/test/docker

This step could be skipped entirely if the location of files on the container and the host are the same (for example using /app also on the host instead of creating a directory named docker).

Also, if using Docker Desktop where the container IP is the same as the hosts's, it is important to choose a location for the container side of the mapping that either (a) does not exist on the host, or (b) is the same as the location on the host. If the directory exists on the host but has different Python files in it, the Location Map will be incorrectly applied to them if you try to debug them.

(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

This can be added as the first line of app.py. After saving the file, Flask should auto-reload it, which will initiate debug and connect to the IDE so that the bug icon in the lower left of Wing's Window turns green and the toolbar changes to its debug configuration. The application keeps running until it reaches a breakpoint or exception.

Next set a breakpoint by clicking leftmost margin to the left of the return statement in app.py and then trigger it by reloading the page in your browser. Now you can use Wing to step through and inspect the data being used in the debug process.

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, the Location Map preference is likely incorrect. 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.

Notes

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, with much less manual configuration, to debug code 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: