diff --git a/.env b/.env index 7a8274f..efb135f 100644 --- a/.env +++ b/.env @@ -10,16 +10,27 @@ MONEROD_TAG=latest MONEROD_RPC_PORT=18081 MONEROD_RESTRICTED_RPC_PORT=18089 MONEROD_P2P_PORT=18080 -MONEROD_EXTRA_PARAMS=--prune-blockchain +MONEROD_ZMQ_RPC_PORT=18082 +MONEROD_ZMQ_PUB_PORT=18083 +MONEROD_EXTRA_PARAMS= MONEROD_accessControlAllowOriginList=* +LWS_TAG=v0.2_0.18 +LWS_PORT=8000 +LWS_EXTRA_PARAMS= + #TOR_TAG=latest -TOR_TAG=0.4.7.7 +TOR_TAG=v0.4.7.8-57f8867 TOR_HTTP_PORT=80 -EXPLORER_TAG=v0.17 +EXPLORER_TAG=v0.18 EXPLORER_PORT=8081 +P2POOL_WALLET=changeme +P2POOL_STRATUM_PORT=3333 +P2POOL_P2P_PORT=37889 +P2POOL_PEERS=65.21.227.114:37889,node.sethforprivacy.com:37889 + GRAFANA_TAG=8.5.4 GF_SECURITY_ADMIN_PASSWORD=xmrsh-admin -PROMETHEUS_TAG=2.36.0 +PROMETHEUS_TAG=v2.36.0 diff --git a/README.md b/README.md index 383ca43..a8fa7b9 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,14 @@ Compatible and tested on: Other distributions with docker pre-installed would probably be compatible as well. +## Demo + +[![asciicast](https://asciinema.org/a/1gL7tNhb3XgPUr26losgZaeCJ.svg)](https://asciinema.org/a/1gL7tNhb3XgPUr26losgZaeCJ) + +## FAQ + +Check the [wiki](https://github.com/vdo/xmr.sh/wiki/FAQ) + ## ToDo - [x] Add wizard for DNS domain selection. @@ -19,11 +27,24 @@ Other distributions with docker pre-installed would probably be compatible as we - [x] Mainnet / Stagenet / Testnet selection - [x] Pruning enabled - [x] Clearnet TLS port selection -- [ ] Uninstall script -- [ ] Documentation +- [x] Uninstall script - [x] Make tor service optional - [x] Block explorer (disabled) - [x] Grafana dashboard -- [ ] arm64 support for all images. -- [ ] monerod-lws support -- [ ] monerod-proxy support. +- [x] arm64 support for all images +- [x] monerod-lws support (experimental) +- [ ] Shellcheck via Github Actions +- [ ] Documentation +- [ ] monerod-proxy support for random node forwarding +- [ ] i2p service +- [ ] p2pool mining + +# Credits + +[@cirocosta](https://github.com/cirocosta) for the metrics exporter and grafana dashboard. + +[@sethforprivacy](https://github.com/sethforprivacy) for providing and maintaining Monero Docker images. + +# Donate XMR 🍕 + +86GwmtuKWtjJBWT8Srn4oqZHbP41k2kpG79xXKKgauJzCmZkFJ5ihwjVnRodVbVjAx64JeB7VyGbF6hEdwpcPcR7Go8x2YZ diff --git a/data/monero-lws/.gitignore b/data/monero-lws/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/data/monero-lws/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/docker-compose.yml b/docker-compose.yml index ca3d72d..368b5c4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,12 @@ version: "3.7" +x-log-config: &log-config + logging: + driver: json-file + options: + max-size: "50m" + max-file: "20" + x-traefik-command-le: &traefik-command-le command: - "--log.level=${TRAEFIK_LOGLEVEL}" @@ -28,9 +35,10 @@ x-traefik-command-nole: &traefik-command-nole x-monerod-command: &monerod-command command: >- - --public-node --no-igd --no-zmq + --public-node --no-igd --enable-dns-blocklist --rpc-restricted-bind-ip=0.0.0.0 --rpc-restricted-bind-port=${MONEROD_RESTRICTED_RPC_PORT} --confirm-external-bind + --zmq-pub tcp://0.0.0.0:${MONEROD_ZMQ_PUB_PORT} --zmq-rpc-bind-port=${MONEROD_ZMQ_RPC_PORT} --zmq-rpc-bind-ip=0.0.0.0 --rpc-bind-port=${MONEROD_RPC_PORT} --rpc-bind-ip=0.0.0.0 ${MONEROD_EXTRA_PARAMS} @@ -38,12 +46,14 @@ x-tor-service: &tor-service tor: container_name: tor image: vdo1138/tor-hidden-service:${TOR_TAG} + restart: unless-stopped links: - monerod environment: MONEROD_TOR_SERVICE_HOSTS: "${TOR_HTTP_PORT}:monerod:${MONEROD_RESTRICTED_RPC_PORT}" volumes: - ./data/tor:/var/lib/tor/hidden_service/ + <<: *log-config x-explorer-service: &explorer-service explorer: @@ -67,13 +77,62 @@ x-explorer-service: &explorer-service - "traefik.http.routers.explorer.tls" - "traefik.http.routers.explorer.service=explorer" - "traefik.http.services.explorer.loadbalancer.server.port=${EXPLORER_PORT}" + <<: *log-config + +x-monero-lws-service: &monero-lws-service + monero-lws: + image: vdo1138/monero-lws:${LWS_TAG} + container_name: monero-lws + restart: unless-stopped + security_opt: + - "no-new-privileges:true" + command: >- + --rest-server http://0.0.0.0:8000 --daemon=tcp://monerod:${MONEROD_ZMQ_RPC_PORT} + --sub=tcp://monerod:${MONEROD_ZMQ_PUB_PORT} --log-level=4 + --confirm-external-bind ${LWS_EXTRA_PARAMS} + volumes: + - ./data/monero-lws:/home/monero-lws/.bitmonero/ + depends_on: + - monerod + labels: + - "traefik.enable=true" + - "traefik.http.routers.monero-lws.rule=(PathPrefix(`/lws`) )" #!nole + # - "traefik.http.routers.monero-lws.rule=(Host(`${DOMAIN}`) && PathPrefix(`/lws`) )" #!le + # - "traefik.http.routers.monero-lws.tls.certresolver=le" #!le + - "traefik.http.middlewares.stripprefix-monero-lws.stripprefix.prefixes=/lws" + - "traefik.http.routers.monero-lws.middlewares=stripprefix-monero-lws" + - "traefik.http.routers.monero-lws.entrypoints=websecure" + - "traefik.http.routers.monero-lws.tls" + - "traefik.http.routers.monero-lws.service=monero-lws" + - "traefik.http.services.monero-lws.loadbalancer.server.port=${LWS_PORT}" + <<: *log-config x-monero-exporter-service: &monero-exporter-service monero-exporter: command: - --monero-addr=http://monerod:${MONEROD_RPC_PORT} container_name: monero-exporter - image: utxobr/monero-exporter@sha256:737413b1054583535e835e1417b61a8d59a4c08723e4a15c61c4249c2a7d69a4 + restart: unless-stopped + image: vdo1138/monero-exporter:0.0.2 + <<: *log-config + +x-p2pool-service: &p2pool-service + p2pool: + image: sethsimmons/p2pool:latest + restart: unless-stopped + container_name: p2pool + #tty: true + #stdin_open: true + volumes: + - ./data/p2pool:/home/p2pool + # - /dev/hugepages:/dev/hugepages:rw + ports: + - ${P2POOL_STRATUM_PORT}:${P2POOL_STRATUM_PORT} + - ${P2POOL_P2P_PORT}:${P2POOL_P2P_PORT} + command: >- + --wallet "${P2POOL_WALLET}" + --stratum "0.0.0.0:${P2POOL_STRATUM_PORT}" --p2p "0.0.0.0:${P2POOL_P2P_PORT}" --rpc-port "${MONEROD_RPC_PORT}" + --addpeers "P2POOL_PEERS" --host "monerod" --no-randomx x-grafana-service: &grafana-service grafana: @@ -81,6 +140,7 @@ x-grafana-service: &grafana-service command: - -config=/etc/grafana/grafana.ini container_name: grafana + restart: unless-stopped image: grafana/grafana:${GRAFANA_TAG} ports: - 3000 @@ -102,6 +162,7 @@ x-grafana-service: &grafana-service - "traefik.http.routers.grafana.tls" - "traefik.http.routers.grafana.service=grafana" - "traefik.http.services.grafana.loadbalancer.server.port=3000" + <<: *log-config x-prometheus-service: &prometheus-service prometheus: @@ -111,20 +172,24 @@ x-prometheus-service: &prometheus-service - --storage.tsdb.path=/data - --storage.tsdb.retention.time=30d container_name: prometheus - image: bitnami/prometheus:${PROMETHEUS_TAG} + restart: unless-stopped + image: prom/prometheus:${PROMETHEUS_TAG} volumes: - ./data/prometheus:/data - ./config/prometheus/config.yaml:/etc/prometheus/config.yaml:ro + <<: *log-config x-watchtower-service: &watchtower-service watchtower: container_name: watchtower + restart: unless-stopped image: containrrr/watchtower:latest volumes: - /var/run/docker.sock:/var/run/docker.sock labels: - com.centurylinklabs.watchtower.enable="false" command: --interval 360 --include-stopped + <<: *log-config services: traefik: @@ -138,6 +203,8 @@ services: - "/var/run/docker.sock:/var/run/docker.sock:ro" <<: *traefik-command-nole #!traefik-command restart: always + <<: *log-config + monerod: container_name: monerod image: sethsimmons/simple-monerod:${MONEROD_TAG} @@ -158,10 +225,13 @@ services: # - "traefik.http.middlewares.corsheader.headers.accessControlAllowOriginList=${MONEROD_accessControlAllowOriginList}" #!cors # - "traefik.http.routers.monerod.middlewares=corsheader" #!cors restart: unless-stopped + <<: *log-config # <<: *tor-service #!tor # <<: *explorer-service #!explorer + # <<: *monero-lws-service #!lws # <<: *monero-exporter-service #!monero-exporter + # <<: *p2pool-service #!p2pool # <<: *grafana-service #!grafana # <<: *prometheus-service #!prometheus # <<: *watchtower-service #!watchtower diff --git a/install b/install index 585605c..aca7cb7 100755 --- a/install +++ b/install @@ -28,7 +28,7 @@ StatInfo="${White}${On_Black}" ################################################################ # Vars # ################################################################ -VERSION="v0.3.1" +VERSION="v0.4.0" XMRSH_INSTALL_CMD="sudo bash -c \"\$(curl -sLSf https://get.xmr.sh)\"" XMRSH_DIR="/opt/xmr.sh" XMRSH_BRANCH="main" @@ -117,7 +117,6 @@ detect_curl() { detect_docker() { echo -ne "${OkBullet}Checking docker... ${Off}" - # docker --version >>"${XMRSH_LOG_FILE}" 2>&1 | grep -q "Docker version" if docker --version >>"${XMRSH_LOG_FILE}" 2>&1; then DOCKER_INSTALLED=true echo -e "${Ok}" @@ -128,7 +127,6 @@ detect_docker() { detect_docker_compose() { echo -ne "${OkBullet}Checking docker compose... ${Off}" - #docker-compose --version >>"${XMRSH_LOG_FILE}" 2>&1 | grep -q "Docker Compose version" if docker-compose --version >>"${XMRSH_LOG_FILE}" 2>&1; then DOCKER_COMPOSE_INSTALLED=true echo -e "${Ok}" @@ -189,12 +187,14 @@ configure_network() { NETWORK="testnet" sed -i "s/MONEROD_P2P_PORT=.*/MONEROD_P2P_PORT=28080/g" .env sed -i "/MONEROD_EXTRA_PARAMS/s/$/ --testnet/g" .env + sed -i "/LWS_EXTRA_PARAMS/s/$/ --network test/g" .env break ;; "stagenet") NETWORK="stagenet" sed -i "s/MONEROD_P2P_PORT=.*/MONEROD_P2P_PORT=38080/g" .env sed -i "/MONEROD_EXTRA_PARAMS/s/$/ --stagenet/g" .env + sed -i "/LWS_EXTRA_PARAMS/s/$/ --network stage/g" .env break ;; *) echo "Invalid network choice!" ;; @@ -219,7 +219,7 @@ configure_tls_domain() { # Set domain and email address in vars sed -i "s/DOMAIN=.*/DOMAIN=${TLS_DOMAIN}/g" .env sed -i "s/TRAEFIK_ACME_EMAIL=.*/TRAEFIK_ACME_EMAIL=${TLS_EMAIL}/g" .env - # Enable LE settings in compose + # Enable Let's Encrypt settings in compose sed -i '/#!le/s/# //g' docker-compose.yml sed -i '/#!nole/s/- /# - /g' docker-compose.yml sed -i "/#\!traefik-command/s/\*traefik-command-nole/\*traefik-command-le/g" docker-compose.yml @@ -241,10 +241,25 @@ configure_tls_port() { fi } +configure_pruning() { + echo -e "${OkBullet}Configuring pruning..." + while true; do + read -r -e -p " Do you want to enable blockchain pruning? [y/n]: " yn + case $yn in + [Yy]*) + sed -i "/MONEROD_EXTRA_PARAMS/s/$/ --prune-blockchain/g" .env + break + ;; + [Nn]*) break ;; + *) echo " Please answer yes or no." ;; + esac + done +} + configure_cors() { echo -e "${OkBullet}Configuring CORS..." while true; do - read -r -e -p " Do you want to enabe CORS headers so the node can be used in web apps? [y/n]: " yn + read -r -e -p " Do you want to enable CORS headers so the node can be used in web apps? [y/n]: " yn case $yn in [Yy]*) sed -i '/#!cors/s/# //g' docker-compose.yml @@ -288,6 +303,44 @@ configure_explorer() { done } +configure_lws() { + echo -e "${OkBullet}Configuring LWS..." + while true; do + read -r -e -p " Do you want to enable the light wallet service (experimental)? [y/n]: " yn + case $yn in + [Yy]*) + sed -i '/#!lws/s/# //g' docker-compose.yml + ENABLE_LWS=true + break + ;; + [Nn]*) break ;; + *) echo " Please answer yes or no." ;; + esac + done +} + +configure_p2pool() { + echo -e "${OkBullet}Configuring p2pool..." + while true; do + read -r -e -p " Do you want to enable the p2pool service? [y/n]: " yn + case $yn in + [Yy]*) + read -r -e -p " Enter the desired primary address which will recieve the rewards. []: " P2P_ADDRESS + while ! echo "${P2P_ADDRESS}" | grep -qP '(4|5|9|A)[a-zA-Z|\d]{94}'; do + echo -e "${WarnBullet}Address is not valid. Remember: subaddresses are not supported by p2pool." + read -r -p " Enter again your primary address: " P2P_ADDRESS + done + sed -i "s/P2POOL_WALLET=.*/P2POOL_WALLET=${P2P_ADDRESS}/g" .env + sed -i '/#!p2pool/s/# //g' docker-compose.yml + ENABLE_P2POOL=true + break + ;; + [Nn]*) break ;; + *) echo " Please answer yes or no." ;; + esac + done +} + configure_grafana() { echo -e "${OkBullet}Configuring grafana..." while true; do @@ -311,7 +364,7 @@ configure_grafana() { configure_watchtower() { echo -e "${OkBullet}Configuring watchtower..." while true; do - read -r -e -p " Do you want to enable automatic updates using watchtower? [y/n]: " yn + read -r -e -p " Do you want to enable automatic node updates using watchtower? [y/n]: " yn case $yn in [Yy]*) sed -i '/#!watchtower/s/# //g' docker-compose.yml @@ -366,7 +419,7 @@ completed() { echo echo -e " ${Red}┌───────────────────────────────────────────────────────────────────────────[info]──" echo -e " ${Red}│${Stat} Network: ${StatInfo}${NETWORK}" - echo -e " ${Red}│${Stat} URL: ${StatInfo}https://${HOST}${PORT_SUFF}" + echo -e " ${Red}│${Stat} Public URL: ${StatInfo}https://${HOST}${PORT_SUFF}" echo -e " ${Red}│${Stat} Public IP: ${StatInfo}${PUBLIC_IP}" if [ "$ENABLE_TOR" = true ]; then @@ -375,6 +428,12 @@ completed() { if [ "$ENABLE_EXPLORER" = true ]; then echo -e " ${Red}│${Stat} Explorer URL: ${StatInfo}https://${HOST}${PORT_SUFF}/explorer" fi + if [ "$ENABLE_LWS" = true ]; then + echo -e " ${Red}│${Stat} LWS URL: ${StatInfo}https://${HOST}${PORT_SUFF}/lws" + fi + if [ "$ENABLE_P2POOL" = true ]; then + echo -e " ${Red}│${Stat} P2Pool stratum: ${StatInfo}${HOST}:3333" + fi if [ "$ENABLE_GRAFANA" = true ]; then echo -e " ${Red}│${Stat} Grafana URL: ${StatInfo}https://${HOST}${PORT_SUFF}/grafana" echo -e " ${Red}│${Stat} Grafana user: ${StatInfo}admin" @@ -405,15 +464,16 @@ install_xmrsh configure_network configure_tls_domain configure_tls_port -# configure_pruning +configure_pruning configure_cors - configure_tor +configure_lws +configure_p2pool # Deployment of explorer disabled until it's stable. # configure_explorer -configure_watchtower configure_grafana -# configure_lws +configure_watchtower + start_xmrsh completed diff --git a/monero-lws-admin b/monero-lws-admin new file mode 100755 index 0000000..4627df9 --- /dev/null +++ b/monero-lws-admin @@ -0,0 +1,2 @@ +#!/bin/bash +docker exec -ti monero-lws /usr/local/bin/monero-lws-admin ${@} diff --git a/uninstall b/uninstall index 428f160..47c79ff 100755 --- a/uninstall +++ b/uninstall @@ -7,21 +7,21 @@ Off='\033[0m' # Text Reset # Regular Colors -Red='\033[0;31m' # Red -Green='\033[0;32m' # Green -Yellow='\033[0;33m' # Yellow -Purple='\033[0;35m' # Purple -White='\033[0;37m' # White +Red='\033[0;31m' # Red +Green='\033[0;32m' # Green +#Yellow='\033[0;33m' # Yellow +#Purple='\033[0;35m' # Purple +White='\033[0;37m' # White # Background On_Black='\033[40m' # Black OkBullet="${Green}${On_Black}:: ${White}${On_Black}" -WarnBullet="${Yellow}${On_Black}:: ${White}${On_Black}" +#WarnBullet="${Yellow}${On_Black}:: ${White}${On_Black}" ErrBullet="${Red}${On_Black}:: ${White}${On_Black}" Ok="${Green}${On_Black} ok.${Off}" Fail="${Red}${On_Black} failed!${Off}" -Nok="${Yellow}${On_Black} nok.${Off}" +#Nok="${Yellow}${On_Black} nok.${Off}" ################################################################ # Vars # @@ -65,17 +65,18 @@ uninstall() { [Yy]*) find . -type f -not -name 'data' -print0 | xargs -0 -I {} rm {} check_return $? + popd >>"${XMRSH_LOG_FILE}" 2>&1 || check_return $? break ;; [Nn]*) - rm -rf ./* + popd >>"${XMRSH_LOG_FILE}" 2>&1 || check_return $? + rm -rf "${XMRSH_DIR}" check_return $? break ;; *) echo " Please answer yes or no." ;; esac done - popd || check_return $? echo -e "${OkBullet}Uninstall complete." }