Docker image for Interactive Brokers TWS hosted by IBC running under TightVNC.
-
User configuration is cleanly separated, allowing one computer to serve many accounts, store configuration in Kubernetes secrets, and for one-size-fits-all images to exist on Docker Hub.
-
In line with Kubernetes best practice, IBC and TWS logs are redirected to container stdout.
-
Docker Hub images are completely transparent, except for upload credentials. CI configuration is checked in, and the build log for each cryptographic image digest can be audited via GitHub Actions.
-
TWS auto-restart is supported. If TWS exits, the container will search for a replacement Java process and continue running when one is found.
-
krallin/tini is used to avoid stray TWS zombie processes accumulating over auto-restarts.
-
Running multiple TWS containers within one Kubernetes pod is supported, to allow real time market data to be shared between live and paper trading accounts.
docker run \
--rm -it \
-e VNC_PASSWORD=123 \
-p 127.0.0.1:5900:5900 \
-p 127.0.0.1:7496:7496 \
dockertws/dockertws:ci
Optionally supply credentials using:
-e IBC_USERNAME=myuser123
-e IBC_PASSWORD=OpenSesame
Optionally supply jts.ini
and tws.xml
from an existing TWS installation
using:
-v /path/to/jts.ini:/conf/jts.ini:ro
-v /path/to/tws.xml:/conf/tws.xml:ro
For each account you intend to use the image with, login to TWS from a desktop
computer, or simply start the container and login through it. Repeat for each
desired account. Now grab jts.ini
from your installation, which will contain
a list of encoded account usernames docker-tws
needs to know where to copy
tws.xml
to.
Simply grab tws.xml
after you have finished customizing it. If you created
the files inside a Docker image, use something like docker cp
to extract
them.
Port | Description |
---|---|
5900 / 5901
| VNC display (modify using VNC_DISPLAY option)
|
7462 / 7463
| IBC telnet server |
7496
| TWS API live trading account |
7497
| TWS API paper trading account (modify using TWS_API_PORT )
|
All paths are optional.
Path | Description |
---|---|
/conf
| Read-only directory of configuration files to install. Usable as a Docker or Kubernetes volume |
/conf/jts.ini
| File to install as ~tws/Jts/jts.ini
|
/conf/tws.xml or tws.xml.gz or tws.xml.zst
| File to install as ~tws/Jts/[profile]/tws.xml . If provided,
jts.ini must also be provided, as it is needed to detect the
profile name.To fit the XML in a Kubernetes secret it is likely necessary to compress it. The image supports zstd specifically for this task, which
outperforms gzip by a factor of 2, which in some cases may be required.
Recommended command line: zstd -19 tws.xml
|
/home/tws
| Home directory that can be mapped to a shared volume such as a Kubernetes
emptyDir . On initial startup, the directory is locked and a
pristine TWS is copied into it, if it was previously empty. See
Simultaneous Live/Paper Containers for details.
|
/home/tws/Jts
| Per-container application directory that can be mapped to a private volume
such as a Kubernetes emptyDir . On initial startup, the
directory is populated with a pristine copy of TWS, if it was previously
empty. pristine TWS is copied into it, if it was previously empty. See
Simultaneous Live/Paper Containers for details.
Avoid storing this volume persistently, as the TWS program code is copied into it, complicating the task of upgrading TWS version in use. |
Your live account and the paper account associated with it may be used simultaneously, with both receiving real-time market data, so long as both are used on the same computer. TWS uses a fingerprinting mechanism to verify this, which breaks if the accounts run in different pods, possibly due to changes in container IP or MAC addresses.
However, by hosting both instances as containers within the same Kubernetes
pod, with a shared volume mapped over /home/tws
, and a per-container private
emptyDir
volume mapped over /home/tws/Jts
, the check succeeds and it
becomes possible to host this configuration with unattended logins, VNC and
restarts for both accounts.
The emptyDir
mapping over /home/tws/Jts
is necessary since it seems
impossible to change the location of /home/tws/Jts/jts.ini
, causing a race at
startup as the copies of IBC running in each pod update this file to configure
their associated trading mode.
An example "combined live/paper" Kubernetes configuration as described below is supplied in example/tws-combined.yml.
Ensure your paper trading account is configured to share real-time market data.
- From the Interactive Brokers web app, click the burger menu in the top left
- Choose "Settings" from near the bottom
- Choose "Account Settings" from the sub-menu
- Click the gear icon next to "Paper Trading Account" in the right-hand column about one third of the way down
- Enable the option to share real-time market data
- Wait a few hours for the configuration change to take effect
When docker-tws
starts, if /home/tws
or /home/tws/Jts
are empty, they are
initialized from a pristine TWS installation stored in the image. The volumes required are:
-
/home/tws
: anemptyDir
shared volume mounted in both containers. This volume will contain at least a magic.hwid
file that appears to be part of the fingerprinting process. -
/home/tws/Jts
: anemptyDir
volume that is private to each container, needed to avoid a startup race condition. -
VNC_DISPLAY
should be set to1
for the paper trading container, so that both VNC servers can share the pod IP address. -
TWS_API_PORT
should be set to7497
for the paper trading container, so that both API servers can share the pod IP address.
See the IBC documentation for a description of IBC settings.
Key | Default | Description |
---|---|---|
JVM_HEAP_SIZE | 4096m | Value of `-Xmx` JVM flag in `tws.vmoptions` |
IBC_USERNAME | ||
IBC_PASSWORD | ||
IBC_FIX | no | |
IBC_FIX_USERNAME | ||
IBC_FIX_PASSWORD | ||
IBC_TRADING_MODE | live | |
IBC_SEND_TWS_LOGS_TO_CONSOLE | yes | If `true`, TWS diagnostic logs will also be sent to the container's stdout |
IBC_STORE_SETTINGS_ON_SERVER | no | |
IBC_MINIMIZE_MAIN_WINDOW | no | |
IBC_MAXIMIZE_MAIN_WINDOW | yes | |
IBC_EXISTING_SESSION_DETECTED | manual | |
IBC_ACCEPT_INCOMING_CONNECTION | accept | |
IBC_SHOW_ALL_TRADES | no | |
IBC_READONLY_LOGIN | no | |
IBC_READONLY_API | ||
IBC_ACCEPT_NON_BROKERAGE_WARNING | yes | |
IBC_AUTO_CLOSEDOWN | yes | |
IBC_CLOSEDOWN_AT | ||
IBC_ALLOW_BLIND_TRADING | no | |
IBC_DISMISS_PASSWORD_EXPIRY | no | |
IBC_DISMISS_NSE_COMPLIANCE | yes | |
IBC_SAVE_TWS_SETTINGS_AT | ||
IBC_CONTROL_FROM | 172.17.0.1 | |
IBC_COMMAND_PROMPT | IBC> | |
IBC_SUPPRESS_INFO_MESSAGES | yes | |
IBC_LOG_COMPONENTS | never | |
TWS_API_PORT | If set, the provided tws.xml is rewritten during container
startup, to replace its API port with the specified value. This allows you
to manage a single tws.xml , with the conflicting setting
preventing it running multiple times within a single Kubernetes pod handled
automatically.
| |
TWS_LOGOFF_TIME | If set, the provided tws.xml is rewritten during container
startup, to replace its auto-logoff time with the specified value. This
may help avoid a race during startup where both paper and live TWS
instances attempt to write their authentication tokens to the same file on
disk, causing one or the other instance to attempt to log in using the
incorrect mode, or reusing an expired token. This allows your to manage a
single tws.xml , with the conflicting setting preventing it
running multiple times within a single Kubernetes pod handled
automatically.
| |
JDWP_PORT | Enable JDWP on port. | |
TZ | America/New_York | Container timezone, used by TWS to render timestamps |
VNC_DISPLAY | 0 | VNC X11 display. This is exposed to allow running multiple TWS instances within one Kubernetes pod, where the network interface is shared. |
VNC_PASSWORD | (random) | VNC server password. If unspecified, a random password is logged to stdout |
VNC_NAME | tws-tradingmode-username | VNC desktop name |
VNC_DEPTH | 24 | VNC desktop color depth |
VNC_GEOMETRY | 1920x1080 | VNC desktop resolution |
X11_ROOT_COLOR | #36648B | xsetroot background color |
Ubuntu 20.04
Package | Description |
---|---|
wget
| Used to fetch TWS installer |
ca-certificates
| Inherited from original docker-tws reop |
tightvncserver
| The VNC server |
openbox
| The window manager |
xterm
| Terminal emulator |
google-chrome-stable
| Allows account management, audit trail, 3D volatility surface to be opened |
unzip
| Used to extract IBC |
openjfx
| Needed at least for online help, "No toolkit found" exception in logs otherwise |
openjdk-8-jre
| Possibly optional, or required otherwise data feeds fail to connect |
libnss3 | Required for Google Chrome |
libnspr4 | Required for Google Chrome |
fonts-liberation | Required for Google Chrome |
fonts-dejavu-core | Required for TWS |
fonts-dejavu-extra | Required for TWS |
libasound2 | Required for sound playback |
libavcodec58 | Required for sound playback |
libavformat58 | Required for sound playback |
libappindicator3-1 | Required for Google Chrome |
libgbm1 | Required for Google Chrome |
libxslt1.1 | Required for JavaFX WebKit (iBot, various other TWS embedded web views) |
libxss1 | Required for Google Chrome |
xdg-utils | Required for Google Chrome |
zstd | Settings file decompression |