diff --git a/chainntnfs/bitcoindnotify/bitcoind.go b/chainntnfs/bitcoindnotify/bitcoind.go index b39f78a43..496589463 100644 --- a/chainntnfs/bitcoindnotify/bitcoind.go +++ b/chainntnfs/bitcoindnotify/bitcoind.go @@ -174,6 +174,8 @@ func (b *BitcoindNotifier) startNotifier() error { // notificationDispatcher is the primary goroutine which handles client // notification registrations, as well as notification dispatches. func (b *BitcoindNotifier) notificationDispatcher() { + defer b.wg.Done() + out: for { select { @@ -436,7 +438,6 @@ out: break out } } - b.wg.Done() } // historicalConfDetails looks up whether a confirmation request (txid/output diff --git a/chainntnfs/btcdnotify/btcd.go b/chainntnfs/btcdnotify/btcd.go index d23a30599..dc36503e1 100644 --- a/chainntnfs/btcdnotify/btcd.go +++ b/chainntnfs/btcdnotify/btcd.go @@ -288,6 +288,8 @@ func (b *BtcdNotifier) onRedeemingTx(tx *btcutil.Tx, details *btcjson.BlockDetai // notificationDispatcher is the primary goroutine which handles client // notification registrations, as well as notification dispatches. func (b *BtcdNotifier) notificationDispatcher() { + defer b.wg.Done() + out: for { select { @@ -487,7 +489,6 @@ out: break out } } - b.wg.Done() } // historicalConfDetails looks up whether a confirmation request (txid/output diff --git a/docker/lnd/Dockerfile b/dev.Dockerfile similarity index 100% rename from docker/lnd/Dockerfile rename to dev.Dockerfile diff --git a/docker/README.md b/docker/README.md index b2b736d89..a6343622e 100644 --- a/docker/README.md +++ b/docker/README.md @@ -322,6 +322,12 @@ and send some amount of bitcoins to `Alice`. - Connect `Bob` node to the `Faucet` and make multihop payment (`Alice->Faucet->Bob`) - Close channel with `Faucet` and check the onchain balance. +### Building standalone docker images + +Instructions on how to build standalone docker images (for development or +production), outside of `docker-compose`, see the +[docker docs](../docs/DOCKER.md). + ### Questions [![Irc](https://img.shields.io/badge/chat-on%20freenode-brightgreen.svg)](https://webchat.freenode.net/?channels=lnd) diff --git a/docker/docker-compose.ltc.yml b/docker/docker-compose.ltc.yml index c3bbd3dca..5bf9c323d 100644 --- a/docker/docker-compose.ltc.yml +++ b/docker/docker-compose.ltc.yml @@ -24,7 +24,7 @@ services: container_name: lnd_ltc build: context: ../ - dockerfile: docker/lnd/Dockerfile + dockerfile: dev.Dockerfile environment: - RPCUSER - RPCPASS diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index f13a400f0..61cd58a5a 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -24,7 +24,7 @@ services: container_name: lnd build: context: ../ - dockerfile: docker/lnd/Dockerfile + dockerfile: dev.Dockerfile environment: - RPCUSER - RPCPASS diff --git a/docker/lnd/start-lnd.sh b/docker/lnd/start-lnd.sh index 1fb8502ff..c7bfe3058 100755 --- a/docker/lnd/start-lnd.sh +++ b/docker/lnd/start-lnd.sh @@ -17,7 +17,7 @@ return() { # set_default function gives the ability to move the setting of default # env variable from docker file to the script thereby giving the ability to the -# user override it durin container start. +# user override it during container start. set_default() { # docker initialized env variables with blank string and we can't just # use -z flag as usually. @@ -45,10 +45,16 @@ DEBUG=$(set_default "$DEBUG" "debug") NETWORK=$(set_default "$NETWORK" "simnet") CHAIN=$(set_default "$CHAIN" "bitcoin") BACKEND="btcd" +HOSTNAME=$(hostname) if [[ "$CHAIN" == "litecoin" ]]; then BACKEND="ltcd" fi +# CAUTION: DO NOT use the --noseedback for production/mainnet setups, ever! +# Also, setting --rpclisten to $HOSTNAME will cause it to listen on an IP +# address that is reachable on the internal network. If you do this outside of +# docker, this might be a security concern! + exec lnd \ --noseedbackup \ "--$CHAIN.active" \ @@ -58,5 +64,6 @@ exec lnd \ "--$BACKEND.rpchost"="blockchain" \ "--$BACKEND.rpcuser"="$RPCUSER" \ "--$BACKEND.rpcpass"="$RPCPASS" \ + "--rpclisten=$HOSTNAME:10009" \ --debuglevel="$DEBUG" \ "$@" diff --git a/docs/DOCKER.md b/docs/DOCKER.md index 2916dde9c..700f5677d 100644 --- a/docs/DOCKER.md +++ b/docs/DOCKER.md @@ -1,25 +1,47 @@ # Docker Instructions +There are two flavors of Dockerfiles available: + - `Dockerfile`: Used for production builds. Checks out the source code from + GitHub during build. The build argument `--build-arg checkout=v0.x.x-beta` + can be used to specify what git tag or commit to check out before building. + - `dev.Dockerfile` Used for development or testing builds. Uses the local code + when building and allows local changes to be tested more easily. + ## Development/testing -For development or testing, or to spin up a `btcd` backend alongside `lnd`, -check out the documentation at [docker/README.md](../docker/README.md). +To build a standalone development image from the local source directory, use the +following command: + +``` +$ docker build --tag=myrepository/lnd-dev -f dev.Dockerfile . +``` + +There is also a `docker-compose` setup available for development or testing that +spins up a `btcd` backend alongside `lnd`. Check out the documentation at +[docker/README.md](../docker/README.md) to learn more about how to use that +setup to create a small local Lightning Network. ## Production -To use Docker in a production environment, you can run `lnd` by first creating -a Docker container, adding the appropriate command-line options as parameters. +To use Docker in a production environment, you can run `lnd` by creating a +Docker container, adding the appropriate command-line options as parameters. + +You first need to build the `lnd` docker image: ``` -$ docker create --name=lnd lightninglabs/lnd [command-line options] +$ docker build --tag=myrepository/lnd --build-arg checkout=v0.11.1-beta . ``` -Then, just start the container: +It is recommended that you checkout the latest released tag. + +You can continue by creating and running the container: ``` -$ docker start lnd +$ docker run lnd [command-line options] ``` +Note: there currently are no automated docker image builds available. + ## Volumes A Docker volume will be created with your `.lnd` directory automatically, and will @@ -28,7 +50,7 @@ persist through container restarts. You can also optionally manually specify a local folder to be used as a volume: ``` -$ docker create --name=lnd -v /media/lnd-docker/:/root/.lnd lightninglabs/lnd [command-line options] +$ docker create --name=mylndcontainer -v /media/lnd-docker/:/root/.lnd myrepository/lnd [command-line options] ``` ## Example @@ -36,13 +58,7 @@ $ docker create --name=lnd -v /media/lnd-docker/:/root/.lnd lightninglabs/lnd [c Here is an example testnet `lnd` that uses Neutrino: ``` -$ docker create --name lnd-testnet lightninglabs/lnd --bitcoin.active --bitcoin.testnet --bitcoin.node=neutrino --neutrino.connect=faucet.lightning.community -``` - -Start the container: - -``` -$ docker start lnd-testnet +$ docker run --name lnd-testnet myrepository/lnd --bitcoin.active --bitcoin.testnet --bitcoin.node=neutrino --neutrino.connect=faucet.lightning.community ``` Create a wallet (and write down the seed): @@ -72,23 +88,23 @@ To test the Docker production image locally, run the following from the project root: ``` -$ docker build . -t lnd:master +$ docker build . -t myrepository/lnd:master ``` To choose a specific branch or tag instead, use the "checkout" build-arg. For example, to build the latest commits in master: ``` -$ docker build . --build-arg checkout=v0.8.0-beta -t lnd:v0.8.0-beta +$ docker build . --build-arg checkout=v0.8.0-beta -t myrepository/lnd:v0.8.0-beta ``` To build the image using the most current tag: ``` -$ docker build . --build-arg checkout=$(git describe --tags `git rev-list --tags --max-count=1`) -t lnd:latest-tag +$ docker build . --build-arg checkout=$(git describe --tags `git rev-list --tags --max-count=1`) -t myrepository/lnd:latest-tag ``` Once the image has been built and tagged locally, start the container: ``` -docker run --name=lnd-testnet -it lnd:1.0 --bitcoin.active --bitcoin.testnet --bitcoin.node=neutrino --neutrino.connect=faucet.lightning.community +docker run --name=lnd-testnet -it myrepository/lnd:latest-tag --bitcoin.active --bitcoin.testnet --bitcoin.node=neutrino --neutrino.connect=faucet.lightning.community ``` diff --git a/lnwallet/btcwallet/btcwallet.go b/lnwallet/btcwallet/btcwallet.go index 9c737fb2c..6adc7ebff 100644 --- a/lnwallet/btcwallet/btcwallet.go +++ b/lnwallet/btcwallet/btcwallet.go @@ -781,6 +781,8 @@ func (t *txSubscriptionClient) Cancel() { // wallet's notification client to a higher-level TransactionSubscription // client. func (t *txSubscriptionClient) notificationProxier() { + defer t.wg.Done() + out: for { select { @@ -830,8 +832,6 @@ out: break out } } - - t.wg.Done() } // SubscribeTransactions returns a TransactionSubscription client which diff --git a/lnwallet/wallet.go b/lnwallet/wallet.go index 7c9d243f2..66ee55828 100644 --- a/lnwallet/wallet.go +++ b/lnwallet/wallet.go @@ -425,6 +425,8 @@ func (l *LightningWallet) ActiveReservations() []*ChannelReservation { // requestHandler is the primary goroutine(s) responsible for handling, and // dispatching replies to all messages. func (l *LightningWallet) requestHandler() { + defer l.wg.Done() + out: for { select { @@ -450,8 +452,6 @@ out: break out } } - - l.wg.Done() } // InitChannelReservation kicks off the 3-step workflow required to successfully diff --git a/peer/brontide.go b/peer/brontide.go index 12780ee49..164bbdf41 100644 --- a/peer/brontide.go +++ b/peer/brontide.go @@ -1836,6 +1836,8 @@ out: } } + // Avoid an exit deadlock by ensuring WaitGroups are decremented before + // disconnect. p.wg.Done() p.Disconnect(exitErr)