diff --git a/.env.template b/.env.template new file mode 100644 index 0000000..a460fd4 --- /dev/null +++ b/.env.template @@ -0,0 +1,11 @@ +ZCASHD_RPCUSER=zcashrpc +ZCASHD_RPCPASSWORD=${PASSWORD_ZCASHD} +ZCASHD_RPCPORT=38232 +ZCASHD_ALLOWIP=0.0.0.0/0 +ZCASHD_DATADIR=/srv/zcashd/.zcash +ZCASHD_PARMDIR=/srv/zcashd/.zcash-params +ZCASHD_GEN=0 +GF_SECURITY_ADMIN_USER=admin +GF_SECURITY_ADMIN_PASSWORD=${PASSWORD_GRAFANA} +LWD_PORT=9067 +ZCASHD_CONF_PATH=/srv/lightwalletd/zcash.conf diff --git a/Dockerfile b/Dockerfile index 97e48c0..b8f4ea4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -41,71 +41,23 @@ # ************************************************************************/ # Create layer in case you want to modify local lightwalletd code -FROM golang:1.11 AS lightwalletd_base +FROM golang:1.13 AS lightwalletd_base -ENV ZCASH_CONF=/root/.zcash/zcash.conf -ENV LIGHTWALLETD_URL=https://github.com/zcash-hackworks/lightwalletd.git +ADD . /go/src/github.com/zcash-hackworks/lightwalletd +WORKDIR /go/src/github.com/zcash-hackworks/lightwalletd +RUN make \ + && /usr/bin/install -c ./server /usr/bin/ -RUN apt-get update && apt-get install make git gcc -WORKDIR /home +ARG LWD_USER=lightwalletd +ARG LWD_UID=2002 -# Comment out line below to use local lightwalletd repo changes -RUN git clone ${LIGHTWALLETD_URL} +RUN useradd --home-dir /srv/$LWD_USER \ + --shell /bin/bash \ + --create-home \ + --uid $LWD_UID\ + $LWD_USER +USER $LWD_USER +WORKDIR /srv/$LWD_USER -# To add local changes to container uncomment this line -#ADD . /home - -RUN cd ./lightwalletd && make -RUN /usr/bin/install -c /home/lightwalletd/server /usr/bin/ - -# Setup layer for zcashd and zcash-cli binary -FROM golang:1.11 AS zcash_builder - -ENV ZCASH_URL=https://github.com/zcash/zcash.git - -RUN apt-get update && apt-get install \ - build-essential pkg-config libc6-dev m4 g++-multilib \ - autoconf libtool ncurses-dev unzip git python python-zmq \ - zlib1g-dev wget curl bsdmainutils automake python-pip -y - -WORKDIR /build -RUN git clone ${ZCASH_URL} - -RUN ./zcash/zcutil/build.sh -j$(nproc) -RUN bash ./zcash/zcutil/fetch-params.sh -RUN /usr/bin/install -c /build/zcash/src/zcashd /build/zcash/src/zcash-cli /usr/bin/ - -# Create layer for lightwalletd and zcash binaries to reduce image size -FROM golang:1.11 AS zcash_runner - -ARG ZCASH_VERSION=2.0.7+3 -ARG ZCASHD_USER=zcash -ARG ZCASHD_UID=1001 -ARG ZCASH_CONF=/home/$ZCASHD_USER/.zcash/zcash.conf - -RUN useradd -s /bin/bash -u $ZCASHD_UID $ZCASHD_USER - -RUN mkdir -p /home/$ZCASHD_USER/.zcash/ && \ - mkdir -p /home/$ZCASHD_USER/.zcash-params/ && \ - chown -R $ZCASHD_USER /home/$ZCASHD_USER/.zcash/ && \ - mkdir /logs/ && \ - mkdir /db/ - -USER $ZCASHD_USER -WORKDIR /home/$ZCASHD_USER/ - -# Use lightwallet server binary from prior layer -COPY --from=lightwalletd_base /usr/bin/server /usr/bin/ -COPY --from=zcash_builder /usr/bin/zcashd /usr/bin/zcash-cli /usr/bin/ -COPY --from=zcash_builder /root/.zcash-params/ /home/$ZCASHD_USER/.zcash-params/ - -# Configure zcash.conf -RUN echo "testnet=1" >> ${ZCASH_CONF} && \ - echo "addnode=testnet.z.cash" >> ${ZCASH_CONF} && \ - echo "rpcbind=127.0.0.1" >> ${ZCASH_CONF} && \ - echo "rpcport=18232" >> ${ZCASH_CONF} && \ - echo "rpcuser=lwd" >> ${ZCASH_CONF} && \ - echo "rpcpassword=`head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo ''`" >> ${ZCASH_CONF} - -VOLUME [/home/$ZCASH_USER/.zcash] -VOLUME [/home/$ZCASH_USER/.zcash-params] +ENTRYPOINT ["server"] +CMD ["--help"] \ No newline at end of file diff --git a/README.md b/README.md index 038a2a9..8e4ddf7 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,10 @@ To view status of [CI pipeline](https://gitlab.com/mdr0id/lightwalletd/pipelines To view detailed [Codecov](https://codecov.io/gh/zcash-hackworks/lightwalletd) report +# Local/Developer docker-compose Usage + +[docs/docker-compose-setup.md](./docs/docker-compose-setup.md) + # Local/Developer Usage First, ensure [Go >= 1.11](https://golang.org/dl/#stable) is installed. Once your go environment is setup correctly, you can build/run the below components. diff --git a/buildenv.sh b/buildenv.sh new file mode 100755 index 0000000..8b127a6 --- /dev/null +++ b/buildenv.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +for i in "$@" +do +case $i in + -h|--help) + echo HELP + exit 0 + ;; + -n=*|--network=*) + NETWORK="${i#*=}" + shift + ;; + *) + echo Unknown option. Use -h for help. + exit -1 + ;; +esac +done + +if [ "$NETWORK" == "" ] +then + echo ZCASHD_NETWORK=testnet +else + echo ZCASHD_NETWORK=$NETWORK +fi + +# sanity check openssl first... + +if [ `openssl rand -base64 32 | wc -c` != 45 ] +then + echo Openssl password generation failed. + exit 1 +fi + +PASSWORD_GRAFANA=`openssl rand -base64 32` +PASSWORD_ZCASHD=`openssl rand -base64 32` + +while read TEMPLATE +do + eval echo $TEMPLATE +done < .env.template diff --git a/cmd/server/main.go b/cmd/server/main.go index 14da87b..823a32b 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -105,12 +105,11 @@ func fileExists(filename string) bool { func main() { opts := &Options{} flag.StringVar(&opts.bindAddr, "bind-addr", "127.0.0.1:9067", "the address to listen on") - flag.StringVar(&opts.tlsCertPath, "tls-cert", "./cert.pem", "the path to a TLS certificate") - flag.StringVar(&opts.tlsKeyPath, "tls-key", "./cert.key", "the path to a TLS key file") + flag.StringVar(&opts.tlsCertPath, "tls-cert", "", "the path to a TLS certificate") + flag.StringVar(&opts.tlsKeyPath, "tls-key", "", "the path to a TLS key file") flag.Uint64Var(&opts.logLevel, "log-level", uint64(logrus.InfoLevel), "log level (logrus 1-7)") flag.StringVar(&opts.logPath, "log-file", "./server.log", "log file to write to") flag.StringVar(&opts.zcashConfPath, "conf-file", "./zcash.conf", "conf file to pull RPC creds from") - flag.BoolVar(&opts.veryInsecure, "no-tls-very-insecure", false, "run without the required TLS certificate, only for debugging, DO NOT use in production") flag.BoolVar(&opts.wantVersion, "version", false, "version (major.minor.patch)") flag.IntVar(&opts.cacheSize, "cache-size", 80000, "number of blocks to hold in the cache") @@ -124,19 +123,16 @@ func main() { } filesThatShouldExist := []string{ - opts.tlsCertPath, - opts.tlsKeyPath, - opts.logPath, opts.zcashConfPath, } + if opts.tlsCertPath != "" { + filesThatShouldExist = append(filesThatShouldExist, opts.tlsCertPath) + } + if opts.tlsKeyPath != "" { + filesThatShouldExist = append(filesThatShouldExist, opts.tlsKeyPath) + } for _, filename := range filesThatShouldExist { - if !fileExists(opts.logPath) { - os.OpenFile(opts.logPath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666) - } - if opts.veryInsecure && (filename == opts.tlsCertPath || filename == opts.tlsKeyPath) { - continue - } if !fileExists(filename) { os.Stderr.WriteString(fmt.Sprintf("\n ** File does not exist: %s\n\n", filename)) flag.Usage() @@ -162,11 +158,15 @@ func main() { // gRPC initialization var server *grpc.Server + var transportCreds credentials.TransportCredentials + var err error - if opts.veryInsecure { - server = grpc.NewServer(LoggingInterceptor()) + if (opts.tlsCertPath == "") && (opts.tlsKeyPath == "") { + log.Warning("Certificate and key not provided, generating self signed values") + tlsCert := common.GenerateCerts() + transportCreds = credentials.NewServerTLSFromCert(tlsCert) } else { - transportCreds, err := credentials.NewServerTLSFromFile(opts.tlsCertPath, opts.tlsKeyPath) + transportCreds, err = credentials.NewServerTLSFromFile(opts.tlsCertPath, opts.tlsKeyPath) if err != nil { log.WithFields(logrus.Fields{ "cert_file": opts.tlsCertPath, @@ -174,8 +174,8 @@ func main() { "error": err, }).Fatal("couldn't load TLS credentials") } - server = grpc.NewServer(grpc.Creds(transportCreds), LoggingInterceptor()) } + server = grpc.NewServer(grpc.Creds(transportCreds), LoggingInterceptor()) // Enable reflection for debugging if opts.logLevel >= uint64(logrus.WarnLevel) { diff --git a/common/generatecerts.go b/common/generatecerts.go new file mode 100644 index 0000000..2b9cb79 --- /dev/null +++ b/common/generatecerts.go @@ -0,0 +1,72 @@ +package common + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/tls" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "fmt" + "log" + "math/big" + "time" +) + +// GenerateCerts create self signed certificate for local development use +func GenerateCerts() (cert *tls.Certificate) { + + privKey, err := rsa.GenerateKey(rand.Reader, 2048) + publicKey := &privKey.PublicKey + + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + log.Fatalf("Failed to generate serial number: %s", err) + } + + template := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + Organization: []string{"Lighwalletd developer"}, + }, + NotBefore: time.Now(), + NotAfter: time.Now().Local().Add(time.Hour * 24 * 365), + + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + } + + // List of hostnames and IPs for the cert + template.DNSNames = append(template.DNSNames, "localhost") + + certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey, privKey) + if err != nil { + log.Fatalf("Failed to create certificate: %s", err) + } + + // PEM encode the certificate (this is a standard TLS encoding) + b := pem.Block{Type: "CERTIFICATE", Bytes: certDER} + certPEM := pem.EncodeToMemory(&b) + fmt.Printf("%s\n", certPEM) + + // PEM encode the private key + privBytes, err := x509.MarshalPKCS8PrivateKey(privKey) + if err != nil { + log.Fatalf("Unable to marshal private key: %v", err) + } + keyPEM := pem.EncodeToMemory(&pem.Block{ + Type: "RSA PRIVATE KEY", Bytes: privBytes, + }) + + // Create a TLS cert using the private key and certificate + tlsCert, err := tls.X509KeyPair(certPEM, keyPEM) + if err != nil { + log.Fatalf("invalid key pair: %v", err) + } + + cert = &tlsCert + return cert + +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..8f41143 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,97 @@ +--- +version: '2' + +services: + lightwalletd: + build: . + env_file: + - .env + #entrypoint: ["/bin/bash", "-c", "sleep infinity"] + command: + - -bind-addr=0.0.0.0:$LWD_PORT + - -cache-size=80000 + - -conf-file=$ZCASHD_CONF_PATH + - -log-file=/dev/stdout + - -log-level=7 + - -tls-cert=./cert.pem + - -tls-key=./cert.key + ports: + - "127.0.0.1:$LWD_PORT:$LWD_PORT" + volumes: + - ./docker/:/srv/lightwalletd + logging: + driver: loki + options: + loki-url: 'http://localhost:3100/api/prom/push' + + zcashd: + image: gcr.io/zcash-web/zcashd:latest + volumes: + - $ZCASHD_DATADIR:/srv/zcashd/.zcash + - $ZCASHD_PARMDIR:/srv/zcashd/.zcash-params + env_file: + - .env + mem_limit: 4G + logging: + driver: loki + options: + loki-url: 'http://localhost:3100/api/prom/push' + + zcashd_exporter: + image: gcr.io/zcash-web/zcashd_exporter + environment: + - ZCASHD_RPCUSER=$ZCASHD_RPCUSER + - ZCASHD_RPCPASSWORD=$ZCASHD_RPCPASSWORD + command: + - --rpc.host=zcashd + - --rpc.port=$ZCASHD_RPCPORT + - --rpc.user=$ZCASHD_RPCUSER + - --rpc.password=$ZCASHD_RPCPASSWORD + ports: + - "127.0.0.1:9100:9100" + logging: + driver: loki + options: + loki-url: 'http://localhost:3100/api/prom/push' + + grafana: + image: grafana/grafana:6.4.3 + entrypoint: + - bash + - -c + - grafana-cli plugins install grafana-piechart-panel && /run.sh + ports: + - "127.0.0.1:3000:3000" + env_file: + - .env + volumes: + - ./docker/grafana/provisioning/:/etc/grafana/provisioning/ + logging: + driver: loki + options: + loki-url: 'http://localhost:3100/api/prom/push' + + prometheus: + image: prom/prometheus:v2.13.1 + ports: + - "127.0.0.1:9090:9090" + volumes: + - ./docker/prometheus/config.yml:/etc/prometheus/prometheus.yml + - promethus_data:/promethus_data + logging: + driver: loki + options: + loki-url: 'http://localhost:3100/api/prom/push' + + loki: + image: grafana/loki:master + ports: + - "127.0.0.1:3100:3100" + command: -config.file=/etc/loki/local-config.yaml + logging: + driver: loki + options: + loki-url: 'http://localhost:3100/api/prom/push' + +volumes: + promethus_data: diff --git a/docker/cert.key b/docker/cert.key new file mode 100644 index 0000000..3c42aaa --- /dev/null +++ b/docker/cert.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCertVgQ0jHcqW9 +NvPszU9Mwi5jsin6edmCIBFLEDdOBBCWd9fkDkVHcaLNgq2uf1DYnhaWcSHiUiP2 +D7sUrtFdR9JZc9REwOwaOInk+ughiGPQ06nnOlhxbHH4TF3hwXLBe1LvEVL7SP3s +liBi88oITC1YrTQ2BXi3vKwL7FsTuCLn8+hlw/l5WNt+JZyA9GvXjwLLr8yf3Xi+ +8HRn3vRyIwy6rxFf2xYmTK0+5pBGBGhkuKuz/V3mJO9hyw8702ccdc7Vi+yETvIr +I6BjmQgH8AzM3J2JjZ/4Jbc78WjTqC8/P7ve4YW19rKmJKvqeY73x2CXC80PQZ8J +2nVMtlu7AgMBAAECggEAXBGi2jSP4LEjevKMeuPw09+C3PN9qcfTLM4AWqYxAIIZ +QcSNLdQd3EMRq93befiC5vxqrKU9fLweA2HDMU/xSAcpBB/RlIa/NsOBNqthzjr9 +dyeoV/IhaMX8Jo3gluEP/TTZvL43gHcsZX4BkohSu5e/Y8kzFvj7vteol05u1bRB +607DW6ONNKCK+upbTIvY3FvaeQ+Y8sZLT1ceQGzmwkNFb0l5qnwmKm3w2jy8y7Ls +lGkVTOXuDpUm1rFYomh1vUetTB1E/B8FokbLlz8shRq3nmWKx/tycW305fqA8j0h +5XWxApARF8LptEXCGTyaqWdZDTMwRrUP4ORqklyf2QKBgQDSU1y4AvRbzDL+dfb7 +3WgNQjkQEmWDDb50hKxK9hat1aOhPa/gFwNKLWPyJpAFNBOczyCHVux6eOYPCH+t +cxf81FfbNHbfTlnfM1yXg1/5r2Mp3selUjun2aSIHQmmI0r+MjpLmFCV/TFDRDRx +IeZlea7adU62XmhIZbD9hw44jwKBgQDBJH9/+U7W4WZc0RocxZDzlW6R2E5R7hBo +F4mfeTUHrPVR5r5Tdxv94eyGqW5ZTRfty9U4btg/t8rOhb2YW9P0LT7BPQ/K/PXu +RjNR12sgZn3XY89/IwitY+SV/8kPq0fQtnjc1YdHGJ7cqW76b2SAGuFSY7bzw4W8 +9fV08+TIFQKBgAxI+j11Trid8MyUL1z+zbkYiSS7Llq9TsaXiUjHnwOAWxJr+/3m +2jZW+GOIhRkItayPHKNLHHz62tU99dc3xcrqzEbthZP9i5pR8bKX5d87s1savCaX +6wwe1lFtAMdHgHXgkS8hMnPQWjRHo5iIFmEO/nucJoDYetbfubrVTKtZAoGAPsmX +rUmlyJMjzL6pR3sugREuDbmM1HOY383vDmm/xIwEgCiL7ORGtEUSuEAyQFOgmMxv +t1XJdQVRp8uwc+w+Ph3LTdSE4s9TP6+QlWV7TOAkvrWSydjgxEU6FU0+1pou0XnQ +VrIPtRwa4M8v5bf6qu6SG0+RNTN1sZUfw3JaCHUCgYBb9wCYDktOzcUTo0xK2j8q +gZotpmKT+1wbZmL+vTRmq9juo3qGjlcRSNJMvFCe1zwC24E3bei+Chld626Do3mN +f2hkrrLIVqsXP2CSOOTZtONsO3VRPaNjdLzreR5V6Oc9StOD/2CPcvaHcaRMaoDl +ylpUUJpnIUaIIRZQvN9GlA== +-----END PRIVATE KEY----- diff --git a/docker/cert.pem b/docker/cert.pem new file mode 100644 index 0000000..27bdab3 --- /dev/null +++ b/docker/cert.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDizCCAnOgAwIBAgIUevPATPP74qY3JPE6s3axxnC8rxwwDQYJKoZIhvcNAQEL +BQAwVTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRQwEgYDVQQKDAtNeU9yZywg +SW5jLjEjMCEGA1UEAwwabGlnaHR3YWxsZXRkLnRlc3RuZXQubG9jYWwwHhcNMTkx +MjE4MTQyNDU0WhcNMjkxMjE1MTQyNDU0WjBVMQswCQYDVQQGEwJVUzELMAkGA1UE +CAwCQ0ExFDASBgNVBAoMC015T3JnLCBJbmMuMSMwIQYDVQQDDBpsaWdodHdhbGxl +dGQudGVzdG5ldC5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AJ6u1WBDSMdypb028+zNT0zCLmOyKfp52YIgEUsQN04EEJZ31+QORUdxos2Cra5/ +UNieFpZxIeJSI/YPuxSu0V1H0llz1ETA7Bo4ieT66CGIY9DTqec6WHFscfhMXeHB +csF7Uu8RUvtI/eyWIGLzyghMLVitNDYFeLe8rAvsWxO4Iufz6GXD+XlY234lnID0 +a9ePAsuvzJ/deL7wdGfe9HIjDLqvEV/bFiZMrT7mkEYEaGS4q7P9XeYk72HLDzvT +Zxx1ztWL7IRO8isjoGOZCAfwDMzcnYmNn/gltzvxaNOoLz8/u97hhbX2sqYkq+p5 +jvfHYJcLzQ9BnwnadUy2W7sCAwEAAaNTMFEwHQYDVR0OBBYEFFNfTC+B2/frL5N+ +h85UjP4Ijq/dMB8GA1UdIwQYMBaAFFNfTC+B2/frL5N+h85UjP4Ijq/dMA8GA1Ud +EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHHE3+/Hn6q5N7P1ImyZwB2s +a6y98BPbmgDpb3iWVGhiPRw2vE7/iW8aJwCPQLl9RJZsyGM447CdxsGbw4U5hBkl +NlFFRBX4b7YLuDrDeTonaIiceWaDbKYqQHggIMZMoXdRnmQQcvuJUUsDnrk1GhQQ +jI58LT4tPl8Xz780NB1+ZjGuVYPnyjk0NRHGSytNEr2KddpCrfJDRoGPRUIMuc7b +gRDQCJ5tw0heJ1HYJcyX1LzZP3u2CX3TqCvYvTSHVwbXgJ6LLOJffXR0b3FwldMa +YwKriZ9NC6wdEdEGtwN0I0rSMOaHMK0+3jMv2Lg9NCubF0p4l19KF9yANdXc+bs= +-----END CERTIFICATE----- diff --git a/docker/gen_cert.sh b/docker/gen_cert.sh new file mode 100644 index 0000000..e8a0a83 --- /dev/null +++ b/docker/gen_cert.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +## In debian +# apt-get update && apt-get install -y openssl + +openssl req -x509 -nodes -newkey rsa:2048 -keyout ./cert.key -out ./cert.pem -days 3650 -subj "/C=US/ST=CA/O=MyOrg, Inc./CN=lightwalletd.testnet.local" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:lightwalletd.testnet.local,DNS:127.0.0.1,DNS:localhost")) \ No newline at end of file diff --git a/docker/grafana/provisioning/datasources/loki.yaml b/docker/grafana/provisioning/datasources/loki.yaml new file mode 100644 index 0000000..4842596 --- /dev/null +++ b/docker/grafana/provisioning/datasources/loki.yaml @@ -0,0 +1,11 @@ +apiVersion: 1 +datasources: +- name: Loki + type: loki + access: proxy + orgId: 1 + url: http://loki:3100 + version: 1 + editable: false + jsonData: + maxLines: 1000 diff --git a/docker/grafana/provisioning/datasources/prometheus.yaml b/docker/grafana/provisioning/datasources/prometheus.yaml new file mode 100644 index 0000000..2234053 --- /dev/null +++ b/docker/grafana/provisioning/datasources/prometheus.yaml @@ -0,0 +1,9 @@ +apiVersion: 1 +datasources: +- name: Prometheus + type: prometheus + access: proxy + orgId: 1 + url: http://prometheus:9090 + version: 1 + editable: false diff --git a/docker/prometheus/config.yml b/docker/prometheus/config.yml new file mode 100644 index 0000000..58bb8ae --- /dev/null +++ b/docker/prometheus/config.yml @@ -0,0 +1,24 @@ +# my global config +global: + scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. + evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. + # scrape_timeout is set to the global default (10s). + +# Alertmanager configuration +alerting: + alertmanagers: + - static_configs: + - targets: + # - alertmanager:9093 + +# Load rules once and periodically evaluate them according to the global 'evaluation_interval'. +rule_files: + # - "first_rules.yml" + # - "second_rules.yml" + +# A scrape configuration containing exactly one endpoint to scrape: +# Here it's Prometheus itself. +scrape_configs: + - job_name: 'zcashd_exporter' + static_configs: + - targets: ['zcashd_exporter:9100'] diff --git a/docker/zcash.conf b/docker/zcash.conf new file mode 100644 index 0000000..cc00b10 --- /dev/null +++ b/docker/zcash.conf @@ -0,0 +1,4 @@ +rpcuser=zcashrpc +rpcpassword=notsecure +rpcbind=zcashd +rpcport=3434 \ No newline at end of file diff --git a/docs/docker-compose-setup.md b/docs/docker-compose-setup.md new file mode 100644 index 0000000..5f8c6dd --- /dev/null +++ b/docs/docker-compose-setup.md @@ -0,0 +1,100 @@ +# Installation and setup + +## Install requirements +- [docker](https://docs.docker.com/install/) +- [docker-compose](https://docs.docker.com/compose/install/) +- loki plugin for docker logs +``` +docker plugin install grafana/loki-docker-driver:latest --alias loki --grant-all-permissions +``` + +## Setup .env file + +Copy `.env.example` to `.env` and change any required paramaters. + +| Variable | Usage | +| ------------- |:-------------:| +| `GF_SECURITY_ADMIN_USER` | Grafana admin user name | +| `ZCASHD_RPCUSER` | zcashd rpc user | +| `ZCASHD_RPCPORT` | zcashd rpc port | +|`ZCASHD_ALLOWIP`| zcashd rpc allowed IPs (don't |change unless you know what you're doing)| +|`ZCASHD_DATADIR`| local location of zcasd data directory. `uid` 2001 needs write access| +|`ZCASHD_PARMDIR`| local location of zcasd data directory. `uid` 2001 needs read access| +|`ZCASHD_NETWORK`| zcashd network to use, `testnet` or `mainnet`| +|`ZCASHD_GEN`| should zcashd mine? `0` or `1` +|`LWD_PORT`| port for lightwalletd to bind to| +|`ZCASHD_CONF_PATH`| path for lightwalletd to pick up configuration| + + +## Populate secret env vars with random values + +``` +./buildenv.sh | tee .env +``` + +## Build initial local docker image + +`docker-compose build` + +## Start the project + +``` +docker-compose up -d +``` + +# Setup and use Grafana + +Open a browser to http://localhost:3000 + +![grafana-login](./images/grafana-login.png) + + +Login with the user (`GF_SECURITY_ADMIN_USER`) and password (`GF_SECURITY_ADMIN_PASSWORD`). +The values can be found in your `.env` file + +Open the `Dashboard Manage` menu on the left + + ![grafana-manage](./images/grafana-manage.png) + +Select `Import` + +![grafana-import](./images/grafana-import-1.png) + +Enter `11325` for the `Grafana.com Dashboard` + +![grafana-import](./images/grafana-import-2.png) + +On the next screen, select the `Prometheus` and `Loki` values (there should only be 1 to select) + +![grafana-configure](./images/grafana-configure.png) + +Click `Import` + + +This should then be taken to the `Zcashd node exporter` dashboard. + +![grafana-zcashd-dashboard](./images/grafana-zcashd-dashboard.png) + +If all goes as planned, the dashboard should start populating data from the container services. + +If there are an issues, you can view all the `docker-compose` services under the `Explore` section. + +# Viewing container logs + +Open the `Explore` menu entry + +![grafana-explore.png](./images/grafana-explore.png) + +Make sure `Loki` is selected as the datasource at the top. + +![grafana-explore2](./images/grafana-explore-2.png) + +Then choose the container to view it's logs. + +![grafana-explore3](./images/grafana-explore-3.png) + +Loki as a rich query syntax to help with log in many ways, for example combine 2 container logs entries: + +![grafana-explore4](./images/grafana-explore-4.png) + +See more here: https://github.com/grafana/loki/blob/master/docs/logql.md \ No newline at end of file diff --git a/docs/images/grafana-configure.png b/docs/images/grafana-configure.png new file mode 100644 index 0000000..50afcbf Binary files /dev/null and b/docs/images/grafana-configure.png differ diff --git a/docs/images/grafana-explore-2.png b/docs/images/grafana-explore-2.png new file mode 100644 index 0000000..d058400 Binary files /dev/null and b/docs/images/grafana-explore-2.png differ diff --git a/docs/images/grafana-explore-3.png b/docs/images/grafana-explore-3.png new file mode 100644 index 0000000..fa33e96 Binary files /dev/null and b/docs/images/grafana-explore-3.png differ diff --git a/docs/images/grafana-explore-4.png b/docs/images/grafana-explore-4.png new file mode 100644 index 0000000..b7c0f3d Binary files /dev/null and b/docs/images/grafana-explore-4.png differ diff --git a/docs/images/grafana-explore.png b/docs/images/grafana-explore.png new file mode 100644 index 0000000..bf0d8ab Binary files /dev/null and b/docs/images/grafana-explore.png differ diff --git a/docs/images/grafana-import-1.png b/docs/images/grafana-import-1.png new file mode 100644 index 0000000..c36e62c Binary files /dev/null and b/docs/images/grafana-import-1.png differ diff --git a/docs/images/grafana-import-2.png b/docs/images/grafana-import-2.png new file mode 100644 index 0000000..26b975e Binary files /dev/null and b/docs/images/grafana-import-2.png differ diff --git a/docs/images/grafana-login.png b/docs/images/grafana-login.png new file mode 100644 index 0000000..befd0b7 Binary files /dev/null and b/docs/images/grafana-login.png differ diff --git a/docs/images/grafana-manage.png b/docs/images/grafana-manage.png new file mode 100644 index 0000000..9fcd726 Binary files /dev/null and b/docs/images/grafana-manage.png differ diff --git a/docs/images/grafana-zcashd-dashboard.png b/docs/images/grafana-zcashd-dashboard.png new file mode 100644 index 0000000..c882af1 Binary files /dev/null and b/docs/images/grafana-zcashd-dashboard.png differ