From 7a2056816d9dceabc10456dfed8024cd254565e6 Mon Sep 17 00:00:00 2001 From: wiz Date: Mon, 11 Jan 2021 23:07:16 +0900 Subject: [PATCH] Update README instructions and nginx.conf for v2.0 release --- Dockerfile | 62 ------------ README.md | 210 +++++++++++++++++----------------------- entrypoint.sh | 10 -- nginx-mempool.conf | 62 ++++++++++++ nginx-nossl-docker.conf | 60 ------------ nginx.conf | 153 ++++++++++++++++++----------- package.json | 29 ------ 7 files changed, 249 insertions(+), 337 deletions(-) delete mode 100644 Dockerfile delete mode 100644 entrypoint.sh create mode 100644 nginx-mempool.conf delete mode 100644 nginx-nossl-docker.conf delete mode 100644 package.json diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index d8e5d0f95..000000000 --- a/Dockerfile +++ /dev/null @@ -1,62 +0,0 @@ -FROM alpine:latest - -RUN mkdir /mempool.space/ -COPY ./backend /mempool.space/backend/ -COPY ./frontend /mempool.space/frontend/ -COPY ./mariadb-structure.sql /mempool.space/mariadb-structure.sql -#COPY ./nginx.conf /mempool.space/nginx.conf - -RUN apk add mariadb mariadb-client jq git nginx npm rsync - -RUN mysql_install_db --user=mysql --datadir=/var/lib/mysql/ -RUN /usr/bin/mysqld_safe --datadir='/var/lib/mysql/'& \ - sleep 60 && \ - mysql -e "create database mempool" && \ - mysql -e "grant all privileges on mempool.* to 'mempool'@'localhost' identified by 'mempool'" && \ - mysql mempool < /mempool.space/mariadb-structure.sql -RUN sed -i "/^skip-networking/ c#skip-networking" /etc/my.cnf.d/mariadb-server.cnf - -RUN export NG_CLI_ANALYTICS=ci && \ - npm install -g typescript && \ - cd /mempool.space/frontend && \ - npm install && \ - cd /mempool.space/backend && \ - npm install && \ - tsc - -COPY ./nginx-nossl-docker.conf /etc/nginx/nginx.conf - -ENV ENV dev -ENV DB_HOST localhost -ENV DB_PORT 3306 -ENV DB_USER mempool -ENV DB_PASSWORD mempool -ENV DB_DATABASE mempool -ENV HTTP_PORT 80 -ENV API_ENDPOINT /api/v1/ -ENV CHAT_SSL_ENABLED false -#ENV CHAT_SSL_PRIVKEY -#ENV CHAT_SSL_CERT -#ENV CHAT_SSL_CHAIN -ENV MEMPOOL_REFRESH_RATE_MS 500 -ENV INITIAL_BLOCK_AMOUNT 8 -ENV DEFAULT_PROJECTED_BLOCKS_AMOUNT 8 -ENV KEEP_BLOCK_AMOUNT 24 -ENV BITCOIN_NODE_HOST bitcoinhost -ENV BITCOIN_NODE_PORT 8332 -ENV BITCOIN_NODE_USER bitcoinuser -ENV BITCOIN_NODE_PASS bitcoinpass -ENV TX_PER_SECOND_SPAN_SECONDS 150 - -#RUN echo "mysqld_safe& sleep 20 && cd /mempool.space/backend && rm -f mempool-config.json && rm -f cache.json && touch cache.json && jq -n env > mempool-config.json && node dist/index.js" > /entrypoint.sh - -RUN cd /mempool.space/frontend/ && \ - npm run build && \ - rsync -av --delete dist/mempool/ /var/www/html/ - -EXPOSE 80 - -COPY ./entrypoint.sh /mempool.space/entrypoint.sh -RUN chmod +x /mempool.space/entrypoint.sh -WORKDIR /mempool.space -CMD ["/mempool.space/entrypoint.sh"] diff --git a/README.md b/README.md index 902c8d15a..621fb4a06 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,22 @@ -# mempool -## a mempool visualizer and explorer for Bitcoin +# The Mempool Open Source Project + +Mempool is the fully featured mempool visualizer and block explorer website and API service running on [mempool.space](https://mempool.space/). The instructions below are for most users at home running on low-powered Raspberry Pi devices, but if you want to run a production website on a powerful server, see the [production setup guide](https://github.com/mempool/mempool/tree/master/production) ![mempool](https://pbs.twimg.com/media/Ei8p_flUcAEjfXE?format=jpg&name=4096x4096) -## Mempool V1 vs Mempool V2 - -Mempool V1 features basic mempool visualization, fee estimation, and transaction tracking and can run directly off a Bitcoin Core full node on a Raspberry Pi. - -Mempool V2 is the fully featured explorer running on [mempool.space](https://mempool.space/), but it requires a fully synced electrs backend running on powerful server hardware. [Guide to install Mempool V2](https://github.com/mempool/mempool/tree/master/production) - -# Mempool V1 using Docker (easy) - -Install from Docker Hub, passing your Bitcoin Core RPC credentials as environment variables: - -```bash -docker pull mempool/mempool:v1.0 -docker create -p 80:80 -e BITCOIN_NODE_HOST=192.168.1.102 -e BITCOIN_NODE_USER=foo -e BITCOIN_NODE_PASS=bar --name mempool mempool/mempool:v1.0 -docker start mempool -docker logs mempool -``` - -You should see mempool starting up, which takes over an hour (needs 8 blocks). When it's ready, visit http://127.0.0.1/ to see your mempool. - -# Mempool V1 not using Docker (advanced) +# Installation ## Dependencies -* Bitcoin (full node required, no pruning, txindex=1) +* Bitcoin Core (no pruning, txindex=1) +* Electrum Server (romanz/electrs) * NodeJS (official stable LTS) -* MySQL or MariaDB (default config) -* Nginx (use supplied nginx.conf) +* MariaDB (default config) +* Nginx (use supplied nginx.conf and nginx-mempool.conf) -## Checking out release tag +## Mempool + +Clone the mempool repo, and checkout the latest release tag: ```bash git clone https://github.com/mempool/mempool cd mempool @@ -41,52 +26,16 @@ You should see mempool starting up, which takes over an hour (needs 8 blocks). W ## Bitcoin Core (bitcoind) -Enable RPC and txindex in bitcoin.conf - +Enable RPC and txindex in `bitcoin.conf`: ```bash rpcuser=mempool rpcpassword=71b61986da5b03a5694d7c7d5165ece5 txindex=1 ``` -## NodeJS - -Install dependencies and build code: - -```bash - # Install TypeScript Globally - npm install -g typescript - - # Frontend - cd frontend - npm install - npm run build - - # Backend - cd ../backend/ - npm install - npm run build -``` - -## Mempool Configuration -In the `backend` folder, make a copy of the sample config and modify it to fit your settings. - -```bash - cp mempool-config.sample.json mempool-config.json -``` - -Edit `mempool-config.json` to add your Bitcoin Core node RPC credentials: -```bash - "BITCOIN_NODE_HOST": "192.168.1.5", - "BITCOIN_NODE_PORT": 8332, - "BITCOIN_NODE_USER": "mempool", - "BITCOIN_NODE_PASS": "71b61986da5b03a5694d7c7d5165ece5", -``` - ## MySQL -Install MariaDB: - +Install MariaDB from OS package manager: ```bash # Linux apt-get install mariadb-server mariadb-client @@ -108,47 +57,69 @@ Create database and grant privileges: Query OK, 0 rows affected (0.00 sec) ``` -From the root folder, initialize database structure: - +From the mempool repo's top-level folder, import the database structure: ```bash mysql -u mempool -p mempool < mariadb-structure.sql ``` -## Running (Backend) - -Create an initial empty cache and start the app: +## Mempool Backend +Install mempool dependencies from npm and build the backend: ```bash - touch cache.json - npm run start # node dist/index.js + # backend + cd ../backend/ + npm install + npm run build ``` -After starting you should see: +In the `backend` folder, make a copy of the sample config and modify it to fit your settings. ```bash - Server started on port 8999 :) - New block found (#586498)! 0 of 1986 found in mempool. 1985 not found. - New block found (#586499)! 0 of 1094 found in mempool. 1093 not found. - New block found (#586500)! 0 of 2735 found in mempool. 2734 not found. - New block found (#586501)! 0 of 2675 found in mempool. 2674 not found. - New block found (#586502)! 0 of 975 found in mempool. 974 not found. - New block found (#586503)! 0 of 2130 found in mempool. 2129 not found. - New block found (#586504)! 0 of 2770 found in mempool. 2769 not found. - New block found (#586505)! 0 of 2759 found in mempool. 2758 not found. - Updating mempool - Calculated fee for transaction 1 / 3257 - Calculated fee for transaction 2 / 3257 - Calculated fee for transaction 3 / 3257 - Calculated fee for transaction 4 / 3257 - Calculated fee for transaction 5 / 3257 - Calculated fee for transaction 6 / 3257 - Calculated fee for transaction 7 / 3257 - Calculated fee for transaction 8 / 3257 - Calculated fee for transaction 9 / 3257 + cp mempool-config.sample.json mempool-config.json ``` -You need to wait for at least *8 blocks to be mined*, so please wait ~80 minutes. -The backend also needs to index transactions, calculate fees, etc. -When it's ready you will see output like this: + +Edit `mempool-config.json` to add your Bitcoin Core node RPC credentials: +```bash +{ + "MEMPOOL": { + "NETWORK": "mainnet", + "BACKEND": "electrum", + "HTTP_PORT": 8999, + "API_URL_PREFIX": "/api/v1/", + "POLL_RATE_MS": 2000 + }, + "CORE_RPC": { + "USERNAME": "mempool", + "PASSWORD": "71b61986da5b03a5694d7c7d5165ece5" + }, + "ELECTRUM": { + "HOST": "127.0.0.1", + "PORT": 50002, + "TLS_ENABLED": true, + "TX_LOOKUPS": false + }, + "DATABASE": { + "ENABLED": true, + "HOST": "localhost", + "PORT": 3306, + "USERNAME": "mempool", + "PASSWORD": "mempool", + "DATABASE": "mempool" + }, + "STATISTICS": { + "ENABLED": true, + "TX_PER_SECOND_SAMPLE_PERIOD": 150 + } +} +``` + +Start the backend: + +```bash + npm run start +``` + +When it's running you should see output like this: ```bash Mempool updated in 0.189 seconds @@ -171,43 +142,38 @@ When it's ready you will see output like this: Updating mempool ``` -## nginx + CertBot (LetsEncrypt) -Setup nginx using the supplied nginx.conf +## Mempool Frontend + +Install mempool dependencies from npm and build the frontend static HTML/CSS/JS: + +```bash + # frontend + cd frontend + npm install + npm run build +``` + +Install the output into nginx webroot folder: + +```bash + sudo rsync -av --delete dist/mempool/ /var/www/html/ +``` + +## nginx + certbot + +Install the supplied nginx.conf and nginx-mempool.conf in /etc/nginx ```bash # install nginx and certbot apt-get install -y nginx python-certbot-nginx + # install the mempool configuration for nginx + cp nginx.conf nginx-mempool.conf /etc/nginx/nginx.conf + # replace example.com with your domain name certbot --nginx -d example.com - # install the mempool configuration for nginx - cp nginx.conf /etc/nginx/nginx.conf - - # edit the installed nginx.conf, and replace all - # instances of example.com with your domain name ``` -Make sure you can access https:/// in browser before proceeding - - -## Running (Frontend) - -Build the frontend static HTML/CSS/JS, rsync the output into nginx folder: - -```bash - cd frontend/ - npm run build - sudo rsync -av --delete dist/mempool/ /var/www/html/ -``` - -### Optional frontend configuration -In the `frontend` folder, make a copy of the sample config and modify it to fit your settings. - -```bash - cp mempool-frontend-config.sample.json mempool-frontend-config.json -``` - -## Try It Out If everything went okay you should see the beautiful mempool :grin: diff --git a/entrypoint.sh b/entrypoint.sh deleted file mode 100644 index eab7121b7..000000000 --- a/entrypoint.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -mysqld_safe& -sleep 5 -nginx -cd /mempool.space/backend -rm -f mempool-config.json -rm -f cache.json -touch cache.json -jq -n env > mempool-config.json -node dist/index.js diff --git a/nginx-mempool.conf b/nginx-mempool.conf new file mode 100644 index 000000000..6da53dfd2 --- /dev/null +++ b/nginx-mempool.conf @@ -0,0 +1,62 @@ + access_log /var/log/nginx/access_mempool.log; + error_log /var/log/nginx/error_mempool.log; + + root /var/www/mempool/browser; + + index index.html; + + # fallback for all URLs i.e. /address/foo /tx/foo /block/000 + location / { + try_files /$lang/$uri /$lang/$uri/ $uri $uri/ /en-US/$uri @index-redirect; + } + location @index-redirect { + add_header vary accept-language; + rewrite (.*) /$lang/index.html; + } + + # location block using regex are matched in order + + # used to rewrite resources from // to /en-US/ + location ~ ^/(ar|bg|bs|ca|cs|da|de|et|el|es|eo|eu|fa|fr|gl|ko|hr|id|it|he|ka|lv|lt|hu|mk|ms|nl|ja|ka|no|nb|nn|pl|pt|pt-BR|ro|ru|sk|sl|sr|sh|fi|sv|th|tr|uk|vi|zh)/resources/ { + rewrite ^/[a-zA-Z-]*/resources/(.*) /en-US/resources/$1; + } + # used for cookie override + location ~ ^/(ar|bg|bs|ca|cs|da|de|et|el|es|eo|eu|fa|fr|gl|ko|hr|id|it|he|ka|lv|lt|hu|mk|ms|nl|ja|ka|no|nb|nn|pl|pt|pt-BR|ro|ru|sk|sl|sr|sh|fi|sv|th|tr|uk|vi|zh)/ { + try_files $uri $uri/ /$1/index.html =404; + } + + # static API docs + location = /api { + try_files $uri $uri/ /en-US/index.html =404; + } + location = /api/ { + try_files $uri $uri/ /en-US/index.html =404; + } + + # mainnet API + location /api/v1/donations { + proxy_pass https://mempool.space; + } + location /api/v1/donations/images { + proxy_pass https://mempool.space; + } + location /api/v1/ws { + proxy_pass http://127.0.0.1:8999/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + } + location /api/v1 { + proxy_pass http://127.0.0.1:8999/api/v1; + } + location /api/ { + proxy_pass http://127.0.0.1:8999/api/v1/; + } + + # mainnet API + location /ws { + proxy_pass http://127.0.0.1:8999/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + } diff --git a/nginx-nossl-docker.conf b/nginx-nossl-docker.conf deleted file mode 100644 index 180ab6a62..000000000 --- a/nginx-nossl-docker.conf +++ /dev/null @@ -1,60 +0,0 @@ -user root; -worker_processes auto; -pid /run/nginx.pid; -include /etc/nginx/modules-enabled/*.conf; - -events { - worker_connections 768; - # multi_accept on; -} - -http { - sendfile on; - tcp_nopush on; - tcp_nodelay on; - keepalive_timeout 65; - types_hash_max_size 2048; - - include /etc/nginx/mime.types; - default_type application/octet-stream; - - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE - ssl_prefer_server_ciphers on; - - access_log /var/log/nginx/access.log; - error_log /var/log/nginx/error.log; - - gzip on; - gzip_comp_level 5; - gzip_min_length 256; - gzip_proxied any; - gzip_vary on; - - gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; # text/html is always compressed by gzip module - - server { - listen 80; - listen [::]:80; - server_name docker.lan; - - root /var/www/html; - - index index.html; - server_name example.com; # managed by Certbot - - location / { - try_files $uri $uri/ /index.html =404; - } - - location /api { - proxy_pass http://127.0.0.1:8999/api; - } - - location /ws { - proxy_pass http://127.0.0.1:8999/; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "Upgrade"; - } - } -} diff --git a/nginx.conf b/nginx.conf index 3d68d7fd4..89a7f68fe 100644 --- a/nginx.conf +++ b/nginx.conf @@ -1,81 +1,126 @@ -user www-data; +user nobody; +pid /var/run/nginx.pid; + worker_processes auto; -pid /run/nginx.pid; -include /etc/nginx/modules-enabled/*.conf; +worker_rlimit_nofile 100000; events { - worker_connections 768; - # multi_accept on; + worker_connections 9000; + multi_accept on; } http { sendfile on; tcp_nopush on; tcp_nodelay on; - keepalive_timeout 300s; - types_hash_max_size 2048; + + server_tokens off; + server_name_in_redirect off; include /etc/nginx/mime.types; default_type application/octet-stream; - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE - ssl_prefer_server_ciphers on; - access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; - proxy_cache off; + # reset timed out connections freeing ram + reset_timedout_connection on; + # maximum time between packets the client can pause when sending nginx any data + client_body_timeout 10s; + # maximum time the client has to send the entire header to nginx + client_header_timeout 10s; + # timeout which a single keep-alive client connection will stay open + keepalive_timeout 69s; + # maximum time between packets nginx is allowed to pause when sending the client data + send_timeout 10s; + # number of requests per connection, does not affect SPDY + keepalive_requests 100; + + # enable gzip compression gzip on; - gzip_comp_level 5; - gzip_min_length 256; - gzip_proxied any; - gzip_vary on; + gzip_vary on; + gzip_comp_level 6; + gzip_min_length 1000; + gzip_proxied expired no-cache no-store private auth; + # text/html is always compressed by gzip module + gzip_types application/javascript application/json application/ld+json application/manifest+json application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard; - gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; # text/html is always compressed by gzip module + # limit request body size + client_max_body_size 10m; - server { - listen 80; - listen [::]:80; - server_name example.com; + # proxy cache + proxy_cache off; + proxy_cache_path /var/cache/nginx keys_zone=cache:20m levels=1:2 inactive=600s max_size=500m; + types_hash_max_size 2048; - if ($host = example.com) { - return 301 https://$host$request_uri; - } # managed by Certbot + # exempt localhost from rate limit + geo $limited_ip { + default 1; + 127.0.0.1 0; + } + map $limited_ip $limited_ip_key { + 1 $binary_remote_addr; + 0 ''; + } - return 404; # managed by Certbot + # rate limit requests + limit_req_zone $limited_ip_key zone=api:5m rate=200r/m; + limit_req_zone $limited_ip_key zone=electrs:5m rate=2000r/m; + limit_req_status 429; + + # rate limit connections + limit_conn_zone $limited_ip_key zone=websocket:10m; + limit_conn_status 429; + + map $http_accept_language $header_lang { + default en-US; + ~*^en-US en-US; + ~*^en en-US; + ~*^ar ar; + ~*^cs cs; + ~*^de de; + ~*^es es; + ~*^fa fa; + ~*^fr fr; + ~*^ja ja; + ~*^ka ka; + ~*^nl nl; + ~*^nn nn; + ~*^pt pt; + ~*^sl sl; + ~*^sv sv; + ~*^tr tr; + ~*^uk uk; + ~*^vi vi; + ~*^zh zh; + } + + map $cookie_lang $lang { + default $header_lang; + ~*^en-US en-US; + ~*^en en-US; + ~*^ar ar; + ~*^cs cs; + ~*^de de; + ~*^es es; + ~*^fa fa; + ~*^fr fr; + ~*^ja ja; + ~*^ka ka; + ~*^nl nl; + ~*^nn nn; + ~*^pt pt; + ~*^sl sl; + ~*^sv sv; + ~*^tr tr; + ~*^uk uk; + ~*^vi vi; + ~*^zh zh; } server { - listen [::]:443 ssl http2; # managed by Certbot - listen 443 ssl http2; # managed by Certbot - ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot - ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot - include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot - ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot - - server_name example.com; # managed by Certbot - - index index.html; - root /var/www/html; - - location / { - try_files $uri $uri/ /index.html =404; - } - - location /api { - proxy_pass http://127.0.0.1:8999/api; - } - - location /electrs/ { - proxy_pass http://127.0.0.1:3000/; - } - - location /ws { - proxy_pass http://127.0.0.1:8999/; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "Upgrade"; - } + listen 127.0.0.1:80; + include /etc/nginx/nginx-mempool.conf; } } diff --git a/package.json b/package.json deleted file mode 100644 index b6bb7a75f..000000000 --- a/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "mempool", - "version": "2.0.0", - "description": "Bitcoin mempool visualizer and blockchain explorer", - "license": "MIT", - "homepage": "https://mempool.space", - "repository": { - "type": "git", - "url": "git+https://github.com/mempool/mempool" - }, - "bugs": { - "url": "https://github.com/mempool/mempool/issues" - }, - "keywords": [ - "bitcoin", - "mempool", - "blockchain", - "explorer", - "liquid" - ], - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "dependencies": { - "mempool-frontend": "2.0.0", - "mempool-backend": "2.0.0" - } -}