From 72912fabe6c83ca747636243c6181266d54b1438 Mon Sep 17 00:00:00 2001 From: Andrew Camilleri Date: Sun, 16 Sep 2018 11:18:44 +0200 Subject: [PATCH] more work on traefik --- Production-NoReverseProxy/README.md | 2 +- Production-Traefik/Production.png | Bin 0 -> 54471 bytes Production-Traefik/README.md | 73 ++++++++++++++++++ Production-Traefik/traefik.toml | 35 +++++++++ build-pregen.ps1 | 1 + build-pregen.sh | 1 + build.ps1 | 2 +- build.sh | 2 +- .../docker-fragments/btcpayserver-nginx.yml | 15 ++++ .../docker-fragments/btcpayserver.yml | 31 +------- .../docker-fragments/nbxplorer.yml | 17 ++++ .../docker-fragments/postgres.yml | 11 +++ .../src/DockerComposition.cs | 9 --- docker-compose-generator/src/Program.cs | 23 +++--- 14 files changed, 170 insertions(+), 52 deletions(-) create mode 100644 Production-Traefik/Production.png create mode 100644 Production-Traefik/README.md create mode 100644 Production-Traefik/traefik.toml create mode 100644 docker-compose-generator/docker-fragments/btcpayserver-nginx.yml create mode 100644 docker-compose-generator/docker-fragments/nbxplorer.yml create mode 100644 docker-compose-generator/docker-fragments/postgres.yml diff --git a/Production-NoReverseProxy/README.md b/Production-NoReverseProxy/README.md index 25de599..eb2ec15 100644 --- a/Production-NoReverseProxy/README.md +++ b/Production-NoReverseProxy/README.md @@ -1,6 +1,6 @@ # About those pre-generated docker-compose -All `docker-compose` files in this folder are generated by running the [build-pregen.sh](build-pregen.sh) (or [build-pregen.ps1](build-pregen.ps1)) script from the fragments located in [docker-compose-generator/docker-fragments](docker-compose-generator/docker-fragments). +All `docker-compose` files in [Production](Production), [Production-NoReverseProxy](Production-NoReverseProxy) and [Production-Traefik](Production-Traefik) are generated by running the [build-pregen.sh](build-pregen.sh) (or [build-pregen.ps1](build-pregen.ps1)) script from the fragments located in [docker-compose-generator/docker-fragments](docker-compose-generator/docker-fragments). The pre-generated `docker-compose` files only cover `btc`, `ltc`, `clightning` without reverse proxy. diff --git a/Production-Traefik/Production.png b/Production-Traefik/Production.png new file mode 100644 index 0000000000000000000000000000000000000000..6a27ef0f07c2bc17ce1637587bc6d0adbee441cc GIT binary patch literal 54471 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 literal 0 HcmV?d00001 diff --git a/Production-Traefik/README.md b/Production-Traefik/README.md new file mode 100644 index 0000000..2ef4dc2 --- /dev/null +++ b/Production-Traefik/README.md @@ -0,0 +1,73 @@ +# About those docker-compose + +All `docker-compose` files in [Production](Production), [Production-NoReverseProxy](Production-NoReverseProxy) and [Production-Traefik](Production-Traefik) are generated by running the [build-pregen.sh](build-pregen.sh) (or [build-pregen.ps1](build-pregen.ps1)) script from the fragments located in [docker-compose-generator/docker-fragments](docker-compose-generator/docker-fragments). + +The pre-generated `docker-compose` files only cover `btc`, `ltc`, `clightning` with `traefik`. + +--- + +We strongly advise you to not use the pre-generated docker-compose of this folder, they are deprecated and kept only for backward compatibility. +Instead use the [build.sh](../build.sh) as documented in (README)(../Readme.md) to generate a docker-compose which fit your needs. + +--- + +The `docker-compose` can be used for production purpose. + +It is composed of: + +1. One full node per supported cryptocurrency (bitcoind/litecoind) +2. A lightweight block explorer ([NBxplorer](https://github.com/dgarage/NBXplorer)) +3. A [BTCPay Server](https://github.com/btcpayserver/btcpayserver) +4. A database (Postgres) +5. A reverse proxy (Traefik) xontainer that also handles SSL certificate renewal + +![Architecture](Production.png) + +[The Deploy on Azure Button](https://github.com/btcpayserver/btcpayserver-azure) is using this `docker-compose` under the hood on an Ubuntu machine. You can use it on any docker supporting host. + +The relevant environment variables are: + +* `NBITCOIN_NETWORK`: The blockchain identifier used by NBitcoin (eg., `regtest`, `testnet`, `mainnet`) +* `BTCPAY_HOST`: The external url used to access the NGINX server from internet. This domain name must point to this machine for Let's Encrypt to create your certificate. (typically with a CNAME or A record) +* `BTCPAY_ROOTPATH`: The root path directory where BTCPay is accessed, more information below. (default: /) +* `LETSENCRYPT_EMAIL`: The email Let's Encrypt will use to notify you about certificate expiration. +* `LIGHTNING_ALIAS`: Optional, if using the integrated lightning feature, customize the alias of your nodes +* `BTCPAY_SSHKEYFILE`: Optional, SSH private key that BTCPay can use to connect to this VM's SSH server (You need to copy the key file on BTCPay's datadir volume) +* `BTCPAY_SSHTRUSTEDFINGERPRINTS`: Optional, BTCPay will ensure that it is connecting to the expected SSH server by checking the host public's key against those fingerprints + +If `BTCPAY_HOST` is `btcpay.example.com` and `BTCPAY_ROOTPATH` is `/btcpay`, then you can access the site via `https://btcpay.example.com/btcpay` + +Use `docker-compose.btc-ltc.yml` for bitcoin and litecoin support, or `docker-compose.btc.yml` for only bitcoin. + +Any unset or empty environment variable will be set for a `regtest` deployment. + +The ports mapped on the host are: + +1. `80` for Let's encrypt +2. `443` for the website +3. `9735` for the bitcoin lightning network node (if used) +4. `9736` for the litecoin lightning network node (if used) + +Example for running on `mainnet`: + +For linux: + +``` +docker-compose up \ + -e "NBITCOIN_NETWORK=mainnet" \ + -e "BTCPAY_HOST=btcpay.example.com" \ + -e "LETSENCRYPT_EMAIL=me@example.com" +``` + +For powershell: + +``` +docker-compose up ` + -e "NBITCOIN_NETWORK=mainnet" ` + -e "BTCPAY_HOST=btcpay.example.com" ` + -e "LETSENCRYPT_EMAIL=me@example.com" +``` + +See also [The guide for docker noobs](../README.md#fornoobs). + +Make sure the domain `btcpay.example.com` point to your server and that port `80` and `443` are open. \ No newline at end of file diff --git a/Production-Traefik/traefik.toml b/Production-Traefik/traefik.toml new file mode 100644 index 0000000..e54e954 --- /dev/null +++ b/Production-Traefik/traefik.toml @@ -0,0 +1,35 @@ +defaultEntryPoints = ["https","http"] + +logLevel = "ERROR" + +[entryPoints] + useXForwardedFor = true + [entryPoints.http] + address = ":80" + [entryPoints.http.redirect] + entryPoint = "https" + [entryPoints.https] + address = ":443" + [entryPoints.https.tls] + +[retry] + +[docker] +endpoint = "unix:///var/run/docker.sock" +watch = true +exposedByDefault = false + +[acme] +storage = "acme.json" +entryPoint = "https" +onHostRule = true +[acme.httpChallenge] +entryPoint = "http" + +[traefikLog] + filePath = "/traefik_logs/traefik.log" + format = "json" + +[accessLog] + filePath = "/traefik_logs/access.log" + format = "json" diff --git a/build-pregen.ps1 b/build-pregen.ps1 index b8faf78..0c1ce52 100755 --- a/build-pregen.ps1 +++ b/build-pregen.ps1 @@ -3,5 +3,6 @@ docker pull btcpayserver/docker-compose-generator docker run -v "$(Get-Location)\Production:/app/Production" ` -v "$(Get-Location)\Production-NoReverseProxy:/app/Production-NoReverseProxy" ` + -v "$(Get-Location)\Production-Traefik:/app/Production-Traefik" ` -v "$(Get-Location)\docker-compose-generator\docker-fragments:/app/docker-fragments" ` --rm btcpayserver/docker-compose-generator pregen \ No newline at end of file diff --git a/build-pregen.sh b/build-pregen.sh index 27fe54c..f430474 100755 --- a/build-pregen.sh +++ b/build-pregen.sh @@ -4,5 +4,6 @@ docker pull btcpayserver/docker-compose-generator docker run -v "$(pwd)/Production:/app/Production" \ -v "$(pwd)/Production-NoReverseProxy:/app/Production-NoReverseProxy" \ + -v "$(pwd)/Production-Traefik:/app/Production-Traefik" \ -v "$(pwd)/docker-compose-generator/docker-fragments:/app/docker-fragments" \ --rm btcpayserver/docker-compose-generator pregen diff --git a/build.ps1 b/build.ps1 index 2eb4277..23ddca3 100755 --- a/build.ps1 +++ b/build.ps1 @@ -23,5 +23,5 @@ If ($BTCPAYGEN_REVERSEPROXY -eq "nginx") { } If ($BTCPAYGEN_REVERSEPROXY -eq "traefik") { - Copy-Item ".\Production\traefik.toml" -Destination ".\Generated" + Copy-Item ".\Production-Traefik\traefik.toml" -Destination ".\Generated" } diff --git a/build.sh b/build.sh index bc66030..d86749e 100755 --- a/build.sh +++ b/build.sh @@ -24,7 +24,7 @@ if [ "$BTCPAYGEN_REVERSEPROXY" == "nginx" ]; then fi if [ "$BTCPAYGEN_REVERSEPROXY" == "traefik" ]; then - cp Production/traefik.toml Generated/traefik.toml + cp Production-Traefik/traefik.toml Generated/traefik.toml fi diff --git a/docker-compose-generator/docker-fragments/btcpayserver-nginx.yml b/docker-compose-generator/docker-fragments/btcpayserver-nginx.yml new file mode 100644 index 0000000..366353a --- /dev/null +++ b/docker-compose-generator/docker-fragments/btcpayserver-nginx.yml @@ -0,0 +1,15 @@ +version: "3" + +services: + + btcpayserver: + environment: + # NGINX settings + VIRTUAL_NETWORK: nginx-proxy + VIRTUAL_PORT: 49392 + VIRTUAL_HOST: ${BTCPAY_HOST} + SSL_POLICY: Mozilla-Modern + + # Let's encrypt settings + LETSENCRYPT_HOST: ${BTCPAY_HOST} + LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL:-} \ No newline at end of file diff --git a/docker-compose-generator/docker-fragments/btcpayserver.yml b/docker-compose-generator/docker-fragments/btcpayserver.yml index 2cf8a8c..7425cc5 100644 --- a/docker-compose-generator/docker-fragments/btcpayserver.yml +++ b/docker-compose-generator/docker-fragments/btcpayserver.yml @@ -16,16 +16,6 @@ services: BTCPAY_ROOTPATH: ${BTCPAY_ROOTPATH:-/} BTCPAY_SSHTRUSTEDFINGERPRINTS: ${BTCPAY_SSHTRUSTEDFINGERPRINTS} BTCPAY_SSHKEYFILE: ${BTCPAY_SSHKEYFILE} - - # NGINX settings - VIRTUAL_NETWORK: nginx-proxy - VIRTUAL_PORT: 49392 - VIRTUAL_HOST: ${BTCPAY_HOST} - SSL_POLICY: Mozilla-Modern - - # Let's encrypt settings - LETSENCRYPT_HOST: ${BTCPAY_HOST} - LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL:-} links: - nbxplorer @@ -34,24 +24,5 @@ services: - "btcpay_datadir:/datadir" - "nbxplorer_datadir:/root/.nbxplorer" - nbxplorer: - restart: unless-stopped - image: nicolasdorier/nbxplorer:1.0.2.31 - expose: - - "32838" - environment: - NBXPLORER_NETWORK: ${NBITCOIN_NETWORK:-regtest} - NBXPLORER_BIND: 0.0.0.0:32838 - volumes: - - "nbxplorer_datadir:/datadir" - - postgres: - restart: unless-stopped - image: postgres:9.6.5 - volumes: - - "postgres_datadir:/var/lib/postgresql/data" - volumes: - postgres_datadir: - btcpay_datadir: - nbxplorer_datadir: \ No newline at end of file + btcpay_datadir: \ No newline at end of file diff --git a/docker-compose-generator/docker-fragments/nbxplorer.yml b/docker-compose-generator/docker-fragments/nbxplorer.yml new file mode 100644 index 0000000..4edc651 --- /dev/null +++ b/docker-compose-generator/docker-fragments/nbxplorer.yml @@ -0,0 +1,17 @@ +version: "3" + +services: + + nbxplorer: + restart: unless-stopped + image: nicolasdorier/nbxplorer:1.0.2.31 + expose: + - "32838" + environment: + NBXPLORER_NETWORK: ${NBITCOIN_NETWORK:-regtest} + NBXPLORER_BIND: 0.0.0.0:32838 + volumes: + - "nbxplorer_datadir:/datadir" + +volumes: + nbxplorer_datadir: \ No newline at end of file diff --git a/docker-compose-generator/docker-fragments/postgres.yml b/docker-compose-generator/docker-fragments/postgres.yml new file mode 100644 index 0000000..d558564 --- /dev/null +++ b/docker-compose-generator/docker-fragments/postgres.yml @@ -0,0 +1,11 @@ +version: "3" + +services: + postgres: + restart: unless-stopped + image: postgres:9.6.5 + volumes: + - "postgres_datadir:/var/lib/postgresql/data" + +volumes: + postgres_datadir: \ No newline at end of file diff --git a/docker-compose-generator/src/DockerComposition.cs b/docker-compose-generator/src/DockerComposition.cs index 65f4256..b9c8f9d 100644 --- a/docker-compose-generator/src/DockerComposition.cs +++ b/docker-compose-generator/src/DockerComposition.cs @@ -42,15 +42,6 @@ namespace DockerGenerator composition.SelectedProxy = (Environment.GetEnvironmentVariable("BTCPAYGEN_REVERSEPROXY") ?? "").ToLowerInvariant(); composition.SelectedLN = (Environment.GetEnvironmentVariable("BTCPAYGEN_LIGHTNING") ?? "").ToLowerInvariant(); composition.AdditionalFragments = (Environment.GetEnvironmentVariable("BTCPAYGEN_ADDITIONAL_FRAGMENTS") ?? "").ToLowerInvariant().Split(';').Where(t => !string.IsNullOrWhiteSpace(t)).ToArray(); - if (composition.SelectedProxy == "traefik" && !composition.AdditionalFragments.Contains("traefik-labels")) - { - var additionalFragments = new List(); - additionalFragments.AddRange(composition.AdditionalFragments); - additionalFragments.Add("traefik-labels"); - - composition.AdditionalFragments = additionalFragments.ToArray(); - } - return composition; } } diff --git a/docker-compose-generator/src/Program.cs b/docker-compose-generator/src/Program.cs index 07fbb35..a62987f 100644 --- a/docker-compose-generator/src/Program.cs +++ b/docker-compose-generator/src/Program.cs @@ -8,18 +8,21 @@ namespace DockerGenerator { class Program { - static void Main(string[] args) { var root = Environment.GetEnvironmentVariable("INSIDE_CONTAINER") == "1" ? FindRoot("app") : Path.GetFullPath(Path.Combine(FindRoot("docker-compose-generator"), "..")); - + + Dictionary ProxyMapping = new Dictionary() + { + {"nginx", Path.GetFullPath(Path.Combine(root, "Production"))}, + {"no-reverseproxy", Path.GetFullPath(Path.Combine(root, "Production-NoReverseProxy"))}, + {"traefik", Path.GetFullPath(Path.Combine(root, "Production-Traefik"))} + }; if(args.Any(a => a == "pregen")) { - var productionLocation = Path.GetFullPath(Path.Combine(root, "Production")); - var testLocation = Path.GetFullPath(Path.Combine(root, "Production-NoReverseProxy")); - foreach(var proxy in new[] { "nginx", "no-reverseproxy", "traefik" }) + foreach(var proxy in ProxyMapping.Keys) { foreach(var lightning in new[] { "clightning", "" }) { @@ -40,11 +43,7 @@ namespace DockerGenerator composition.SelectedCryptos.Add(ltc); composition.SelectedLN = lightning; composition.SelectedProxy = proxy; - if (composition.SelectedProxy == "traefik") - { - composition.AdditionalFragments = new []{"traefik-labels"}; - } - new Program().Run(composition, name, new string[] {"nginx", "traefik"}.Contains(proxy)? productionLocation : testLocation); + new Program().Run(composition, name, ProxyMapping[proxy]); } } } @@ -76,15 +75,19 @@ namespace DockerGenerator case "nginx": fragments.Add("nginx"); + fragments.Add("btcpayserver-nginx"); break; case "traefik": fragments.Add("traefik"); + fragments.Add("traefik-labels"); break; case "no-reverseproxy": fragments.Add("btcpayserver-noreverseproxy"); break; } fragments.Add("btcpayserver"); + fragments.Add("nbxplorer"); + fragments.Add("postgres"); foreach(var crypto in CryptoDefinition.GetDefinitions()) { if(!composition.SelectedCryptos.Contains(crypto.Crypto))