Home

Awesome

Interactive Brokers Gateway Docker

<img src="https://github.com/gnzsnz/ib-gateway-docker/blob/master/logo.png" height="300" alt="IB Gateway Docker"/>

What is it?

A docker image to run Interactive Brokers Gateway and TWS without any human interaction on a docker container

It includes:

Supported Tags

Images are provided for IB gateway and TWS. With the following tags:

ImageChannelIB Gateway VersionIBC VersionDocker Tags
ib-gatewaylatest10.32.1m3.20.0latest 10.32 10.32.1m
ib-gatewaystable10.30.1r3.20.0stable 10.30 10.30.1r
tws-rdesktoplatest10.32.1m3.20.0latest 10.32 10.32.1m
tws-rdesktopstable10.30.1r3.20.0stable 10.30 10.30.1r

All tags are available in the container repository for ib-gateway and tws-rdesktop. IB Gateway and TWS share the same version numbers and tags.

How to use it?

For the two images available, ib-gateway and tws-rdesktop, you can use the sample docker compose files as a starting point.

Create a docker-compose.yml file (or include ib-gateway services on your existing one). The sample files provided can be used as starting point, ib-gateway compose and tws-rdesktop compose.

Looking for help? Please go to discussion section for common problems and solutions.

name: algo-trader
services:
  ib-gateway:
    restart: always
    build:
      context: ./stable
      tags:
        - "ghcr.io/gnzsnz/ib-gateway:stable"
    image: ghcr.io/gnzsnz/ib-gateway:stable
    environment:
      TWS_USERID: ${TWS_USERID}
      TWS_PASSWORD: ${TWS_PASSWORD}
      TRADING_MODE: ${TRADING_MODE:-paper}
      TWS_SETTINGS_PATH: ${TWS_SETTINGS_PATH:-}
      TWS_ACCEPT_INCOMING: ${TWS_ACCEPT_INCOMING:-}
      READ_ONLY_API: ${READ_ONLY_API:-}
      VNC_SERVER_PASSWORD: ${VNC_SERVER_PASSWORD:-}
      TWOFA_TIMEOUT_ACTION: ${TWOFA_TIMEOUT_ACTION:-exit}
      BYPASS_WARNING: ${BYPASS_WARNING:-}
      AUTO_RESTART_TIME: ${AUTO_RESTART_TIME:-}
      AUTO_LOGOFF_TIME: ${AUTO_LOGOFF_TIME:-}
      TWS_COLD_RESTART: ${TWS_COLD_RESTART:-}
      SAVE_TWS_SETTINGS: ${SAVE_TWS_SETTINGS:-}
      RELOGIN_AFTER_TWOFA_TIMEOUT: ${RELOGIN_AFTER_TWOFA_TIMEOUT:-no}
      TWOFA_EXIT_INTERVAL: ${TWOFA_EXIT_INTERVAL:-60}
      TWOFA_DEVICE: ${TWOFA_DEVICE:-}
      EXISTING_SESSION_DETECTED_ACTION: ${EXISTING_SESSION_DETECTED_ACTION:-primary}
      ALLOW_BLIND_TRADING: ${ALLOW_BLIND_TRADING:-no}
      TIME_ZONE: ${TIME_ZONE:-Etc/UTC}
      TZ: ${TIME_ZONE:-Etc/UTC}
      CUSTOM_CONFIG: ${CUSTOM_CONFIG:-NO}
      JAVA_HEAP_SIZE: ${JAVA_HEAP_SIZE:-}
      SSH_TUNNEL: ${SSH_TUNNEL:-}
      SSH_OPTIONS: ${SSH_OPTIONS:-}
      SSH_ALIVE_INTERVAL: ${SSH_ALIVE_INTERVAL:-}
      SSH_ALIVE_COUNT: ${SSH_ALIVE_COUNT:-}
      SSH_PASSPHRASE: ${SSH_PASSPHRASE:-}
      SSH_REMOTE_PORT: ${SSH_REMOTE_PORT:-}
      SSH_USER_TUNNEL: ${SSH_USER_TUNNEL:-}
      SSH_RESTART: ${SSH_RESTART:-}
      SSH_VNC_PORT: ${SSH_VNC_PORT:-}
#    volumes:
#      - ${PWD}/jts.ini:/home/ibgateway/Jts/jts.ini
#      - ${PWD}/config.ini:/home/ibgateway/ibc/config.ini
#      - ${PWD}/tws_settings/:${TWS_SETTINGS_PATH:-/home/ibgateway/Jts}
#      - ${PWD}/ssh/:/home/ibgateway/.ssh
    ports:
      - "127.0.0.1:4001:4003"
      - "127.0.0.1:4002:4004"
      - "127.0.0.1:5900:5900"

All environment variables are common between ibgateway and TWS image, unless specifically stated. The container can be configured with the following environment variables:

VariableDescriptionDefault
TWS_USERIDThe TWS username.
TWS_PASSWORDThe TWS password.
TWS_PASSWORD_FILEThe file containing TWS password.
TRADING_MODElive or paper. From 10.26.1k it supports both which will start ib-gateway or TWS in live AND paper mode in parallel within the container.paper
TWS_USERID_PAPERIf TRADING_MODE=both, then this is required to pass paper account usernot defined
TWS_PASSWORD_PAPERIf TRADING_MODE=both, then this is required to pass paper account passwordnot defined
TWS_PASSWORD_PAPER_FILEIf TRADING_MODE=both, then this is required to pass paper account passwordnot defined
READ_ONLY_APIyes or no. See IBC documentationnot defined
VNC_SERVER_PASSWORDVNC server password. If not defined, then VNC server will NOT start. Specific to ibgateway, ignored by TWS.not defined (VNC disabled)
VNC_SERVER_PASSWORD_FILEVNC server password. If not defined, then VNC server will NOT start. Specific to ibgateway, ignored by TWS.not defined (VNC disabled)
TWOFA_TIMEOUT_ACTION'exit' or 'restart', set to 'restart if you set AUTO_RESTART_TIME. See IBC documentationexit
TWOFA_DEVICEsecond factor authentication device. See IBC documentationnot defined
BYPASS_WARNINGSettings relate to the corresponding 'Precautions' checkboxes in the API section of the Global Configuration dialog. Accepted values yes, no if not set, the existing TWS/Gateway configuration is unchangednot defined
AUTO_RESTART_TIMEtime to restart IB Gateway, does not require daily 2FA validation. format hh:mm AM/PM. See IBC documentationnot defined
AUTO_LOGOFF_TIMEAuto-Logoff: at a specified time, TWS shuts down tidily, without restartingnot defined
TWS_COLD_RESTARTIBC >= 3.19 set this value to hh:mmnot defined
SAVE_TWS_SETTINGSautomatically save its settings on a schedule of your choosing. You can specify one or more specific times, ex SaveTwsSettingsAt=08:00 12:30 17:30not defined
RELOGIN_AFTER_TWOFA_TIMEOUTsupport relogin after timeout. See IBC documentationno
EXISTING_SESSION_DETECTED_ACTIONSet Existing Session Detected Action. See IBC documentationprimary
ALLOW_BLIND_TRADINGTWS displays a dialog to warn you against blind trading.See IBC documentationno
TIME_ZONESupport for timezone, see your TWS jts.ini file for valid values on a tz database. This sets time zone for IB Gateway. If jts.ini exists it will not be set. if TWS_SETTINGS_PATH is set and stored in a volume, jts.ini will already exists so this will not be used. Examples Europe/Paris, America/New_York, Asia/Tokyo"Etc/UTC"
TWS_SETTINGS_PATHSettings path used by IBC's parameter --tws_settings_path. Use with a volume to preserve settings in the volume. If TRADING_MODE=both this will be the prefix four your settings. ex /config/tws_settings_live and /config/tws_settings_paper.
TWS_ACCEPT_INCOMINGSee IBC documentation, possible values accept, reject, manualmanual
CUSTOM_CONFIGIf set to yes, then run.sh will not generate config files using env variables. You should mount config files. Use with care and only if you know what you are doing.NO
JAVA_HEAP_SIZESet Java heap, default 768MB, TWS might need more. Proposed value 1024. Enter just the number, don't enter units, ex mb. See Increase Memory Size for TWSnot defined
SSH_TUNNELIf set to yes then socat won't start, instead a remote ssh tunnel is started. if set to both then socat AND remote ssh tunnel are started. SSH keys should be provided to container through ~/.ssh volume.not defined
SSH_OPTIONSadditional options for ssh clientnot defined
SSH_ALIVE_INTERVALssh ServerAliveInterval setting. Don't set it in SSH_OPTIONS as this behavior is undefined.20
SSH_ALIVE_COUNTssh ServerAliveCountMax setting. Don't set it in SSH_OPTIONS as this behavior is undefined.not defined
SSH_PASSPHRASEpassphrase for ssh keys. If set the container will start ssh-agent and add ssh keysnot defined
SSH_PASSPHRASE_FILEfile containing passphrase for ssh keys. If set the container will start ssh-agent and add ssh keysnot defined
SSH_REMOTE_PORTRemote port for ssh tunnel. If TRADING_MODE=both then SSH_REMOTE_PORT is set to paper port 4002/7498Same port than IB gateway 4001/4002 or 7497/7498
SSH_USER_TUNNELuser@server to connect tonot defined
SSH_RESTARTNumber of seconds to wait before restarting tunnel in case of disconnection.5
SSH_VNC_PORTIf set, then a remote ssh tunnel will be created with remote port equal to SSH_VNC_PORT. Specific to ibgateway, ignored by TWS.not defined
SSH_RDP_PORTIf set, then a remote ssh tunnel will be created with remote port equal to SSH_RDP_PORT. Specific to TWS, ignored by ibgateway.not defined
PUIDUser uid for user abc (linuxserver default user name). Specific to TWS, ignored by ibgateway.1000
PGIDUser gid for user abc (linuxserver default user name). Specific to TWS, ignored by ibgateway.1000
PASSWDPassword for user abc (linuxserver default user name). Specific to TWS, ignored by ibgateway.abc
PASSWD_FILEFile containing password for user abc (linuxserver default user name). Specific to TWS, ignored by ibgateway.abc

Create an .env on root directory. Example .env file:

TWS_USERID=myTwsAccountName
TWS_PASSWORD=myTwsPassword
# ib-gateway
#TWS_SETTINGS_PATH=/home/ibgateway/Jts
# tws
#TWS_SETTINGS_PATH=/config/tws_settings
TWS_SETTINGS_PATH=
TWS_ACCEPT_INCOMING=
TRADING_MODE=paper
READ_ONLY_API=no
VNC_SERVER_PASSWORD=myVncPassword
TWOFA_TIMEOUT_ACTION=restart
TWOFA_DEVICE=
BYPASS_WARNING=
AUTO_RESTART_TIME=11:59 PM
AUTO_LOGOFF_TIME=
TWS_COLD_RESTART=
SAVE_TWS_SETTINGS=
RELOGIN_AFTER_TWOFA_TIMEOUT=yes
EXISTING_SESSION_DETECTED_ACTION=primary
ALLOW_BLIND_TRADING=no
TIME_ZONE=Europe/Zurich
CUSTOM_CONFIG=
SSH_TUNNEL=
SSH_OPTIONS=
SSH_ALIVE_INTERVAL=
SSH_ALIVE_COUNT=
SSH_PASSPHRASE=
SSH_REMOTE_PORT=
SSH_USER_TUNNEL=
SSH_RESTART=
SSH_VNC_PORT=

Once docker-compose.yml and .env are in place you can start the container with:

docker compose up

You can use vnc for ib-gateway or RDP for TWS.

Ports

The following ports will be ready for usage on the ib-gateway container and docker host:

PortDescription
4003TWS API port for live accounts. Through socat, internal TWS API port 4001. Mapped externally to 4001 in sample docker-compose.yml.
4004TWS API port for paper accounts. Through socat, internal TWS API port 4002. Mapped externally to 4002 in sample docker-compose.yml.
5900When VNC_SERVER_PASSWORD was defined, the VNC server port.

TWS image uses the following ports

PortDescription
7498TWS API port for live accounts. Through socat, internal TWS API port 7496. Mapped externally to 7496 in sample tws-docker-compose.yml.
7499TWS API port for paper accounts. Through socat, internal TWS API port 7497. Mapped externally to 7497 in sample tws-docker-compose.yml.
3389Port for RDP server. Mapped externally to 3370 in sample tws-docker-compose.yml.

Utility socat is used to publish TWS API port from container's 127.0.0.1:4001/4002 to container's 0.0.0.0:4003/4004, the sample docker-file.yml maps ports to the host back to 4001/4002. This way any application can use the "standard" IB Gateway ports. For TWS 127.0.0.1:7496/7497 to container's 0.0.0.0:7498/7499, and tws-docker-file.yml will map ports to host back to 7496/7497.

Note that with the above docker-compose.yml, ports are only exposed to the docker host (127.0.0.1), but not to the host network. To expose it to the host network change the port mappings on accordingly (remove the '127.0.0.1:'). Attention: See Leaving localhost

Using TWS

From 10.26.1h it's possible to run TWS in a container. tws-rdesktop image provides a desktop environment that allows to use TWS.

Performance considerations for TWS

tws-rdesktop has the following recomended settings.

In tws-docker-compose.yml:

The start up script will disable xfce compositing, as this has a significant impact on performance.

Customizing the image

Most if not all of the settings needed to run IB Gateway in a container are available as environment variables.

However, if you need to go beyond what's available, the image can be customized by overwriting the default configuration files with custom ones. To do this you must set environment variable CUSTOM_CONFIG=yes. By setting CUSTOM_CONFIG=yes run.sh script will not replace environment variables on config files. You must provide config files ready to be used by IB gateway/TWS and IBC, please make sure that you are familiar with IBC settings.

Image IB Gateway and IBC config file locations:

AppConfig fileDefault
IB Gateway/home/ibgateway/Jts/jts.inijts.ini
IBC/home/ibgateway/ibc/config.iniconfig.ini

For TWS image config file locations are:

AppConfig fileDefault
TWS/opt/ibkr/jts.inijts.ini
IBC/opt/ibc/config.iniconfig.ini

Sample settings:

...
    environment:
      - CUSTOM_CONFIG: yes
...
    volumes:
      - ${PWD}/config.ini:/home/ibgateway/ibc/config.ini
      - ${PWD}/jts.ini:/home/ibgateway/Jts/jts.ini # for IB Gateway
      - ${PWD}/jts.ini:/opt/ibkr/jts.ini # for TWS
      - ${PWD}/config.ini:/opt/ibc/config.ini # for TWS
...

Preserve settings across containers

You can preserve IB Gateway configuration by setting environment variable $TWS_SETTINGS_PATH and setting a volume

...
    environment:
      - TWS_SETTINGS_PATH: /home/ibgateway/tws_settings # IB Gateway
      - TWS_SETTINGS_PATH: /config/tws_settings # tws rdesktop
...
    volumes:
      - ${PWD}/tws_settings:/home/ibgateway/tws_settings # IB Gateway
      - ${PWD}/config:/config # for TWS we use linuxserver /config volume
...

For TWS it's recommended to use TWS_SETTINGS_PATH, as there is a good amount of data written to disk.

Important: when you save your config in a volume, file jts.ini will be saved. TIME_ZONE will only be applied to jts.ini if the file does not exists (first run) but not once the file exists. This is to avoid overwriting your settings.

Security Considerations

Leaving localhost

The IB API protocol is based on an unencrypted, unauthenticated, raw TCP socket connection between a client and the IB Gateway. If the port to IB API is open to the network, every device on it (including potential rogue devices) can access your IB account via the IB Gateway.

Because of this, the default docker-compose.yml only exposes the IB API port to the localhost on the docker host, but not to the whole network.

If you want to connect to IB Gateway from a remote device, consider adding an additional layer of security (e.g. TLS/SSL or SSH tunnel) to protect the 'plain text' TCP sockets against unauthorized access or manipulation.

Possible IB API port configurations

Some examples of possible configurations

SSH Tunnel

You can optionally setup an SSH tunnel to avoid exposing IB Gateway port. The container DOES NOT run an SSH server (sshd), what it does is to create a remote tunnel using ssh client. So basically it will connect to an ssh server and expose IB Gateway port there.

An example setup would be to run ib-gateway-docker with a sidecar ssh bastion and a jupyter-quant, which provides a fully working algorithmic trading environment. In simple terms ib gateway opens a remote port on ssh bastion and listen to connections on it. While jupyter-quant will open a local port that is tunneled into bastion on the same port opened by ib-gateway-docker. This combination of tunnels will expose IB API port into jupyter-quant making it available for use with ib_insync. The only port available to the outside world is the ssh bastion port, which has hardened security defaults and cryptographic key authentication.

Sample ssh tunnels for reference.

# on ib gateway - this is managed by the container
ssh -NR 4001:localhost:4001 ibgateway@bastion
# on juypter-quant container.
eval $(ssh-agent) # start agent
ssh-add # add keys to agent
#  -f will send it to foreground
ssh -o ServerAliveInterval=20 -o ServerAliveCountMax=3 -fNL 4001:localhost:4001 jupyter@bastion
# on desktop connect to VNC
ssh -o ServerAliveInterval=20 -o ServerAliveCountMax=3 -NL 5900:localhost:5900 trader@bastion

It would look like this

       _____________
      |  IB Gateway | \   :4001
       -------------  |
                      |
      _____________   |
      | SSH Bastion | /   :4001
      -------------   \
                       |
                       |
      _______________  |
     | Jupyter Quant |/  :4001
      ---------------

ib-gateway-docker is using ServerAliveInterval and ServerAliveCountMax ssh settings to keep the tunnel open. Additionally it will restart the tunnel automatically if it's stopped, and will keep trying to restart it.

Minimal ssh tunnel setup:

In addition to the environment variables listed above you need to pass ssh keys to ib-gateway-docker container. This is achieved through a volume mount

...
    volumes:
      - ${PWD}/ssh:/home/ibgateway/.ssh # IB Gateway
      - ${PWD}/config/ssh:/config/.ssh # TWS
...

TWS image will search ssh keys on HOME directory, so store keys on /config/.ssh

Make sure that:

Credentials

This image does not contain nor store any user credentials.

They are provided as environment variable during the container startup and the host is responsible to properly protect it.

From 10.29.1e and 10.19.2m it's possible to use docker secrets. If the _FILE environment variable is defined, then that file will be used to get credentials.

Sample docker-compose.yml:

name: algo-trader
services:
  ib-gateway:
  ...
  environment:
    ...
    TWS_PASSWORD_FILE: /run/secrets/tws_password
    SSH_PASSPHRASE_FILE: /run/secrets/ssh_passphrase
    VNC_SERVER_PASSWORD_FILE: /run/secrets/vnc_password
    ...
  secrets:
    - tws_password
    - ssh_passphrase
    - vnc_password
  ...
secrets:
  tws_password:
    file: tws_password.txt
  ssh_passphrase:
    file: ssh_password.txt
  vnc_password:
    file: vnc_password.txt

In "dicussions" section you will find full examples for ibgateway and tws-rdesktop

RDP

tws-rdesktop will create a new TLS certificate every time the container starts. You can create your own certificate following this instructions. Once this steps are put in place the same TLS certificate will be used every time, which will allow you to trust it in your RDP client.

Troubleshooting socat and ssh

In case you experience problems with the API connection, you can restart the socat process

docker exec -it algo-trader-ib-gateway-1 pkill -x socat

After SSH_RESTART seconds socat will restart the connection. If SSH_RESTART is not set, by default the restart period will be 5 seconds.

For ssh tunnel,

docker exec -it algo-trader-ib-gateway-1 pkill -x ssh

The ssh tunnel will restart after 5 seconds if SSH_RESTART is not set, or the value in seconds defined in SSH_RESTART.

IB Gateway installation files

Note that the Dockerfile does not download IB Gateway installer files from IB homepage but from the github-releases of this project.

This is because it shall be possible to (re-)build the image, targeting a specific Gateway version, but IB only provide download links for the latest or stable version (there is no 'old version' download archive).

The installer files stored on releases have been downloaded from IB homepage and renamed to reflect the version.

IF you feel adventurous and you want to download Gateway installer from IB homepage directly, or use your local installation file, change this line on Dockerfile RUN curl -sSL https://github.com/gnzsnz/ib-gateway-docker/raw/gh-pages/ibgateway-releases/ibgateway-${IB_GATEWAY_VERSION}-standalone-linux-x64.sh --output ibgateway-${IB_GATEWAY_VERSION}-standalone-linux-x64.sh to download (or copy) the file from the source you prefer.

Example: change to RUN curl -sSL https://download2.interactivebrokers.com/installers/ibgateway/stable-standalone/ibgateway-stable-standalone-linux-x64.sh --output ibgateway-${IB_GATEWAY_VERSION}-standalone-linux-x64.sh for using current stable version from IB homepage.

How to build locally step by step

  1. Clone this repo

      git clone https://github.com/gnzsnz/ib-gateway-docker
    
  2. Change docker file to use your local IB Gateway installer file, instead of Loading it from this project releases: Open Dockerfile on editor and replace this lines:

    RUN curl -sSL https://github.com/gnzsnz/ib-gateway-docker/raw/gh-pages/ibgateway-releases/ibgateway-${IB_GATEWAY_VERSION}-standalone-linux-x64.sh \
        --output ibgateway-${IB_GATEWAY_VERSION}-standalone-linux-x64.sh
    RUN curl -sSL https://github.com/gnzsnz/ib-gateway-docker/raw/gh-pages/ibgateway-releases/ibgateway-${IB_GATEWAY_VERSION}-standalone-linux-x64.sh.sha256 \
        --output ibgateway-${IB_GATEWAY_VERSION}-standalone-linux-x64.sh.sha256
    

    with

    COPY ibgateway-${IB_GATEWAY_VERSION}-standalone-linux-x64.sh
    
  3. Remove RUN sha256sum --check ./ibgateway-${IB_GATEWAY_VERSION}-standalone-linux-x64.sh.sha256 from Dockerfile (unless you want to keep checksum-check)

  4. Download IB Gateway and name the file ibgateway-${IB_GATEWAY_VERSION}-standalone-linux-x64.sh, where {IB_GATEWAY_VERSION} must match the version as configured on Dockerfile (first line)

  5. Download IBC and name the file IBCLinux-3.20.0.zip, where {IBC_VERSION} must match the version as configured on Dockerfile

  6. Build and run: docker-compose up --build