A Complete Beginners Guide to Installing a Lightning Node on Linux (2021 Edition)

Running LND With a Bitcoin Core Full Node

21 min readFeb 22, 2021



In 2018 I made a tutorial for getting a Bitcoin full node up and running on Linux, and I provided a complete step-by-step process, along with explainers for how to use & understand the bash shell, and what certain commands and their flags did. It’s been 3 years since, it’s been fully updated here, and what you’re reading now is the new supplementary Lighting tutorial.

This tutorial is 1 of 3 being published in tandem. The primary tutorial brings the other two together to run over Tor and connect your phone’s Bitcoin & Lightning wallets to it. The other two (which includes this one) function as standalone tutorials for both Bitcoin & Lightning respectively, and they completely break down the entire node installation process for beginners:



Table Of Contents

  • Introduction
  • Part 0Just The Commands (For Quick Reference)
  • Part 1Installing ‘Go’ & LND
  • Part 2 Configuring LND & Syncing The Graph
  • Part 3 Funding Your Wallet
  • Part 4 Opening Channels
  • Part 5Connecting The Zap Mobile Wallet
  • Extra Guidance
    How To Create A Transaction Index
    How To Recompile/Update Bitcoin Core
    How To Update LND


If you followed my Bitcoin tutorial you can just skip straight to Part 1.

There’s a few requirements & assumptions this tutorial has if you are arriving here with a Bitcoin node already installed. You may use this tutorial to install Lightning (LND), but this tutorial is meant to follow up the install process detailed in my Bitcoin tutorial. If you did not follow that process, please make note of the details below:

1: You need to have ‘bitcoind’ installed (Bitcoin Core):

We’ll be installing the LND implementation of the Lightning Network. LND is compatible with specific Bitcoin node backends, so you will need to have one of these installed for LND to work:

  • btcd
  • neutrino
  • bitcoind

This tutorial requires you have bitcoind installed, also known as Bitcoin Core.

2: ‘bitcoind’ needs to be compiled with ZeroMQ:

If you didn’t not arrive here from my Bitcoin tutorial, then it’s possible you did not have a required LND dependency when you installed Bitcoin.

You’ll need to recompile Bitcoin after you install the ZeroMQ library:
$ sudo apt-get install libzmq3-dev

I’ve provided instructions for how to do this here.

3: This guide is designed for Debian based Linux operating systems:

I’m working with Kubuntu, which is very similar to Ubuntu, and a Debian based operating system. If you’re using a non-Debian version of Linux then you might have to work the guide a bit to suite your needs.

It also uses AMD64 architecture. There are a few steps that will need to be modified if you aren’t using an AMD64 distribution. They will be made clear, but you may also need additional dependencies (that is on you).

4: Install directory can be changed:

The install directory (~/code/lnd) used in this tutorial is chosen with my Bitcoin tutorial in mind, and is meant to be friendly to Linux beginners. Feel free to change the install path at your own discretion. I do not recommend changing the default data directory (~/.lnd), it may cause issues.

5: You may want to resync Bitcoin with the configuration txindex=1:

LND performs better if your Bitcoin Core node has a “transaction index”. Your bitcoin.conf file should include a line that says txindex=1. If it doesn’t, that’s fine, but you may want to consider syncing your node again with that setting on.

I’ve provided instructions for how to do this here.

Part 0 — For Those Who Just Want The Commands

You’ll notice that this section is very short, but the tutorial is pretty long. I’m putting these 8 commands in the beginning to demonstrate that this is all we are really doing (plus copy & pasting text into a configuration file). This tutorial is designed for beginners to Linux, so all facets of the following steps will be explained in detail, and then some.

Download & Install Go:

$ wget https://dl.google.com/go/go1.15.6.linux-amd64.tar.gz$ sudo tar -C /usr/local -xzf go1.15.6.linux-amd64.tar.gz

Prep for LND Install:

$ echo "export PATH=$PATH:~/go/bin:/usr/local/go/bin" >> ~/.bashrc

Clone the LND Repository:

$ cd ~/code$ git clone https://github.com/lightningnetwork/lnd

Install LND:

$ cd ~/code/lnd$ git checkout tags/v0.12.0-beta$ make install

Part 1 — Installing ‘Go’ & LND

Installing LND is pretty quick and simple, but LND specifically needs one more dependency installed other than the dependencies installed for Bitcoin (including the ZeroMQ one mentioned above).

Go is the programming language that LND is written in, so we’ll need to install it first. Originally LND needed to be installed within the Go directory, but that is no longer necessary, along with some other steps we can fortunately skip, allowing the bulk of this tutorial to focus on using our Lightning node.

Downloading & Installing Go:

First we’re going to get the Go package from the Google URL in the command below, then we’re going to verify the SHA256 checksum against what it is supposed to be.

$ wget https://dl.google.com/go/go1.15.6.linux-amd64.tar.gz$ sha256sum go1.15.6.linux-amd64.tar.gz | awk -F " " '{ print $1 }'

The output from the sha256sum command should be this:


Next we’re going to install Go by extracting (“unzipping”) the .tar.gz package we downloaded.

tar , sometimes called tarball, is a file archiving tool, and is very similar to the more familiar zip file format.

$ sudo tar -C /usr/local -xzf go1.15.6.linux-amd64.tar.gz

The -C flag will instruct the tar command to place the files into the directory specified (/usr/local). The files in this archive will be within a folder named /go when extracted, so the final install path when complete will be /usr/local/go.

The -xzf flags are commonly used when extracting & installing software.

Just like there is zip (archive) and unzip (extract), the -x flag instructs tar to extract the files.

The -z flag tells the tar command that we’re working with a .tar.gz file, which is a compressed archive.

The -f flag outputs the files & directories just as described in the archive.

Prepping & Installing LND:

When we install LND, LND will need to reference the Go binaries we just installed, so the first thing we’re going to do is redefine the shell’s PATH variable.

When executing commands & scripts, they need to exist somewhere, and the where needs to be defined. The PATH variable tells the shell where to look for commands & scripts. When LND is installing, it will ask the shell something like “can you defrost the steak I bought earlier today?” We know the steak is probably in the freezer. The shell has no idea where we installed that Go binary.

If you were to type echo $PATH the output would show you what directories are currently defined:

$ echo $PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

Each directory is separated by a : , like so: directory1:directory2 .
So that same output can also be interpreted like this:

1: /usr/local/sbin
2: /usr/local/bin
3: /usr/sbin
4: /usr/bin
5: /sbin
6: /bin
7: /usr/games
8: /usr/local/games
9: /snap/bin

We need to add two other directories to this list.
To do this we’re going to enter the following command:

$ echo "export PATH=$PATH:~/go/bin:/usr/local/go/bin" >> ~/.bashrc

export will redefine PATH by making it equal to what it already is (that long list), plus the~/go/bin and /usr/local/go/bin directories.

echo, the way it’s being used here, will take the output of the export command inside the quotes, and then send it into (via >>) the file ~/.bashrc on a new line.

~/.bashrc is one of a few files that the shell will reference when you launch the shell. If there is ever a time in the future where you need to redefine you PATH variable, you’ll want to open that file and edit the line we just added.

Go ahead and close the shell, and then open a new one so it can load the redefined PATH variable we just set.

If you were to type echo $PATH again after running that command and opening a new shell, the output would now show this:

$ echo $PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:~/go/bin:/usr/local/go/bin

Now with the PATH variable defined, let’s move to where we want to clone the LND repository, and then clone it:

$ cd ~/code$ git clone https://github.com/lightningnetwork/lnd

Finally, move into the /lnd directory created from cloning the repository, and then install LND:

$ cd ~/code/lnd$ git checkout tags/v0.12.0-beta$ make install
Video cuts off after 60 seconds, but the install time was less than 2 minutes. This video was recorded before LND v0.12.0-beta was released.

Part 2 — Configuring LND & Syncing The Graph

In this section we’re going to create a lnd.conf file and configure LND to work the way we want it to. Then we’re going to revisit the bitcoin.conf file and modify it so LND will work with Bitcoin Core. Finally, we’re going to launch Bitcoin & Lightning, create a Lightning wallet, and allow the Lightning Graph to sync.

Configuring The lnd.conf File

We’re going to create a lnd.conf file and copy everything below into it. Before we do that though, let’s cover what each setting is doing, and the changes we’ll need to make:

## LND Settings# Lets LND know to run on top of Bitcoin (as opposed to Litecoin)
# Lets LND know you are running Bitcoin Core (not btcd or Neutrino)
## Bitcoind Settings# Tells LND what User/Pass to use to RPC to the Bitcoin node
# Allows LND & Bitcoin Core to communicate via ZeroMQ
## Zap Settings# Tells LND to listen on all of your computer's interfaces
# This could alternatively be set to your router's subnet IP
# Tells LND where to listen for RPC messages
# This could also be set to your router's subnet IP

LND Settings:

These are fairly straightforward settings to explain. LND needs to know a few things before launching:

  1. Whether it’s going to run on top of Bitcoin or Litecoin: bitcoin.active=true
  2. Whether to use the main network, or the test network:
  3. What kind of Bitcoin client it’s going to connect to:

Bitcoind Settings:

LND will communicate with our Bitcoin Core node via RPC, and via ZeroMQ. Both the lnd.conf & bitcoin.conf will need to be configured for this, but we will cover editing the bitcoin.conf file after this.

The only configuration RPC needs is setting a username & password. This is unrelated to your operating system’s username & password. LND needs to know what that username & password is. Replace the text next to bitcoind.rpcuser= & bitcoind.rpcpass= with whatever you want, just make sure it’s reasonably secure.

To configure ZeroMQ, we just need to specify where to send and listen for those messages, and over what ports. No changes to the config text we’re going to copy are necessary for this.

Zap Settings:

If you’re going to install the Zap mobile wallet, you’ll need to configure LND so you can connect via LND’s gRPC interface. (This will not be the same for the Tor guide. Over Tor, Zap will use LND’s REST interface. Do not worry about this right now.)

tslextraip= allows you to set your router’s subnet IP address so LND listens for connections coming from your router. LND uses a TLS certificate to manage these connections. By default LND will create a TLS certificate that only allows connections from the same computer that LND is running on, so we need to specify where else LND should listen for connections before the TLS certificate is created.

Connections from Zap on your phone will be over the Internet, so your phone will reach your router first. Then your router will have to forward that connection to your computer running LND. Everyone’s router subnet varies, so using lets LND listen on all possible subnets and helps keeps things simple for this tutorial. It works and you don’t need to change it, but you could.

rpclisten= tells LND where to listen for gRPC connections. After including the subnet (or in our case all subnets) above into the TLS certificate, which allows the connections from the router, we now need to specify that gRPC should listen for connections from the router, and over what port. (We’ll cover port forwarding later on.)

When we launch LND it’s going to create a hidden /.lnd folder where the node’s data and configurations will be placed, similar to the /.bitcoin directory.

We’re going to create that directory in advance, along with the lnd.conf file:

$ mkdir -p ~/.lnd && touch ~/.lnd/lnd.conf

And then we’re going to paste the config text above into that file:

Configuring The bitcoin.conf File

If you followed the Bitcoin Beginners Guide, you only need to add this under the current settings in the bitcoin.conf file located in ~/.bitcoin:

# Allows LND to connect to the Bitcoin node via an RPC user & pass
# Allows LND & Bitcoin Core to communicate via ZeroMQ

Make sure to replace the bold sections above with the RPC username and password you put in the lnd.conf file.

These additions to the config file should be self explanatory if you read the previous section. We’re just making sure both config files have the same settings.

If you did not follow that guide, your bitcoin.conf file will be located elsewhere, and you may want to consider adding txindex=1 and resyncing the blockchain, as LND will perform better.

Launching Bitcoin & LND

Launch Bitcoin if it’s not already running and make sure it’s fully synced. If you started the Bitcoin GUI using bitcoin-qt, go ahead and close out the application, and then relaunch Bitcoin using bitcoind. We don’t need or want the GUI any longer:

$ bitcoind

Now that Bitcoin is running, wait about a minute (watch the log output) and then open a second terminal and launch LND via the following command:

$ lnd
We’ll use the 3rd terminal window in the next step.

Creating The Lightning Wallet

When launching LND for the first time, you’ll be prompted in the terminal to create a wallet before LND can proceed (highlighted at the end of the video above):

[INF] LTND: Waiting for wallet encryption password. Use `lncli create` to create a wallet, `lncli unlock` to 
unlock an existing wallet, or `lncli changepassword` to change the password of an existing wallet and unlock it.

We need to open a new terminal to enter the command for creating a new wallet (video below). So go ahead and open a new terminal, then enter:

$ lncli create

When creating the wallet we’ll be prompted for a few different things:

1: Create a password for the wallet file:

Input wallet password:  
Confirm password:

2: Do you have a seed phrase you want to import? (We will choose ’n’ for no.):

Do you have an existing cipher seed mnemonic you want to use? (Enter y/n): n

3: Encrypt the wallet seed with a passphrase (also known as a 25th word):

Your cipher seed can optionally be encrypted. 
Input your passphrase if you wish to encrypt it (or press enter to proceed without a cipher seed passphrase):

Whatever you decide to do, write all of this down and keep it safe.

After the wallet is created we’ll see more output from the terminal running LND. It will begin finding other Lighting Network peers and gathering node & channel information. You now have a Lightning node!

Part 3 — Funding Your Wallet

With our Lightning node up and running, and the wallet created, the first thing we’re going to do is generate an address so we can send some Bitcoin to it. LND doesn’t have a GUI, so this will all be through the terminal. Later on the Zap wallet will function as our GUI.

Address Generation & Funding

To generate an address enter the following into a terminal:

$ lncli newaddress np2wkh

(If you want to generate a native Segwit address, use p2wkh instead.)

All you need to do now is send Bitcoin to that address. For the purposes of this tutorial I’m going to send 0.0015 BTC.

If you’re using a mobile phone to send the Bitcoin, you may find it easier to scan a QR code. If you wish to, at the cost of some privacy, paste your newly generated address into the search box on https://blockstream.info/, and it will generate a QR code for you:

Once the Bitcoin is sent, we’ll need to wait for it to be confirmed into a block. This could take 30 seconds, or a day, depending on the fee that you paid, and the current network conditions.

In the meantime, we can check the confirmation status using this command:

$ lncli walletbalance

Keep checking until the “confirmed balance” changes from 0, to the amount of Bitcoin that you sent. LND will display this in sats (satoshis).

When it finally confirms, you can use the following command to check for how many confirmations your transaction has, among other information:

$ lncli listunspent

Part 4 — Opening Channels

After a couple of confirmations, we’re ready to begin opening a channel. Before we do so, we need to decide what node we’re going to open a channel with first, then establish a connection with it, and finally open the channel.

Picking A Node And Connecting To It

Every node has a “node ID” (a public key), including ours. When we connect with that node, a secure communication line with that node will be established, which will then allow us to securely create a channel with that node. For the purposes of this tutorial I’m going to connect to ACINQ’s Lightning node. You can choose any node you would like, although for your first channel you’ll want to pick a node with decent liquidity. ACINQ’s public key, IP address, and port number can be found on LN browser sites like 1ml.com:

In the terminal, enter the following (all one string),

$ lncli connect 03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f@

The command format above is [PublicKey] @ [IPAddress] : [Port] without any spaces or brackets. After entering the command, as seen in the picture below, the LND logs will show you that the connection was established (if successful).

Opening A Channel

Once the connection is established, to open the channel we’ll need to use the command lncli openchannel, but it will require us to specify what node, and the amount. This will be done using the flags --node_key= & --local_amt=.

The following command it what I used:

$ lncli openchannel --node_key=03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f --local_amt=10000

When opening a channel, the amount that we enter will specify how large the channel will be, and it will not include the fees required to open that channel. Therefor we cannot use all of the satoshis we just sent to the LN node. The video below will demonstrate the error we receive if we try to:

Instead, use a smaller amount than the total when opening the channel:

After opening the channel and receiving the transaction ID, we can use LND to check the status via this command:

$ lncli pendingchannels

The LN requires a channel’s transaction to have 3 confirmations before it can be used. When the channel is finally confirmed 3 times it is considered opened, and the output from lncli pendingchannels will look like this instead:

Now that the channel is finally opened, we can begin making payments. You have a functional non-routing LN node. Payments can be made using LND directly, but now we’re going to connect LND to the Zap wallet and use Zap’s interface instead.

Part 5 — Connecting The Zap Mobile Wallet

This section will guide you through connecting the Zap mobile wallet for iOS with our LND node. You may also use the desktop version of Zap if you’d like. First we will need to install LND Connect, which is a small piece of software that will generate a QR code we will use to connect our Zap wallet to LND. After we scan the QR code Zap will be connected over the local network, so if you you are using Zap over WiFi at home you’ll be able to interact with LND at this point. After that we can optionally set up port forwarding on our router, which will enable us to connect Zap to our LND node over the Internet.

Installing LND Connect

To install LND Connect, just run the following commands and make sure you replace ‘satoshi’ with your username:

$ go get -d github.com/LN-Zap/lndconnect$ cd /home/satoshi/go/src/github.com/LN-Zap/lndconnect$ make

Connecting Zap

Zap can be found on the iOS store. Just download it, launch it, and put it to the side for now. Alternatively you can download the desktop version and follow the same steps with a little bit of intuition.

With LND running, in a terminal enter the following:

$ cd ~$ lndconnect --image

This will create a QR code image in your home directory with the name lndconnect-qr.png. From your file browser open the image, and then scan it using Zap:

Once it’s scanned Zap will attempt to connect to your node, and if successful you should see a screen showing your node’s current balance:

At this point you may consider the tutorial complete. If Zap cannot connect, you either need to review the LND configuration settings we made earlier.

Using Zap To Control & View Our LND Node

Once Zap connects you’ll be displayed with a Send/Receive screen that shows our node’s total balance, which includes the send capacity of all our channels and whatever remaining Bitcoin we have in our wallet that isn’t currently in a channel.

From the Send/Receive screen, swipe right and then select the Channels menu:

This will display your current channels, their individual capacity, and how they are balanced. Since all we did so far was open a channel, our channel should only have capacity to send payments, like so:

Once you start making payments, you’ll then be able to receive payments as well, and this will be represented like so:

You can also open channels by clicking the + sign at the top right, and close channels by click on the one you want to close and then clicking ‘Close Channel’:

Port Forwarding

This section is going to require a little bit of intuition. The main reason for this is everyone has a different brand of router, and I won’t be able to guide you through your router’s settings.

If you don’t know what port forwarding is watch this video. Essentially, when our Zap wallet from our phone tries to connect to LND using our IP address, it will reach our router, not our computer. We need to tell our router to send the data to our computer running LND.

When you do get to the router’s port settings, here’s the information you’ll need:

  • External Port: 10009
  • Internal Port: 10009
  • Internal Host/IP: <Your-Computers-Local-IP>
  • Protocol: TCP

To access our router, we simply need to type in the router’s address into our web browser. Since we’re on Linux, we can find that address by opening a terminal and typing route -n, and then looking for the “Gateway” column:

The output from this command can be a bit messy, depending on your setup. You’ll want to look for an address that isn’t in the Gateway column, and then paste that into your web browser. My router’s address is, which is a pretty common one used by many routers. Another common address is Alternatively you can Google your router’s brand to try and find out what the address is.

Once you are able to access your router’s login page, you’ll also need to Google the default username & password for that router. Many of them have both the user & password set to “admin” & “admin”.

After logging in, your router should show you all the devices connected to it. Since my laptop’s device name is nakamoto, I can easily identify it in the router settings, and see the IP address associated with your device. That’s the local IP address.

Navigate to the port forwarding section of your routers interface and input the required information. I’m not going to be able to guide you any further than this. You’ll need to find instructions for you router if it’s unclear.

Enabling The UFW (Uncomplicated Firewall)

Port forwarding tells your router to allow connections over the Internet to get routed to a specified port on your computer, in our case: port 10009.

Depending on your Linux setup, you may need to tell the computer to allow connections on that port from your router. You may also just want to enable a simple firewall for security, and then open port 10009 for Zap.

To enable the UFW and then allow the UFW to listen on 10009 from the router, enter the following (replace with your router’s address we obtained from the port forwarding section above):

$ sudo ufw allow from to any port 10009 comment 'This allows Zap to grpc to LND from the router'$ sudo ufw enable$ sudo ufw status

With the UFW enabled, in the future if you decide to run any other clients, services, or applications that interact over your LAN, you may need to manually perform the ufw allow step for other ports. Just keep that in mind.

Testing Small Payments

Once you have a channel, making payments on the LN is very easy. Wherever you go to pay, a LN ‘invoice’ will be provided to you, and you just scan or copy it to your wallet by clicking on the “Send” button. This section will simply provide you with a list of places you can make some test payments.

Lightning Websites

The following websites are interesting/unique ways you can interact with Lightning. These are not endorsements of these concepts at scale, or the kind of value they actually provide to the network. They’re just interesting ways you can test payments:

https://satoshis.place/ let’s you draw on a public wall and pay via Lightning.

https://pollofeed.com/ has a live stream of chickens that you can feed.

https://yalls.org/ lets you read posts for a small payment.


Alternatively you can make a small donation to the Human Rights Foundation over Lightning:

Extra Guidance

In the future you may want to upgrade your Lightning node, or you may need to resync Bitcoin Core for this tutorial because you didn’t have the transaction index (txindex=1) that LND uses for performance, or you may need to recompile Bitcoin Core because you didn’t have thelibzmq3-dev dependency required for LND. The steps below will help you for these scenarios.

How To Create A Transaction Index

If you don’t have a transaction index, you’ll need your node to create one before running LND. If you didn’t have txindex=1 in your bitcoin.conf file then you don’t have a transaction index. There’s two scenarios for creating one:

  1. Your node is pruned, with no txindex.
  2. Your node is not pruned, with no txindex.

The first thing you want to do for both scenarios is follow the bitcoin.conf steps in this tutorial and make sure you have txindex=1 set in the config file. When that is complete, follow the proper steps below:

If your node is pruned: Start bitcoind with a reindex and let it resync the whole blockchain:

$ bitcoind -reindex

If your node is not pruned: Just start bitcoind normally and let it create the txindex, now that the bitcoin.conf file has the instructions for your node:

$ bitcoind

How To Recompile/Update Bitcoin Core

Recompiling Bitcoin Core and updating Bitcore Core are essentially the same procedure. We’re going to delete or rename the Bitcoin install directory, and then just reinstall Bitcoin all over again with the newer version.

We do not need to:

  • re-sync or re-validate the blockchain
  • create the bitcoin.conf file again
  • re-install any packages or dependencies (unless you’re specifically recompiling because you did not have libzmq3-dev installed, then you would want to install that package first, then recompile Bitcoin Core)

If you followed this tutorial, the install directory is ~/code/bitcoin The non-hidden folder.

If you did not follow this tutorial, the install directory may be ~/bitcoin.

In contrast, the data directory is the hidden folder with the period before the word bitcoin: ~/.bitcoin . Do not delete this folder. Leaving this alone will prevent you from having to re-sync or re-validate the blockchain. Your bitcoin.conf file is there, along with your list of peers, among other things.

If you’re running and old Bitcoin client and want to follow this tutorial, I recommend renaming the install directory to something like “bitcoin-old”, and then just follow the steps from the beginning.

You can double check your client version running this command:

$ bitcoind --version

How To Update LND

To update LND, open a terminal and enter the following commands.

  1. Replace satoshi with your username.
  2. If you followed this tutorial, Go should be installed in your home directory. If not, replace /home/satoshi/go with wherever you have Go installed.
$ cd /home/satoshi/go/src/github.com/lightningnetwork/lnd$ git pull$ make clean && make && make install