# Intro > Русская версия: [README.ru-RU.md](README.ru-RU.md) [PyBitmessage](https://bitmessage.org/) is a client of the Bitmessages P2P communication protocol used to send encrypted messages to another person or to many subscribers. PyBitmessage client running as a daemon in docker container with XML-RPC API enabled. This repository covers the docker deployment only. # Usage The container generates a Bitmessage Deterministic Addresses based on a `BITMESSAGE_SEED_PHRASE` variable. Here are some example snippets to help you get started creating a container. The container has two ports and they are not interchangeable. **8442** is the XML-RPC API: it controls the daemon completely and has no TLS, so set your own credentials and keep it on loopback. **8444** is the Bitmessage P2P port: publish it to let other nodes connect in, leave it unpublished to stay outbound-only. The daemon listens on both inside the container either way. ## docker-compose ```yaml services: pybitmessage: build: context: https://git.bitdeals.org/private/bitmessage.git dockerfile: ./docker/Dockerfile image: registry.bitdeals.org/bitmessage environment: - BITMESSAGE_API_USER=CHANGE_ME - BITMESSAGE_API_PASSWORD=CHANGE_ME - BITMESSAGE_SEED_PHRASE=bitmessage_seed_phrase - BITMESSAGE_SEED_ADDRESSES=1 - BITMESSAGE_TTL=172800 - BITMESSAGE_STOPRESENDINGAFTERXDAYS=60 - BITMESSAGE_MAXTOTALCONNECTIONS=40 ports: - 127.0.0.1:8442:8442 # API — loopback only - 8444:8444 # P2P — omit this line to stay outbound-only volumes: - bitmessage:/home/bitmessage volumes: bitmessage: ``` ## docker cli ```sh docker run -d \ -e BITMESSAGE_API_USER=CHANGE_ME \ -e BITMESSAGE_API_PASSWORD=CHANGE_ME \ -e BITMESSAGE_SEED_PHRASE=bitmessage_seed_phrase \ -e BITMESSAGE_SEED_ADDRESSES=1 \ -e BITMESSAGE_TTL=172800 \ -e BITMESSAGE_STOPRESENDINGAFTERXDAYS=60 \ -e BITMESSAGE_MAXTOTALCONNECTIONS=40 \ -p 127.0.0.1:8442:8442 \ -p 8444:8444 \ -v bitmessage:/home/bitmessage \ registry.bitdeals.org/bitmessage ``` # Parameters Container images are configured using parameters passed at runtime. |Parameter|Function| |:--------|:-------| |-p 127.0.0.1:8442|API port. The daemon always binds `0.0.0.0` inside the container, so what you publish decides who reaches it| |-p 8444|Bitmessage P2P port. Optional: without it the node still connects out to peers, it just cannot be connected to. Must be published as `8444:8444` — see Notes| |-v /home/bitmessage|Data directory: `keys.dat` (identity, settings) and `messages.dat`. Without it the node is a new node after every update| |-e BITMESSAGE_API_USER|XML-RPC API user. Default: `bitmessage_api_user` — change it| |-e BITMESSAGE_API_PASSWORD|XML-RPC API password. Default: `bitmessage_api_password` — change it, see Notes| |-e BITMESSAGE_SEED_PHRASE|Create Deterministic Addresses password. Default: regenerated on every start, giving different addresses each time. Only used when `BITMESSAGE_SEED_ADDRESSES` is above `0`| |-e BITMESSAGE_SEED_ADDRESSES|Number of Deterministic Addresses to generate. Default: `0`| |-e BITMESSAGE_TTL|The expiration of newly send messages, in seconds. Default: `172800`| |-e BITMESSAGE_STOPRESENDINGAFTERXDAYS|Stop resending unreceived message after X days. Default: `30`| |-e BITMESSAGE_APIVARIANT|provides xml or json-RPC API. Default: `legacy`| |-e BITMESSAGE_MAXTOTALCONNECTIONS|Cap on all connections at once, inbound and outbound together (`maxoutboundconnections` is 8, so this minus 8 is the inbound headroom). Default: `200`, the PyBitmessage stock value — lower it when the P2P port is published| # Notes - `%` cannot be used in the API password: it breaks PyBitmessage's own config reader, and every API call then returns `500` while `keys.dat` looks correct. Other characters are fine, the container escapes them. - Clients must percent-encode the credentials — they go into `http://user:password@host:port/`, where `@`, `#`, `/` and `:` change how the URL parses. The scripts in this image do; yours has to as well. - The container turns healthy once the daemon has a network connection, which on a new node takes a few minutes. The start period also covers the startup `VACUUM` of `messages.dat`. - **The P2P port must be published as `8444:8444`.** The daemon tells peers the port from its own config (`port` in `keys.dat`), not the port you mapped it to, so `8555:8444` advertises a port nobody can reach. A different host port needs `extport` in `keys.dat`, which this container does not template. - **Your own address is never configured.** The version message carries a hardcoded `127.0.0.1` that every peer discards in favour of the IP it sees on the socket, and it takes the port from that same message. So a node with 8444 published is found by the network on its own, as soon as it connects out — there is no host IP or DNS name to set anywhere. The one exception is a Tor hidden service, which needs an explicit `onionhostname`. - **Publishing 8444 is a deliberate security trade-off.** The daemon runs on Python 2 and already parses untrusted data from its outbound peers, so an open port does not create that exposure — it changes *who* may connect, *when*, and *how many*. The pre-handshake parser becomes reachable by anyone, and the practical risk is resource exhaustion rather than code execution. Keep `BITMESSAGE_MAXTOTALCONNECTIONS` low and put memory and CPU limits on the container.