THE PHOTON SPHERE

Interactive Brokers' Trader Workstation (TWS) container with GUI

Create an Interactive Brokers’ Trader Workstation platform Docker image that uses your computer’s native GUI. This can be useful when your operating system is not supported by Trader Workstation or no recent version is available.

The docker image is based on alekna/docker-ib-tws Docker image (by Laurynas Alekna), but this derived version displays the GUI directly on your host computer. Which is a lot snappier and more robust. It is also based on https://tpaschalis.github.io/sandboxed-browser-with-docker for the browser sandbox from a container and sound problems (?) fix.

On the Docker host computer, if you run the container manually, do not forget to use xhost to allow access to the X-server, as follows.

xhost +LOCAL:

See the Makefile for an easier way to to build and start the container.

The below project is on github: maridonkers/ib-tws-docker. I use it under NixOS to run IB TWS stable.

Disclaimer

Read Interactive Brokers’ Warnings and Disclosures information. Also beware: this method of deploying IB TWS (via a Docker container) is not endorsed nor supported by IB. Caveat emptor.

Shared files with container

This is done via the data subdirectory. Check if your uid is 1000 via the id command. If it is not then find and change all uid instances in the files of the project and change the 1000 to your uid value.

Define the image via a Dockerfile

The Dockerfile:

# Interactive Brokers' Trader Workstation (TWS) container with GUI
# displaying on the Docker host's X-server.
#
# This is based on alekna/ib-tws Interactive Brokers' Trader
# Workstation (TWS) docker container, which uses VNC to access the
# GUI.
#   https://github.com/alekna/docker-ib-tws
#
# It is also based on
#   https://tpaschalis.github.io/sandboxed-browser-with-docker
#
# and for a browser sandbox from a container and sound problems (?) fix.
#   https://github.com/TheBiggerGuy/docker-pulseaudio-example
#

FROM debian:buster

# Timezone is also in docker-compose file.
ENV HOME /root
ENV TZ Europe/Amsterdam
ENV SHELL /bin/bash

# Install basic Desktop environment for ibtws.
RUN apt-get update; \
    apt-get upgrade -y; \
    apt-get install -y procps sudo curl less vim-nox zip openbox tint2 pcmanfm xfce4-terminal; \
    apt-get clean

RUN sed -i "s#\smain\s*\$# main contrib non-free#" /etc/apt/sources.list

# The Chromium web browser must be installed because TWS apparently
# uses its functionality for e.g. iBot.
#
# Configure browser in TWS settings, as follows:
#   /usr/bin/firefox or /usr/bin/chromium
#
RUN apt-get update; \
    apt-get install -y \
      firefox-esr \
      chromium \
      chromium-l10n \
      fonts-liberation \
      fonts-roboto \
      hicolor-icon-theme \
      libcanberra-gtk-module \
      libexif-dev \
      libgl1-mesa-dri \
      libgl1-mesa-glx \
      libpango1.0-0 \
      libv4l-0 \
      fonts-symbola \
      pulseaudio-utils \
      libglib2.0-0 \
      libavcodec58 \
      libavformat58 \
      --no-install-recommends; \
    rm -rf /var/lib/apt/lists/*; \
    apt-get clean

# Create a non-root account to run TWS with.
RUN useradd -ms /bin/bash --uid 1000 --gid 100 tws; \
    usermod -G audio,video tws;

# RUN echo "tws ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

# Check the pulse-client.conf file (is your uid 1000 ?).
COPY pulse-client.conf /etc/pulse/client.conf

USER tws
WORKDIR /home/tws
ENV HOME /home/tws

RUN mkdir -p /home/tws/Downloads; \
    mkdir -p /home/tws/Desktop; \
    mkdir -p /home/tws/bin

# Retrieve and install TWS (and its embedded JRE). Choose between stable and latest.
# Stable: https://download2.interactivebrokers.com/installers/tws/stable/tws-stable-linux-x64.sh
# Latest: https://download2.interactivebrokers.com/installers/tws/latest/tws-latest-linux-x64.sh
RUN cd /home/tws ; \
    curl -sO https://download2.interactivebrokers.com/installers/tws/latest/tws-latest-linux-x64.sh; \
    echo "/home/tws/Jts" | sh ./tws-latest-linux-x64.sh; \
    rm ./tws-latest-linux-x64.sh

# The DISPLAY variable is required to display TWS on your desktop.
ENV PS1='$ '
ENV DISPLAY=":0"

# Start the installed Interactive Brokers' TWS. Its GUI will display on
# the computer that is hosting the Docker container. Be sure to allow
# access to its X-server via the following command:
#   xhost +LOCAL:
#
RUN echo "" >> /home/tws/.bashrc ;\
    echo "echo \"Press Ctrl+C within 5 seconds to abort TWS start...\""  >> /home/tws/.bashrc ;\
    echo "sleep 5" >> /home/tws/.bashrc ;\
    echo "Jts/tws" >> /home/tws/.bashrc
ENTRYPOINT ["/bin/bash"]

The pulse-client.conf file:

# Connect to the host's server using the mounted UNIX socket
default-server = unix:/run/user/1000/pulse/native

# Prevent a server running in the container
autospawn = no
daemon-binary = /bin/true

# Prevent the use of shared memory
enable-shm = false

The Docker compose file

version: "2.0"
services:
  "tws":
    image: ib-tws
    build: .
    stdin_open: true
    tty: true
    privileged: true
    security_opt:
      - seccomp:"./chrome.json"
    devices:
      - "/dev/snd/:/dev/snd/"
    ipc: host
    environment:
      - TZ=Europe/Amsterdam
    network_mode: host
    volumes:
      - "./data:/home/tws/data:rw"
      - "./.mozilla:/home/tws/.mozilla:rw"
      - "./Jts:/home/tws/Jts:rw"
      - "/tmp/.X11-unix/:/tmp/.X11-unix/:ro"
      - "~/.Xauthority:/home/tws/.Xauthority:rw"
      - "/var/lib/usbmux:/var/lib/usbmux"
      - "/var/run/user/1000/pulse:/run/user/1000/pulse"
      - "/etc/asound.conf:/etc/asound.conf"

Makefile

Use the make command to build the Docker container and bring it up. The Makefile is shown below. Initially use make rebuild to create the container. Then simply use make to run it (leave the command prompt window open). After exit of TWS use CTRL+C to abort the container. To bring it down completely, use make down.

# Brings up the Docker container, which automatically starts IB TWS.
# The attach can be used to connect to the command prompt in the
# container, where e.g. a Ctrl-c can be used to force a stop.
#
all: up 

up:
    xhost +LOCAL:
    docker-compose up

down:
    sync
    docker-compose down

# If problems persist after a force-down then manually restart Docker daemon.
force-down:
    sync
    docker rm -f ib_tws_1

ls:
    docker ps -a

# Get custom seccomp profile (the wget) for browser sound.
rebuild:
    mkdir -p ./Jts
    mkdir -p ./data
    wget https://raw.githubusercontent.com/jfrazelle/dotfiles/master/etc/docker/seccomp/chrome.json -O ./chrome.json
    xhost +LOCAL:
    docker-compose build --no-cache

build:
    xhost +LOCAL:
    docker-compose build

attach:
    xhost +LOCAL:
    docker attach ib_tws_1

shell:
    xhost +LOCAL:
    docker exec -it ib_tws_1 /bin/bash

IB TWS running

If it fails then check Interactive Brokers’ server status page to see if there’s e.g. any scheduled maintenace.

First time build:

make rebuild

After a lot of downloading and building the Docker container is ready. Subsequent builds (normally not necessary) use the then already built container and will therefore be much faster. Simply running it does not require a new build.

Running the container:

make

NOTE: To configure the browser enter /usr/bin/firefox in TWS settings.

Graphical problems

In case of problems, try disabling the compositor in desktop settings and re-login. I specifically had problems with xfwm4 (the XFCE window manager) and disabling the compositor didn’t help, so I switched back to KDE Plasma, which is lightweight these days. Also KDE feels much snappier, is apparently more robust and more feature rich. Why on earth did I switch to XMonad and then xfce? (It was something about KDE being heavy on resources, which is apparently no longer true nowadays.)