diff --git a/.gitignore b/.gitignore index 55194bb..11b954d 100644 --- a/.gitignore +++ b/.gitignore @@ -293,3 +293,4 @@ BTCPayServer/wwwroot/bundles/* !BTCPayServer/wwwroot/bundles/.gitignore Production/.env +.vscode/ diff --git a/Production/docker-compose.btc-ltc.yml b/Production/docker-compose.btc-ltc.yml index fc450c2..56acdec 100644 --- a/Production/docker-compose.btc-ltc.yml +++ b/Production/docker-compose.btc-ltc.yml @@ -1,107 +1,98 @@ -version: "3" - -# This run BTCPay behind NGINX reverse proxy configured with Let's Encrypt - +version: 3 services: nginx: restart: always image: nginx container_name: nginx ports: - - "80:80" - - "443:443" + - "80:80" + - "443:443" volumes: - - "nginx_conf:/etc/nginx/conf.d" - - "nginx_vhost:/etc/nginx/vhost.d" - - "nginx_html:/usr/share/nginx/html" - - "nginx_certs:/etc/nginx/certs:ro" + - "nginx_conf:/etc/nginx/conf.d" + - "nginx_vhost:/etc/nginx/vhost.d" + - "nginx_html:/usr/share/nginx/html" + - "nginx_certs:/etc/nginx/certs:ro" links: - - btcpayserver - + - btcpayserver nginx-gen: restart: always image: jwilder/docker-gen container_name: nginx-gen volumes: - - "/var/run/docker.sock:/tmp/docker.sock:ro" - - "./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro" - - "nginx_conf:/etc/nginx/conf.d" - - "nginx_vhost:/etc/nginx/vhost.d" - - "nginx_html:/usr/share/nginx/html" - - "nginx_certs:/etc/nginx/certs:ro" + - "/var/run/docker.sock:/tmp/docker.sock:ro" + - "./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro" + - "nginx_conf:/etc/nginx/conf.d" + - "nginx_vhost:/etc/nginx/vhost.d" + - "nginx_html:/usr/share/nginx/html" + - "nginx_certs:/etc/nginx/certs:ro" entrypoint: /usr/local/bin/docker-gen -notify-sighup nginx -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf links: - - nginx - + - nginx letsencrypt-nginx-proxy-companion: restart: always image: jrcs/letsencrypt-nginx-proxy-companion container_name: letsencrypt-nginx-proxy-companion volumes: - - "/var/run/docker.sock:/var/run/docker.sock:ro" - - "nginx_conf:/etc/nginx/conf.d" - - "nginx_vhost:/etc/nginx/vhost.d" - - "nginx_html:/usr/share/nginx/html" - - "nginx_certs:/etc/nginx/certs:rw" + - "/var/run/docker.sock:/var/run/docker.sock:ro" + - "nginx_conf:/etc/nginx/conf.d" + - "nginx_vhost:/etc/nginx/vhost.d" + - "nginx_html:/usr/share/nginx/html" + - "nginx_certs:/etc/nginx/certs:rw" environment: NGINX_DOCKER_GEN_CONTAINER: "nginx-gen" NGINX_PROXY_CONTAINER: "nginx" ACME_CA_URI: ${ACME_CA_URI:-https://acme-staging.api.letsencrypt.org/directory} links: - - nginx - + - nginx btcpayserver: restart: always image: nicolasdorier/btcpayserver:1.0.1.53 expose: - - "49392" + - "49392" environment: - # BTCPay settings BTCPAY_POSTGRES: User ID=postgres;Host=postgres;Port=5432;Database=btcpayserver${NBITCOIN_NETWORK:-regtest} BTCPAY_NETWORK: ${NBITCOIN_NETWORK:-regtest} - BTCPAY_CHAINS: "btc,ltc" - BTCPAY_BTCEXPLORERURL: http://nbxplorer:32838/ - BTCPAY_LTCEXPLORERURL: http://nbxplorer:32838/ BTCPAY_BIND: 0.0.0.0:49392 BTCPAY_EXTERNALURL: https://${BTCPAY_HOST}/ - - # NGINX settings VIRTUAL_NETWORK: nginx-proxy VIRTUAL_PORT: 49392 VIRTUAL_HOST: ${BTCPAY_HOST} - - # Let's encrypt settings LETSENCRYPT_HOST: ${BTCPAY_HOST} LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL:-yourname@example.com} - + BTCPAY_CHAINS: "btc,ltc" + BTCPAY_BTCEXPLORERURL: http://nbxplorer:32838/ + BTCPAY_LTCEXPLORERURL: http://nbxplorer:32838/ links: - - nbxplorer - - postgres + - nbxplorer + - postgres volumes: - - "btcpay_datadir:/datadir" - - "nbxplorer_datadir:/root/.nbxplorer" - + - "btcpay_datadir:/datadir" + - "nbxplorer_datadir:/root/.nbxplorer" nbxplorer: restart: always image: nicolasdorier/nbxplorer:1.0.1.23 - expose: - - "32838" + expose: + - "32838" environment: NBXPLORER_NETWORK: ${NBITCOIN_NETWORK:-regtest} - NBXPLORER_CHAINS: "btc,ltc" + NBXPLORER_BIND: 0.0.0.0:32838 + BTCPAY_CHAINS: "btc,ltc" NBXPLORER_BTCRPCURL: http://bitcoind:43782/ NBXPLORER_BTCNODEENDPOINT: bitcoind:39388 NBXPLORER_LTCRPCURL: http://litecoind:43782/ NBXPLORER_LTCNODEENDPOINT: litecoind:39388 - NBXPLORER_BIND: 0.0.0.0:32838 - links: - - bitcoind - - litecoind volumes: - - "nbxplorer_datadir:/datadir" - - "bitcoin_datadir:/root/.bitcoin" - - "litecoin_datadir:/root/.litecoin" - + - "nbxplorer_datadir:/datadir" + - "bitcoin_datadir:/root/.bitcoin" + - "litecoin_datadir:/root/.litecoin" + links: + - bitcoind + - litecoind + postgres: + restart: always + image: postgres:9.6.5 + volumes: + - "postgres_datadir:/var/lib/postgresql/data" bitcoind: restart: always container_name: btcpayserver_bitcoind @@ -113,17 +104,10 @@ services: port=39388 whitelist=0.0.0.0/0 expose: - - "43782" - - "39388" + - "43782" + - "39388" volumes: - - "bitcoin_datadir:/data" - - postgres: - restart: always - image: postgres:9.6.5 - volumes: - - "postgres_datadir:/var/lib/postgresql/data" - + - "bitcoin_datadir:/data" litecoind: restart: always container_name: btcpayserver_litecoind @@ -135,18 +119,17 @@ services: port=39388 whitelist=0.0.0.0/0 expose: - - "43782" - - "39388" + - "43782" + - "39388" volumes: - - "litecoin_datadir:/data" - + - "litecoin_datadir:/data" volumes: - nginx_conf: - nginx_vhost: - nginx_html: - nginx_certs: - bitcoin_datadir: - litecoin_datadir: - postgres_datadir: - btcpay_datadir: - nbxplorer_datadir: \ No newline at end of file + nginx_conf: + nginx_vhost: + nginx_html: + nginx_certs: + postgres_datadir: + btcpay_datadir: + nbxplorer_datadir: + bitcoin_datadir: + litecoin_datadir: diff --git a/Production/docker-compose.btc.yml b/Production/docker-compose.btc.yml index 98b1666..5c42025 100644 --- a/Production/docker-compose.btc.yml +++ b/Production/docker-compose.btc.yml @@ -1,101 +1,93 @@ -version: "3" - -# This run BTCPay behind NGINX reverse proxy configured with Let's Encrypt -# Same as docker-compose.btc.yml keeping for not breaking legacy docker-azure users - +version: 3 services: nginx: restart: always image: nginx container_name: nginx ports: - - "80:80" - - "443:443" + - "80:80" + - "443:443" volumes: - - "nginx_conf:/etc/nginx/conf.d" - - "nginx_vhost:/etc/nginx/vhost.d" - - "nginx_html:/usr/share/nginx/html" - - "nginx_certs:/etc/nginx/certs:ro" + - "nginx_conf:/etc/nginx/conf.d" + - "nginx_vhost:/etc/nginx/vhost.d" + - "nginx_html:/usr/share/nginx/html" + - "nginx_certs:/etc/nginx/certs:ro" links: - - nbxplorer - + - btcpayserver nginx-gen: restart: always image: jwilder/docker-gen container_name: nginx-gen volumes: - - "/var/run/docker.sock:/tmp/docker.sock:ro" - - "./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro" - - "nginx_conf:/etc/nginx/conf.d" - - "nginx_vhost:/etc/nginx/vhost.d" - - "nginx_html:/usr/share/nginx/html" - - "nginx_certs:/etc/nginx/certs:ro" + - "/var/run/docker.sock:/tmp/docker.sock:ro" + - "./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro" + - "nginx_conf:/etc/nginx/conf.d" + - "nginx_vhost:/etc/nginx/vhost.d" + - "nginx_html:/usr/share/nginx/html" + - "nginx_certs:/etc/nginx/certs:ro" entrypoint: /usr/local/bin/docker-gen -notify-sighup nginx -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf links: - - nginx - + - nginx letsencrypt-nginx-proxy-companion: restart: always image: jrcs/letsencrypt-nginx-proxy-companion container_name: letsencrypt-nginx-proxy-companion volumes: - - "/var/run/docker.sock:/var/run/docker.sock:ro" - - "nginx_conf:/etc/nginx/conf.d" - - "nginx_vhost:/etc/nginx/vhost.d" - - "nginx_html:/usr/share/nginx/html" - - "nginx_certs:/etc/nginx/certs:rw" + - "/var/run/docker.sock:/var/run/docker.sock:ro" + - "nginx_conf:/etc/nginx/conf.d" + - "nginx_vhost:/etc/nginx/vhost.d" + - "nginx_html:/usr/share/nginx/html" + - "nginx_certs:/etc/nginx/certs:rw" environment: NGINX_DOCKER_GEN_CONTAINER: "nginx-gen" NGINX_PROXY_CONTAINER: "nginx" ACME_CA_URI: ${ACME_CA_URI:-https://acme-staging.api.letsencrypt.org/directory} links: - - nginx - + - nginx btcpayserver: restart: always image: nicolasdorier/btcpayserver:1.0.1.53 expose: - - "49392" + - "49392" environment: - # BTCPay settings BTCPAY_POSTGRES: User ID=postgres;Host=postgres;Port=5432;Database=btcpayserver${NBITCOIN_NETWORK:-regtest} BTCPAY_NETWORK: ${NBITCOIN_NETWORK:-regtest} - BTCPAY_BTCEXPLORERURL: http://nbxplorer:32838/ BTCPAY_BIND: 0.0.0.0:49392 BTCPAY_EXTERNALURL: https://${BTCPAY_HOST}/ - - # NGINX settings VIRTUAL_NETWORK: nginx-proxy VIRTUAL_PORT: 49392 VIRTUAL_HOST: ${BTCPAY_HOST} - - # Let's encrypt settings LETSENCRYPT_HOST: ${BTCPAY_HOST} LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL:-yourname@example.com} - + BTCPAY_CHAINS: "btc" + BTCPAY_BTCEXPLORERURL: http://nbxplorer:32838/ links: - - nbxplorer - - postgres + - nbxplorer + - postgres volumes: - - "btcpay_datadir:/datadir" - - "nbxplorer_datadir:/root/.nbxplorer" - + - "btcpay_datadir:/datadir" + - "nbxplorer_datadir:/root/.nbxplorer" nbxplorer: restart: always image: nicolasdorier/nbxplorer:1.0.1.23 - expose: - - "32838" + expose: + - "32838" environment: NBXPLORER_NETWORK: ${NBITCOIN_NETWORK:-regtest} + NBXPLORER_BIND: 0.0.0.0:32838 + BTCPAY_CHAINS: "btc" NBXPLORER_BTCRPCURL: http://bitcoind:43782/ NBXPLORER_BTCNODEENDPOINT: bitcoind:39388 - NBXPLORER_BIND: 0.0.0.0:32838 - links: - - bitcoind volumes: - - "nbxplorer_datadir:/datadir" - - "bitcoin_datadir:/root/.bitcoin" - + - "nbxplorer_datadir:/datadir" + - "bitcoin_datadir:/root/.bitcoin" + links: + - bitcoind + postgres: + restart: always + image: postgres:9.6.5 + volumes: + - "postgres_datadir:/var/lib/postgresql/data" bitcoind: restart: always container_name: btcpayserver_bitcoind @@ -107,23 +99,16 @@ services: port=39388 whitelist=0.0.0.0/0 expose: - - "43782" - - "39388" + - "43782" + - "39388" volumes: - - "bitcoin_datadir:/data" - - postgres: - restart: always - image: postgres:9.6.5 - volumes: - - "postgres_datadir:/var/lib/postgresql/data" - + - "bitcoin_datadir:/data" volumes: - nginx_conf: - nginx_vhost: - nginx_html: - nginx_certs: - bitcoin_datadir: - postgres_datadir: - btcpay_datadir: - nbxplorer_datadir: \ No newline at end of file + nginx_conf: + nginx_vhost: + nginx_html: + nginx_certs: + postgres_datadir: + btcpay_datadir: + nbxplorer_datadir: + bitcoin_datadir: diff --git a/Production/docker-compose.yml b/Production/docker-compose.yml index 98b1666..5c42025 100644 --- a/Production/docker-compose.yml +++ b/Production/docker-compose.yml @@ -1,101 +1,93 @@ -version: "3" - -# This run BTCPay behind NGINX reverse proxy configured with Let's Encrypt -# Same as docker-compose.btc.yml keeping for not breaking legacy docker-azure users - +version: 3 services: nginx: restart: always image: nginx container_name: nginx ports: - - "80:80" - - "443:443" + - "80:80" + - "443:443" volumes: - - "nginx_conf:/etc/nginx/conf.d" - - "nginx_vhost:/etc/nginx/vhost.d" - - "nginx_html:/usr/share/nginx/html" - - "nginx_certs:/etc/nginx/certs:ro" + - "nginx_conf:/etc/nginx/conf.d" + - "nginx_vhost:/etc/nginx/vhost.d" + - "nginx_html:/usr/share/nginx/html" + - "nginx_certs:/etc/nginx/certs:ro" links: - - nbxplorer - + - btcpayserver nginx-gen: restart: always image: jwilder/docker-gen container_name: nginx-gen volumes: - - "/var/run/docker.sock:/tmp/docker.sock:ro" - - "./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro" - - "nginx_conf:/etc/nginx/conf.d" - - "nginx_vhost:/etc/nginx/vhost.d" - - "nginx_html:/usr/share/nginx/html" - - "nginx_certs:/etc/nginx/certs:ro" + - "/var/run/docker.sock:/tmp/docker.sock:ro" + - "./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro" + - "nginx_conf:/etc/nginx/conf.d" + - "nginx_vhost:/etc/nginx/vhost.d" + - "nginx_html:/usr/share/nginx/html" + - "nginx_certs:/etc/nginx/certs:ro" entrypoint: /usr/local/bin/docker-gen -notify-sighup nginx -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf links: - - nginx - + - nginx letsencrypt-nginx-proxy-companion: restart: always image: jrcs/letsencrypt-nginx-proxy-companion container_name: letsencrypt-nginx-proxy-companion volumes: - - "/var/run/docker.sock:/var/run/docker.sock:ro" - - "nginx_conf:/etc/nginx/conf.d" - - "nginx_vhost:/etc/nginx/vhost.d" - - "nginx_html:/usr/share/nginx/html" - - "nginx_certs:/etc/nginx/certs:rw" + - "/var/run/docker.sock:/var/run/docker.sock:ro" + - "nginx_conf:/etc/nginx/conf.d" + - "nginx_vhost:/etc/nginx/vhost.d" + - "nginx_html:/usr/share/nginx/html" + - "nginx_certs:/etc/nginx/certs:rw" environment: NGINX_DOCKER_GEN_CONTAINER: "nginx-gen" NGINX_PROXY_CONTAINER: "nginx" ACME_CA_URI: ${ACME_CA_URI:-https://acme-staging.api.letsencrypt.org/directory} links: - - nginx - + - nginx btcpayserver: restart: always image: nicolasdorier/btcpayserver:1.0.1.53 expose: - - "49392" + - "49392" environment: - # BTCPay settings BTCPAY_POSTGRES: User ID=postgres;Host=postgres;Port=5432;Database=btcpayserver${NBITCOIN_NETWORK:-regtest} BTCPAY_NETWORK: ${NBITCOIN_NETWORK:-regtest} - BTCPAY_BTCEXPLORERURL: http://nbxplorer:32838/ BTCPAY_BIND: 0.0.0.0:49392 BTCPAY_EXTERNALURL: https://${BTCPAY_HOST}/ - - # NGINX settings VIRTUAL_NETWORK: nginx-proxy VIRTUAL_PORT: 49392 VIRTUAL_HOST: ${BTCPAY_HOST} - - # Let's encrypt settings LETSENCRYPT_HOST: ${BTCPAY_HOST} LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL:-yourname@example.com} - + BTCPAY_CHAINS: "btc" + BTCPAY_BTCEXPLORERURL: http://nbxplorer:32838/ links: - - nbxplorer - - postgres + - nbxplorer + - postgres volumes: - - "btcpay_datadir:/datadir" - - "nbxplorer_datadir:/root/.nbxplorer" - + - "btcpay_datadir:/datadir" + - "nbxplorer_datadir:/root/.nbxplorer" nbxplorer: restart: always image: nicolasdorier/nbxplorer:1.0.1.23 - expose: - - "32838" + expose: + - "32838" environment: NBXPLORER_NETWORK: ${NBITCOIN_NETWORK:-regtest} + NBXPLORER_BIND: 0.0.0.0:32838 + BTCPAY_CHAINS: "btc" NBXPLORER_BTCRPCURL: http://bitcoind:43782/ NBXPLORER_BTCNODEENDPOINT: bitcoind:39388 - NBXPLORER_BIND: 0.0.0.0:32838 - links: - - bitcoind volumes: - - "nbxplorer_datadir:/datadir" - - "bitcoin_datadir:/root/.bitcoin" - + - "nbxplorer_datadir:/datadir" + - "bitcoin_datadir:/root/.bitcoin" + links: + - bitcoind + postgres: + restart: always + image: postgres:9.6.5 + volumes: + - "postgres_datadir:/var/lib/postgresql/data" bitcoind: restart: always container_name: btcpayserver_bitcoind @@ -107,23 +99,16 @@ services: port=39388 whitelist=0.0.0.0/0 expose: - - "43782" - - "39388" + - "43782" + - "39388" volumes: - - "bitcoin_datadir:/data" - - postgres: - restart: always - image: postgres:9.6.5 - volumes: - - "postgres_datadir:/var/lib/postgresql/data" - + - "bitcoin_datadir:/data" volumes: - nginx_conf: - nginx_vhost: - nginx_html: - nginx_certs: - bitcoin_datadir: - postgres_datadir: - btcpay_datadir: - nbxplorer_datadir: \ No newline at end of file + nginx_conf: + nginx_vhost: + nginx_html: + nginx_certs: + postgres_datadir: + btcpay_datadir: + nbxplorer_datadir: + bitcoin_datadir: diff --git a/docker-compose-generator/docker-compose-generator.sln b/docker-compose-generator/docker-compose-generator.sln new file mode 100644 index 0000000..31202ff --- /dev/null +++ b/docker-compose-generator/docker-compose-generator.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "docker-compose-generator", "src/docker-compose-generator.csproj", "{0900AF35-48E8-46E2-85B3-BA3847EE0844}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0900AF35-48E8-46E2-85B3-BA3847EE0844}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0900AF35-48E8-46E2-85B3-BA3847EE0844}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0900AF35-48E8-46E2-85B3-BA3847EE0844}.Debug|x64.ActiveCfg = Debug|Any CPU + {0900AF35-48E8-46E2-85B3-BA3847EE0844}.Debug|x64.Build.0 = Debug|Any CPU + {0900AF35-48E8-46E2-85B3-BA3847EE0844}.Debug|x86.ActiveCfg = Debug|Any CPU + {0900AF35-48E8-46E2-85B3-BA3847EE0844}.Debug|x86.Build.0 = Debug|Any CPU + {0900AF35-48E8-46E2-85B3-BA3847EE0844}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0900AF35-48E8-46E2-85B3-BA3847EE0844}.Release|Any CPU.Build.0 = Release|Any CPU + {0900AF35-48E8-46E2-85B3-BA3847EE0844}.Release|x64.ActiveCfg = Release|Any CPU + {0900AF35-48E8-46E2-85B3-BA3847EE0844}.Release|x64.Build.0 = Release|Any CPU + {0900AF35-48E8-46E2-85B3-BA3847EE0844}.Release|x86.ActiveCfg = Release|Any CPU + {0900AF35-48E8-46E2-85B3-BA3847EE0844}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/docker-compose-generator/docker-fragments/bitcoin.yml b/docker-compose-generator/docker-fragments/bitcoin.yml new file mode 100644 index 0000000..8f1c2d1 --- /dev/null +++ b/docker-compose-generator/docker-fragments/bitcoin.yml @@ -0,0 +1,33 @@ +version: "3" + +services: + bitcoind: + restart: always + container_name: btcpayserver_bitcoind + image: nicolasdorier/docker-bitcoin:0.16.0 + environment: + BITCOIN_EXTRA_ARGS: | + rpcport=43782 + ${NBITCOIN_NETWORK:-regtest}=1 + port=39388 + whitelist=0.0.0.0/0 + expose: + - "43782" + - "39388" + volumes: + - "bitcoin_datadir:/data" + nbxplorer: + environment: + BTCPAY_CHAINS: "btc" + NBXPLORER_BTCRPCURL: http://bitcoind:43782/ + NBXPLORER_BTCNODEENDPOINT: bitcoind:39388 + links: + - bitcoind + volumes: + - "bitcoin_datadir:/root/.bitcoin" + btcpayserver: + environment: + BTCPAY_CHAINS: "btc" + BTCPAY_BTCEXPLORERURL: http://nbxplorer:32838/ +volumes: + bitcoin_datadir: \ No newline at end of file diff --git a/docker-compose-generator/docker-fragments/btcpayserver.yml b/docker-compose-generator/docker-fragments/btcpayserver.yml new file mode 100644 index 0000000..a1ba90a --- /dev/null +++ b/docker-compose-generator/docker-fragments/btcpayserver.yml @@ -0,0 +1,53 @@ +version: "3" + +services: + + btcpayserver: + restart: always + image: nicolasdorier/btcpayserver:1.0.1.53 + expose: + - "49392" + environment: + # BTCPay settings + BTCPAY_POSTGRES: User ID=postgres;Host=postgres;Port=5432;Database=btcpayserver${NBITCOIN_NETWORK:-regtest} + BTCPAY_NETWORK: ${NBITCOIN_NETWORK:-regtest} + BTCPAY_BIND: 0.0.0.0:49392 + BTCPAY_EXTERNALURL: https://${BTCPAY_HOST}/ + + # NGINX settings + VIRTUAL_NETWORK: nginx-proxy + VIRTUAL_PORT: 49392 + VIRTUAL_HOST: ${BTCPAY_HOST} + + # Let's encrypt settings + LETSENCRYPT_HOST: ${BTCPAY_HOST} + LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL:-yourname@example.com} + + links: + - nbxplorer + - postgres + volumes: + - "btcpay_datadir:/datadir" + - "nbxplorer_datadir:/root/.nbxplorer" + + nbxplorer: + restart: always + image: nicolasdorier/nbxplorer:1.0.1.23 + expose: + - "32838" + environment: + NBXPLORER_NETWORK: ${NBITCOIN_NETWORK:-regtest} + NBXPLORER_BIND: 0.0.0.0:32838 + volumes: + - "nbxplorer_datadir:/datadir" + + postgres: + restart: always + 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 diff --git a/docker-compose-generator/docker-fragments/litecoin.yml b/docker-compose-generator/docker-fragments/litecoin.yml new file mode 100644 index 0000000..0ba23a4 --- /dev/null +++ b/docker-compose-generator/docker-fragments/litecoin.yml @@ -0,0 +1,34 @@ +version: "3" + +services: + litecoind: + restart: always + container_name: btcpayserver_litecoind + image: nicolasdorier/docker-litecoin:0.14.2 + environment: + BITCOIN_EXTRA_ARGS: | + rpcport=43782 + ${NBITCOIN_NETWORK:-regtest}=1 + port=39388 + whitelist=0.0.0.0/0 + expose: + - "43782" + - "39388" + volumes: + - "litecoin_datadir:/data" + nbxplorer: + environment: + BTCPAY_CHAINS: "ltc" + NBXPLORER_LTCRPCURL: http://litecoind:43782/ + NBXPLORER_LTCNODEENDPOINT: litecoind:39388 + links: + - litecoind + volumes: + - "litecoin_datadir:/root/.litecoin" + btcpayserver: + environment: + BTCPAY_LTCEXPLORERURL: http://nbxplorer:32838/ + BTCPAY_CHAINS: "ltc" + +volumes: + litecoin_datadir: \ No newline at end of file diff --git a/docker-compose-generator/docker-fragments/nginx.yml b/docker-compose-generator/docker-fragments/nginx.yml new file mode 100644 index 0000000..7bd55e1 --- /dev/null +++ b/docker-compose-generator/docker-fragments/nginx.yml @@ -0,0 +1,55 @@ +version: "3" + +services: + nginx: + restart: always + image: nginx + container_name: nginx + ports: + - "80:80" + - "443:443" + volumes: + - "nginx_conf:/etc/nginx/conf.d" + - "nginx_vhost:/etc/nginx/vhost.d" + - "nginx_html:/usr/share/nginx/html" + - "nginx_certs:/etc/nginx/certs:ro" + links: + - btcpayserver + + nginx-gen: + restart: always + image: jwilder/docker-gen + container_name: nginx-gen + volumes: + - "/var/run/docker.sock:/tmp/docker.sock:ro" + - "./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro" + - "nginx_conf:/etc/nginx/conf.d" + - "nginx_vhost:/etc/nginx/vhost.d" + - "nginx_html:/usr/share/nginx/html" + - "nginx_certs:/etc/nginx/certs:ro" + entrypoint: /usr/local/bin/docker-gen -notify-sighup nginx -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf + links: + - nginx + + letsencrypt-nginx-proxy-companion: + restart: always + image: jrcs/letsencrypt-nginx-proxy-companion + container_name: letsencrypt-nginx-proxy-companion + volumes: + - "/var/run/docker.sock:/var/run/docker.sock:ro" + - "nginx_conf:/etc/nginx/conf.d" + - "nginx_vhost:/etc/nginx/vhost.d" + - "nginx_html:/usr/share/nginx/html" + - "nginx_certs:/etc/nginx/certs:rw" + environment: + NGINX_DOCKER_GEN_CONTAINER: "nginx-gen" + NGINX_PROXY_CONTAINER: "nginx" + ACME_CA_URI: ${ACME_CA_URI:-https://acme-staging.api.letsencrypt.org/directory} + links: + - nginx + +volumes: + nginx_conf: + nginx_vhost: + nginx_html: + nginx_certs: \ No newline at end of file diff --git a/docker-compose-generator/src/DockerComposeDefinition.cs b/docker-compose-generator/src/DockerComposeDefinition.cs new file mode 100644 index 0000000..fed2a25 --- /dev/null +++ b/docker-compose-generator/src/DockerComposeDefinition.cs @@ -0,0 +1,132 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using System.Text; +using YamlDotNet.RepresentationModel; +using YamlDotNet.Serialization; +using System.IO; + +namespace DockerGenerator +{ + public class DockerComposeDefinition + { + string[] _Fragments; + private string _Name; + + public DockerComposeDefinition(string name, string[] fragments) + { + _Fragments = fragments; + _Name = name; + } + + public string FragmentLocation + { + get; set; + } + public string BuildOutputDirectory + { + get; set; + } + + public string GetFilePath() + { + return Path.Combine(BuildOutputDirectory, $"docker-compose.{_Name}.yml"); + } + public void Build() + { + Console.WriteLine($"Generating {GetFilePath()}"); + var deserializer = new DeserializerBuilder().Build(); + var serializer = new SerializerBuilder().Build(); + + Console.WriteLine($"With fragments:"); + foreach(var fragment in _Fragments) + { + Console.WriteLine($"\t{fragment}"); + } + var services = new List>(); + var volumes = new List>(); + + foreach(var doc in _Fragments.Select(f => ParseDocument(f))) + { + if(doc.Children["services"] is YamlMappingNode fragmentServicesRoot) + { + services.AddRange(fragmentServicesRoot.Children); + } + + if(doc.Children["volumes"] is YamlMappingNode fragmentVolumesRoot) + { + volumes.AddRange(fragmentVolumesRoot.Children); + } + } + + + YamlMappingNode output = new YamlMappingNode(); + output.Add("version", new YamlScalarNode("3")); + output.Add("services", new YamlMappingNode(Merge(services))); + output.Add("volumes", new YamlMappingNode(volumes)); + var result = serializer.Serialize(output); + var outputFile = GetFilePath(); + File.WriteAllText(outputFile, result.Replace("''", "")); + Console.WriteLine($"Generated {outputFile}"); + Console.WriteLine(); + } + + private KeyValuePair[] Merge(List> services) + { + return services + .GroupBy(s => s.Key.ToString(), s=> s.Value) + .Select(group => + (GroupName: group.Key, + MainNode: group.OfType().Single(n=> n.Children.ContainsKey("image")), + MergedNodes: group.OfType().Where(n => !n.Children.ContainsKey("image")))) + .Select(_ => + { + foreach(var node in _.MergedNodes) + { + foreach(var child in node) + { + var childValue = child.Value; + if(!_.MainNode.Children.TryGetValue(child.Key, out var mainChildValue)) + { + mainChildValue = child.Value; + _.MainNode.Add(child.Key, child.Value); + } + else if(childValue is YamlMappingNode childMapping && mainChildValue is YamlMappingNode mainChildMapping) + { + foreach(var leaf in childMapping) + { + if(mainChildMapping.Children.TryGetValue(leaf.Key, out var mainLeaf)) + { + if(leaf.Value is YamlScalarNode leafScalar && mainLeaf is YamlScalarNode leafMainScalar) + { + leafMainScalar.Value = leafMainScalar.Value + "," + leaf.Value; + } + } + else + { + mainChildMapping.Add(leaf.Key, leaf.Value); + } + } + } + else if(childValue is YamlSequenceNode childSequence && mainChildValue is YamlSequenceNode mainSequence) + { + foreach(var c in childSequence.Children) + { + mainSequence.Add(c); + } + } + } + } + return new KeyValuePair(_.GroupName, _.MainNode); + }).ToArray(); + } + + private YamlMappingNode ParseDocument(string fragment) + { + var input = new StringReader(File.ReadAllText(Path.Combine(FragmentLocation, $"{fragment}.yml"))); + YamlStream stream = new YamlStream(); + stream.Load(input); + return (YamlMappingNode)stream.Documents[0].RootNode; + } + } +} diff --git a/docker-compose-generator/src/Program.cs b/docker-compose-generator/src/Program.cs new file mode 100644 index 0000000..76b71d9 --- /dev/null +++ b/docker-compose-generator/src/Program.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.IO; +using YamlDotNet.Serialization; + +namespace DockerGenerator +{ + class Program + { + static void Main(string[] args) + { + new Program().Run(); + } + + private void Run() + { + List defs = new List(); + var btc = new DockerComposeDefinition("btc", + new string[] { "nginx", "btcpayserver", "bitcoin" }); + defs.Add(btc); + defs.Add(new DockerComposeDefinition("btc-ltc", + new string[] { "nginx", "btcpayserver", "bitcoin", "litecoin" })); + + var fragmentLocation = FindLocation("docker-fragments"); + var productionLocation = FindLocation("Production"); + foreach(var def in defs) + { + def.FragmentLocation = fragmentLocation; + def.BuildOutputDirectory = productionLocation; + def.Build(); + } + File.Copy(btc.GetFilePath(), Path.Combine(new FileInfo(btc.GetFilePath()).Directory.FullName, "docker-compose.yml"), true); + } + + private string FindLocation(string path) + { + while(true) + { + if(Directory.Exists(path)) + return path; + path = Path.Combine("..", path); + } + } + } +} diff --git a/docker-compose-generator/src/docker-compose-generator.csproj b/docker-compose-generator/src/docker-compose-generator.csproj new file mode 100644 index 0000000..8d4d196 --- /dev/null +++ b/docker-compose-generator/src/docker-compose-generator.csproj @@ -0,0 +1,16 @@ + + + + Exe + netcoreapp2.0 + DockerGenerator + + + + + + + + + + diff --git a/generate-docker-compose.ps1 b/generate-docker-compose.ps1 new file mode 100644 index 0000000..d2d2e84 --- /dev/null +++ b/generate-docker-compose.ps1 @@ -0,0 +1 @@ +cd .\docker-compose-generator; dotnet run -p .\src\docker-compose-generator.csproj; cd ..; \ No newline at end of file