hsjoberg / fork-explorer

Check how a BIP9-like softfork signalling goes
https://taproot.watch
MIT License
125 stars 36 forks source link

Dockerfile? #41

Open schildbach opened 3 years ago

schildbach commented 3 years ago

Wouldn't a Dockerfile be nice for building this project and running it within Docker?

I'm thinking of implementing this if there is interest.

hsjoberg commented 3 years ago

Hi @schildbach! Long-time fan of your wallet.

Definitely! I would appreciate any help here (my plate is pretty full at the moment). A Dockerfile would also lower the barrier to self-host fork-explorer (which is encouraged) as there's no need to install Deno on the machine. Just for that reason alone I think it's a huge benefit for the project to provide a Dockerfile.

schildbach commented 3 years ago

Ok, I put together a quick proof of concept. The Dockerfile:

FROM hayd/alpine-deno:1.9.2

COPY . fork-explorer/
WORKDIR fork-explorer/

EXPOSE 8080

ENTRYPOINT ./build-frontend.sh && ./run-server.sh

Copy and edit the config (excerpt):

[...]
  server: {
    host: "0.0.0.0",
    port: 8080,
  },

  bitcoinRpc: {
    server: "http://bitcoind:8332",
    user: "user",
    password: "secret",
  },
[...]

Then run docker build -t fork-explorer . to build the image.

Example for docker-compose.yml:

  fork-explorer:
    image: fork-explorer
    depends_on:
      - bitcoind
    ports:
      - "80:8080"

Problems & ideas:

  1. Tried to use Debian and install all deps from there. Sadly, Deno is not packaged for Debian yet. So I tried to build Deno from source, which failed both on buster and bullseye but for different reasons. I didn't want to compile specific Cargo and/or Rust versions, so I wimped out and used the pre-made "hayd/alpine-deno" Docker image as a base.
  2. The config file format is rather clunky for typical Docker users who expect a couple of key-value pairs as quick configuration. I think I'd like to introduce a bit of environment variable substitution for the most used configuration points. Advanced users can always map the entire config.ts file.
  3. I see the issue of RPC cookie coming up. In my setup, I've got the cookie in a Docker secret in the <user>:<hash> notation, but the config.ts format appears to expect it as two separate values. Perhaps we need more flexibility here. Bitcoind has a couple of auth mechanisms for its RPC interface.
  4. Startup time is quite long (5-10 mins), even if the Docker image has already been built. First, it has to run build-frontend.sh as this compiles your config.ts into the server (am I right about this, not sure?). Second, before run-server.sh serves anything it fetches 2016 blocks which takes longer than I expected. It should only need block headers, no? Is some form of server side persistence implemented or planned? In this case, we should put that into a Docker volume.

Any thoughts? Ideas?

schildbach commented 3 years ago

Ah, the coin base is needed for mining pool detection, right? That would explain the slow sync time.

hsjoberg commented 3 years ago

Thank you for all the work so far!

Tried to use Debian and install all deps from there. Sadly, Deno is not packaged for Debian yet. So I tried to build Deno from source, which failed both on buster and bullseye but for different reasons. I didn't want to compile specific Cargo and/or Rust versions, so I wimped out and used the pre-made "hayd/alpine-deno" Docker image as a base.

Right, yes I think hayd/alpine-deno is pretty popular. You can also just get the official compiled binary from their site (deno is intentionally just one file, one of the stated goals): https://github.com/hsjoberg/fork-explorer/blob/8782314bfd76f6287393517664bbb598ce45ee3f/deploy-cloudflare-pages.sh#L4-L5

The config file format is rather clunky for typical Docker users who expect a couple of key-value pairs as quick configuration. I think I'd like to introduce a bit of environment variable substitution for the most used configuration points. Advanced users can always map the entire config.ts file.

Yes, one of the bets I made with this project is to use a Typescript configuration file, it paid off in some ways (guarantee existence and datatype of things on build-time) but in some areas it didn't. If you could combine config.ts but with env variables, that would be appreciated.

I see the issue of RPC cookie coming up. In my setup, I've got the cookie in a Docker secret in the : notation, but the config.ts format appears to expect it as two separate values. Perhaps we need more flexibility here. Bitcoind has a couple of auth mechanisms for its RPC interface.

Yes, I am using and developing with bitcoind's RPC HTTP Basic Auth mode, but I know that you can use a cookie with bitcoind as well, you're welcome to add support for that in fork-explorer.

Startup time is quite long (5-10 mins), even if the Docker image has already been built. First, it has to run build-frontend.sh as this compiles your config.ts into the server (am I right about this, not sure?).

Yes it builds the react project (to /frontend/dist) together with the config.ts configuration.

Second, before run-server.sh serves anything it fetches 2016 blocks which takes longer than I expected. It should only need block headers, no?

Unfortunately no... I have to do three requests for each block:

This is something I would like to fix but I'm out of ideas currently. bitcoind also does not let us do any batch fetch AFAICT so there are a lot of back-and-forth here.