talaia-labs / rust-teos

The Eye of Satoshi - Lightning Watchtower
https://talaia.watch
MIT License
128 stars 62 forks source link

Create the rust-teos dockerize #197

Closed anmode closed 12 months ago

anmode commented 1 year ago

Solve: #195

anmode commented 1 year ago

Can i update the docs when this pR looks good to merge??

sr-gi commented 1 year ago

Can i update the docs when this pR looks good to merge??

The docs need to be part of this PR. I'd suggest you write a draft because they'll also need to be reviewed

anmode commented 1 year ago

Can i update the docs when this pR looks good to merge??

The docs need to be part of this PR. I'd suggest you write a draft because they'll also need to be reviewed

Ohh okayy got that. I'll write the draft.

anmode commented 1 year ago

@sr-gi what should be done in this PR??

sr-gi commented 1 year ago

@sr-gi what should be done in this PR??

Can i update the docs when this pR looks good to merge??

The docs need to be part of this PR. I'd suggest you write a draft because they'll also need to be reviewed

Where are the docs?

sr-gi commented 1 year ago

Also, just as a general comment, you do not need to add screenshots of your builds nor tests runs. Not sure if that was a requirement in other projects you may have contributed to but there's no need here.

Reviewers are expected to build and test your code, plus there's CI for automated testing.

anmode commented 1 year ago

@sr-gi what should be done in this PR??

Can i update the docs when this pR looks good to merge??

The docs need to be part of this PR. I'd suggest you write a draft because they'll also need to be reviewed

Where are the docs?

Ohhhh oKay sorry!!. Just updating soon. Thanks. Ok I'll remember for future reference. Not to add build test screenshot. Ahh is see automated testing is there!.

anmode commented 1 year ago

After Successful testing I'll push! Thanks for the suggestions.

tsjk commented 1 year ago

Yeah, I was also curious about tor support. I haven't quite bothered to gather how it works without docker, but given that no password is needed I assume the control socket i magically found and used, and it is assumed that the user running teosd has access. Perhaps the control socket can be wired into the container? Not sure how socket files can be shared though... I have used containers that uses socat to wire things in, but that usually requires some init system in the container - which complicates things.

tsjk commented 1 year ago

...and some people still use x86_64. :)

sr-gi commented 1 year ago

Yeah, I was also curious about tor support. I haven't quite bothered to gather how it works without docker, but given that no password is needed I assume the control socket i magically found and used, and it is assumed that the user running teosd has access. Perhaps the control socket can be wired into the container? Not sure how socket files can be shared though... I have used containers that uses socat to wire things in, but that usually requires some init system in the container - which complicates things.

Just came to mind that it may be worth checking how CoreLN manages this, given they also provide docker containers and support Tor management over the control port.

anmode commented 1 year ago

2284a51-

  1. I have to remove watchtower-plugin from cargo.toml as when i tried to ignore the plugin folder to copy in the image , the cargo.toml was creating problem as it want watchtower-plugin current dir. [Just to build image and i will revert this one]. Or is there other way to?? please suggest
  2. Added .dockerignore file
  3. Image created successfully and here the info: Screenshot 2023-03-11 at 9 36 33 AM Screenshot 2023-03-11 at 9 36 27 AM

I recently learn docker! That's why taking some time and i am now bit familiar :) i stuck at:


anmolagrawal@Anmols-MacBook-Air rust-teos % docker run -e BTC_NETWORK=regtest -e BTC_RPC_USER=test1 -e BTC_RPC_PASSWORD=test1@ -e BTC_RPC_PORT=18443 -e API_BIND=127.0.0.1 -e API_PORT=1234 teos

2023-03-11T04:26:04.906Z INFO  [teosd] Loading default configuration
2023-03-11T04:26:04.913Z INFO  [teosd] Tower keys not found. Creating a fresh set
2023-03-11T04:26:04.919Z INFO  [teosd] tower_id: 02dc6dfca583cc143a5e599804ca888072ed6b81a2e9dba3d20cdc52df9ce16dc1
2023-03-11T04:26:04.921Z ERROR [teosd] Failed to connect to bitcoind. Error: Connection refused (os error 111)
tsjk commented 1 year ago

3GB image? Wouldn't it be better to make a static (musl?) build and bundle that in an alpine base image (or something with an init system if needed).

mariocynicys commented 1 year ago

3GB image? Wouldn't it be better to make a static (musl?) build and bundle that in an alpine base image (or something with an init system if needed).

Woahh, that's BIG.

I think this has to do with the base image as you stated and the build dependencies as well. We could do cargo clean or just delete the whole source code directory all together after building. We might also wanna use alpine as a base image or delete the .rustup directory (or whatever directory the rust tool chain is installed in) after building.

tsjk commented 1 year ago

I actually managed to build a static teosd and teos-cli with musl (which I now use on Debian - seems fine). So, using a builder base image and then moving the binaries to another base image is totally doable. However, getting tor to work may require changing the code. I run tor in a container (but not teosd yet). The api_bind address is registered for forwarding tor connections to... If running teosd on the host this can be worked around by setting api_bind to some globally available interface (and selectively denying connections with a firewall if needed), but if both tor and teosd are in containers one has to resort to something else.

anmode commented 1 year ago

Thanks, @tsjk @mariocynicys for the suggestions! That's cool @tsjk I'll try to reduce the image size. and after that seek for issue for TOR.

tsjk commented 1 year ago

To build statically, I patched teos-common/Cargo.toml

diff --git a/teos-common/Cargo.toml b/teos-common/Cargo.toml
index be0cb48..d43c057 100644
--- a/teos-common/Cargo.toml
+++ b/teos-common/Cargo.toml
@@ -16,6 +16,7 @@ serde_json = "1.0"
 tonic = "0.6"

 # Crypto
+openssl = { version = "*", features = [ "vendored"] }
 rand = "0.8.4"
 chacha20poly1305 = "0.8.0"

and did (on Debian stable):

sudo apt install musl-tools
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add x86_64-unknown-linux-musl
RUSTFLAGS='-C target-feature=+crt-static' cargo \
  install --locked --path teos --target x86_64-unknown-linux-musl

I think that you ought carry out the changes that apply only to the docker build (such as patching Cargo.toml) as a step in the building process and not require these changes to be applied when not needed.

sr-gi commented 1 year ago

3GB image? Wouldn't it be better to make a static (musl?) build and bundle that in an alpine base image (or something with an init system if needed).

@anmode I think this may be useful to achieve what @tsjk was referring to: https://docs.docker.com/build/building/multi-stage/

@tsjk If you have some expertise with multi-stage builds, maybe @anmode could use some help.

Thanks for the suggestion and for actively commenting on this btw!

anmode commented 1 year ago

3GB image? Wouldn't it be better to make a static (musl?) build and bundle that in an alpine base image (or something with an init system if needed).

@anmode I think this may be useful to achieve what @tsjk was referring to: https://docs.docker.com/build/building/multi-stage/

@tsjk If you have some expertise with multi-stage builds, maybe @anmode could use some help.

Thanks for the suggestion and for actively commenting on this btw!

yeahh sure!! @tsjk please if you can guide that would be appreciated... @sr-gi i am now able to build image of 1gb is that ok??

sr-gi commented 1 year ago

3GB image? Wouldn't it be better to make a static (musl?) build and bundle that in an alpine base image (or something with an init system if needed).

@anmode I think this may be useful to achieve what @tsjk was referring to: https://docs.docker.com/build/building/multi-stage/ @tsjk If you have some expertise with multi-stage builds, maybe @anmode could use some help. Thanks for the suggestion and for actively commenting on this btw!

yeahh sure!! @tsjk please if you can guide that would be appreciated... @sr-gi i am now able to build image of 1gb is that ok??

It's better, but I think we can do even better following @tsjk recommendations for the multistage build

anmode commented 1 year ago

3GB image? Wouldn't it be better to make a static (musl?) build and bundle that in an alpine base image (or something with an init system if needed).

@anmode I think this may be useful to achieve what @tsjk was referring to: https://docs.docker.com/build/building/multi-stage/ @tsjk If you have some expertise with multi-stage builds, maybe @anmode could use some help. Thanks for the suggestion and for actively commenting on this btw!

yeahh sure!! @tsjk please if you can guide that would be appreciated... @sr-gi i am now able to build image of 1gb is that ok??

It's better, but I think we can do even better following @tsjk recommendations for the multistage build

Yeah! That's ok...btw i have used mutli stage now - two stages!! Thanks

sr-gi commented 1 year ago

3GB image? Wouldn't it be better to make a static (musl?) build and bundle that in an alpine base image (or something with an init system if needed).

@anmode I think this may be useful to achieve what @tsjk was referring to: https://docs.docker.com/build/building/multi-stage/ @tsjk If you have some expertise with multi-stage builds, maybe @anmode could use some help. Thanks for the suggestion and for actively commenting on this btw!

yeahh sure!! @tsjk please if you can guide that would be appreciated... @sr-gi i am now able to build image of 1gb is that ok??

It's better, but I think we can do even better following @tsjk recommendations for the multistage build

Yeah! That's ok...btw i have used mutli stage now - two stages!! Thanks

Where have you used two stages? I don't see any changes reflecting that.

anmode commented 1 year ago

3GB image? Wouldn't it be better to make a static (musl?) build and bundle that in an alpine base image (or something with an init system if needed).

@anmode I think this may be useful to achieve what @tsjk was referring to: https://docs.docker.com/build/building/multi-stage/ @tsjk If you have some expertise with multi-stage builds, maybe @anmode could use some help. Thanks for the suggestion and for actively commenting on this btw!

yeahh sure!! @tsjk please if you can guide that would be appreciated... @sr-gi i am now able to build image of 1gb is that ok??

It's better, but I think we can do even better following @tsjk recommendations for the multistage build

Yeah! That's ok...btw i have used mutli stage now - two stages!! Thanks

Where have you used two stages? I don't see any changes reflecting that.

actually i did not pushed! I have asked...should i try to reduce more and i don't know it would be possible or not? if 1gb is fine. I'll push the code!

sr-gi commented 1 year ago

Push the code and we can check what you've done. It's hard to know if your approach is right if we don't see the approach!

anmode commented 1 year ago

Push the code and we can check what you've done. It's hard to know if your approach is right if we don't see the approach!

ohh okayy!!

tsjk commented 1 year ago

It's better. I'd still opt for a musl static build and an alpine image, if possible. Perhaps I find time this evening to make a sketch. And, can't you do

cargo install --locked --path teos

instead of needing to change Cargo.toml?

anmode commented 1 year ago

It's better. I'd still opt for a musl static build and an alpine image, if possible. Perhaps I find time this evening to make a sketch. And, can't you do

cargo install --locked --path teos

instead of needing to change Cargo.toml?

ohh ok thanks. I'll try to do this.. actually previously i was facing the issue..that's why i had to change the cargo.toml.

sr-gi commented 1 year ago

It's better. I'd still opt for a musl static build and an alpine image, if possible. Perhaps I find time this evening to make a sketch. And, can't you do

cargo install --locked --path teos

instead of needing to change Cargo.toml?

Yeah, certainly changing Cargo.toml should be avoided if possible. Otherwise, it should only be conditionally changed (not like the current approach where the plugin is simply dropped altogether).

tsjk commented 1 year ago

Something like this, maybe. Hopefully you can fill in the gaps.

# 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-TEOSd
RUN apt-get update &&\
    apt-get -y --no-install-recommends install libffi-dev libssl-dev musl-tools pkg-config

RUN cd /tmp/rust-teos\
    # Rustfmt is needed to format the grpc stubs generated by tonic.
    && rustup target add x86_64-unknown-linux-musl\
    && rustup component add rustfmt\
    && sed -i -E 's@(^#Crypto.*)@\1\nopenssl = { version = "*", features = [ "vendored"] }@' teos-common/Cargo.toml\
    && RUSTFLAGS='-C target-feature=+crt-static' cargo build --manifest-path=teos/Cargo.toml --locked --release --target x86_64-unknown-linux-musl

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

# UID and GID for the TEOSd user
ENV TEOSD_UID=1001 TEOSD_GID=1001

# Copy the teos binary 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 ${TEOSD_GID} -S teosd\
    && adduser -S -G teosd -u ${TEOSD_UID} teosd

# Expose the default port used by Rust-TEOSd
EXPOSE 9814/tcp

# Create a volume for the TEOS data directory
VOLUME ["/home/teosd/.teos"]

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

# Start Rust-TEOS when the container starts
ENTRYPOINT [ "/entrypoint.sh" ]

Alpine has no bash by default, but I think your entrypoint is ash-compatible - just change the shebang (to /bin/sh). I have neither inspected the resulting image, nor tested running it. But it builds. So even if there are bugs these ought be easily fixed.

The resulting image is 41MB.

tsjk commented 1 year ago

Wiring in tor is non-trivial, I think. But as a first step the user can set up the hidden service in tor and direct it to onion_hidden_service_port in the teosd container. If tor is run in a container one can set up a socket proxy (with systemd or socat). I'm guessing the onion_v3_sk contains the secret key for the hidden service, and that this can be migrated to tor - if one wants to migrate to docker and keep the tor onion host name).

sr-gi commented 1 year ago

Wiring in tor is non-trivial, I think. But as a first step the user can set up the hidden service in tor and direct it to onion_hidden_service_port in the teosd container. If tor is run in a container one can set up a socket proxy (with systemd or socat). I'm guessing the onion_v3_sk contains the secret key for the hidden service, and that this can be migrated to tor - if one wants to migrate to docker and keep the tor onion host name).

This actually rang a bell. The guys at embassyOS had a similar use case, so I guess a similar solution may work? https://github.com/talaia-labs/rust-teos/issues/174

tsjk commented 1 year ago

Wiring in tor is non-trivial, I think. But as a first step the user can set up the hidden service in tor and direct it to onion_hidden_service_port in the teosd container. If tor is run in a container one can set up a socket proxy (with systemd or socat). I'm guessing the onion_v3_sk contains the secret key for the hidden service, and that this can be migrated to tor - if one wants to migrate to docker and keep the tor onion host name).

This actually rang a bell. The guys at embassyOS had a similar use case, so I guess a similar solution may work? #174

Eh. Which part? If I'd migrate, I'd migrate the key, add the hidden service to torrc (with tor in a container) pointing to like ${DOCKER_GATEWAY_IP}:9814 and then setup a socket proxy from ${DOCKER_GATEWAY_IP}:9814 to localhost:9814 on the host, and have localhost:9814 as a map into the teos container.

sr-gi commented 1 year ago

Eh. Which part? If I'd migrate, I'd migrate the key, add the hidden service to torrc (with tor in a container) pointing to like ${DOCKER_GATEWAY_IP}:9814 and then setup a socket proxy from ${DOCKER_GATEWAY_IP}:9814 to ${TEOS_CONTAINER_IP}:9814 on the host.

The part of allowing teos to be hooked to Tor without needing to use the control port. IIRC they made Tor create the hidden service and pointed the address::port where the tower API was being offered (check https://github.com/talaia-labs/rust-teos/issues/174#issuecomment-1399071933, https://github.com/talaia-labs/rust-teos/issues/174#issuecomment-1402262536 and https://github.com/talaia-labs/rust-teos/issues/174#issuecomment-1402998582)

Given the tower does not create the hidden service itself, there is no onion_service_sk to be moved around, that's on Tor's side.

tsjk commented 1 year ago

Eh. Which part? If I'd migrate, I'd migrate the key, add the hidden service to torrc (with tor in a container) pointing to like ${DOCKER_GATEWAY_IP}:9814 and then setup a socket proxy from ${DOCKER_GATEWAY_IP}:9814 to ${TEOS_CONTAINER_IP}:9814 on the host.

The part of allowing teos to be hooked to Tor without needing to use the control port. IIRC they made Tor create the hidden service and pointed the address::port where the tower API was being offered (check #174 (comment), #174 (comment) and #174 (comment))

Given the tower does not create the hidden service itself, there is no onion_service_sk to be moved around, that's on Tor's side.

I think we have very similar ideas. I mixed in onion_v3_sk for people wanting to migrate their current non-containerized setup into a container. Note also that I edited the text you quoted. :)

sr-gi commented 1 year ago

Eh. Which part? If I'd migrate, I'd migrate the key, add the hidden service to torrc (with tor in a container) pointing to like ${DOCKER_GATEWAY_IP}:9814 and then setup a socket proxy from ${DOCKER_GATEWAY_IP}:9814 to ${TEOS_CONTAINER_IP}:9814 on the host.

The part of allowing teos to be hooked to Tor without needing to use the control port. IIRC they made Tor create the hidden service and pointed the address::port where the tower API was being offered (check #174 (comment), #174 (comment) and #174 (comment)) Given the tower does not create the hidden service itself, there is no onion_service_sk to be moved around, that's on Tor's side.

I think we have very similar ideas. I mixed in onion_v3_sk for people wanting to migrate their current non-containerized setup into a container. Note also that I edited the text you quoted. :)

Yep, I think those two solutions are actually compatible, if not really the same.

Oh, gotcha wrt to migrating one to the other. If there is a way to let Tor pull a key from a file (no matter what format they use) it should be trivial to build an "export-tor-key" command that deals with that and that can be put into a docker volume used by Tor.

I'd even consider changing the onion_service_sk format to match that so it is even easier.

tsjk commented 1 year ago

Eh. Which part? If I'd migrate, I'd migrate the key, add the hidden service to torrc (with tor in a container) pointing to like ${DOCKER_GATEWAY_IP}:9814 and then setup a socket proxy from ${DOCKER_GATEWAY_IP}:9814 to ${TEOS_CONTAINER_IP}:9814 on the host.

The part of allowing teos to be hooked to Tor without needing to use the control port. IIRC they made Tor create the hidden service and pointed the address::port where the tower API was being offered (check #174 (comment), #174 (comment) and #174 (comment)) Given the tower does not create the hidden service itself, there is no onion_service_sk to be moved around, that's on Tor's side.

I think we have very similar ideas. I mixed in onion_v3_sk for people wanting to migrate their current non-containerized setup into a container. Note also that I edited the text you quoted. :)

Yep, I think those two solutions are actually compatible, if not really the same.

Oh, gotcha wrt to migrating one to the other. If there is a way to let Tor pull a key from a file (no matter what format they use) it should be trivial to build an "export-tor-key" command that deals with that and that can be put into a docker volume used by Tor.

I'd even consider changing the onion_service_sk format to match that so it is even easier.

Sounds good! I actually looked into trying to convert the teos key to tor-format using openssl (and some manipulation tools). I didn't manage it. But using like https://github.com/cretz/bine/tree/master/torutil it should be doable. However, having the format used by teos closer to what is used in tor with a straightforward instruction how to create/export hostname, hs_ed25519_public_key and hs_ed25519_secret_key would be even better.

orbitalturtle commented 1 year ago

Hey all, just curious about the status of this? Is it still be worked on? I'm curious because I'd find this super useful :)

sr-gi commented 1 year ago

I don't think the comments were ever addressed. The approach was good though, it may be worth retaking if you're interested @orbitalturtle

orbitalturtle commented 1 year ago

@sr-gi Sounds good, I'll take a shot at it

tsjk commented 1 year ago

I think the only real unsolved issue is about the conversion of a non-containerized teosd to a containerized one. I mean, the Dockerfile in the comments seemed to work when I pasted it, but we didn't really get to solving the conversion between Tor's secret key format and teosd's.

orbitalturtle commented 12 months ago

@tsjk Awesome, I used your Dockerfile from above and worked like a charm with a couple tweaks. :confetti_ball:

And makes sense about the teosd/Tor conversion. I'm thinking I'll submit a new PR with your working Dockerfile and some documentation on how to use it (unless you'd like to since you and @anmode are the main authors). Then I'll think through this Tor conversion problem some more.

tsjk commented 12 months ago

@tsjk Awesome, I used your Dockerfile from above and worked like a charm with a couple tweaks. 🎊

And makes sense about the teosd/Tor conversion. I'm thinking I'll submit a new PR with your working Dockerfile and some documentation on how to use it (unless you'd like to since you and @anmode are the main authors). Then I'll think through this Tor conversion problem some more.

I appreciate you asking. Go for it. :)

anmode commented 12 months ago

@tsjk Awesome, I used your Dockerfile from above and worked like a charm with a couple tweaks. :confetti_ball:

And makes sense about the teosd/Tor conversion. I'm thinking I'll submit a new PR with your working Dockerfile and some documentation on how to use it (unless you'd like to since you and @anmode are the main authors). Then I'll think through this Tor conversion problem some more.

Yeah please go ahead!.. :) Please tag this pR so we didn't loose this convo nd history.