Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dockerfile and instructions #227

Merged
merged 2 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Refer to [INSTALL.md](INSTALL.md)

Make sure `bitcoind` is running before running `teosd` (it will fail at startup if it cannot connect to `bitcoind`). [Here](DEPENDENCIES.md#installing-bitcoind) you can find a sample bitcoin.conf.

Please see [Docker instructions](docker/README.md) for instructions on how to set up `teosd` in Docker.

### Starting the tower daemon ♖

Once installed, you can start the tower by running:
Expand Down
49 changes: 49 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Use the rust image as the base image for the build stage
FROM rust:latest AS builder

# Copy the rust-teos source code
COPY . /tmp/rust-teos

# Install the dependencies required for building rust-teos
RUN apt-get update\
orbitalturtle marked this conversation as resolved.
Show resolved Hide resolved
&& apt-get -y --no-install-recommends install libffi-dev libssl-dev musl-tools pkg-config

RUN cd /tmp/rust-teos \
&& rustup target add x86_64-unknown-linux-musl \
# Rustfmt is needed to format the grpc stubs generated by tonic
&& rustup component add rustfmt \
# Cross compile with musl as the target, so teosd can run on alpine
&& RUSTFLAGS='-C target-feature=+crt-static' cargo build --manifest-path=teos/Cargo.toml --locked --release --target x86_64-unknown-linux-musl
mariocynicys marked this conversation as resolved.
Show resolved Hide resolved

# Use a new stage with a smaller base image to reduce image size
FROM alpine:latest

RUN apk update && apk upgrade

# UID and GID for the teosd user
ENV TEOS_UID=1001 TEOS_GID=1001

# Copy the teos binaries from the build stage to the new stage
COPY --from=builder \
/tmp/rust-teos/target/x86_64-unknown-linux-musl/release/teosd \
/tmp/rust-teos/target/x86_64-unknown-linux-musl/release/teos-cli /usr/local/bin/

# Copy the entrypoint script to the container
COPY docker/entrypoint.sh /entrypoint.sh

# Set the entrypoint script as executable and add running user
RUN chmod +x /entrypoint.sh \
&& addgroup -g ${TEOS_GID} -S teos \
&& adduser -S -G teos -u ${TEOS_UID} teos

# Expose the default port used by teosd
EXPOSE 9814/tcp

# Switch user so that we don't run stuff as root
USER teos

# Create the teos data directory
RUN mkdir /home/teos/.teos

# Start teosd when the container starts
ENTRYPOINT [ "/entrypoint.sh" ]
113 changes: 113 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
## Running `teosd` in a docker container
A `teos` image can be built from the Dockerfile located in `docker`. You can create the image by running:
orbitalturtle marked this conversation as resolved.
Show resolved Hide resolved

cd rust-teos
docker build -f docker/Dockerfile -t teos .

Then we can create a container by running:

docker run -it teos

One way to feed `teos` custom config options is to set environment variables:

docker run -it -e <ENV_VARIABLES> teos

Notice that the ENV variables are optional, if unset the corresponding default setting is used. The following ENVs are available:

```
- API_BIND=<teos_api_hostname>
- API_PORT=<teos_api_port>
- RPC_BIND=<teos_rpc_hostname>
- RPC_PORT=<teos_rpc_port>
- BTC_NETWORK=<btc_network>
- BTC_RPC_CONNECT=<btc_node_hostname>
- BTC_RPC_PORT=<btc_node_port>
- BTC_RPC_USER=<btc_rpc_username>
- BTC_RPC_PASSWORD=<btc_rpc_password>
# The following options can be set turned on by setting them to "true"
- DEBUG=<debug_bool>
- DEPS_DEBUG=<deps_debug_bool>
- OVERWRITE_KEY=<overwrite_key_bool>
- FORCE_UPDATE=<force_update_bool>
orbitalturtle marked this conversation as resolved.
Show resolved Hide resolved
```

### Volume persistence

You may also want to run docker with a volume, so you can have data persistence in `teosd` databases and keys.
If so, run:

docker volume create teos-data
orbitalturtle marked this conversation as resolved.
Show resolved Hide resolved

And add the the mount parameter to `docker run`:

-v teos-data:/home/teos/.teos

If you are running `teosd` and `bitcoind` in the same machine, continue reading for how to create the container based on your OS.

### `bitcoind` running on the same machine (UNIX)
The easiest way to run both together in the same machine using UNIX is to set the container to use the host network.

For example, if both `teosd` and `bitcoind` are running on default settings, run:

```
docker run \
--network=host \
--name teos \
-v teos-data:/home/teos/.teos \
-e BTC_RPC_USER=<btc_rpc_username> \
-e BTC_RPC_PASSWORD=<btc_rpc_password> \
-it teos
```

Notice that you may still need to set your RPC authentication details, since, hopefully, your credentials won't match the `teosd` defaults.

### `bitcoind` running on the same machine (OSX or Windows)

Docker for OSX and Windows does not allow to use the host network (nor to use the `docker0` bridge interface). To work around this
you can use the special `host.docker.internal` domain:

```
docker run \
-p 9814:9814 \
-p 8814:8814 \
--name teos \
-v teos-data:/home/teos/.teos \
-e BTC_RPC_CONNECT=host.docker.internal \
orbitalturtle marked this conversation as resolved.
Show resolved Hide resolved
-e BTC_RPC_USER=<btc_rpc_username> \
-e BTC_RPC_PASSWORD=<btc_rpc_password> \
-e API_BIND=0.0.0.0 \
-e RPC_BIND=0.0.0.0 \
-it teos
```

Notice that we also needed to add `API_BIND=0.0.0.0` and `RPC_BIND=0.0.0.0` to bind the API to all interfaces of the container.
Otherwise it will bind to `localhost` and we won't be able to send requests to the tower from the host.
sr-gi marked this conversation as resolved.
Show resolved Hide resolved

### Interacting with a TEOS instance

Once our `teos` instance is running in the container, we can interact with it using `teos-cli`. We have two main ways of doing so:

1) You can open a shell to the Docker instance by calling:

`docker exec -it <CONTAINER_NAME> sh`

Then you can use the `teos-cli` binary from inside the container as you would use it from your host machine.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this would really work

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm can you elaborate? Tested and it seems to work for me.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you run teos-cli from the host pointing to the container? That should raise an authentication issue, given the credentials of your .teos outside the container are different to the ones inside

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So option 1 is running within the Docker instance so there shouldn't be an authentication issue. But yes, if running from the host machine, then you have to use option 2 (below)


2) Using `teos-cli` remotely (assuming you have it installed in the source machine) and pointing to the container. To do so, you will need to copy over the necessary credentials to the host machine. To do so, you can follow the instructions in [the main README](https://github.com/talaia-labs/rust-teos/blob/master/README.md#running-teos-cli-remotely).

### Plugging in Tor

You may have noticed, in the above section where the environment variables are covered, that the Tor options are nowhere to be found. That's because these instructions assume that users will likely be setting up Tor in another container.

On the machine where you have Tor running, you can follow [these instructions](https://community.torproject.org/onion-services/setup/) for setting up a hidden service manually.

For instance, if you're running `teosd` in a Docker container on the same machine as where Tor is running, you can create a hidden service from the host machine to hide the IP of the `teosd` API (listening on port 9814 for example). If you're using Linux, you can do so by editing your `torrc` file on the host machine with the below option:

```
HiddenServiceDir /var/lib/tor/teosd # Path for Linux. This may differ depending on your OS.
HiddenServicePort 9814 127.0.0.1:9814
```

Then restart Tor.

If all works correctly, the hidden service public key will be located in the `HiddenServiceDir` you set above, in the file called `hostname`.
66 changes: 66 additions & 0 deletions docker/entrypoint.sh
orbitalturtle marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/bin/sh

# Define the start command
START_COMMAND="teosd"

# Set the API bind address
if [[ ! -z ${API_BIND} ]]; then
START_COMMAND="$START_COMMAND --apibind $API_BIND"
fi

# Set the API port
if [[ ! -z ${API_PORT} ]]; then
START_COMMAND="$START_COMMAND --apiport $API_PORT"
fi

# Set the RPC bind address
if [[ ! -z ${RPC_BIND} ]]; then
START_COMMAND="$START_COMMAND --rpcbind $RPC_BIND"
fi

# Set the RPC port
if [[ ! -z ${RPC_PORT} ]]; then
START_COMMAND="$START_COMMAND --rpcport $RPC_PORT"
fi

# Set the Bitcoin network
if [[ ! -z ${BTC_NETWORK} ]]; then
START_COMMAND="$START_COMMAND --btcnetwork $BTC_NETWORK"
fi

# Set the Bitcoin RPC credentials
if [[ ! -z ${BTC_RPC_USER} ]]; then
START_COMMAND="$START_COMMAND --btcrpcuser $BTC_RPC_USER"
fi

if [[ ! -z ${BTC_RPC_PASSWORD} ]]; then
START_COMMAND="$START_COMMAND --btcrpcpassword $BTC_RPC_PASSWORD"
fi

# Set the Bitcoin RPC connection details
if [[ ! -z ${BTC_RPC_CONNECT} ]]; then
START_COMMAND="$START_COMMAND --btcrpcconnect $BTC_RPC_CONNECT"
fi

if [[ ! -z ${BTC_RPC_PORT} ]]; then
START_COMMAND="$START_COMMAND --btcrpcport $BTC_RPC_PORT"
fi

if [ "${DEBUG}" == "true" ]; then
START_COMMAND="$START_COMMAND --debug"
fi

if [ "${DEPS_DEBUG}" == "true" ]; then
START_COMMAND="$START_COMMAND --depsdebug"
fi

if [ "${OVERWRITE_KEY}" == "true" ]; then
START_COMMAND="$START_COMMAND --overwritekey"
fi

if [ "${FORCE_UPDATE}" == "true" ]; then
START_COMMAND="$START_COMMAND --forceupdate"
fi

# Start the TEOS daemon
$START_COMMAND
Loading