From b198537eb7cd255a55f8d92ae2bbeccb8c25bb08 Mon Sep 17 00:00:00 2001
From: librelois <c@elo.tf>
Date: Wed, 1 Jun 2022 21:56:55 +0200
Subject: [PATCH] chore(doc): rework README & doc architecture

---
 README.md                                     | 142 ++++++------------
 docker-compose.yml                            |  16 +-
 docker/compose/gdem-local2.docker-compose.yml |  61 --------
 docker/compose/gdev-mirror.docker-compose.yml |  28 ++--
 .../compose/gdev-validator.docker-compose.yml |  31 ++--
 .../compose/hydra-indexer.docker-compose.yml  |  71 ---------
 .../compose/live-template.docker-compose.yml  |  63 --------
 docs/user/autocompletion.md                   |  32 ++++
 docs/user/mirror.md                           |  60 ++++++++
 9 files changed, 188 insertions(+), 316 deletions(-)
 delete mode 100644 docker/compose/gdem-local2.docker-compose.yml
 delete mode 100644 docker/compose/hydra-indexer.docker-compose.yml
 create mode 100644 docs/user/autocompletion.md
 create mode 100644 docs/user/mirror.md

diff --git a/README.md b/README.md
index d4b8a89ce..9bc153f39 100644
--- a/README.md
+++ b/README.md
@@ -2,119 +2,108 @@
 
 A rewriting of duniter based on [Substrate](https://www.substrate.io/) framework.
 
-## Usage
+duniter-v2s is under active development, only a test network called "ÄžDev" is deployed.
 
-### Docker
+## Use
 
-The easiest way to use duniter-v2s is to use the docker image.
+### Join ÄžDev network
 
-#### Releases images
+The easiest way is to use the docker image.
 
-For the moment, duniter-v2s does not have a first release yet.
+Minimal command to deploy a **temporary** mirror peer:
 
-#### Test images
+```docker
+docker run -it -p9944:9944 -e DUNITER_CHAIN_NAME=gdev duniter/duniter-v2s:v0.1.0 --tmp --execution=Wasm
+```
 
-At each commit on master, an image with the tag `debug-sha-********` is published, where `********`
-corresponds to the first 8 hash characters of the commit.
+To go further, read [How to deploy a permanent mirror node on ÄžDev network](./docs/user/mirror.md).
 
-Usage:
+### Create your local blockchain
+
+It can be useful to deploy your local blockchain, for instance to have a controled environement
+to develop/test an application that interact with the blockchain.
 
 ```docker
-docker run -it -p9944:9944 --name duniter-v2s duniter/duniter-v2s:debug-sha-b836f1a6
+docker run -it -p9944:9944 duniter/duniter-v2s:v0.1.0 --tmp
 ```
 
-Then open `https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944` in a browser.
+Or use the `docker-compose.yml` at the root of this repository.
 
-### Docker compose
+#### Control when your local blockchain should produce blocks
 
-This repository contains a docker-compose file at the root of the repository, it is configured to
-be able to launch a development node on the ÄŸdev currency (single-node currency).
+By default, your local blockchain produce a new block every 6 seconds, which is not practical in some cases.
 
-Other docker-compose files are suggested in the `docker/compose` folder:
+You can decide when to produce blocks with the cli option `--sealing`, , there are 2 possible modes:
 
-- `gtest-local2.docker-compose.yml`: Configured to launch 2 validators on ÄŸdem currency.
+* `--sealing=instant`: produce a block immediately upon receiving a transaction into the transaction pool
+* `--sealing=manual`: produce a block upon receiving an RPC request (method `engine_createBlock`).
 
-## Setup
+### Autocompletion
 
-First, complete the [basic setup instructions](./docs/dev/setup.md).
+See [autocompletion](./docs/user/autocompletion.md).
 
-## Build
+## Test
 
-NOTE: You must first follow the instructions in the [Setup] section (#setup).
+### Test a specific commit
 
-Use the following command to build the node without launching it:
+At each commit on master, an image with the tag `debug-sha-********` is published, where `********`
+corresponds to the first 8 hash characters of the commit.
 
-```sh
-cargo build
+Usage:
+
+```docker
+docker run -it -p9944:9944 --name duniter-v2s duniter/duniter-v2s:debug-sha-b836f1a6
 ```
 
-## Run
+Then open `https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944` in a browser.
 
-Use Rust's native `cargo` command to build and launch the node:
+Enable detailed logging:
 
-```sh
-cargo run -- --dev --tmp
+```docker
+docker run -it -p9944:9944 --name duniter-v2s \
+  -e RUST_LOG=debug \
+  -e RUST_BACKTRACE=1 \
+  -lruntime=debug \
+  duniter/duniter-v2s:debug-sha-b836f1a6
 ```
 
 ## Contribute
 
 Before any contribution, please read carefully the [CONTRIBUTING](./CONTRIBUTING.md) file and our [git conventions](./docs/dev/git-conventions.md).
 
-## Embedded Docs
-
-Once the project has been built, the following command can be used to explore all parameters and
-subcommands:
-
-```sh
-./target/release/duniter -h
-```
-
-### Autocompletion
+### Setup your dev environment
 
-One can generate autocompletion for its favorite shell using the following option:
-
-```sh
-cargo run --release -- completion --generator <GENERATOR>
-```
+First, complete the [basic setup instructions](./docs/dev/setup.md).
 
-Where `GENERATOR` can be any of `bash`, `elvish`, `fish`, `powershell` and `zsh`.
+### Build
 
-#### Bash
+NOTE: You must first follow the instructions in the [Setup] section (#setup).
 
-First, get the completion file in a known place:
+Use the following command to build the node without launching it:
 
 ```sh
-mkdir -p ~/.local/share/duniter
-cargo run --release -- completion --generator bash > ~/.local/share/duniter/completion.bash
+cargo build
 ```
 
-You can now manually source the file when needed:
+### Run
 
-```sh
-source ~/.local/share/duniter/completion.bash
-```
-
-Or you can automatically source it at `bash` startup by adding this to your `~/.bashrc` file:
+Use Rust's native `cargo` command to build and launch the node:
 
 ```sh
-[[ -f $HOME/.local/share/duniter/completion.bash ]] && source $HOME/.local/share/duniter/completion.bash
+cargo run -- --dev --tmp
 ```
 
-You can now enjoy semantic completion of the `./target/release/duniter` command using `<Tab>` key.
+This will deploy a local blockchain with test accounts (Alice, Bob, etc) in the genesis.
 
 ## Single-Node Development Chain
 
 This command will start the single-node development chain with persistent state:
 
 ```bash
-./target/debug/duniter --dev
+./target/debug/duniter --dev --tmp
 ```
 
-Purge the development chain's state:
-
-```bash
-./target/debug/duniter purge-chain --dev
-```
+Then open `https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944` in a browser.
 
 Start the development chain with detailed logging:
 
@@ -122,11 +111,6 @@ Start the development chain with detailed logging:
 RUST_LOG=debug RUST_BACKTRACE=1 ./target/debug/duniter -lruntime=debug --dev
 ```
 
-## Connect with Polkadot-JS Apps Front-end
-
-Once the node template is running locally, you can connect it with **Polkadot-JS Apps** front-end
-to interact with your chain. [Click here](https://polkadot.js.org/apps/#/explorer?rpc=ws://localhost:9944) connecting the Apps to your local node template.
-
 ## Multi-Node Local Testnet
 
 If you want to see the multi-node consensus algorithm in action, refer to
@@ -258,29 +242,3 @@ A FRAME pallet is compromised of a number of blockchain primitives:
 - Errors: When a dispatchable fails, it returns an error.
 - Config: The `Config` configuration interface is used to define the types and parameters upon
   which a FRAME pallet depends.
-
-## Run in Docker
-
-First, install [Docker](https://docs.docker.com/get-docker/) and
-[Docker Compose](https://docs.docker.com/compose/install/).
-
-Then run the following command to start a single node development chain.
-
-```bash
-./scripts/docker_run.sh
-```
-
-This command will firstly compile your code, and then start a local development network. You can
-also replace the default command (`cargo build && ./target/debug/duniter --dev --ws-external`)
-by appending your own. A few useful ones are as follow.
-
-```bash
-# Run duniter node without re-compiling
-./scripts/docker_run.sh ./target/debug/duniter --dev --ws-external
-
-# Purge the local dev chain
-./scripts/docker_run.sh ./target/debug/duniter purge-chain --dev
-
-# Check whether the code is compilable
-./scripts/docker_run.sh cargo check
-```
diff --git a/docker-compose.yml b/docker-compose.yml
index 13f37f4d7..a2fce42a8 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -3,22 +3,22 @@ version: "3.5"
 services:
   duniter-v2s:
     container_name: duniter-v2s
-    image: duniter/duniter-v2s:debug-latest
+    image: duniter/duniter-v2s:v0.1.0
     ports:
       # telemetry
-      - "127.0.0.1:9615:9615"
+      - 9615:9615
       # rpc
-      - "127.0.0.1:9933:9933"
+      - 9933:9933
       # rpc-ws
-      - "127.0.0.1:9944:9944"
+      - 9944:9944
       # p2p
-      - "30333:30333"
+      - 30333:30333
     environment:
-      DUNITER_INSTANCE_NAME: "my_instance"
+      DUNITER_INSTANCE_NAME: "duniter_local"
       DUNITER_CHAIN_NAME: "dev"
       #DUNITER_DISABLE_PROMETHEUS: "false"
     volumes:
-      - data:/var/lib/duniter
+      - duniter-local-data:/var/lib/duniter
 
 volumes:
-  data:
+  duniter-local-data:
diff --git a/docker/compose/gdem-local2.docker-compose.yml b/docker/compose/gdem-local2.docker-compose.yml
deleted file mode 100644
index 14f5dc037..000000000
--- a/docker/compose/gdem-local2.docker-compose.yml
+++ /dev/null
@@ -1,61 +0,0 @@
-version: "3.5"
-
-services:
-  duniter-1:
-    container_name: duniter-1
-    image: duniter/duniter-v2s:local
-    ports:
-      # telemetry
-      - "127.0.0.1:9615:9615"
-      # rpc
-      - "127.0.0.1:9933:9933"
-      # rpc-ws
-      - "127.0.0.1:9944:9944"
-      # p2p
-      - "30333:30333"
-    environment:
-      DUNITER_INSTANCE_NAME: "my_instance"
-      DUNITER_CHAIN_NAME: "local"
-      #DUNITER_DISABLE_PROMETHEUS: "false"
-    command: ["--alice", "--node-key", "0000000000000000000000000000000000000000000000000000000000000001"]
-    volumes:
-      - data:/var/lib/lc-core
-    networks:
-      app_net:
-        ipv4_address: 172.16.238.10
-
-
-  duniter-2:
-    container_name: duniter-2
-    image: duniter/duniter-v2s:local
-    ports:
-      # telemetry
-      - "127.0.0.1:9616:9615"
-      # rpc
-      - "127.0.0.1:9934:9933"
-      # rpc-ws
-      - "127.0.0.1:9945:9944"
-      # p2p
-      - "30334:30333"
-    environment:
-      DUNITER_INSTANCE_NAME: "my_instance"
-      DUNITER_CHAIN_NAME: "local"
-      #DUNITER_DISABLE_PROMETHEUS: "false"
-    command: ["--bob", "--bootnodes", "/ip4/172.16.238.10/tcp/30333/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp"]
-    volumes:
-      - data2:/var/lib/lc-core
-    networks:
-      app_net:
-        ipv4_address: 172.16.238.11
-
-volumes:
-  data:
-  data2:
-
-networks:
-  app_net:
-    driver: bridge
-    ipam:
-      driver: default
-      config:
-        - subnet: 172.16.238.0/24
diff --git a/docker/compose/gdev-mirror.docker-compose.yml b/docker/compose/gdev-mirror.docker-compose.yml
index 0d353bec4..ed881978d 100644
--- a/docker/compose/gdev-mirror.docker-compose.yml
+++ b/docker/compose/gdev-mirror.docker-compose.yml
@@ -2,27 +2,35 @@ version: "3.4"
 
 services:
   duniter-rpc:
-    image: duniter/duniter-v2s:sha-142d4763
+    image: duniter/duniter-v2s:v0.1.0
     restart: unless-stopped
     ports:
-      - "9615:9615"
-      - "9933:9933"
-      - "9944:9944"
-      - "30333:30333"
+      # telemetry
+      - 127.0.0.1:9615:9615
+      # rpc
+      - 127.0.0.1:9933:9933
+      # rpc-ws
+      - 127.0.0.1:9944:9944
+      # p2p
+      - 30333:30333
     volumes:
-      - ./duniter-data/:/var/lib/duniter/
+      - ./node.key:/etc/duniter/node.key
+      - duniter-rpc-data:/var/lib/duniter/
     environment:
       - DUNITER_CHAIN_NAME=gdev
     command:
       - "--execution"
       - "Wasm"
       - "--node-key-file"
-      - "/var/lib/duniter/node-key"
+      - "/var/lib/duniter/node.key"
       - "--public-addr"
-      # SERVER_IP should be replaced by the public IP of your server
+      # SERVER_DOMAIN should be replaced by a domain name that point on your server
       #
       # The PEER_ID should be replaced by the output of this command:
-      # docker run --rm -it --entrypoint duniter -v $PWD/duniter-data/:/var/lib/duniter/  duniter/duniter-v2s:sha-142d4763 key generate-node-key --file /var/lib/duniter/node-key.txt
-      - "/ip4/SERVER_IP/tcp/30333/p2p/PEER_ID"
+      # docker run --rm -it --entrypoint duniter -v $PWD:/var/lib/duniter/  duniter/duniter-v2s:v0.1.0 key generate-node-key --file /var/lib/duniter/node.key
+      - "/dns/SERVER_DOMAIN/tcp/30333/p2p/PEER_ID"
       - "--rpc-cors"
       - "all"
+
+volumes:
+  duniter-rpc-data:
diff --git a/docker/compose/gdev-validator.docker-compose.yml b/docker/compose/gdev-validator.docker-compose.yml
index 49c83c8f5..e9f3b57bc 100644
--- a/docker/compose/gdev-validator.docker-compose.yml
+++ b/docker/compose/gdev-validator.docker-compose.yml
@@ -2,13 +2,17 @@ version: "3.4"
 
 services:
   duniter-rpc:
-    image: duniter/duniter-v2s:sha-142d4763
+    image: duniter/duniter-v2s:v0.1.0
     restart: unless-stopped
     ports:
-      - "9615:9615"
-      - "9933:9933"
-      - "9944:9944"
-      - "30333:30333"
+      # telemetry
+      - 127.0.0.1:9615:9615
+      # rpc
+      - 127.0.0.1:9933:9933
+      # rpc-ws
+      - 127.0.0.1:9944:9944
+      # p2p
+      - 30333:30333
     volumes:
       - ./duniter-rpc/:/var/lib/duniter/
     environment:
@@ -22,18 +26,23 @@ services:
       # SERVER_IP should be replaced by the public IP of your server
       #
       # The PEER_ID should be replaced by the output of this command:
-      # docker run --rm -it --entrypoint -v $PWD/duniter-rpc/:/var/lib/duniter/ duniter duniter/duniter-v2s:sha-142d4763 key generate-node-key --file /var/lib/duniter/node-key.txt
+      # docker run --rm -it --entrypoint -v $PWD/duniter-rpc/:/var/lib/duniter/ duniter duniter/duniter-v2s:v0.1.0 key generate-node-key --file /var/lib/duniter/node-key.txt
       - "/ip4/SERVER_IP/tcp/30333/p2p/PEER_ID"
       - "--rpc-cors"
       - "all"
 
   duniter-validator:
-    image: duniter/duniter-v2s:sha-142d4763
+    image: duniter/duniter-v2s:v0.1.0
     restart: unless-stopped
     ports:
-      - "9616:9615"
-      - "127.0.0.1:9945:9944"
-      - "30334:30333"
+      # telemetry
+      - 127.0.0.1:9616:9615
+      # rpc
+      - 127.0.0.1:9934:9933
+      # rpc-ws
+      - 127.0.0.1:9945:9944
+      # p2p
+      - 30334:30333
     volumes:
       - ./duniter-validator/:/var/lib/duniter/
     environment:
@@ -47,7 +56,7 @@ services:
       # SERVER_IP should be replaced by the public IP of your server
       #
       # The PEER_ID should be replaced by the output of this command:
-      # docker run --rm -it --entrypoint duniter -v $PWD/duniter-validator/:/var/lib/duniter/ duniter/duniter-v2s:sha-142d4763 key generate-node-key --file /var/lib/duniter/node-key.txt
+      # docker run --rm -it --entrypoint duniter -v $PWD/duniter-validator/:/var/lib/duniter/ duniter/duniter-v2s:v0.1.0 key generate-node-key --file /var/lib/duniter/node-key.txt
       - "/ip4/SERVER_IP/tcp/30334/p2p/PEER_ID"
       - "--rpc-methods=Unsafe"
       - "--validator"
diff --git a/docker/compose/hydra-indexer.docker-compose.yml b/docker/compose/hydra-indexer.docker-compose.yml
deleted file mode 100644
index 2770ba593..000000000
--- a/docker/compose/hydra-indexer.docker-compose.yml
+++ /dev/null
@@ -1,71 +0,0 @@
-version: "3.4"
-
-services:
-  db:
-    image: postgres:12
-    restart: always
-    volumes:
-      - /var/lib/postgresql/data
-    environment:
-      POSTGRES_USER: postgres
-      POSTGRES_PASSWORD: postgres
-
-  duniter-1:
-    image: duniter/duniter-v2s:debug-sha-b836f1a6
-    restart: unless-stopped
-    ports:
-      - "9944:9944"
-
-  indexer:
-    image: subsquid/hydra-indexer:5
-    restart: unless-stopped
-    environment:
-      - WORKERS_NUMBER=1
-      - DB_NAME=indexer
-      - DB_HOST=db
-      - DB_USER=postgres
-      - DB_PASS=postgres
-      - DB_PORT=5432
-      - REDIS_URI=redis://redis:6379/0
-      - FORCE_HEIGHT=true
-      - BLOCK_HEIGHT=0 # starting block height
-      - WS_PROVIDER_ENDPOINT_URI=ws://duniter-1:9944/
-    depends_on:
-      - db
-      - redis
-    command: >
-      sh -c "yarn db:bootstrap && yarn start:prod"
-
-  indexer-gateway:
-    image: subsquid/hydra-indexer-gateway:5
-    restart: unless-stopped
-    depends_on:
-      - redis
-      - db
-      - indexer-status-service
-      - indexer
-    ports:
-      - "4010:8080"
-    environment:
-      - DEV_MODE=true
-      - DB_NAME=indexer
-      - DB_HOST=db
-      - DB_USER=postgres
-      - DB_PASS=postgres
-      - DB_PORT=5432
-      - HYDRA_INDEXER_STATUS_SERVICE=http://indexer-status-service:8081/status
-
-  indexer-status-service:
-    image: subsquid/hydra-indexer-status-service:5
-    restart: unless-stopped
-    depends_on:
-      - redis
-    environment:
-      REDIS_URI: redis://redis:6379/0
-      PORT: 8081
-
-  redis:
-    image: redis:6.0-alpine
-    restart: always
-    ports:
-      - "6379"
diff --git a/docker/compose/live-template.docker-compose.yml b/docker/compose/live-template.docker-compose.yml
index 6d3e333c4..106456872 100644
--- a/docker/compose/live-template.docker-compose.yml
+++ b/docker/compose/live-template.docker-compose.yml
@@ -1,15 +1,6 @@
 version: "3.4"
 
 services:
-  db:
-    image: postgres:12
-    restart: always
-    volumes:
-      - /var/lib/postgresql/data
-    environment:
-      POSTGRES_USER: postgres
-      POSTGRES_PASSWORD: postgres
-
   duniter-rpc:
     image: duniter/duniter-v2s:DUNITER_IMAGE_TAG
     restart: unless-stopped
@@ -47,57 +38,3 @@ services:
       - "--validator"
       - "--rpc-cors"
       - "all"
-
-  indexer:
-    image: subsquid/hydra-indexer:5
-    restart: unless-stopped
-    environment:
-      - WORKERS_NUMBER=1
-      - DB_NAME=indexer
-      - DB_HOST=db
-      - DB_USER=postgres
-      - DB_PASS=postgres
-      - DB_PORT=5432
-      - REDIS_URI=redis://redis:6379/0
-      - FORCE_HEIGHT=true
-      - BLOCK_HEIGHT=0 # starting block height
-      - WS_PROVIDER_ENDPOINT_URI=ws://duniter-rpc:9944/
-    depends_on:
-      - db
-      - redis
-    command: >
-      sh -c "yarn db:bootstrap && yarn start:prod"
-
-  indexer-gateway:
-    image: subsquid/hydra-indexer-gateway:5
-    restart: unless-stopped
-    depends_on:
-      - redis
-      - db
-      - indexer-status-service
-      - indexer
-    ports:
-      - "4010:8080"
-    environment:
-      - DEV_MODE=true
-      - DB_NAME=indexer
-      - DB_HOST=db
-      - DB_USER=postgres
-      - DB_PASS=postgres
-      - DB_PORT=5432
-      - HYDRA_INDEXER_STATUS_SERVICE=http://indexer-status-service:8081/status
-
-  indexer-status-service:
-    image: subsquid/hydra-indexer-status-service:5
-    restart: unless-stopped
-    depends_on:
-      - redis
-    environment:
-      REDIS_URI: redis://redis:6379/0
-      PORT: 8081
-
-  redis:
-    image: redis:6.0-alpine
-    restart: always
-    ports:
-      - "6379"
diff --git a/docs/user/autocompletion.md b/docs/user/autocompletion.md
new file mode 100644
index 000000000..ec524d426
--- /dev/null
+++ b/docs/user/autocompletion.md
@@ -0,0 +1,32 @@
+# Autocompletion
+
+One can generate autocompletion for its favorite shell using the following option:
+
+```sh
+cargo run --release -- completion --generator <GENERATOR>
+```
+
+Where `GENERATOR` can be any of `bash`, `elvish`, `fish`, `powershell` and `zsh`.
+
+## Bash
+
+First, get the completion file in a known place:
+
+```sh
+mkdir -p ~/.local/share/duniter
+cargo run --release -- completion --generator bash > ~/.local/share/duniter/completion.bash
+```
+
+You can now manually source the file when needed:
+
+```sh
+source ~/.local/share/duniter/completion.bash
+```
+
+Or you can automatically source it at `bash` startup by adding this to your `~/.bashrc` file:
+
+```sh
+[[ -f $HOME/.local/share/duniter/completion.bash ]] && source $HOME/.local/share/duniter/completion.bash
+```
+
+You can now enjoy semantic completion of the `./target/release/duniter` command using `<Tab>` key.
diff --git a/docs/user/mirror.md b/docs/user/mirror.md
new file mode 100644
index 000000000..5c82ea6cb
--- /dev/null
+++ b/docs/user/mirror.md
@@ -0,0 +1,60 @@
+# How to deploy a permanent mirror node on ÄžDev network
+
+## Publish a node
+
+### Duniter part
+- Add this docker-compose on your server :
+[docker/compose/gdev-mirror.docker-compose.yml](https://git.duniter.org/nodes/rust/duniter-v2s/-/blob/master/docker/compose/gdev-mirror.docker-compose.yml)
+- Edit lines 26: `"/dns/SERVER_DOMAIN/tcp/30333/p2p/PEER_ID"`
+  with your domain name an the PEER_ID you get using te command in comment.
+- If you have write access errors run in docker-compose.yml folder : `chmod o+rwX -R .`
+- `docker-compose up -d` to start your node
+### Reverse-proxy part (with Nginx)
+In `/etc/nginx/sites-enabled/gdev.YOUR_DOMAIN` put (you can probably do simpler) :
+```
+server {
+  server_name gdev.YOUR_DOMAIN.fr;
+
+  listen 443 ssl http2;
+  ssl_certificate /etc/nginx/ssl/YOUR_DOMAIN.cert;
+  ssl_certificate_key /etc/nginx/ssl/YOUR_DOMAIN.key;
+
+  root /nowhere;
+
+  add_header X-Frame-Options SAMEORIGIN;
+  add_header X-XSS-Protection "1; mode=block";
+  proxy_redirect off;
+  proxy_buffering off;
+  proxy_set_header Host $host;
+  proxy_set_header X-Real-IP $remote_addr;
+  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+  proxy_set_header X-Forwarded-Proto $scheme;
+  proxy_set_header X-Forwarded-Port $server_port;
+  proxy_read_timeout 90;
+
+  location /http {
+    proxy_pass http://localhost:9933;
+    proxy_http_version 1.1;
+  }
+  location /ws {
+    proxy_pass http://localhost:9944;
+
+    proxy_set_header Upgrade $http_upgrade;
+    proxy_set_header Connection "upgrade";
+    proxy_http_version 1.1;
+
+    proxy_read_timeout 1200s;
+    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+    proxy_set_header Host $host;
+  }
+}
+```
+and replace `YOUR_DOMAIN` by your domain each time.
+
+- [generate your ssl certificates](https://github.com/acmesh-official/acme.sh) with let's encrypt
+  if you don't already have a wildcard certificate.
+- `service nginx reload`
+
+Your node is now online as a mirror node. It's fully capable for wallet use.
+
+To go further, read [How to become a (black)smith](./smith.md)
-- 
GitLab