# \[GUIDE\] Installing charge-lnd (in a docker) to automate your fee policies

**URL:** <https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187>\
**Category:** General Discussion\
**Created:** [July 27, 2021, 10:08am UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187 "2021-07-27T10:08:20Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![The\_Lorax](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.umbrel.com/the_lorax/32/847_2.png) [@The\_Lorax](https://community.umbrel.com/u/The_Lorax)\
**Post date:** [July 27, 2021, 10:08am UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/1 "2021-07-27T10:08:20Z")

</div>

**Update: I’ve published this on Y’alls as well, for those of you who wish to tip anonymously [Y'alls: How to automatically update your routing f](https://yalls.org/articles/97d67df1-d721-417d-a6c0-11d793739be9:0965AC5E-56CD-4870-9041-E69616660E6F/0d395aab-d85d-4039-a5cc-682950e89a9d)**

Greetings, all

I’m happy to report that I now have [charge-lnd](https://github.com/accumulator/charge-lnd) working smoothly on Umbrel, in a docker. Getting this to work took me a few weeks, and generous help and a lot of patience from Jorijn (one of the developers of charge-lnd) and my friend @yuvadm. Thanks guys!

I wanted to create a guide for all of you who are non-technical (like me), so that you can simply follow along with the steps and get auto-fee management on your node. As you probably know, Umbrel is notoriously finicky about you playing with it’s core files, so **my main objective here was to install all files either on the SSD, to prevent you from losing your configurations during updates, or within a docker container, so that no core system functionality or apps are disturbed**

Alright, let’s begin:

* * *

## 1. Log in to your Umbrel’s ssh via a command line tool on your computer (Terminal on Mac, for example):

```auto
ssh -t umbrel@Umbrel.local

```

You’ll need your admin password, which is the one you set on the back end.

## 2. Create a directory on the SSD for the config file (so it doesn’t get erased upon updates or SD card reflashes)

```auto
mkdir -p /mnt/data/upgrades/charge-lnd

```

## 3. Create a config file there:

```auto
sudo nano /mnt/data/upgrades/charge-lnd/charge.config

```

## 4. Populate the file with the rules you want, using [the sample config file](https://github.com/accumulator/charge-lnd/blob/master/charge.config.example)

You can change these rules at any time, and add to them as you go along, so I suggest starting with something basic.

If you need an explanation of how the parameters and rules work, [here is a list of the parameters and their explanations](https://github.com/accumulator/charge-lnd).

**Here is my config file, for a starting reference point:**

```auto
[default]
# 'default' is special, it is used if no other policy matches a channel
strategy = static
base_fee_msat = 0
fee_ppm = 97

[ignored_channels]
# don't let charge-lnd set fees (strategy=ignore) for channels to/from the specified nodes
node.id = 021c97a90a411ff2b10dc2a8e32de2f29d2fa49d41bfbb52bd416e460db0747d0d

strategy = ignore

[leafnode]
# charge non-routing (private=true) peers a bit more for our service
chan.private = true
strategy = static
fee_ppm = 150

[proportional]
# 'proportional' can also be used to auto balance (lower fee rate when low remote balance & higher rate when higher remote balance)
# fee_ppm decreases linearly with the channel balance ratio (min_fee_ppm when ratio is 1, max_fee_ppm when ratio is 0
strategy = proportional
min_fee_ppm = 50
max_fee_ppm = 250

```

## 5. Now, we need to find the IP of your docker.

Run this command:

```auto
sudo nano ~/umbrel/.env

```

Find the line with _LND\_IP_ in it, and copy that IP address. Exit without saving.

## 6. Run the docker

The way charge-lnd works is by running the container “one time” - rather than keeping it open and alive persistently. This is different from other docker installations that Umbrel uses, but it doesn’t matter. We can ask our Pi to run the docker from the files hosted on the web.

First, make sure that you are in the right directory…

```auto
cd ~

```

Now, create the docker w/ the file you’ve already created as the config file. **Don’t forget to replace the IP address with the one you found above.**

```
docker run --rm -it --network=umbrel_main_network \
-e GRPC_LOCATION=LND.IP.ADDRESS.GOES.HERE:10009 \
-e LND_DIR=/data/.lnd \
-e CONFIG_LOCATION=/app/charge.config \
-v /home/umbrel/umbrel/lnd:/data/.lnd \
-v /mnt/data/upgrades/charge-lnd/charge.config:/app/charge.config \
accumulator/charge-lnd:latest

```

If everything works as expected, you’ll see a list of all of your channels, and the changes that have been made according to your rules / policies.

 ![image](https://canada1.discourse-cdn.com/flex030/uploads/getumbrel/original/1X/c02c755db4f2c264e1d39bc7511a103013aaa1b9.png)

Check that you’re happy with how it’s applying rules.

If not, go ahead and edit the charge.config file on your hard disk that we created, then run the above “run” command again.

## 7. Now, Automate it!

Once you’re happy with everything, you can optionally set up a “crontab” job to automatically run this command every X minutes or hours.

Simply type:

```auto
crontab -e

```

The system will create a new crontab file, since none exists.

In this file, you can put the following, all on one line **(make sure to update the IP address in this to yours)**:

```auto
0 * * * * docker run --rm --network=umbrel_main_network -e GRPC_LOCATION=YOUR.LND.IP.ADDRESS:10009 -e LND_DIR=/data/.lnd -e CONFIG_LOCATION=/app/charge.config -v /home/umbrel/umbrel/lnd:/data/.lnd -v /mnt/data/upgrades/charge-lnd/charge.config:/app/charge.config accumulator/charge-lnd:latest

```

This will run your charge-lnd script _once every hour_. This is the maximum recommended frequency by charge-lnd, as running it more frequently can result in failed routes or other confusion and chatter on the network.

If you wish to run it more/less frequently, that’s up to you, and you can find the instructions for changing the `0 * * * *` part of the command above here: [https://crontab.guru](https://crontab.guru)

## That’s all!

If you’ve followed the steps above correctly, everything should work just fine, and update your routing policies every hour on the hour.

This guide was created with the help and support of a LOT of people MUCH smarter than me - and of course, it leverages the awesome (and free) script written by accumulator - so make sure to support their work.

With that said, if you appreciate this guide and would like to see me create MORE guides like this, you’re welcome to tip myself or any of the folks who helped me using Telegram [@LNTXBot](https://t.me/lntxbot):

```auto
/tip 100 @The_Lorax_LN

```

```auto
/tip 100 @jorijn

```

```auto
/tip 100 @yuvadm

```

Thanks for reading, I hope you enjoyed this guide.

Happy routing!

EDIT: Removed docker login, it’s no longer necessary

---

<div class="post-metadata">

**Author:** ![takebit](https://avatars.discourse-cdn.com/v4/letter/t/a3d4f5/32.png) [@takebit](https://community.umbrel.com/u/takebit)\
**Post date:** [July 27, 2021, 11:11am UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/2 "2021-07-27T11:11:59Z")

</div>

Great guide! I needed this.

The Docker login I did in #5 did not work in my environment, so I’ll leave the one I used.

```auto
docker login docker.pkg.github.com --username <your_github_user_name> --password-stdin <generated_token_not_password>

```

---

<div class="post-metadata">

**Author:** ![The\_Lorax](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.umbrel.com/the_lorax/32/847_2.png) [@The\_Lorax](https://community.umbrel.com/u/The_Lorax)\
**Post date:** [July 27, 2021, 11:17am UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/3 "2021-07-27T11:17:35Z")

</div>

everything else worked correctly? I was worried that I had some mistakes in the ~/umbrel type thing etc.

---

<div class="post-metadata">

**Author:** ![takebit](https://avatars.discourse-cdn.com/v4/letter/t/a3d4f5/32.png) [@takebit](https://community.umbrel.com/u/takebit)\
**Post date:** [July 27, 2021, 11:23am UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/4 "2021-07-27T11:23:06Z")

</div>

Thanks, I don’t think there was a problem.  
The only thing is that some people might miss it if you don’t tell them that they need to enter the IP again in the following command as well.

> [@The\_Lorax](#):
>
> In this file, you can put the following, all on one line:
> 
> ```auto
> 0 * * * * docker run --rm --network=umbrel_main_network -e GRPC_LOCATION=YOUR.LND.IP.ADDRESS:10009 -e LND_DIR=/data/.lnd -e CONFIG_LOCATION=/app/charge.config -v /home/umbrel/umbrel/lnd:/data/.lnd -v /home/umbrel/umbrel/apps/charge-lnd/charge.config:/app/charge.config accumulator/charge-lnd:latest
> 
> ```
> 
> This will run your charge-lnd script _once every hour_. This is the maximum recommended frequency by charge-lnd, as running it more frequently can result in failed routes or other confusion and chatter on the network.

---

<div class="post-metadata">

**Author:** ![The\_Lorax](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.umbrel.com/the_lorax/32/847_2.png) [@The\_Lorax](https://community.umbrel.com/u/The_Lorax)\
**Post date:** [July 27, 2021, 11:47am UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/5 "2021-07-27T11:47:42Z")

</div>

Good call. I went ahead and updated this.  
Hope it increases your routing fees 🙂

---

<div class="post-metadata">

**Author:** ![lukeonchain](https://avatars.discourse-cdn.com/v4/letter/l/f14d63/32.png) [@lukeonchain](https://community.umbrel.com/u/lukeonchain)\
**Post date:** [August 3, 2021, 5:20am UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/6 "2021-08-03T05:20:32Z")

</div>

hey @The_Lorax. small suggestion for step #6  
the below command might be better to find LND\_IP (less tech savvy won’t have to worry about accidentally saving the file, just saying)

> cat ~/umbrel/.env | grep LND\_IP  
> LND\_IP=192.168.1.100

---

<div class="post-metadata">

**Author:** ![Diesel](https://avatars.discourse-cdn.com/v4/letter/d/6bbea6/32.png) [@Diesel](https://community.umbrel.com/u/Diesel)\
**Post date:** [August 5, 2021, 7:19pm UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/7 "2021-08-05T19:19:30Z")

</div>

> [@The\_Lorax](#):
>
> ```auto
> [default]
> # 'default' is special, it is used if no other policy matches a channel
> strategy = static
> base_fee_msat = 0
> fee_ppm = 97
> 
> [ignored_channels]
> # don't let charge-lnd set fees (strategy=ignore) for channels to/from the specified nodes
> node.id = 021c97a90a411ff2b10dc2a8e32de2f29d2fa49d41bfbb52bd416e460db0747d0d
> 
> strategy = ignore
> 
> [leafnode]
> # charge non-routing (private=true) peers a bit more for our service
> chan.private = true
> strategy = static
> fee_ppm = 150
> 
> [proportional]
> # 'proportional' can also be used to auto balance (lower fee rate when low remote balance & higher rate when higher remote balance)
> # fee_ppm decreases linearly with the channel balance ratio (min_fee_ppm when ratio is 1, max_fee_ppm when ratio is 0
> strategy = proportional
> min_fee_ppm = 50
> max_fee_ppm = 250
> 
> ```

I’m trying this with no experience in Terminal on my Mac outside of changing my Node Alias and color…

With that being said, I can’t get past step 4. I copied and pasted what you’ve shown but then do I need to hit ‘write out’? Then I have a lot of other options after I hit write out if that is the right step as it says ‘file name to write’ such as DOS format, Mac format, Append, prepend, etc.

Any comments for a real beginner would be greatly appreciated.

---

<div class="post-metadata">

**Author:** ![biglebowski](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.umbrel.com/biglebowski/32/925_2.png) [@biglebowski](https://community.umbrel.com/u/biglebowski)\
**Post date:** [August 6, 2021, 5:15pm UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/8 "2021-08-06T17:15:08Z")

</div>

Great tutorial The\_Lorax!

Your twitter story on the 18th of july was my inspiration to get started with getumbrel and lightning!  
Hope to open a channel to you soon, waiting for some incoming liquidity.

I sent you some sats via Telegram.

---

<div class="post-metadata">

**Author:** ![The\_Lorax](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.umbrel.com/the_lorax/32/847_2.png) [@The\_Lorax](https://community.umbrel.com/u/The_Lorax)\
**Post date:** [August 8, 2021, 10:40am UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/9 "2021-08-08T10:40:12Z")

</div>

Hey! Thanks for the sats. Kind of you.  
And thanks for the channel. Glad my thread impacted you!

---

<div class="post-metadata">

**Author:** ![The\_Lorax](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.umbrel.com/the_lorax/32/847_2.png) [@The\_Lorax](https://community.umbrel.com/u/The_Lorax)\
**Post date:** [August 8, 2021, 10:41am UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/10 "2021-08-08T10:41:11Z")

</div>

Yo!  
You need to write out, so Ctrl+X, then just hit enter, to save the file with the same file name it’s offering you (we definitely don’t want to change that file name). It should be offering you the file name of charge.config if you did everything right (that’s the file that the program looks for). If not, you can save it as that, and as long as you’re in the right directory, it will ;pick up that file

---

<div class="post-metadata">

**Author:** ![Diesel](https://avatars.discourse-cdn.com/v4/letter/d/6bbea6/32.png) [@Diesel](https://community.umbrel.com/u/Diesel)\
**Post date:** [August 9, 2021, 3:11pm UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/11 "2021-08-09T15:11:48Z")

</div>

Thanks! I skipped to 6. and copied the IP address and am now trying to jump into 7. but when I paste the command I can’t move lines to change my IP address. I’m assuming this is something basic that I’m missing. I’m entering this command (#7.) after logging into SSH Umbrel as I did in step 1.

---

<div class="post-metadata">

**Author:** ![takebit](https://avatars.discourse-cdn.com/v4/letter/t/a3d4f5/32.png) [@takebit](https://community.umbrel.com/u/takebit)\
**Post date:** [August 9, 2021, 4:06pm UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/12 "2021-08-09T16:06:33Z")

</div>

After copied the command, why don’t you use Notepad or something to replace the IP address with the one you got in step 6 and then paste it line by line?

---

<div class="post-metadata">

**Author:** ![Brethberie](https://avatars.discourse-cdn.com/v4/letter/b/278dde/32.png) [@Brethberie](https://community.umbrel.com/u/Brethberie)\
**Post date:** [August 14, 2021, 3:59am UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/13 "2021-08-14T03:59:56Z")

</div>

> [@The\_Lorax](#):
>
> `docker login [docker.pkg.github.com](http://docker.pkg.github.com/) --username <your_github_user_name> --password <generated_token_not_password>`

Correct input for me was: ‘docker login [docker.pkg.github.com](http://docker.pkg.github.com) --username \<your\_github\_user\_name\> --password \<generated\_token\_not\_password\>’

---

<div class="post-metadata">

**Author:** ![The\_Lorax](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.umbrel.com/the_lorax/32/847_2.png) [@The\_Lorax](https://community.umbrel.com/u/The_Lorax)\
**Post date:** [August 14, 2021, 4:37am UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/14 "2021-08-14T04:37:55Z")

</div>

I removed Step 5, it’s not necessary anymore.

---

<div class="post-metadata">

**Author:** ![Diesel](https://avatars.discourse-cdn.com/v4/letter/d/6bbea6/32.png) [@Diesel](https://community.umbrel.com/u/Diesel)\
**Post date:** [August 16, 2021, 11:32am UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/15 "2021-08-16T11:32:09Z")

</div>

I was able to get Step 6 entered but this is what I got back and didn’t see any of my channels being updated as you noted I should:

Traceback (most recent call last):  
File “/usr/local/bin/charge-lnd”, line 5, in   
from charge\_lnd.charge\_lnd import main  
File “/usr/local/lib/python3.9/site-packages/charge\_lnd/charge\_lnd.py”, line 146, in   
success = main()  
File “/usr/local/lib/python3.9/site-packages/charge\_lnd/charge\_lnd.py”, line 30, in main  
config = Config(arguments.config)  
File “/usr/local/lib/python3.9/site-packages/charge\_lnd/config.py”, line 18, in **init**  
with open(config\_file, “r”) as f:  
IsADirectoryError: [Errno 21] Is a directory: ‘/app/charge.config’

Any idea what could be going on with this error shown?

A couple other things:

1. When I try to make sure I’m in the right directory and type cd ~ after logging into ssh-Umbrel by typing my password - Nothing happens. Am I possibly not in the right directory?
2. I think I accidentally ran the step 6 command without updating my IP address once, not sure if that could have messed something up with this command
3. I simply copy and pasted the sample config file in step 4 without updating any lines. As a dumb questions here I’m thinking I may have needed to update with my channel ID information before writing the config file out?

Thanks, I know my questions are probably pretty unintelligent but maybe there’s someone even less savvy with command line out there than me that will get find some of this useful!

---

<div class="post-metadata">

**Author:** ![The\_Lorax](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.umbrel.com/the_lorax/32/847_2.png) [@The\_Lorax](https://community.umbrel.com/u/The_Lorax)\
**Post date:** [August 19, 2021, 7:48am UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/16 "2021-08-19T07:48:05Z")

</div>

Hi unfortunately I don’t know what the deal is with the error above, I think maybe there should be something above what you pasted that I’m not seeing, or I just don’t understand it (I’m not a coder, after all).

If you do cd ~ and you’re already in the home directory, nothing will happen.

---

<div class="post-metadata">

**Author:** ![takebit](https://avatars.discourse-cdn.com/v4/letter/t/a3d4f5/32.png) [@takebit](https://community.umbrel.com/u/takebit)\
**Post date:** [August 22, 2021, 5:51pm UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/18 "2021-08-22T17:51:05Z")

</div>

After updating the OS, I was able to make it work again by recreating the charge.config.

```auto
sudo rmdir ~/umbrel/apps/charge-lnd/charge.config

```

create the “charge.config” again.

```auto
sudo nano ~/umbrel/apps/charge-lnd/charge.config

```

---

<div class="post-metadata">

**Author:** ![Dan](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.umbrel.com/dan/32/584_2.png) [@Dan](https://community.umbrel.com/u/Dan)\
**Post date:** [August 22, 2021, 8:09pm UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/19 "2021-08-22T20:09:40Z")

</div>

Tried your steps but got:

**Error writing /home/umbrel/umbrel/apps/charge-lnd/charge.config: Is a directory**

Any tips what I did wrong? (total noob who can barely make directory)

Edit: Apparently somehow it is needed to delete directory this way:  
**rmdir ~/umbrel/apps/charge-lnd**

```
    Then:

```

**mkdir ~/umbrel/apps/charge-lnd**

```
    Finally once again:

```

**sudo nano ~/umbrel/apps/charge-lnd/charge.config**

---

<div class="post-metadata">

**Author:** ![takebit](https://avatars.discourse-cdn.com/v4/letter/t/a3d4f5/32.png) [@takebit](https://community.umbrel.com/u/takebit)\
**Post date:** [August 22, 2021, 8:26pm UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/20 "2021-08-22T20:26:17Z")

</div>

I encountered this problem when I updated to 0.4.0 last month.  
At that time, I deleted “~/umbrel/apps/charge-lnd” and followed the instructions from step 2.

I thought I just had to recreate the charge.config as I wrote earlier.

---

<div class="post-metadata">

**Author:** ![The\_Lorax](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.umbrel.com/the_lorax/32/847_2.png) [@The\_Lorax](https://community.umbrel.com/u/The_Lorax)\
**Post date:** [August 23, 2021, 7:41am UTC](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187/21 "2021-08-23T07:41:24Z")

</div>

Yes, it’s been brought to my attention that anything saved in the /umbrel/directory or below it will be rewritten on software update. I need to update the guide a little bit and change the directory, the crontab, etc. I’ll try to do it now.

[Next page](https://community.umbrel.com/t/guide-installing-charge-lnd-in-a-docker-to-automate-your-fee-policies/2187.md?page=2)
