Ride-The-Lightning / RTL

Ride The Lightning - A full function web browser app for LND, C-Lightning and Eclair
MIT License
739 stars 157 forks source link

Docker #44

Closed badokun closed 5 years ago

badokun commented 5 years ago

To improve adoption and testing it would be nice to have this packaged up as a docker image.

saubyk commented 5 years ago

Will you be interested in collaborating and testing with your docker setup? We are docker noobs here. We can create an image, but need some help with testing.

badokun commented 5 years ago

I'd love to help but really fully occupied at the moment. Besides a regular day-job, also working on my own lightning-metrics project (https://github.com/badokun/lightning-metrics).

I like what you guys are doing so would like to explore more

JeffVandrewJr commented 5 years ago

@saubyk I can get this into Docker for you, in a format where it could be potentially integrated into BTCPay if you wanted.

You'd need to make the following changes to your code first to make it Docker-friendly:

  1. Allow the following options in your config file to be optionally set by environmental variable:
lndServerUrl=https://localhost:8080/v1
macroonPath=C:\Users\<User>\AppData\Local\Lnd\data\chain\bitcoin\testnet 
nodeAuthType=DEFAULT 
lndConfigPath=C:\Users\<User>\AppData\Local\Lnd\lnd.conf
  1. Allow the location of RTL.conf to be optionally set by environmental variable. I would need this so I can put the config file in a separate Docker volume to make it persist.

  2. Allow the http authentication credentials to be saved to and read from a "cookie file" exactly the way Spark Wallet does it for C-lightning. (Like this: https://github.com/shesek/spark-wallet/pull/8) It would be nice to have cookie file location should be set through environmental variable.

I don't know the first thing about NodeJS, but if you can add those options I should be able to get you into a nice Docker container so we can see if RTL jives well with BTCPay.

saubyk commented 5 years ago

@JeffVandrewJr Thanks for responding on this thread and the offer to collaborate. This is music to our ears! :-) Thanks for the pointers as well to make it work with BTCPay Server. Item 1 and 2 in your comment above, are comparatively easy to accomplish. Item 3 may require some time. But we will start working on this right away. Will keep you posted, as soon as we have a workable image to test with.

For item 1, are there specific environment variables that we need to specify, from BTCPay stack?

Thanks again.

JeffVandrewJr commented 5 years ago

@saubyk You can give the environmental variables any descriptive name you want, since the environment namespace is limited by container anyway. I can set them as equal to machine-level env variables when I do the docker-compose.

If any of the above sounded confusing, don't worry about it, the TLDR is just that you can call those variables whatever you want.

When you're done, you don't even need to worry about creating a Docker image. Once the application has the updates we discussed above, just let me know and I'll write the Dockerfile for you and show you how to automate pushing images to Docker Hub.

JeffVandrewJr commented 5 years ago

@saubyk Also the cookie file doesn't have to necessarily be exactly the same as Spark; there just needs to be a cookie file with whatever login credentials you use that I can pass via URL to allow access to the dashboard.

ShahanaFarooqui commented 5 years ago

Hey @JeffVandrewJr we are done with changes on item 1 and 2. We have a few queries regarding the cookie requirement. It may be good to get on a phone call to discuss this. Please let us know a good time to connect. I can DM you on twitter for contact info.

saubyk commented 5 years ago

The following optional parameters can now be passed to RTL via the command line, at the time of initiating the server: lndServerUrl macaroonPath nodeAuthType lndConfigPath rtlConfFilePath

E.g. node rtl --lndServerUrl=https://localhost:8080/v1 --macaroonPath=/home/admin/.lnd/data/chain/bitcoin/mainnet --nodeAuthType=CUSTOM --lndConfigPath=/home/admin/.lnd --rtlConfFilePath=/home/admin/Projects/RTL

JeffVandrewJr commented 5 years ago

@ShahanaFarooqui @saubyk Hey guys, great work! Thanks for working so quickly!

We can definitely talk by phone, but before we do, I just wanted to write out a few things that may make everything clearer. I think the remaining changes are actually going to be pretty simple, but if you're confused at all we'll totally work it out.

Setting the configuration items via command line flags like you did is a big improvement, but it would be cleaner if they were set via environment instead. I'll give you an example.

A user should be able to do this from the command line:

export LND_SERVER_URL="https://localhost:8080/v1"
node rtl

and that should be exactly equivalent to this from the command line:

node rtl --lndServerUrl=https://localhost:8080/v1

Once I do the docker-compose, you'll see why it's better that way.

I don't know NodeJS, but from googling it appears that this is easy to do. NodeJS apparently provides access to all environmental variables via process.env. So in the above example, you'd want your code to check process.env.LND_SERVER_URL. If that variable was unset, it should exhibit some default behavior (perhaps checking the conf file for lndServerUrl), otherwise if process.env.LND_SERVER_URL is set, the value of process.env.LND_SERVER_URL should automatically be applied to lndServerUrl.

The same concept would apply to all of the other items that you have set with command line flags.

Moving onto the "cookie file." Right now, it appears from your documentation that you authenticate via password, which is fine.

If that's the case, here are the steps (in order) your app would take at startup:

  1. Check process.env.RTL_RANDOM_PASS. If that environmental variable is set to 1, then any password data in the config file should be completely ignored. If process.env.RTL_RANDOM_PASS is not set to 1, on the other hand, then your app should keep its normal default behavior.

  2. Assuming RTL_RANDOM_PASS is 1, check cookiePath (which we'll be setting through an environmental variable from the command line: RTL_COOKIE_PATH) to see if a file is there. If there is no cookie file in the path, the app should generate a random strong password and create a text file called cookie which contains the newly-generated password. You can store this file in plain text, as it's going to reside in a shared Docker volume only accessible by the BTCPay container and the RTL container. The file never gets stored in the user's browser or anything like that. You're only generating a new random password if the cookie file does not already exist at cookiePath. Otherwise, if the cookie file does already exist, you simply consider the password from the already existing cookie file to be RTL's password.

That would basically be it. The only other change would be to check the URL parameters when someone accesses RTL, and if there is a password parameter, do not bother the user with a login but instead read the password from the URL parameter to see if it matches.

For example, assume the user's password is testpassword and RTL is being hosted at rtl.com. In that case, assume the user visits:

https://rtl.com?access-key=testpassword

In that case, the user should not be prompted for a login. Instead, RTL should read testpassword from the access-key URL parameter, see if it's the correct password, and if so, authenticate the user.

In real life, obviously the randomly generated password should be much longer and stronger than the example.

The reason we're doing this cookie file thing is because when we deploy, we want there to be a direct link to RTL from within the BTCPay admin panel. The user is already logged into BTCPay, so we don't want them to have to log into RTL separately. We want a seamless experience so that RTL will be the default way to manage LND within BTCPay assuming our eventual pull request is approved. BTCPay will have access to the cookie file via shared Docker volume, and will read the cookie file so that it can pass the password right in the URL, so that any logged in BTCPay administrator will be able to seamlessly access the RTL dashboard like any other screen within BTCPay.

If you didn't understand that last paragraph right now, don't worry about it; you'll get it when you see it in Docker. The important thing is to get the environmental variable reading and cookie file capability working so I can make a compatible Docker image.

Great work so far! I think this is going to be awesome. If this is unclear, you can DM me and we can set a time to talk.

Also if any of my suggestions don't jibe with what you're trying to do with the app or are otherwise no good, let me know!

saubyk commented 5 years ago

@JeffVandrewJr Thanks for the detailed explanation, its extremely helpful. We are in agreement with this approach, and we will start working on it now.

  1. We will create the environment variables for configurable RTL parameters
  2. Regarding the cookie approach, per our understanding, the solution is basically a single-sign-on (SSO) for BTCPay app stack. We will utilize a RTL_SSO flag to configure this method of authentication in the application (RTL_SSO = 1 implies, SSO via an external cookie).

There is one more application security nuance in RTL, which we have not discussed, which is the inactive session time out. Please view the below issue for details: https://github.com/ShahanaFarooqui/RTL/issues/40 RTL currently has a pre-defined session timeout of 60 mins.

Is there any user session timeout configured in BTCPay? If yes, should this be orchestrated as well b/w BTCPay and RTL? If no, should we remove session timeout in case of SSO?

If we want to keep this feature, the behavior of the application would need to be designed if the session times out in RTL. e.g. upon timeout user can be presented with a page, which will indicate that session is timed out due to inactivity and needs to be re-opened from BTCPay.

JeffVandrewJr commented 5 years ago

@saubyk This all sounds good.

Just to make sure we're on the same page, when SSO is set, it's RTL that is generating the random password and cookie file (unless one is already set).

I'm actually not sure what the inactivity timeout is in BTCPay, but synchronizing the timeouts wouldn't matter since a user could be active in BTCPay while being inactive in RTL.

It seems like you'd have three options on dealing with the timeout:

  1. You could theoretically disable timeouts.

  2. You could leave the 60 min timeout, and if the timeout was hit you would need to do a redirect sending the user to the BTCPay services page. (The BTCPay services page is the page in the admin panel where the user can access all plugins, including presumably RTL when our PR is approved.) The BTCPay services page is always the domain stored in the BTCPAY_HOST environmental variable followed by /server/services. So if process.env.BTCPAY_HOST was example.com, the services page would be https://example.com/server/services.

  3. This option 3 is slightly more complex but I want to give you guys all possible options. You could bag the whole cookie idea that Spark uses altogether, and instead authenticate the way I authenticate my Quickbooks plugin. With the Quickbooks plugin, I outsource all authentication to BTCPay as follows. Every time a user makes a request to my Quickbooks plugin, the plugin makes a request to https://btcpay.example.com/server/users. If the first response to that request is a 200, the plugin knows that the user is logged into BTCPay and can therefore just let the user into the plugin without any further authentication. If the first response is not 200, we know the user is not logged into BTCPay and then instead redirect back to the BTCPay login page (https://btcpay.example.com/Account/Login). This method works because RTL and BTCPay will be on the same domain, so you should have the ability to grab the user's BTCPay cookie, and you'll always know the domain by checking the BTCPAY_HOST environmental variable.

Option 3 is a little more complicated since you would need to set up a BTCPay testing environment make sure it's working for you.

Any of those three methods works! Whichever you guys prefer from a simplicity and security standpoint is totally fine. If you have any other idea I haven't considered, let me know!

JeffVandrewJr commented 5 years ago

@saubyk Just a follow up on my last post here, personally I think your timeout is good and I would do either Option 2 with the redirect on timeout or Option 3, but whatever you guys think is best works.

saubyk commented 5 years ago

@JeffVandrewJr Thanks again for a detailed response.

For the application timeout, our preference is to go with option 2, which we believe is the best way to ensure that RTL is not too tightly integrated with BTCPayserver and the same hooks can be used to integrate with other app stacks as well.

We will create a new environment variable to configure the url for the logout redirect page (LOGOUT_REDIRECT), which the user will be redirected to, upon session timeout or manual logout from RTL.

JeffVandrewJr commented 5 years ago

@saubyk Perfect. Whenever you've got something ready for me to put into a container, hit me up.

saubyk commented 5 years ago

hey @JeffVandrewJr we are done with the changes.

You can now utilize the following environment variables for hooking into RTL:

PORT (port number for the rtl node server, default 3000) LND_SERVER_URL (LND server URL for REST APIs, default https://localhost:8080/v1) MACAROON_PATH (Path for the folder containing 'admin.macaroon' file) NODE_AUTH_TYPE (For stand alone RTL authentication allowed values - CUSTOM, DEFAULT) LND_CONFIG_PATH (Full path of the lnd.conf file including the file name) RTL_CONFIG_PATH (Full path of the RTL.conf file including the file name) BITCOIND_CONFIG_PATH (Full path of the bitcoind.conf file including the file name) RTL_SSO (1 - single sign on via an external cookie, 0 - stand alone RTL authentication) RTL_COOKIE_PATH (Full path of the cookie file including the file name) LOGOUT_REDIRECT_LINK (URL to re-direct to after logout/timeout from RTL)

Please let us know if you any further queries and how ever else we can help to move this forward.

Thanks

JeffVandrewJr commented 5 years ago

@saubyk @ShahanaFarooqui Great! I just forked you so I can start testing Docker images on my end. In the meantime, here are some things you can do to prep everything:

  1. Create an account on Docker Hub: https://hub.docker.com/ Do not associate it to your GitHub, because we'll be hosting images on Docker Hub but using CircleCI for automated Docker image builds.

  2. Merge my PR #47, which adds CircleCI automated builds for Docker.

  3. Go to https://circleci.com/ and create an account for yourself. Your account should be created under the login associated with the RTL Github repo.

  4. Once you've created your CircleCI account, assuming you've merged my PR, CircleCI will detect the CircleCI config file in the repo, and you'll be able to add RTL as a CircleCI project. Add RTL as a project, then in the project settings, add three environmental variables:

    DOCKERHUB_PASS
    DOCKERHUB_REPO
    DOCKERHUB_USER

    [Note that these variables aren't in your code anywhere; you just set them in the CircleCI project.]

They should be self-explanatory as to what values to use for the variables. Keep in mind that DOCKERHUB_REPO is in this format user/reponame. For instance my LibrePatron repo is jvandrew/patron.

These steps will automate the building of future Docker images when you make updates to RTL.

I'll explain more later after I draft up the necessary Dockerfile and compose fragment. Once I have those drafted and have tested then in the BTCPay environment, we can get rolling for real.

JeffVandrewJr commented 5 years ago

@saubyk @ShahanaFarooqui After you guys create the accounts on Docker Hub and CircleCI mentioned in my above comment, I have two questions for you.

Right now I've build two test Docker images for RTL: one larger one with the optional canvas dependency and one smaller one without it. Both images skip the fsevents dependency since that's a Mac thing.

I was able to get canvas to install correctly in the Docker image correctly by adding a bunch of apk dependencies. Doing so made the container larger, which is fine if we need canvas, but if we don't need canvas we're better off skipping those dependencies.

So my questions are:

  1. Should I build the smaller image without canvas or the larger image with canvas? If canvas is necessary (or if it adds cool functionality to RTL), I'll build the larger one.

  2. (Unrelated topic) When using SSO, if I'm passing the password to RTL using URL parameter, is this the format? https://example.com?access-key=<some-key> Or did you guys use a parameter name different from access-key? I haven't tried out the SSO yet as I'm headed to bed, but thought I'd ask.

ShahanaFarooqui commented 5 years ago

@JeffVandrewJr We will create these accounts by today eod. In the mean while, please note our answers below: 1: Canvas was an optional dependency used by our QR code generator library. So, we decided to replace the 'angular2-qrcode' library with 'angularx-qrcode'. The replaced library has a single dependency and should be lighter and easier to install. Please let us know if that helps to keep the container smaller.

2: Apologies that we forgot to mention that in our last comment :). The parameter name is 'access-key' and example link should look like https://example.com?access-key=A98D45CD9572BD294D6AAAAE4679F4FC9AD2084F1D9BC96B20E2

JeffVandrewJr commented 5 years ago

@saubyk @ShahanaFarooqui

Hey guys, I've got RTL running nicely via docker-compose, which is great!

But there is one big issue I'm having as well as three very minor UI issues. They are:

  1. The major issue is that when I launch RTL, even though I have the LND_SERVER_URL environmental variable set, RTL ignores the variable and uses the default https://localhost:8080/v1 instead. The reason I know this is happening is that when I log into RTL, the Node Config menu shows: lndServerUrl=https://localhost:8080/v1 and the dashboard just shows spinning circles rather than pulling data from lnd. (The Node Config menu is finding the lnd config file, however, because I am able to view it .) Please see if you can duplicate that behavior. If not, let me know.

  2. Small UI thing: If SSO is turned on and someone tries to visit the RTL without an access key, right now they get a popup telling them SSO failed. Instead of getting a popup like that, I think it would be better UI if they were redirected back to LOGOUT REDIRECT LINK instead.

  3. Small UI thing: Right now if someone logs into RTL successfully but RTL can't reach LND, the user gets a little graphic that says 401Single Sign on Failed! Really they shouldn't get that message since they did in fact sign on successfully. It would be better if that said "Attempting to reach LND" or something like that.

  4. Small UI thing: The main RTL dashboard currently advises people not to use lightning on Mainnet. Can we suppress that message? Lightning is obviously experimental but merchants managing lnd via RTL are obviously going to be using this in production and know what they're getting into.

saubyk commented 5 years ago

Hey @JeffVandrewJr

For item # 1 RTL is giving precedence to the environment variables for all the parameters. We have now made a change to print all the variables in the log file as well. The contents of the RTL.conf are not over-written by the environment variables. Which implies that if the parameters in the conf file are different, when you view the file from the app, it will show the values on the file. The values being used by the app are the ones getting printed in the log. Please set enableLogging=true in the RTL.conf file to generate the log. If you are getting the spinners on RTL, it means that the app is not able to connect to LND for some other reason. Can you please share a screen shot of the app, so that we can investigate what may be the issue? Also share the parameters you are getting in the log file. The log file will get generated at <RTL_CONFIG_PATH>/logs/RTL.log

For item # 2 We believe that just re-directing the user to the logout redirect page, without showing any reason for failure like SSO Auth failure, might be non-intuitive and may not give a clue to the user for troubleshooting. May need some more thought on how to design this process flow better.

For item # 3 We reviewed the code, the SSO failure message only appears in case of the authentication failure via the cookie. Lets resolve the main issue concerning item # 1, then we may get more insight into this particular issue, if at all.

For item # 4 We meant to eventually bring it up and discuss with you. Just being extra cautious here. We meant to remain in alpha phase for at-least 3 months after the initial launch in Oct 2018. Happy to remove the message once we complete our integration work with BTCPay and close out this issue. A bit jittery, but happy! :-)

ShahanaFarooqui commented 5 years ago

@JeffVandrewJr Docker Hub and Circle CI setup are also done. Thanks for the detailed instructions.

JeffVandrewJr commented 5 years ago

@saubyk @ShahanaFarooqui

Also here is the SSO failure message, even when SSO did not fail: screenshot_2019-02-13_22-50-52

JeffVandrewJr commented 5 years ago

@saubyk @ShahanaFarooqui

Update: The big issue is fixed! I simply had to change the LND REST URL to http instead of https because of how BTCPay handles it. I'm now able to use RTL normally within BTCPay.

I'm excited because you guys put together a really nice dashboard.

I did encounter a couple of small bugs after getting everything set up. I can do the PR to BTCPay-Docker whenever you guys want; it's totally up to you guys how many of these you want to fix (or if you want to fix them at all) before I do it. You don't necessarily need to fix all of this, just what you feel is important. Just let me know!

  1. On the LND wallet screen, I couldn't get the QR codes to scan. I tried with two different testnet wallets. This QR code issue was related to having redshift night mode on my monitor, which doesn't affect BTCPay QR codes but does affect RTL for whatever reason. Anyway, it's not an RTL bug, so this is totally fine.
  2. When I sent payments to the LND wallet, there was a delay before they showed up in my unconfirmed balance. If this delay is related to the lnd API, let me know since obviously in that case there is nothing we can do about it. (I'm normally a c-lightning user.) And after the payments did show up in Unconfirmed Transactions, they then didn't show up in my "List Transactions" screen. There was an additional delay before they showed up in "List Transactions."
  3. When the "List Transactions" screen is empty and you click on it, you get an empty popup window that can't be closed by clicking "close". I've attached a screenshot. You then have to refresh the page to get rid of it. screenshot_2019-02-13_23-35-43
  4. On invoice creation, the QR code overlaps the text. Screenshot below: screenshot_2019-02-14_02-20-31
  5. On the "Add Channel" screen, nodes that don't have aliases have no identifier to use when choosing, so you get a menu with lots of blank space. It seems like if a node doesn't have an alias, instead of being blank in the menu, maybe put the beginning of the pubkey? Screenshot below: screenshot_2019-02-14_02-25-23

I can do the PR to BTCPay-Docker whenever you guys want; it's totally up to you guys how many of these you want to fix (or if you want to fix them at all) before I do it. You don't necessarily need to fix all of this, just what you feel is important. Just let me know!

saubyk commented 5 years ago

@JeffVandrewJr This is great news. Thanks for all this effort. :-)

We’ll work on the issues you have reported today. We are a bit unsure about issue 2, which appears to be LND problem, rather than RTL problem. We’ll inspect the code again to be double sure.

Expect the issues to be addressed by later this evening. Thanks again.

saubyk commented 5 years ago

@JeffVandrewJr Issue # 1, we lowered the QR correction level and you might be able to scan it with red shift now. Issue # 2, we were not able to replicate this issue. this might have to do with the response from LND at your end. Issue # 3, Fixed Issue # 4, Firefox specific issue, fixed now. Issue # 5, Peers with no alias, will now have the first 15 characters of the pub key in the Add channel drop down. Finaly, removed the standard alpha release warning and upgraded RTL to beta phase. (There is a playful warning on the wallet page, to remind users to be a bit cautious). Thanks.

JeffVandrewJr commented 5 years ago

@saubyk @ShahanaFarooqui Great guys!

I just made PR #49, which changes your Dockerfile slightly (and also corrects something in the original CircleCI config file I pushed).

The Dockerfile changes do not contain anything BTCPay-specific. It is a totally "clean" Dockerfile that you can use with any setup. All of the BTCPay-specific stuff is in a separate docker-compose file which will reside outside of the RTL repository.

Steps from there:

saubyk commented 5 years ago

Hi @JeffVandrewJr We are done with all the above. The build process was smooth and seamless! :-) The latest release is now tagged with v0.2.0 The docker hub image is available at: https://hub.docker.com/r/shahanafarooqui/rtl

Please let us know, the next steps, if any. And thanks again for your help and guidance.

JeffVandrewJr commented 5 years ago

@saubyk @ShahanaFarooqui Great guys!

So when I did my final round of tests before doing a BTCPay PR, I ran into a problem. The good news is that it is a very easy fix.

When I attempted to do a setup/teardown of BTCPay with RTL integrated into the BTCPay docker-compose, the RTL container hung on being stopped. This usually is caused by processes preventing the container from properly stopping.

This is very easily fixable in Docker by simply adding a tini Entrypoint; tini is basically a very tiny init that is great at handling off SIGTERM signals from the Docker daemon to the processes inside the container. This PR adds tini to the Dockerfile. It only expands the container image by 10kb.

Steps from here:

Once the new release is tagged, I should be able to prepare the PR to use the docker-compose fragment I put together for the BTCPay PR.

saubyk commented 5 years ago

hey @JeffVandrewJr New release is tagged with v0.2.1, docker image is built and uploaded on the repo: https://hub.docker.com/r/shahanafarooqui/rtl

JeffVandrewJr commented 5 years ago

@saubyk @ShahanaFarooqui

We're all set! Here is the PR for BTCPay: https://github.com/btcpayserver/btcpayserver-docker/pull/99

JeffVandrewJr commented 5 years ago

@saubyk @ShahanaFarooqui

Hey guys, we did run into a bit of a problem.

Like most solutions you guys will eventually be integrating with, BTCPay uses nginx as a reverse proxy, so requests to a specific URL are passed from nginx over to the node server on port 3000.

In my initial testing, I had RTL running on a subdomain (rtl.<btcpay-host>.com) and everything worked perfectly.

When I moved it over to a sub-URI (<host>.com/rtl, for example) we had problems. I tried a few different sub-URIs. Using rtl as a sub-URI gave different behavior from all the others, as explained below.

Using the /rtl sub-URI gave an "empty" looking version of RTL:

screenshot_2019-02-18_18-17-15

On the other hand, using different sub-URIs (example, <host>/ride), just caused a blank white screen to load.

I assume the difference in behavior between the rtl sub-URI and all the others is because <host>/rtl has some specific use in your code. That's totally fine, as the actual sub-URI we use doesn't matter, but it would be good for it to work correctly on sub-URIs in general to cut down on the number of SSL certificates (if that's possible).

Do you know why I would be getting this behavior on sub-URIs but not when hosted on a main domain or subdomain? If so, is it an easy fix?

saubyk commented 5 years ago

Hey @JeffVandrewJr We are serving the RTL UI at sub-uri '/rtl/', so you can try with the location setting in nginx as below:

location /rtl/ { proxy_pass http://lnd_bitcoin_rtl:3000/rtl/; ... }

JeffVandrewJr commented 5 years ago

Hey guys, check out my PR #53, which updates CircleCi to support both ARM and x64. Doing this update should speed up getting RTL merged into BTCPay, as well as offer support for the Raspberry Pi version of BTCPay.

ShahanaFarooqui commented 5 years ago

@JeffVandrewJr We merged the pr and released version 0.2.4 with the change. Images are available on docker hub now. Thanks.

ShahanaFarooqui commented 5 years ago

Hey @JeffVandrewJr merged your PR and release 0.2.5. Images are available on docker hub now.

badokun commented 5 years ago

Good work guys! Sorry I couldnt contribute

ShahanaFarooqui commented 5 years ago

No problem but thanks for opening up the issue. It helped us to connect with the perfect guy :).

saubyk commented 5 years ago

Docker integration with BTCPayserver is complete now, closing this issue. Huge credit to @JeffVandrewJr to make this happen. Thanks @badokun for opening this ticket, which eventually led to this integration and collaboration. Thanks @NicolasDorier for all the help and guidance. Looking forward to continued collaboration.

Thanks.