running ``ib`` gateway in ``docker``
------------------------------------
We have a config based on a well maintained community
image from `@gnzsnz`:

https://github.com/gnzsnz/ib-gateway-docker


To startup this image simply run the command::

    docker compose up

(For further usage^ see the official `docker-compose`_ docs)


And you should have the following socket-available services by
default:

- ``x11vnc1 @ 127.0.0.1:5900``
- ``ib-gw @ 127.0.0.1:4002``

You can now attach to the container via a VNC client with password-auth;
here is an example using ``vncclient`` on ``linux``::

    vncviewer localhost:5900

now enter the pw (password) you set via an (see second code blob)
`.env file`_ or pw-file according to the `credentials section`_.

If you want to change away from their default config see the example
`docker-compose.yml`-config issue and config-section of the readme,

  - https://github.com/gnzsnz/ib-gateway-docker?tab=readme-ov-file#configuration
  - https://github.com/gnzsnz/ib-gateway-docker/discussions/103

.. _.env file: https://github.com/gnzsnz/ib-gateway-docker?tab=readme-ov-file#how-to-use-it
.. _docker-compose: https://docs.docker.com/compose/
.. _credentials section: https://github.com/gnzsnz/ib-gateway-docker?tab=readme-ov-file#credentials


Connecting to the API from `piker`
---------------------------------
In order to expose the container's API endpoint to the
`brokerd/datad/ib` actor, we need to add a section to the user's
`brokers.toml` config (note the below is similar to the repo-shipped
template file),

.. code:: toml

    [ib]
    # define the (set of) host-port socketaddrs that
    # brokerd.ib will scan to connect to an API endpoint
    # (ib-gw or ib-tws listening instances)
    hosts = [
        '127.0.0.1',
    ]
    ports = [
        4002,  # gw
        7497,  # tws
    ]

    # When API endpoints are being scanned durin startup, the order
    # of user-defined-account "names" (as defined below) here
    # determines which py-client connection is given priority to be
    # used for data-feed-requests by according to whichever client
    # connected to an API endpoing which reported the equivalent
    # account number for that name.
    prefer_data_account = [
        'paper',
        'margin',
        'ira',
    ]

    # define "aliases" (names) for each account number
    # such that the names can be reffed and logged throughout
    # `piker.accounting` subsys and more easily
    # referred to  by the user.
    #
    # These keys will be the set exposed through the order-mode
    # account-selection UI so that numbers are never shown.
    [ib.accounts]
    paper = 'XX0000000'
    margin = 'X0000000'
    ira = 'X0000000'


the broker daemon can also connect to the container's VNC server for
added functionalies including,

- viewing the API endpoint program's GUI for manual interventions,
- workarounds for historical data throttling using hotkey hacks,

Add a further section to `brokers.toml` which maps each API-ep's
port to a table of VNC server connection info like,

.. code:: toml

    [ib.vnc_addrs]
    4002 = {host = 'localhost', port = 5900, pw = 'doggy'}

The `pw = 'doggy'` here ^ should the same value as the particular
container instances `.env` file setting (when it was run),

.. code:: ini

    VNC_SERVER_PASSWORD='doggy'


IF you also want to run ``TWS``
-------------------------------
You can also run it containerized,

https://github.com/gnzsnz/ib-gateway-docker?tab=readme-ov-file#using-tws


SECURITY stuff (advanced, only if you're paranoid)
--------------------------------------------------
First and foremost if doing a "distributed" container setup where you
run the ``ib-gw`` docker container and your connecting API client
(likely ``ib_async`` from python) on **different hosts** be sure to
read the `security considerations`_ section!

And for a further (somewhat paranoid) perspective from
a long-time-ago serious devops eng..

Though "``ib``" claims they filter remote host connections outside
``localhost`` (aka ``127.0.0.1`` on ipv4) it's prolly justified if
you'd like to filter the socket at the *OS level* using a stateless
firewall rule::

    ip rule add not unicast iif lo to 0.0.0.0/0 dport 4002


We will soon have this either baked into our own custom derivative
image (or patched into the current upstream one after further testin)
but for now you'll have to do it urself, diggity dawg.

.. _security considerations: https://github.com/gnzsnz/ib-gateway-docker?tab=readme-ov-file#security-considerations
