lnbits deployment seems to work

This commit is contained in:
counterweight 2025-08-20 16:02:48 +02:00
parent a41e1d9383
commit 0db4cf94b5
Signed by: counterweight
GPG key ID: 883EDBAA726BD96C
4 changed files with 249 additions and 1 deletions

View file

@ -43,4 +43,8 @@ This describes how to prepare each machine before deploying services on them.
* Run `ansible-playbook -i inventory.ini infra/01_user_and_access_setup_playbook.yml -e 'ansible_user="your root user here"'` * Run `ansible-playbook -i inventory.ini infra/01_user_and_access_setup_playbook.yml -e 'ansible_user="your root user here"'`
* Then, configure firewall access, fail2ban and auditd with `ansible-playbook -i inventory.ini infra/02_firewall_and_fail2ban_playbook.yml`. Since the user we will use is now present, there is no need to specify the user anymore. * Then, configure firewall access, fail2ban and auditd with `ansible-playbook -i inventory.ini infra/02_firewall_and_fail2ban_playbook.yml`. Since the user we will use is now present, there is no need to specify the user anymore.
Note that, by applying these playbooks, both the root user and the `counterweight` user will use the same SSH pubkey for auth. Note that, by applying these playbooks, both the root user and the `counterweight` user will use the same SSH pubkey for auth.
## GPG Keys
Some of the backups are stored encrypted for security. To allow this, fill in the gpg variables listed in `example.inventory.ini` under the `lapy` block.

View file

@ -142,3 +142,34 @@ ntfy is a notifications server.
### Backups ### Backups
Given that ntfy is almost stateless, no backups are made. If it blows up, simply set it up again. Given that ntfy is almost stateless, no backups are made. If it blows up, simply set it up again.
## LNBits
LNBits is a Lightning Network wallet and accounts system.
### Deploy
* Decide what subdomain you want to serve LNBits on and add it to `services/lnbits/lnbits_vars.yml` on the `lnbits_subdomain`.
* Note that you will have to add a DNS entry to point to the VPS public IP.
* Run the deployment playbook: `ansible-playbook -i inventory.ini services/lnbits/deploy_lnbits_playbook.yml`.
### Configure
* LNBits will be available for you to create a superuser on first start. Do that and store the creds safely.
* From that point on, you can configure through the Web UI.
* Some advice around specifics of LNbits:
* The default setup uses a FakeWallet backend for testing. Configure a real Lightning backend as needed by modifying the `.env` file located or using the superuser UI.
* For security, disable the new users registration.
### Set up backups to Lapy
* Make sure rsync is available on the host and on Lapy.
* Run the backup playbook: `ansible-playbook -i inventory.ini services/lnbits/setup_backup_lnbits_to_lapy.yml`.
* A first backup process gets executed and then a cronjob is set up to refresh backups periodically. The script backs up both the `.env` file and the sqlite database. Backups are gpg encrypted for safety.
### Restoring to a previous state
* Stop LNBits.
* Overwrite the data folder with one of the backups.
* Start it up again.

View file

@ -0,0 +1,196 @@
- name: Deploy LNBits with Poetry and configure Caddy reverse proxy
hosts: vipy
become: yes
vars_files:
- ../../infra_vars.yml
- ./lnbits_vars.yml
vars:
lnbits_domain: "{{ lnbits_subdomain }}.{{ root_domain }}"
tasks:
- name: Create lnbits directory
file:
path: "{{ lnbits_dir }}"
state: directory
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: '0755'
- name: Install required system packages
apt:
name:
- python3.11
- python3.11-venv
- python3-pip
- git
- curl
- build-essential
- pkg-config
- libffi-dev
state: present
update_cache: yes
- name: Install Poetry
shell: |
curl -sSL https://install.python-poetry.org | python3 -
args:
creates: "{{ lookup('env', 'HOME') }}/.local/bin/poetry"
become: yes
become_user: "{{ ansible_user }}"
- name: Add Poetry to PATH
lineinfile:
path: "{{ lookup('env', 'HOME') }}/.bashrc"
line: 'export PATH="$HOME/.local/bin:$PATH"'
state: present
become: yes
become_user: "{{ ansible_user }}"
- name: Clone LNBits repository
git:
repo: https://github.com/lnbits/lnbits.git
dest: "{{ lnbits_dir }}/lnbits"
version: main
accept_hostkey: yes
- name: Change ownership of LNBits directory to user
file:
path: "{{ lnbits_dir }}/lnbits"
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
recurse: yes
- name: Install LNBits dependencies
command: $HOME/.local/bin/poetry install --only main
args:
chdir: "{{ lnbits_dir }}/lnbits"
- name: Copy .env.example to .env
copy:
src: "{{ lnbits_dir }}/lnbits/.env.example"
dest: "{{ lnbits_dir }}/lnbits/.env"
remote_src: yes
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: '0644'
- name: Configure LNBits environment variables
lineinfile:
path: "{{ lnbits_dir }}/lnbits/.env"
regexp: "^{{ item.key }}="
line: "{{ item.key }}={{ item.value }}"
state: present
loop:
- key: "LNBITS_BACKEND_WALLET_CLASS"
value: "FakeWallet"
- key: "LNBITS_ADMIN_UI"
value: "true"
- key: "HOST"
value: "0.0.0.0"
- key: "PORT"
value: "{{ lnbits_port }}"
- key: "LNBITS_DATA_FOLDER"
value: "{{ lnbits_data_dir }}"
- key: "LNBITS_EXTENSIONS_PATH"
value: "{{ lnbits_data_dir }}/extensions"
- name: Create systemd service file for LNBits
copy:
dest: /etc/systemd/system/lnbits.service
content: |
[Unit]
Description=LNBits
After=network.target
[Service]
Type=simple
User={{ ansible_user }}
WorkingDirectory={{ lnbits_dir }}/lnbits
ExecStart=/home/{{ ansible_user }}/.local/bin/poetry run lnbits
Restart=always
RestartSec=30
Environment=PYTHONUNBUFFERED=1
[Install]
WantedBy=multi-user.target
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: '0644'
- name: Reload systemd
systemd:
daemon_reload: yes
- name: Enable and start LNBits service
systemd:
name: lnbits
enabled: yes
state: started
- name: Create Fail2Ban filter for LNBits
copy:
dest: /etc/fail2ban/filter.d/lnbits.local
owner: root
group: root
mode: '0644'
content: |
[INCLUDES]
before = common.conf
[Definition]
failregex = ^.*?Invalid credentials.*?IP: <ADDR>.*$
ignoreregex =
- name: Create Fail2Ban jail for LNBits
copy:
dest: /etc/fail2ban/jail.d/lnbits.local
owner: root
group: root
mode: '0644'
content: |
[lnbits]
enabled = true
port = http,https
filter = lnbits
logpath = /var/log/lnbits/lnbits.log
maxretry = 10
findtime = 10m
bantime = 1h
- name: Restart fail2ban to apply changes
systemd:
name: fail2ban
state: restarted
- name: Ensure Caddy sites-enabled directory exists
file:
path: "{{ caddy_sites_dir }}"
state: directory
owner: root
group: root
mode: '0755'
- name: Ensure Caddyfile includes import directive for sites-enabled
lineinfile:
path: /etc/caddy/Caddyfile
line: 'import sites-enabled/*'
insertafter: EOF
state: present
backup: yes
- name: Create Caddy reverse proxy configuration for lnbits
copy:
dest: "{{ caddy_sites_dir }}/lnbits.conf"
content: |
{{ lnbits_domain }} {
reverse_proxy localhost:{{ lnbits_port }} {
header_up X-Forwarded-Host {{ lnbits_domain }}
}
}
owner: root
group: root
mode: '0644'
- name: Reload Caddy to apply new config
command: systemctl reload caddy

View file

@ -0,0 +1,17 @@
# General
lnbits_dir: /opt/lnbits
lnbits_data_dir: "{{ lnbits_dir }}/data"
lnbits_port: 8765
# Caddy
caddy_sites_dir: /etc/caddy/sites-enabled
lnbits_subdomain: wallet
# Remote access
remote_host: "{{ groups['vipy'][0] }}"
remote_user: "{{ hostvars[remote_host]['ansible_user'] }}"
remote_key_file: "{{ hostvars[remote_host]['ansible_ssh_private_key_file'] | default('') }}"
# Local backup
local_backup_dir: "{{ lookup('env', 'HOME') }}/lnbits-backups"
backup_script_path: "{{ lookup('env', 'HOME') }}/.local/bin/lnbits_backup.sh"