extrange / ibkr-docker

Run IBKR Gateway/TWS in a Docker container
210 stars 41 forks source link

USERNAME not working for me with docker compose #111

Closed karypid closed 1 month ago

karypid commented 1 month ago

Hello,

When I launch the container directly with docker, it works fine:

> docker run -d \
  -p "127.0.0.1:6080:6080" \
  -p "127.0.0.1:8888:8888" \
  --ulimit nofile=10000 \
  -e USERNAME=myptuser \
  -e PASSWORD='myptpass' \
  -e IBC_TradingMode=paper \
  ghcr.io/extrange/ibkr:stable
0ab5ff4e84228c57ff79c68e286c65f2532021cfabb7fcec4cd8374cfe24823b

With the above I can connect to Xvnc and TWS is running and logged in (with paper trading mode).

When I use this however, I cannot login due to the username being filled in being my actual username:

> cat .env 
USERNAME=myptuser
# wrap password in single quotes if $, /, or \ are present
PASSWORD='myptpass'

> cat compose.yml 
---
services:
  ibkr:
    image: ghcr.io/extrange/ibkr:stable # latest, stable, 10.21, 10.21.1p etc
    ports:
      - "127.0.0.1:6080:6080" # noVNC browser access
      - "127.0.0.1:8888:8888" # API access
    ulimits:
      nofile: 10000 # See FAQ
    environment:
      USERNAME: ${USERNAME}
      PASSWORD: ${PASSWORD}
      TWOFA_TIMEOUT_ACTION: restart
      GATEWAY_OR_TWS: tws
      # Variables prefixed with IBC_ override IBCAlpha`s config.ini:
      IBC_TradingMode: paper
      # IBC_ReadOnlyApi: yes

Running docker compose up gives:

...
ibkr-1  | 2024-10-02 22:56:01:002 IBC: detected frame entitled: Login; event=Activated
ibkr-1  | 2024-10-02 22:56:01:004 IBC: detected frame entitled: Login; event=Focused
ibkr-1  | 2024-10-02 22:56:01:005 IBC: detected frame entitled: Login; event=Opened
ibkr-1  | 2024-10-02 22:56:01:005 IBC: Login dialog WINDOW_OPENED: LoginState is LOGGED_OUT
ibkr-1  | 2024-10-02 22:56:01:005 IBC: trading mode from settings: tradingMode=paper
ibkr-1  | 2024-10-02 22:56:01:005 IBC: Setting Trading mode = paper
ibkr-1  | 2024-10-02 22:56:01:078 IBC: Setting user name
ibkr-1  | 2024-10-02 22:56:01:079 IBC: Setting password
ibkr-1  | 2024-10-02 22:56:01:079 IBC: Login attempt: 1
ibkr-1  | 2024-10-02 22:56:01:080 IBC: trading mode from settings: tradingMode=paper
ibkr-1  | 2024-10-02 22:56:01:100 IBC: Button was disabled, has been enabled: Paper Log In
ibkr-1  | 2024-10-02 22:56:01:100 IBC: Click button: Paper Log In

But when I connect to Xvnc, I see the login dialog with username filled in being wrong. It is filled in with my actual LINUX user account (what I get when I run whoami) instead of the value in .env. As a result login fails. If I edit the username to replace it with myptuser and press the Login button, then TWS logs in normally (so the password filled in is correct).

I looked at start.sh and see that in the end it runs:

exec /opt/ibc/scripts/ibcstart.sh "${TWS_MAJOR_VERSION}" $command \
    "--user=${USERNAME:-}" \
    "--pw=${PASSWORD:-}" \
    "--on2fatimeout=${TWOFA_TIMEOUT_ACTION:-restart}" \
    "--tws-settings-path=${TWS_SETTINGS_PATH:-}"

I entered the running container (which failed to login) and found:

> docker exec -it c9d0fd40740c /bin/sh
# ps -ef | grep ibcstart
root           1       0  0 22:55 ?        00:00:00 /bin/bash /opt/ibc/scripts/ibcstart.sh 1019 --user=MYUNIXUSER --pw=myptpass  --on2fatimeout=restart --tws-settings-path=
root         191     184  0 22:59 pts/0    00:00:00 grep ibcstart

So indeed the environment variable has not taken effect when bringing up with docker compose up.

I'm not sure what to make of this. Anyone else experiencing the same?

karypid commented 1 month ago

In fact, docker inspect confirms that this is the value passed in when creating the container:

> docker inspect c9d0fd40740c | grep Env -A 9
            "Env": [
                "PASSWORD=myptpass",
                "TWOFA_TIMEOUT_ACTION=restart",
                "GATEWAY_OR_TWS=tws",
                "IBC_TradingMode=paper",
                "USERNAME=MY_UNIX_USERNAME",              <<<<< !!! (this is wrong)
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "IBC_VERSION=3.20.0",
                "INSTALL_FILENAME=ibgateway-10.19.2p-standalone-linux-x64.sh"
            ],

I am 100% certain I have not mistyped USERNAME in my .env file:

> grep USERNAME .env compose.yml --color
.env:USERNAME='myptuser'
compose.yml:      USERNAME: ${USERNAME}

The above output is colored and all 3 instances of USERNAME are highlighted...

karypid commented 1 month ago

I edited start.sh locally to end as follows:

> cat start.sh | tail -n 5
exec /opt/ibc/scripts/ibcstart.sh "${TWS_MAJOR_VERSION}" $command \
    "--user=${IBKRUSER:-}" \
    "--pw=${PASSWORD:-}" \
    "--on2fatimeout=${TWOFA_TIMEOUT_ACTION:-restart}" \
    "--tws-settings-path=${TWS_SETTINGS_PATH:-}"

> > ./build.sh stable 10.19.2p
> cd stable
> docker image build . -t myibkr:latest
....
 => => writing image sha256:743eed2df1ed99f3d3959689744978f8eaf268186259ffad15b438f8d405f095                                           0.0s 
 => => naming to docker.io/library/myibkr:latest                                                                                       0.0s

Then updated the compose file to use my local image and fired up a container with that variable:

> cat .env
IBKRUSER='myptuser'
# wrap password in single quotes if $, /, or \ are present
PASSWORD='myptpass'

> cat compose.yml 
---
services:
  ibkr:
    image: myibkr:latest # latest, stable, 10.21, 10.21.1p etc
    ports:
      - "127.0.0.1:6080:6080" # noVNC browser access
      - "127.0.0.1:8888:8888" # API access
    ulimits:
      nofile: 10000 # See FAQ
    environment:
      IBKRUSER: ${IBKRUSER}
      PASSWORD: ${PASSWORD}
      TWOFA_TIMEOUT_ACTION: restart
      GATEWAY_OR_TWS: tws
      # Variables prefixed with IBC_ override IBCAlpha`s config.ini:
      IBC_TradingMode: paper
      # IBC_ReadOnlyApi: yes

> docker compose up
...

This worked perfectly fine for me. I think the problem is that USERNAME is defined in my environment (maybe because I use fish for my shell?):

> env | grep USERNAME
myunixusername

I guess when the variable is set, then it overrides the .env content. This fixes it for me:

USERNAME=MYPTUSERNAME docker compose up

If anyone else comes across this, hope this helps...

P.S. it might be a good idea to rename the variables to IBKRUSER / IBKRPASS as these generic names might clash for random environments (like mine).