mirror of
https://github.com/getAlby/hub.git
synced 2026-08-13 12:33:39 +02:00
Merge 531b66929f into 0c24ab84c1
This commit is contained in:
commit
9fdef9ad58
13 changed files with 459 additions and 0 deletions
85
deploy/digitalocean/README.md
Normal file
85
deploy/digitalocean/README.md
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
# Deploy Alby Hub on DigitalOcean (Marketplace 1-Click App)
|
||||
|
||||
A submission-ready scaffold for publishing Alby Hub as a DigitalOcean Marketplace 1-Click Droplet App. Follows the layout documented at [digitalocean/marketplace-partners](https://github.com/digitalocean/marketplace-partners).
|
||||
|
||||
## What this scaffold produces
|
||||
|
||||
A Droplet image (Ubuntu 24.04) with:
|
||||
- docker-ce pre-installed
|
||||
- `ghcr.io/getalby/hub:latest` pre-pulled
|
||||
- caddy 2 for TLS termination (Let's Encrypt)
|
||||
- A `systemd` unit that runs Alby Hub at boot with a persistent `/opt/albyhub/data` volume
|
||||
- A first-boot cloud-init script that prompts for `DOMAIN` via droplet user-data or auto-configures IP-only access
|
||||
- A first-login MOTD with the Hub URL and onboarding steps
|
||||
|
||||
## Directory layout
|
||||
|
||||
```
|
||||
deploy/digitalocean/
|
||||
├── README.md # this file
|
||||
├── marketplace-image.json # Packer template (input to `packer build`)
|
||||
├── scripts/
|
||||
│ ├── 01-install-albyhub.sh # installs docker, caddy, pulls image, drops systemd unit
|
||||
│ ├── 90-cleanup.sh # DigitalOcean-required log/history cleanup
|
||||
│ └── 99-img_check.sh # DigitalOcean-required image validation
|
||||
└── files/
|
||||
├── etc/
|
||||
│ ├── systemd/system/albyhub.service # systemd unit for the container
|
||||
│ ├── caddy/Caddyfile # caddy reverse-proxy config
|
||||
│ └── update-motd.d/99-albyhub # first-login message
|
||||
└── var/lib/cloud/scripts/per-instance/
|
||||
└── 01-albyhub-firstboot.sh # first-boot config (runs once on each new droplet)
|
||||
```
|
||||
|
||||
## Building the image
|
||||
|
||||
Prerequisites: `packer` ≥ 1.9, a DigitalOcean API token with `write` scope.
|
||||
|
||||
```bash
|
||||
export DIGITALOCEAN_API_TOKEN=dop_v1_...
|
||||
packer init deploy/digitalocean/marketplace-image.json
|
||||
packer build deploy/digitalocean/marketplace-image.json
|
||||
```
|
||||
|
||||
Packer creates a snapshot in your DO account. To test: launch a droplet from that snapshot, wait ~60 seconds, SSH in, read the MOTD, open the URL.
|
||||
|
||||
## Submitting to the Marketplace
|
||||
|
||||
1. Apply at [digitalocean.com/landing/partner-application](https://www.digitalocean.com/landing/partner-application) (Partner Pod program).
|
||||
2. Fork [digitalocean/marketplace-partners](https://github.com/digitalocean/marketplace-partners) and open a PR that references the snapshot ID.
|
||||
3. Provide marketing assets:
|
||||
- Logo: [doc/logo.svg](../../doc/logo.svg)
|
||||
- Category: `Blockchain` (they have a dedicated bitcoin subcategory)
|
||||
- Short description: "Your own bitcoin lightning node — connectable, feature-rich, self-sovereign."
|
||||
- Long description: adapt the top of the main [README.md](../../README.md).
|
||||
- Recommended droplet size: **Basic Regular 2 GB RAM / 1 vCPU / 50 GB SSD** ($12/mo at the time of writing). Call out that 1 GB is not enough for the embedded LDK node.
|
||||
4. Iterate on DO's validation feedback (their reviewers will run `99-img_check.sh` and manual checks).
|
||||
|
||||
## Droplet user-data options
|
||||
|
||||
Users can pre-configure the deploy by passing cloud-init user-data when creating the droplet:
|
||||
|
||||
```yaml
|
||||
#cloud-config
|
||||
write_files:
|
||||
- path: /etc/albyhub/hub.env
|
||||
content: |
|
||||
DOMAIN=albyhub.example.com
|
||||
BASE_URL=https://albyhub.example.com
|
||||
```
|
||||
|
||||
If `DOMAIN` is set, Caddy requests a Let's Encrypt cert automatically on first boot. If not, the droplet serves Hub on `http://<public-ip>:8080` — the MOTD walks users through setting a domain afterwards.
|
||||
|
||||
## Affiliate attribution
|
||||
|
||||
Add `?refcode=albyhub` (or whatever Alby's DO affiliate code is at submission time) to every "Deploy on DigitalOcean" link in marketing materials. Per DO's affiliate terms: 10%/mo for 12 months on referred spend + $25 per paying referral after first $25 spend.
|
||||
|
||||
## Caveats to surface on the listing page
|
||||
|
||||
- **Backup `/opt/albyhub/data` regularly.** Holds the encrypted seed, channel state, and SQLite db. Loss = loss of funds.
|
||||
- **Lightning p2p port 9735 is opened in the droplet firewall by the provisioner.** If the user enables DigitalOcean's Cloud Firewall on top, they must allow 9735 there too.
|
||||
- **Self-custody tradeoff.** Same wording as the Hostinger listing — a VPS-hosted lightning node is less sovereign than a home node-distribution.
|
||||
|
||||
## Support surface
|
||||
|
||||
A new Alby Hub release that changes the container interface must trigger a new Packer build + snapshot + marketplace update. Add to the Hub release checklist. DO supports "update image in place" via a new snapshot push — existing users don't auto-upgrade, so release notes must tell them to `docker compose pull && docker compose up -d` (or use the MOTD update hint).
|
||||
8
deploy/digitalocean/files/etc/caddy/Caddyfile
Normal file
8
deploy/digitalocean/files/etc/caddy/Caddyfile
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# Caddy terminates TLS on :443 and proxies to the Alby Hub container on 127.0.0.1:8080.
|
||||
# The DOMAIN placeholder is rewritten by /var/lib/cloud/scripts/per-instance/01-albyhub-firstboot.sh
|
||||
# based on droplet user-data. If no DOMAIN is set, the firstboot script replaces the whole
|
||||
# file with a :80 site block so Hub is reachable over plain HTTP.
|
||||
|
||||
{$DOMAIN:localhost} {
|
||||
reverse_proxy 127.0.0.1:8080
|
||||
}
|
||||
25
deploy/digitalocean/files/etc/systemd/system/albyhub.service
Normal file
25
deploy/digitalocean/files/etc/systemd/system/albyhub.service
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
[Unit]
|
||||
Description=Alby Hub (bitcoin lightning node)
|
||||
After=docker.service network-online.target
|
||||
Requires=docker.service
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
EnvironmentFile=-/etc/albyhub/hub.env
|
||||
Environment=ALBYHUB_IMAGE=ghcr.io/getalby/hub:latest
|
||||
ExecStartPre=-/usr/bin/docker rm -f albyhub
|
||||
ExecStart=/usr/bin/docker run --rm --name albyhub \
|
||||
--env-file /etc/albyhub/hub.env \
|
||||
-e WORK_DIR=/data/albyhub \
|
||||
-e LDK_LISTENING_ADDRESSES=[::]:9735 \
|
||||
-v /opt/albyhub/data:/data \
|
||||
-p 127.0.0.1:8080:8080 \
|
||||
-p 9735:9735 \
|
||||
${ALBYHUB_IMAGE}
|
||||
ExecStop=/usr/bin/docker stop albyhub
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
27
deploy/digitalocean/files/etc/update-motd.d/99-albyhub
Executable file
27
deploy/digitalocean/files/etc/update-motd.d/99-albyhub
Executable file
|
|
@ -0,0 +1,27 @@
|
|||
#!/bin/sh
|
||||
# First-login motd for Alby Hub droplets.
|
||||
|
||||
PUBLIC_IP=$(curl -s --max-time 2 http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address || echo "<your-droplet-ip>")
|
||||
DOMAIN=$(grep -s '^DOMAIN=' /etc/albyhub/hub.env | cut -d= -f2-)
|
||||
|
||||
cat <<EOF
|
||||
|
||||
✨ Alby Hub is installed on this droplet.
|
||||
|
||||
Status: systemctl status albyhub
|
||||
Logs: journalctl -u albyhub -f
|
||||
Data: /opt/albyhub/data (BACK THIS UP — holds your seed and channel state)
|
||||
Config: /etc/albyhub/hub.env
|
||||
|
||||
EOF
|
||||
|
||||
if [ -n "$DOMAIN" ]; then
|
||||
echo " Open Alby Hub: https://$DOMAIN"
|
||||
else
|
||||
echo " Open Alby Hub: http://$PUBLIC_IP:8080"
|
||||
echo ""
|
||||
echo " To enable TLS, set DOMAIN in /etc/albyhub/hub.env, point your DNS at"
|
||||
echo " $PUBLIC_IP, then run: systemctl restart caddy albyhub"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
#!/bin/bash
|
||||
# Runs once on the first boot of a droplet launched from the Alby Hub marketplace snapshot.
|
||||
# Reads /etc/albyhub/hub.env (optionally pre-populated via cloud-init user-data) and
|
||||
# rewrites the Caddy config to match: TLS + domain if DOMAIN is set, plain HTTP otherwise.
|
||||
set -euo pipefail
|
||||
|
||||
ENV_FILE=/etc/albyhub/hub.env
|
||||
CADDYFILE=/etc/caddy/Caddyfile
|
||||
|
||||
touch "$ENV_FILE"
|
||||
|
||||
DOMAIN=$(grep -s '^DOMAIN=' "$ENV_FILE" | cut -d= -f2- || true)
|
||||
|
||||
if [ -n "$DOMAIN" ]; then
|
||||
cat > "$CADDYFILE" <<EOF
|
||||
$DOMAIN {
|
||||
reverse_proxy 127.0.0.1:8080
|
||||
}
|
||||
EOF
|
||||
grep -q '^BASE_URL=' "$ENV_FILE" || echo "BASE_URL=https://$DOMAIN" >> "$ENV_FILE"
|
||||
else
|
||||
# No domain — expose Hub on :80 over plain HTTP for IP-based access.
|
||||
cat > "$CADDYFILE" <<EOF
|
||||
:80 {
|
||||
reverse_proxy 127.0.0.1:8080
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
systemctl restart caddy
|
||||
systemctl restart albyhub
|
||||
45
deploy/digitalocean/marketplace-image.json
Normal file
45
deploy/digitalocean/marketplace-image.json
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"variables": {
|
||||
"token": "{{env `DIGITALOCEAN_API_TOKEN`}}",
|
||||
"image_name": "albyhub-snapshot-{{timestamp}}",
|
||||
"albyhub_image": "ghcr.io/getalby/hub:latest"
|
||||
},
|
||||
"builders": [
|
||||
{
|
||||
"type": "digitalocean",
|
||||
"api_token": "{{user `token`}}",
|
||||
"image": "ubuntu-24-04-x64",
|
||||
"region": "fra1",
|
||||
"size": "s-1vcpu-2gb",
|
||||
"ssh_username": "root",
|
||||
"snapshot_name": "{{user `image_name`}}",
|
||||
"droplet_name": "packer-albyhub-{{timestamp}}"
|
||||
}
|
||||
],
|
||||
"provisioners": [
|
||||
{
|
||||
"type": "file",
|
||||
"source": "files/",
|
||||
"destination": "/tmp/files"
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"inline": [
|
||||
"cp -r /tmp/files/* /",
|
||||
"rm -rf /tmp/files"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"environment_vars": [
|
||||
"ALBYHUB_IMAGE={{user `albyhub_image`}}",
|
||||
"DEBIAN_FRONTEND=noninteractive"
|
||||
],
|
||||
"scripts": [
|
||||
"scripts/01-install-albyhub.sh",
|
||||
"scripts/90-cleanup.sh",
|
||||
"scripts/99-img_check.sh"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
36
deploy/digitalocean/scripts/01-install-albyhub.sh
Executable file
36
deploy/digitalocean/scripts/01-install-albyhub.sh
Executable file
|
|
@ -0,0 +1,36 @@
|
|||
#!/bin/bash
|
||||
# Provisioner: install docker + caddy, pre-pull Alby Hub image, register systemd unit.
|
||||
# Runs during Packer build against a fresh Ubuntu 24.04 droplet.
|
||||
set -euxo pipefail
|
||||
|
||||
: "${ALBYHUB_IMAGE:=ghcr.io/getalby/hub:latest}"
|
||||
|
||||
apt-get update
|
||||
apt-get install -y ca-certificates curl gnupg ufw
|
||||
|
||||
install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
chmod a+r /etc/apt/keyrings/docker.gpg
|
||||
echo \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
|
||||
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" > /etc/apt/sources.list.d/docker.list
|
||||
|
||||
curl -fsSL https://dl.cloudsmith.io/public/caddy/stable/gpg.key | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
|
||||
curl -fsSL https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt | tee /etc/apt/sources.list.d/caddy-stable.list
|
||||
|
||||
apt-get update
|
||||
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin caddy
|
||||
|
||||
docker pull "$ALBYHUB_IMAGE"
|
||||
|
||||
mkdir -p /opt/albyhub/data /etc/albyhub
|
||||
touch /etc/albyhub/hub.env
|
||||
|
||||
ufw --force enable
|
||||
ufw allow OpenSSH
|
||||
ufw allow 80/tcp
|
||||
ufw allow 443/tcp
|
||||
ufw allow 9735/tcp
|
||||
|
||||
systemctl enable albyhub.service
|
||||
systemctl enable caddy
|
||||
23
deploy/digitalocean/scripts/90-cleanup.sh
Executable file
23
deploy/digitalocean/scripts/90-cleanup.sh
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/bash
|
||||
# Standard DigitalOcean Marketplace cleanup: strip logs, shell history, cloud-init state,
|
||||
# and package-manager caches before snapshot. Mirrors the upstream sample in
|
||||
# https://github.com/digitalocean/marketplace-partners/blob/master/scripts/90-cleanup.sh
|
||||
set -euxo pipefail
|
||||
|
||||
apt-get -y autoremove
|
||||
apt-get -y autoclean
|
||||
|
||||
rm -rf /tmp/* /var/tmp/*
|
||||
rm -rf /var/log/*.gz /var/log/*.[0-9] /var/log/*-????????
|
||||
: > /var/log/wtmp
|
||||
: > /var/log/lastlog
|
||||
: > /var/log/auth.log
|
||||
: > /var/log/syslog
|
||||
|
||||
rm -rf /root/.ssh /root/.bash_history /root/.cache /root/.lesshst
|
||||
rm -rf /home/*/.ssh /home/*/.bash_history /home/*/.cache /home/*/.lesshst
|
||||
|
||||
cloud-init clean --logs
|
||||
rm -rf /var/lib/cloud/instances/*
|
||||
|
||||
truncate -s 0 /etc/machine-id
|
||||
22
deploy/digitalocean/scripts/99-img_check.sh
Executable file
22
deploy/digitalocean/scripts/99-img_check.sh
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
#!/bin/bash
|
||||
# DigitalOcean Marketplace image validator (local dry-run). The official img_check.sh
|
||||
# is shipped via https://github.com/digitalocean/marketplace-partners and must pass
|
||||
# before submission. This local version covers the Alby Hub-specific invariants.
|
||||
set -euo pipefail
|
||||
|
||||
fail() { echo "FAIL: $*" >&2; exit 1; }
|
||||
|
||||
command -v docker >/dev/null || fail "docker not installed"
|
||||
docker image inspect ghcr.io/getalby/hub:latest >/dev/null || fail "alby hub image not pre-pulled"
|
||||
command -v caddy >/dev/null || fail "caddy not installed"
|
||||
|
||||
[[ -f /etc/systemd/system/albyhub.service ]] || fail "albyhub.service missing"
|
||||
systemctl is-enabled albyhub.service >/dev/null || fail "albyhub.service not enabled"
|
||||
systemctl is-enabled caddy >/dev/null || fail "caddy not enabled"
|
||||
|
||||
[[ -f /etc/caddy/Caddyfile ]] || fail "Caddyfile missing"
|
||||
[[ -f /var/lib/cloud/scripts/per-instance/01-albyhub-firstboot.sh ]] || fail "firstboot script missing"
|
||||
[[ -f /etc/update-motd.d/99-albyhub ]] || fail "motd missing"
|
||||
[[ -d /opt/albyhub/data ]] || fail "/opt/albyhub/data not created"
|
||||
|
||||
echo "OK: image looks valid for marketplace submission"
|
||||
3
deploy/hostinger/Caddyfile
Normal file
3
deploy/hostinger/Caddyfile
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{$DOMAIN} {
|
||||
reverse_proxy albyhub:8080
|
||||
}
|
||||
60
deploy/hostinger/README.md
Normal file
60
deploy/hostinger/README.md
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
# Deploy Alby Hub on Hostinger VPS
|
||||
|
||||
A Hostinger Application Catalog template for Alby Hub. Hostinger wraps a `docker-compose.yml` with a prompt-driven env-var UI and ships it under their VPS Docker templates (see precedents: [openclaw](https://www.hostinger.com/vps/docker/openclaw), [hermes-agent](https://www.hostinger.com/vps/docker/hermes-agent)).
|
||||
|
||||
## Artifacts in this directory
|
||||
|
||||
- **[docker-compose.yml](./docker-compose.yml)** — two services: Alby Hub (port 8080, lightning p2p port 9735) and an optional Caddy reverse proxy (ports 80/443) activated with the `tls` compose profile. Volume `albyhub-data` persists the SQLite db, seed, channel state, and LDK data.
|
||||
- **[Caddyfile](./Caddyfile)** — reverse proxy config that terminates TLS for `${DOMAIN}` and proxies to `albyhub:8080`. Caddy auto-provisions a Let's Encrypt cert on startup when a real DNS name is set.
|
||||
|
||||
## Deploying without submitting to Hostinger (works today)
|
||||
|
||||
Any Hostinger VPS with the Ubuntu 24.04 + Docker template already provisioned can run this:
|
||||
|
||||
```bash
|
||||
curl -O https://raw.githubusercontent.com/getAlby/hub/master/deploy/hostinger/docker-compose.yml
|
||||
curl -O https://raw.githubusercontent.com/getAlby/hub/master/deploy/hostinger/Caddyfile
|
||||
|
||||
# No TLS (IP-only access on port 8080):
|
||||
docker compose up -d
|
||||
|
||||
# With TLS (requires DNS pointed at the VPS):
|
||||
DOMAIN=albyhub.example.com BASE_URL=https://albyhub.example.com docker compose --profile tls up -d
|
||||
```
|
||||
|
||||
## Submitting to the Hostinger Application Catalog
|
||||
|
||||
Hostinger does not publish a public submission process. Reach out to Hostinger BD / partnerships with this package:
|
||||
|
||||
| Asset | Source |
|
||||
|---|---|
|
||||
| Title | `Alby Hub` |
|
||||
| Tagline | `Your own bitcoin lightning node` |
|
||||
| Category | `Finance` / `Self-hosted` |
|
||||
| Logo (SVG) | [doc/logo.svg](../../doc/logo.svg) |
|
||||
| Long description | Adapt the top of the main [README.md](../../README.md) |
|
||||
| `docker-compose.yml` | [./docker-compose.yml](./docker-compose.yml) |
|
||||
| Reverse proxy config | [./Caddyfile](./Caddyfile) |
|
||||
| User-facing env-var schema | See table below |
|
||||
| Minimum VPS plan | KVM 2 (2 GB RAM, 1 shared vCPU, 50 GB NVMe) |
|
||||
| Post-deploy URL | `http://{public_ip}:8080` (or `https://{domain}` when TLS profile active) |
|
||||
|
||||
### Env vars to surface in Hostinger's template UI
|
||||
|
||||
| Key | Label | Default | Required |
|
||||
|---|---|---|---|
|
||||
| `DOMAIN` | Your domain (optional, for TLS) | *empty* | No |
|
||||
| `BASE_URL` | Public URL of this Hub (e.g. `https://albyhub.example.com`) | `http://localhost:8080` | No |
|
||||
| `LDK_ESPLORA_SERVER` | Blockchain API endpoint | `https://electrs.getalbypro.com` | No |
|
||||
|
||||
Every other env var from [config/models.go](../../config/models.go) keeps its default; do not surface them in the Hostinger UI or users will be overwhelmed.
|
||||
|
||||
## Caveats to surface on the listing page
|
||||
|
||||
- **Backup the `albyhub-data` volume regularly.** It holds the encrypted seed, channel state, and SQLite db. Loss = loss of funds.
|
||||
- **Lightning p2p on port 9735 needs the VPS firewall open.** Hostinger's default firewall blocks it; link users to Hostinger's firewall docs.
|
||||
- **Self-custody tradeoff.** A VPS-hosted lightning node is less sovereign than a home node-distribution (umbrel, start9). Mention this honestly in the listing so users choose eyes-open.
|
||||
|
||||
## Support surface
|
||||
|
||||
A new Alby Hub release that changes the container interface must also be smoke-tested against this compose file. Add to the Hub release checklist.
|
||||
46
deploy/hostinger/docker-compose.yml
Normal file
46
deploy/hostinger/docker-compose.yml
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
services:
|
||||
albyhub:
|
||||
image: ghcr.io/getalby/hub:latest
|
||||
container_name: albyhub
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
WORK_DIR: /data/albyhub
|
||||
BASE_URL: ${BASE_URL:-http://localhost:8080}
|
||||
LDK_ESPLORA_SERVER: https://electrs.getalbypro.com
|
||||
LDK_LISTENING_ADDRESSES: "[::]:9735"
|
||||
volumes:
|
||||
- albyhub-data:/data
|
||||
ports:
|
||||
- "8080:8080"
|
||||
- "9735:9735"
|
||||
networks:
|
||||
- albyhub
|
||||
|
||||
caddy:
|
||||
image: caddy:2-alpine
|
||||
container_name: albyhub-caddy
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- albyhub
|
||||
environment:
|
||||
DOMAIN: ${DOMAIN:-}
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- caddy-data:/data
|
||||
- caddy-config:/config
|
||||
networks:
|
||||
- albyhub
|
||||
profiles:
|
||||
- tls
|
||||
|
||||
volumes:
|
||||
albyhub-data:
|
||||
caddy-data:
|
||||
caddy-config:
|
||||
|
||||
networks:
|
||||
albyhub:
|
||||
driver: bridge
|
||||
48
deploy/railway/README.md
Normal file
48
deploy/railway/README.md
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# Deploy Alby Hub on Railway
|
||||
|
||||
A "Deploy on Railway" one-click template for Alby Hub. Railway templates are created in Railway's dashboard and shared as a `https://railway.com/template/<id>` URL — there is no repo-committed template file. This document defines the exact config to enter in the dashboard so the template is reproducible.
|
||||
|
||||
## Template configuration
|
||||
|
||||
Create a new service in a Railway template with the following settings.
|
||||
|
||||
### Source
|
||||
- **Type:** Docker image
|
||||
- **Image:** `ghcr.io/getalby/hub:latest`
|
||||
|
||||
### Volumes
|
||||
- **Mount path:** `/data`
|
||||
- **Size:** 1 GB (users on larger wallets should resize after deploy)
|
||||
|
||||
### Networking
|
||||
- **Public HTTP port:** `8080` (Railway will assign a `*.up.railway.app` domain and terminate TLS)
|
||||
- **Lightning p2p port 9735:** *not exposed.* Railway's HTTP proxy does not forward arbitrary TCP, so inbound channel opens are not reachable by default. Users who need inbound p2p should deploy on a VPS provider (DigitalOcean, Hostinger) instead. Document this clearly on the template's Railway listing.
|
||||
|
||||
### Environment variables
|
||||
| Key | Value | Notes |
|
||||
|---|---|---|
|
||||
| `WORK_DIR` | `/data/albyhub` | Matches `render.yaml`. Data persists on the `/data` volume. |
|
||||
| `BASE_URL` | `${{RAILWAY_PUBLIC_DOMAIN}}` | Prefix with `https://` if Railway's variable doesn't include it. Needed for OAuth redirects and copy-to-clipboard URLs. |
|
||||
| `LDK_ESPLORA_SERVER` | `https://electrs.getalbypro.com` | Same default as `render.yaml`. Override for self-hosted esplora. |
|
||||
| `PORT` | *(leave unset)* | Defaults to 8080, matches Railway's exposed port. |
|
||||
| `AUTO_UNLOCK_PASSWORD` | *(leave unset)* | Users can opt in after first-run for auto-start on reboot. Trades custody for convenience — do not pre-fill. |
|
||||
|
||||
All other env vars from [config/models.go](../../config/models.go) use their defaults. Surface only `LDK_ESPLORA_SERVER` and `AUTO_UNLOCK_PASSWORD` as user-editable in the Railway template UI; keep `WORK_DIR` and `BASE_URL` locked.
|
||||
|
||||
## README button (paste once template is live)
|
||||
|
||||
Once the template URL is known, add this to the main [README.md](../../README.md) next to the existing Render button:
|
||||
|
||||
```markdown
|
||||
[](https://railway.com/template/<TEMPLATE_ID>?utm_campaign=alby-hub)
|
||||
```
|
||||
|
||||
Replace `utm_campaign=alby-hub` consistently with the other marketplace buttons so conversion can be attributed.
|
||||
|
||||
## Economics
|
||||
|
||||
Railway's [template kickback program](https://blog.railway.com/p/template-kickback-program-cash) returns 25% of the first 12 months of infrastructure spend from each deploy to the template owner. The receiving account should be owned by Alby (not a personal account) so the revenue flows through the business.
|
||||
|
||||
## Support surface
|
||||
|
||||
Each template deploy is a live Alby Hub instance that expects `ghcr.io/getalby/hub:latest` to keep working. Before a breaking image change lands, verify that a fresh Railway deploy still completes onboarding. Add to the Hub release checklist.
|
||||
Loading…
Add table
Add a link
Reference in a new issue