mirror of
https://github.com/runcitadel/core.git
synced 2024-11-11 16:30:38 +00:00
Switch to Caddy
This commit is contained in:
parent
0507684211
commit
2999eb0931
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -21,7 +21,7 @@ db/*
|
|||
statuses/*
|
||||
app-data
|
||||
apps
|
||||
nginx/*
|
||||
caddy/*
|
||||
i2p/*
|
||||
docker-compose.override.yml
|
||||
|
||||
|
@ -39,7 +39,7 @@ db/citadel-seed/*
|
|||
!tor/run/.gitkeep
|
||||
!tor/.gitkeep
|
||||
!db/.gitkeep
|
||||
!nginx/.gitkeep
|
||||
!caddy/.gitkeep
|
||||
!i2p/.gitkeep
|
||||
|
||||
!**/*.license
|
||||
|
|
76
apps/stores.yml
Normal file
76
apps/stores.yml
Normal file
|
@ -0,0 +1,76 @@
|
|||
- id: citadel
|
||||
name: Citadel app store
|
||||
tagline: The official app store by the Citadel team
|
||||
icon: https://icons.runcitadel.space/app-stores/main.svg
|
||||
developers: The Citadel developers
|
||||
license: AGPL-3.0-or-later
|
||||
apps:
|
||||
lightning-terminal: 76bfe58c1b6cbc2ea23309c3217750318ac27075
|
||||
code-server: 76bfe58c1b6cbc2ea23309c3217750318ac27075
|
||||
lightning-shell: 76bfe58c1b6cbc2ea23309c3217750318ac27075
|
||||
lnmarkets: a819714e71f3ab24c15dda4110cde0e6da0c8c42
|
||||
mempool: 3fed81a6ff73bf1600ff4132bfe82d04660c0aae
|
||||
bitcartcc: 3fed81a6ff73bf1600ff4132bfe82d04660c0aae
|
||||
lnme: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
robosats: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
btcpay-server: 76bfe58c1b6cbc2ea23309c3217750318ac27075
|
||||
thunderhub: 39433b0675a1b43e9ecbbfad6c8cc82b12667fac
|
||||
synapse-admin: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
btc-rpc-explorer: 76bfe58c1b6cbc2ea23309c3217750318ac27075
|
||||
node-red: 3fed81a6ff73bf1600ff4132bfe82d04660c0aae
|
||||
gitea: cc93b09639e3cfc5c271be5f34073d2afe29809c
|
||||
nextcloud: 6ff003d693753a021bb104d091c6c7a50e438e4d
|
||||
sphinx-relay: d62423ec8ed163fe4e689dc7d6e019324a86dc56
|
||||
specter-desktop: 153e2dbd1b6827f2bcd4756d1932101af0bbfac4
|
||||
oak-node: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
tallycoin-connect: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
btc-rpc-explorer-public-fast: 76bfe58c1b6cbc2ea23309c3217750318ac27075
|
||||
agora: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
kollider: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
lndhub: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
woofbot: 931bcab746129838ad539b2d535786865e2bd7a4
|
||||
wordpress: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
krystal-bull: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
snowflake: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
ride-the-lightning: 153e2dbd1b6827f2bcd4756d1932101af0bbfac4
|
||||
lnbits: db645071fd1241ca35eb2ffa42d5309884f1ed4d
|
||||
ringtools: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
usocial: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
vaultwarden: d901ad3315853224c7c77d6b61ef850c14e255bb
|
||||
squeaknode: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
itchysats: 3fed81a6ff73bf1600ff4132bfe82d04660c0aae
|
||||
fulcrum: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
jam: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
nostr-relay: 132fb6d853f905431ea3c20097fa06e5e04a505a
|
||||
electrs: 29bacf5a4b571d1e4b0e49e85ff9c219a551b76e
|
||||
bluewallet: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
lnplus: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
ln-visualizer: 22b6f7e549a8e772dbf9f594dce66487ef0fd698
|
||||
lndg: 53b0aae0f8cb7364ace04f7282118358744c89ce
|
||||
bitfeed: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
element: 36315f17b00450eea62e8d525a670a629ab1ebf8
|
||||
tailscale: 14eddca042802891b02e0d5f8999a2a1dd40c080
|
||||
synapse: 996b62274dabea9653852aa57b575d3b97ed96c5
|
||||
btc-rpc-explorer-public: 76bfe58c1b6cbc2ea23309c3217750318ac27075
|
||||
uptime-kuma: 8500658ad8bc5c869c9e17d14a8b668b5d51ffaf
|
||||
spigot-mc: 974ac0549be3c6038dcd2bb0705bb6b722a8b4ff
|
||||
commit: 14eddca042802891b02e0d5f8999a2a1dd40c080
|
||||
repo: https://github.com/citadel-core/apps
|
||||
branch: main
|
||||
subdir: v4
|
||||
- id: citadel
|
||||
name: Citadel app store
|
||||
tagline: The official app store by the Citadel team
|
||||
icon: https://icons.runcitadel.space/app-stores/main.svg
|
||||
developers: The Citadel developers
|
||||
license: Proprietary
|
||||
apps:
|
||||
samourai-server: 496d384c754d5e68dc03c8390e8e81b8ee9dc125
|
||||
photoprism: 496d384c754d5e68dc03c8390e8e81b8ee9dc125
|
||||
simple-torrent: 496d384c754d5e68dc03c8390e8e81b8ee9dc125
|
||||
home-assistant: 496d384c754d5e68dc03c8390e8e81b8ee9dc125
|
||||
pi-hole: 496d384c754d5e68dc03c8390e8e81b8ee9dc125
|
||||
commit: 496d384c754d5e68dc03c8390e8e81b8ee9dc125
|
||||
repo: https://github.com/citadel-core/apps-nonfree
|
||||
branch: main
|
||||
subdir: v4
|
10
cli/citadel
10
cli/citadel
|
@ -330,11 +330,11 @@ if [[ "$command" = "configure" ]]; then
|
|||
exit
|
||||
fi
|
||||
|
||||
if [[ "$2" = "nginx" ]]; then
|
||||
edit_file $CITADEL_ROOT/nginx/nginx.conf
|
||||
prompt_apply_config nginx false
|
||||
exit
|
||||
fi
|
||||
#if [[ "$2" = "nginx" ]]; then
|
||||
#edit_file $CITADEL_ROOT/nginx/nginx.conf
|
||||
#prompt_apply_config nginx false
|
||||
#exit
|
||||
#fi
|
||||
|
||||
if $persist; then
|
||||
echo "NOTE: As of now persisted config changes will not be kept when updating Citadel."
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
compose: v2.12.2
|
||||
dashboard: ghcr.io/runcitadel/dashboard:citadel-0.0.10@sha256:8920719b77a1db517e60742d72a4b63230f170d980d116f8e01974247e8da148
|
||||
manager: ghcr.io/citadel-core/api:main@sha256:720a6ab0c0ada97e57186519b6c22f5a1d58ab5301e967363b905113a6cbe068
|
||||
middleware: ghcr.io/runcitadel/middleware:main@sha256:b18065b02fffca0facef456109cf0de1b6cb4391f6b2186b6cd467ce6caf7642
|
||||
app-cli: ghcr.io/citadel-core/app-manager:main@sha256:0e029661c7918921c3fcc4b18b9a07ed431ab47d608f35d2365da20eb58667a9
|
||||
tor: lncm/tor:0.4.7.9@sha256:86c2fe9d9099e6376798979110b8b9a3ee5d8adec27289ac4a5ee892514ffe92
|
||||
dashboard: ghcr.io/runcitadel/dashboard:no-https@sha256:7fc5a5b70496240e6e48a381e8ac3c7978e7343285fda4951c00846580d6216d
|
||||
manager: runcitadel/api:main@sha256:12d299d8850d830fa5abd0e64c8537dfcbaec662de18376b0d7b01fa59895132
|
||||
middleware: ghcr.io/runcitadel/middleware:main@sha256:cbd5fd2ab5afe420025c61e276d21c79a004d6148b8dfdd58649adb55907682b
|
||||
app-cli: runcitadel/app-manager:backports@sha256:dde9197ed141e516f8300bbcdf76915366eacdda65639522d9358d4d1420a673
|
||||
tor: ghcr.io/runcitadel/tor-latest:main@sha256:761948a86f8367238eb61f991cf87094b12a8a772be0eabec00d66164d13075f
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
# SPDX-FileCopyrightText: 2022 Citadel and contributors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
services:
|
||||
tor:
|
||||
container_name: tor
|
||||
image: lncm/tor:0.4.7.9@sha256:86c2fe9d9099e6376798979110b8b9a3ee5d8adec27289ac4a5ee892514ffe92
|
||||
image: ghcr.io/runcitadel/tor-latest:main@sha256:761948a86f8367238eb61f991cf87094b12a8a772be0eabec00d66164d13075f
|
||||
user: toruser
|
||||
restart: on-failure
|
||||
volumes:
|
||||
|
@ -16,9 +12,11 @@ services:
|
|||
networks:
|
||||
default:
|
||||
ipv4_address: $TOR_PROXY_IP
|
||||
extra_hosts:
|
||||
- host.docker.internal:host-gateway
|
||||
app-tor:
|
||||
container_name: app-tor
|
||||
image: lncm/tor:0.4.7.9@sha256:86c2fe9d9099e6376798979110b8b9a3ee5d8adec27289ac4a5ee892514ffe92
|
||||
image: ghcr.io/runcitadel/tor-latest:main@sha256:761948a86f8367238eb61f991cf87094b12a8a772be0eabec00d66164d13075f
|
||||
user: toruser
|
||||
restart: on-failure
|
||||
volumes:
|
||||
|
@ -27,9 +25,11 @@ services:
|
|||
networks:
|
||||
default:
|
||||
ipv4_address: $APPS_TOR_IP
|
||||
extra_hosts:
|
||||
- host.docker.internal:host-gateway
|
||||
app-2-tor:
|
||||
container_name: app-2-tor
|
||||
image: lncm/tor:0.4.7.9@sha256:86c2fe9d9099e6376798979110b8b9a3ee5d8adec27289ac4a5ee892514ffe92
|
||||
image: ghcr.io/runcitadel/tor-latest:main@sha256:761948a86f8367238eb61f991cf87094b12a8a772be0eabec00d66164d13075f
|
||||
user: toruser
|
||||
restart: on-failure
|
||||
volumes:
|
||||
|
@ -38,9 +38,11 @@ services:
|
|||
networks:
|
||||
default:
|
||||
ipv4_address: $APPS_2_TOR_IP
|
||||
extra_hosts:
|
||||
- host.docker.internal:host-gateway
|
||||
app-3-tor:
|
||||
container_name: app-3-tor
|
||||
image: lncm/tor:0.4.7.9@sha256:86c2fe9d9099e6376798979110b8b9a3ee5d8adec27289ac4a5ee892514ffe92
|
||||
image: ghcr.io/runcitadel/tor-latest:main@sha256:761948a86f8367238eb61f991cf87094b12a8a772be0eabec00d66164d13075f
|
||||
user: toruser
|
||||
restart: on-failure
|
||||
volumes:
|
||||
|
@ -49,22 +51,17 @@ services:
|
|||
networks:
|
||||
default:
|
||||
ipv4_address: $APPS_3_TOR_IP
|
||||
nginx:
|
||||
container_name: nginx
|
||||
image: nginx:1.21.6@sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767
|
||||
depends_on:
|
||||
- dashboard
|
||||
extra_hosts:
|
||||
- host.docker.internal:host-gateway
|
||||
caddy:
|
||||
container_name: caddy
|
||||
image: ghcr.io/runcitadel/caddy:main@sha256:a64ed99ad821ab53119c5e314aab47b37406c5d6caf1ec0bcd65c8da981823d8
|
||||
volumes:
|
||||
- ${PWD}/nginx:/etc/nginx
|
||||
- ${PWD}/caddy/data:/data
|
||||
- ${PWD}/caddy/Caddyfile:/etc/caddy/Caddyfile
|
||||
restart: on-failure
|
||||
stop_grace_period: 30s
|
||||
ports:
|
||||
- ${NGINX_PORT}:80
|
||||
- 433:433
|
||||
- ${NGINX_SSL_PORT}:443
|
||||
networks:
|
||||
default:
|
||||
ipv4_address: $NGINX_IP
|
||||
network_mode: host
|
||||
bitcoin:
|
||||
container_name: bitcoin
|
||||
image: ghcr.io/runcitadel/bitcoinknots:main@sha256:5fbee0f6f0d09d42aacc11c373ffe6162210c42ce21e6eba294e547e3ad80219
|
||||
|
@ -102,7 +99,7 @@ services:
|
|||
ipv4_address: $LND_IP
|
||||
dashboard:
|
||||
container_name: dashboard
|
||||
image: ghcr.io/runcitadel/dashboard:citadel-0.0.10@sha256:8920719b77a1db517e60742d72a4b63230f170d980d116f8e01974247e8da148
|
||||
image: ghcr.io/runcitadel/dashboard:no-https@sha256:7fc5a5b70496240e6e48a381e8ac3c7978e7343285fda4951c00846580d6216d
|
||||
restart: on-failure
|
||||
stop_grace_period: 1m30s
|
||||
networks:
|
||||
|
@ -110,7 +107,7 @@ services:
|
|||
ipv4_address: $DASHBOARD_IP
|
||||
manager:
|
||||
container_name: manager
|
||||
image: ghcr.io/citadel-core/api:main@sha256:39f1caca276bb7b439613ce9e9a33a5a942143feb5ac6abbe079a9c85e19d56d
|
||||
image: runcitadel/api:main@sha256:12d299d8850d830fa5abd0e64c8537dfcbaec662de18376b0d7b01fa59895132
|
||||
depends_on:
|
||||
- tor
|
||||
restart: on-failure
|
||||
|
@ -119,7 +116,7 @@ services:
|
|||
volumes:
|
||||
- ${PWD}/info.json:/info.json
|
||||
- ${PWD}/db:/db
|
||||
- ${PWD}/events:/events
|
||||
- ${PWD}/karen.socket:/karen.socket
|
||||
- ${PWD}/apps:/apps
|
||||
- ${PWD}/lnd:/lnd:ro
|
||||
- ${PWD}/statuses:/statuses
|
||||
|
@ -134,6 +131,7 @@ services:
|
|||
DEVICE_HOSTS: ${DEVICE_HOSTS:-"http://citadel.local"}
|
||||
DEVICE_HOSTNAME: ${DEVICE_HOSTNAME:-""}
|
||||
MIDDLEWARE_API_URL: http://$MIDDLEWARE_IP
|
||||
MIDDLEWARE_API_PORT: 3000
|
||||
SEED_FILE: /db/citadel-seed/seed
|
||||
BITCOIN_HOST: $BITCOIN_IP
|
||||
BITCOIN_P2P_PORT: $BITCOIN_P2P_PORT
|
||||
|
@ -156,12 +154,14 @@ services:
|
|||
I2P_USERNAME: i2pd
|
||||
ELECTRUM_HOST: $APP_ELECTRUM_IP
|
||||
ELECTRUM_PORT: 50001
|
||||
KAREN_SOCKET: /karen.socket
|
||||
IP_ADDR: $DEVICE_IP
|
||||
networks:
|
||||
default:
|
||||
ipv4_address: $MANAGER_IP
|
||||
middleware:
|
||||
container_name: middleware
|
||||
image: ghcr.io/runcitadel/middleware:main@sha256:fdb8b40a651cb4563c754c3f29d1826d32460100c9846d185e8609f0b357eec6
|
||||
image: ghcr.io/runcitadel/middleware:main@sha256:cbd5fd2ab5afe420025c61e276d21c79a004d6148b8dfdd58649adb55907682b
|
||||
depends_on:
|
||||
- bitcoin
|
||||
- lightning
|
||||
|
@ -171,7 +171,7 @@ services:
|
|||
- ${PWD}/lnd:/lnd
|
||||
- jwt-public-key:/jwt-public-key
|
||||
environment:
|
||||
PORT: '3005'
|
||||
PORT: '3000'
|
||||
BITCOIN_HOST: $BITCOIN_IP
|
||||
RPC_PORT: $BITCOIN_RPC_PORT
|
||||
RPC_USER: $BITCOIN_RPC_USER
|
||||
|
@ -217,7 +217,6 @@ services:
|
|||
networks:
|
||||
default:
|
||||
ipv4_address: $I2P_IP
|
||||
|
||||
networks:
|
||||
default:
|
||||
name: citadel_main_network
|
||||
|
@ -226,5 +225,7 @@ networks:
|
|||
config:
|
||||
- subnet: $NETWORK_IP/24
|
||||
volumes:
|
||||
jwt-public-key: null
|
||||
jwt-private-key: null
|
||||
jwt-public-key:
|
||||
name: citadel-jwt-public-key
|
||||
jwt-private-key:
|
||||
name: citadel-jwt-private-key
|
||||
|
|
|
@ -21,6 +21,8 @@ EOF
|
|||
|
||||
wait
|
||||
|
||||
docker restart caddy &
|
||||
|
||||
"${CITADEL_ROOT}/scripts/app" start installed &
|
||||
cat <<EOF > "$CITADEL_ROOT"/statuses/update-status.json
|
||||
{"state": "installing", "progress": 60, "description": "Starting apps", "updateTo": "$RELEASE"}
|
||||
|
|
|
@ -1,220 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# SPDX-FileCopyrightText: 2022 Citadel and contributors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
try:
|
||||
import crossplane
|
||||
except ImportError:
|
||||
print("Crossplane not found. Please run 'sudo pip3 install crossplane'")
|
||||
exit(1)
|
||||
import os
|
||||
import argparse
|
||||
import shutil
|
||||
import json
|
||||
|
||||
|
||||
def parse_dotenv(file_path):
|
||||
envVars: dict = {}
|
||||
with open(file_path, 'r') as file:
|
||||
for line in file:
|
||||
line = line.strip()
|
||||
if line.startswith('#') or len(line) == 0:
|
||||
continue
|
||||
if '=' in line:
|
||||
key, value = line.split('=', 1)
|
||||
value = value.strip('"').strip("'")
|
||||
envVars[key] = value
|
||||
else:
|
||||
print("Error: Invalid line in {}: {}".format(file_path, line))
|
||||
print(
|
||||
"Line should be in the format KEY=VALUE or KEY=\"VALUE\" or KEY='VALUE'")
|
||||
exit(1)
|
||||
return envVars
|
||||
|
||||
|
||||
# Usage: add-https --service service_name --cert path_to_certificate --key path_to_key --domain domain_name
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Create an HTTPS proxy for an app on Citadel')
|
||||
parser.add_argument('--service', required=True,
|
||||
help='The service to add HTTPS to')
|
||||
parser.add_argument('--cert', required=True,
|
||||
help='The path to the SSL certificate (.pem)')
|
||||
parser.add_argument('--key', required=True, help='The path to the SSL key (.key)')
|
||||
parser.add_argument('--domain', required=True, help='The domain name')
|
||||
args = parser.parse_args()
|
||||
domain = args.domain
|
||||
service = args.service
|
||||
cert = args.cert
|
||||
key = args.key
|
||||
|
||||
node_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
nginx_config_file = os.path.join(node_root, 'nginx', 'nginx.conf')
|
||||
registry_file = os.path.join(node_root, 'apps', 'registry.json')
|
||||
with open(registry_file) as file:
|
||||
registry = json.load(file)
|
||||
|
||||
port = None
|
||||
for app in registry:
|
||||
if app['name'] == service:
|
||||
if "internalPort" in app:
|
||||
port = app['internalPort']
|
||||
break
|
||||
|
||||
original_config = crossplane.parse(nginx_config_file)
|
||||
parsedConfig = original_config["config"][0]["parsed"]
|
||||
|
||||
|
||||
ip_env_var = "APP_{}_WEB_IP".format(
|
||||
service.upper().replace("-", "_")
|
||||
)
|
||||
|
||||
ip_alt_env_var = "APP_{}_MAIN_IP".format(
|
||||
service.upper().replace("-", "_")
|
||||
)
|
||||
|
||||
port_env_var = "APP_{}_WEB_PORT".format(
|
||||
service.upper().replace("-", "_")
|
||||
)
|
||||
|
||||
port_alt_env_var = "APP_{}_MAIN_PORT".format(
|
||||
service.upper().replace("-", "_")
|
||||
)
|
||||
|
||||
env = parse_dotenv(os.path.join(node_root, '.env'))
|
||||
|
||||
ip=None
|
||||
if ip_env_var in env:
|
||||
ip = env[ip_env_var]
|
||||
elif ip_alt_env_var in env:
|
||||
ip = env[ip_alt_env_var]
|
||||
else:
|
||||
print("Error: No IP found for {}".format(service))
|
||||
exit(1)
|
||||
|
||||
if port == None:
|
||||
if port_env_var in env:
|
||||
port = env[port_env_var]
|
||||
elif port_alt_env_var in env:
|
||||
port = env[port_alt_env_var]
|
||||
else:
|
||||
print("Error: No port found for {}".format(service))
|
||||
exit(1)
|
||||
|
||||
if service == "btcpay-server":
|
||||
port = 1234
|
||||
|
||||
if service == "lnme":
|
||||
port = 1323
|
||||
|
||||
actual_url="http://{}:{}".format(ip, port)
|
||||
|
||||
|
||||
# Get the first element of config where the directive property is 'http'
|
||||
http_element = next(x for x in parsedConfig if x["directive"] == "http")
|
||||
|
||||
config = {
|
||||
"directive": "server",
|
||||
"args": [],
|
||||
"block": [
|
||||
{
|
||||
"directive": "listen",
|
||||
"args": ["443", "ssl", "http2"]
|
||||
},
|
||||
{
|
||||
"directive": "server_name",
|
||||
"args": [domain]
|
||||
},
|
||||
{
|
||||
"directive": "ssl_certificate",
|
||||
"args": [domain + ".pem"]
|
||||
},
|
||||
{
|
||||
"directive": "ssl_certificate_key",
|
||||
"args": [domain + ".key"]
|
||||
},
|
||||
{
|
||||
"directive": "ssl_protocols",
|
||||
"args": ["TLSv1", "TLSv1.1", "TLSv1.2"]
|
||||
},
|
||||
{
|
||||
"directive": "ssl_ciphers",
|
||||
"args": ["HIGH:!aNULL:!MD5"]
|
||||
},
|
||||
{
|
||||
"directive": "location",
|
||||
"args": ["/"],
|
||||
"block": [
|
||||
{
|
||||
"directive": "proxy_pass",
|
||||
"args": [actual_url]
|
||||
},
|
||||
{
|
||||
"directive": "proxy_http_version",
|
||||
"args": ["1.1"]
|
||||
},
|
||||
{
|
||||
"directive": "proxy_set_header",
|
||||
"args": ["Upgrade", "$http_upgrade"]
|
||||
},
|
||||
{
|
||||
"directive": "proxy_set_header",
|
||||
"args": ["Connection", "upgrade"]
|
||||
},
|
||||
{
|
||||
"directive": "proxy_set_header",
|
||||
"args": ["Host", "$host"]
|
||||
},
|
||||
{
|
||||
"directive": "proxy_set_header",
|
||||
"args": ["X-Real-IP", "$remote_addr"]
|
||||
},
|
||||
{
|
||||
"directive": "proxy_set_header",
|
||||
"args": ["X-Forwarded-For", "$remote_addr"]
|
||||
},
|
||||
{
|
||||
"directive": "proxy_set_header",
|
||||
"args": ["X-Forwarded-Proto", "$scheme"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
redirect_config = {
|
||||
"directive": "server",
|
||||
"args": [],
|
||||
"block": [
|
||||
{
|
||||
"directive": "listen",
|
||||
"args": ["433"]
|
||||
},
|
||||
{
|
||||
"directive": "server_name",
|
||||
"args": [domain]
|
||||
},
|
||||
{
|
||||
"directive": "return",
|
||||
"args": ["301", "https://$host$request_uri"]
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
# Now, copy the given certificate and key to the correct location
|
||||
newCertLocation = os.path.join(node_root, 'nginx', domain + '.pem')
|
||||
newKeyLocation = os.path.join(node_root, 'nginx', domain + '.key')
|
||||
shutil.copy(cert, newCertLocation)
|
||||
shutil.copy(key, newKeyLocation)
|
||||
|
||||
http_element["block"].append(config)
|
||||
http_element["block"].append(redirect_config)
|
||||
newConfig = crossplane.build(parsedConfig)
|
||||
# Write newConfig to nginx_config_file
|
||||
with open(nginx_config_file, 'w') as file:
|
||||
file.write(newConfig)
|
||||
|
||||
print("Configuration successful!")
|
||||
print("To increase security, we recommend not exposing our IP by using services like cloudflare.")
|
||||
print("Also, please restart nginx using this command: sudo docker restart nginx")
|
92
scripts/configure
vendored
92
scripts/configure
vendored
|
@ -4,16 +4,19 @@
|
|||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
import sys
|
||||
import os
|
||||
from lib.rpcauth import get_data
|
||||
import re
|
||||
import subprocess
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import yaml
|
||||
import subprocess
|
||||
import sys
|
||||
from binascii import hexlify
|
||||
from os import urandom
|
||||
from time import sleep
|
||||
|
||||
import yaml
|
||||
from lib.rpcauth import get_data
|
||||
|
||||
|
||||
def generate_password(size):
|
||||
"""Create size byte hex salt"""
|
||||
|
@ -88,6 +91,7 @@ with open("./db/dependencies.yml", "r") as file:
|
|||
# upon the user-supplied value of $NETWORK
|
||||
# If the network is not specified, then use the mainnet
|
||||
BITCOIN_NETWORK=os.environ.get('NETWORK') or 'mainnet'
|
||||
DEVICE_IP=os.environ.get("DEVICE_IP")
|
||||
|
||||
# Check if network neither mainnet nor testnet nor regtest
|
||||
if BITCOIN_NETWORK not in ['mainnet', 'testnet', 'signet', 'regtest']:
|
||||
|
@ -137,8 +141,8 @@ def parse_dotenv(file_path):
|
|||
############ Generate configuration variables ############
|
||||
##########################################################
|
||||
|
||||
NGINX_PORT=os.environ.get('NGINX_PORT') or "80"
|
||||
NGINX_SSL_PORT=os.environ.get('NGINX_SSL_PORT') or "443"
|
||||
CADDY_PORT=os.environ.get('CADDY_PORT') or "80"
|
||||
CADDY_HTTPS_PORT=os.environ.get('CADDY_PORT') or "443"
|
||||
UPDATE_CHANNEL="stable"
|
||||
|
||||
if reconfiguring:
|
||||
|
@ -155,14 +159,15 @@ if reconfiguring:
|
|||
BITCOIN_RPC_USER=dotenv['BITCOIN_RPC_USER']
|
||||
BITCOIN_RPC_PASS=dotenv['BITCOIN_RPC_PASS']
|
||||
BITCOIN_RPC_AUTH=dotenv['BITCOIN_RPC_AUTH']
|
||||
TOR_PASSWORD=dotenv['TOR_PASSWORD']
|
||||
TOR_HASHED_PASSWORD=dotenv['TOR_HASHED_PASSWORD']
|
||||
NGINX_PORT=dotenv['NGINX_PORT']
|
||||
NGINX_SSL_PORT="443"
|
||||
if 'NGINX_SSL_PORT' in dotenv:
|
||||
NGINX_SSL_PORT=dotenv['NGINX_SSL_PORT']
|
||||
if NGINX_SSL_PORT == "80" and NGINX_PORT == "80":
|
||||
NGINX_SSL_PORT="443"
|
||||
if 'NGINX_PORT' in dotenv:
|
||||
CADDY_PORT=dotenv['NGINX_PORT']
|
||||
if 'CADDY_PORT' in dotenv:
|
||||
CADDY_PORT=dotenv['CADDY_PORT']
|
||||
CADDY_HTTPS_PORT="443"
|
||||
if 'CADDY_HTTPS_PORT' in dotenv:
|
||||
CADDY_HTTPS_PORT=dotenv['CADDY_HTTPS_PORT']
|
||||
if CADDY_HTTPS_PORT == "80" and CADDY_PORT == "80":
|
||||
CADDY_HTTPS_PORT="443"
|
||||
if 'UPDATE_CHANNEL' in dotenv and dotenv['UPDATE_CHANNEL'] != "main" and dotenv['UPDATE_CHANNEL'] != "migration":
|
||||
UPDATE_CHANNEL=dotenv['UPDATE_CHANNEL']
|
||||
if 'I2P_PASSWORD' in dotenv:
|
||||
|
@ -176,7 +181,6 @@ else:
|
|||
BITCOIN_RPC_DETAILS=get_data(BITCOIN_RPC_USER)
|
||||
BITCOIN_RPC_AUTH=BITCOIN_RPC_DETAILS['auth']
|
||||
BITCOIN_RPC_PASS=BITCOIN_RPC_DETAILS['password']
|
||||
|
||||
# Pull Tor image and generate Tor password
|
||||
print("Generating Tor password\n")
|
||||
os.system('docker pull --quiet {}'.format(dependencies["tor"]))
|
||||
|
@ -255,19 +259,17 @@ if BITCOIN_NETWORK == "testnet":
|
|||
# IP addresses for services
|
||||
NETWORK_IP="10.21.21.0"
|
||||
GATEWAY_IP="10.21.21.1"
|
||||
NGINX_IP="10.21.21.2"
|
||||
DASHBOARD_IP="10.21.21.3"
|
||||
MANAGER_IP="10.21.21.4"
|
||||
MIDDLEWARE_IP="10.21.21.5"
|
||||
NEUTRINO_SWITCHER_IP="10.21.21.6"
|
||||
DASHBOARD_NEW_IP="10.21.21.7"
|
||||
BITCOIN_IP="10.21.21.8"
|
||||
LND_IP="10.21.21.9"
|
||||
TOR_PROXY_IP="10.21.21.11"
|
||||
APPS_TOR_IP="10.21.21.12"
|
||||
APPS_2_TOR_IP="10.21.21.13"
|
||||
APPS_3_TOR_IP="10.21.21.14"
|
||||
I2P_IP="10.21.21.15"
|
||||
BITCOIN_IP="10.21.21.7"
|
||||
LND_IP="10.21.21.8"
|
||||
TOR_PROXY_IP="10.21.21.9"
|
||||
APPS_TOR_IP="10.21.21.10"
|
||||
APPS_2_TOR_IP="10.21.21.11"
|
||||
APPS_3_TOR_IP="10.21.21.12"
|
||||
I2P_IP="10.21.21.13"
|
||||
|
||||
# Ports
|
||||
BITCOIN_RPC_PORT="8332"
|
||||
|
@ -323,22 +325,7 @@ def replace_vars(file_path):
|
|||
file_contents = file.read()
|
||||
return re.sub(r'<(.*?)>', lambda m: get_var(convert_to_upper(m.group(1)), locals(), file_path), file_contents)
|
||||
|
||||
templates_to_build = {
|
||||
"./templates/torrc-core-sample": "./tor/torrc-core",
|
||||
"./templates/lnd-sample.conf": "./lnd/lnd.conf",
|
||||
"./templates/bitcoin-sample.conf": "./bitcoin/bitcoin.conf",
|
||||
"./templates/.env-sample": "./.env",
|
||||
"./templates/nginx-sample.conf": "./nginx/nginx.conf",
|
||||
"./templates/i2p-sample.conf": "./i2p/i2pd.conf",
|
||||
"./templates/i2p-tunnels-sample.conf": "./i2p/tunnels.conf"
|
||||
}
|
||||
|
||||
print("Generating configuration files...")
|
||||
|
||||
# Loop through templates_to_build and build them
|
||||
for template_path, output_path in templates_to_build.items():
|
||||
if output_path == "./nginx/nginx.conf" and os.path.isfile(output_path):
|
||||
continue
|
||||
def build_template(template_path, output_path):
|
||||
data = replace_vars(template_path)
|
||||
# If output path is a list, then it is a list of output paths
|
||||
if isinstance(output_path, list):
|
||||
|
@ -355,9 +342,15 @@ for template_path, output_path in templates_to_build.items():
|
|||
with open(output_path, 'w') as file:
|
||||
file.write(data)
|
||||
|
||||
print("Generated configuration files\n")
|
||||
print("Generating configuration files...")
|
||||
build_template("./templates/torrc-core-sample", "./tor/torrc-core")
|
||||
build_template("./templates/bitcoin-sample.conf", "./bitcoin/bitcoin.conf")
|
||||
build_template("./templates/i2p-sample.conf", "./i2p/i2pd.conf")
|
||||
build_template("./templates/i2p-tunnels-sample.conf", "./i2p/tunnels.conf")
|
||||
build_template("./templates/lnd-sample.conf", "./lnd/lnd.conf")
|
||||
build_template("./templates/.env-sample", "./.env")
|
||||
|
||||
print("Checking if Docker Compose is installed...")
|
||||
print("Ensuring Docker Compose is up to date...")
|
||||
download_docker_compose()
|
||||
|
||||
print("Updating core services...")
|
||||
|
@ -377,14 +370,21 @@ try:
|
|||
except: pass
|
||||
|
||||
if not reconfiguring:
|
||||
print("Updating apps...\n")
|
||||
print("Downloading apps...\n")
|
||||
os.system('./scripts/app update')
|
||||
else:
|
||||
print("Updating apps...\n")
|
||||
print("Generating app configuration...\n")
|
||||
os.system('./scripts/app generate')
|
||||
|
||||
# Touch status_dir/configured
|
||||
with open(status_dir+'/configured', 'w') as file:
|
||||
file.write('')
|
||||
|
||||
print("Configuring permissions...\n")
|
||||
try:
|
||||
os.system('chown -R 1000:1000 {}'.format(CITADEL_ROOT))
|
||||
except: pass
|
||||
|
||||
print("Configuration successful\n")
|
||||
print("You can now start Citadel by running:")
|
||||
print(" sudo ./scripts/start")
|
||||
|
|
|
@ -6,7 +6,7 @@ statuses
|
|||
tor/*
|
||||
logs/*
|
||||
app-data/*
|
||||
nginx/*
|
||||
caddy/*
|
||||
services/installed.yml
|
||||
apps/*
|
||||
i2p/*
|
||||
|
|
|
@ -8,3 +8,4 @@ apps/docker-compose.common.yml
|
|||
services/bitcoin/*
|
||||
services/lightning/*
|
||||
db/dependencies.yml
|
||||
apps/stores.yml
|
||||
|
|
|
@ -120,8 +120,6 @@ cat <<EOF > "$CITADEL_ROOT"/statuses/update-status.json
|
|||
{"state": "installing", "progress": 80, "description": "Starting new containers", "updateTo": "$RELEASE"}
|
||||
EOF
|
||||
cd "$CITADEL_ROOT"
|
||||
# Delete old nginx.conf
|
||||
rm -rf nginx/nginx.conf
|
||||
./scripts/start || true
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ How over-the-air updates work on Citadel.
|
|||
|
||||
## Execution Flow
|
||||
|
||||
1. New developments across the any/entire fleet of Citadel's services (bitcoind, lnd, dashboard, middleware, etc) are made, which maintain their own independent version-control and release-schedule. Subsequently, their new docker images are built, tagged and pushed to Docker Hub.
|
||||
1. New developments across the any/entire fleet of Citadel's services (bitcoind, dashboard, manager, etc) are made, which maintain their own independent version-control and release-schedule. Subsequently, their new docker images are built, tagged and pushed to Docker Hub.
|
||||
|
||||
2. The newly built and tagged images are updated in the main repository's (i.e. this repo) [`docker-compose.yml`](https://github.com/runcitadel/core/blob/main/docker-compose.yml) file.
|
||||
|
||||
|
|
|
@ -5,13 +5,12 @@
|
|||
|
||||
# Citadel Core
|
||||
DEVICE_HOSTNAME=<device-hostname>.local
|
||||
DEVICE_IP=<device-ip>
|
||||
NETWORK_IP=<network-ip>
|
||||
GATEWAY_IP=<gateway-ip>
|
||||
NGINX_IP=<nginx-ip>
|
||||
NGINX_PORT=<nginx-port>
|
||||
NGINX_SSL_PORT=<nginx-ssl-port>
|
||||
CADDY_PORT=<caddy-port>
|
||||
CADDY_HTTPS_PORT=<caddy-https-port>
|
||||
DASHBOARD_IP=<dashboard-ip>
|
||||
DASHBOARD_NEW_IP=<dashboard-new-ip>
|
||||
MANAGER_IP=<manager-ip>
|
||||
MIDDLEWARE_IP=<middleware-ip>
|
||||
NEUTRINO_SWITCHER_IP=<neutrino-switcher-ip>
|
||||
|
|
75
templates/Caddyfile.jinja
Normal file
75
templates/Caddyfile.jinja
Normal file
|
@ -0,0 +1,75 @@
|
|||
{% if https_options and https_options.agreed_lets_encrypt_tos and https_options.email %}
|
||||
{
|
||||
acme_ca https://acme-v02.api.letsencrypt.org/directory
|
||||
email {{ https_options.email }}
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
:{{CADDY_PORT}} {
|
||||
route /api/* {
|
||||
uri strip_prefix /api
|
||||
reverse_proxy {{MIDDLEWARE_IP}}:3000
|
||||
}
|
||||
|
||||
route /api-v2/* {
|
||||
uri strip_prefix /api-v2
|
||||
reverse_proxy {{MANAGER_IP}}:3000
|
||||
}
|
||||
|
||||
reverse_proxy {{DASHBOARD_IP}}:3004
|
||||
}
|
||||
|
||||
|
||||
|
||||
{% if https_options and https_options.agreed_lets_encrypt_tos and https_options.email and https_options.app_domains and https_options.app_domains.dashboard %}
|
||||
{{https_options.app_domains.dashboard}} {
|
||||
{% if https_options.user and https_options.user.username and https_options.user.password and https_options.app_domains.dashboard is ending_with(".runningcitadel.com") %}
|
||||
tls {
|
||||
dns runningcitadel {{ https_options.user.username }} {{ https_options.user.password }}
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
route /api/* {
|
||||
uri strip_prefix /api
|
||||
reverse_proxy {{MIDDLEWARE_IP}}:3000
|
||||
}
|
||||
|
||||
route /api-v2/* {
|
||||
uri strip_prefix /api-v2
|
||||
reverse_proxy {{MANAGER_IP}}:3000
|
||||
}
|
||||
|
||||
reverse_proxy {{DASHBOARD_IP}}:3004
|
||||
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% for app_id, entries in caddy_entries %}
|
||||
{% for entry in entries %}
|
||||
:{{entry.public_port}} {
|
||||
{% set container_ip_entry = "APP_" ~ app_id ~ "_" ~ entry.container_name ~ "_IP" | upper | replace(from="-", to="_") %}
|
||||
reverse_proxy {{ ip_map[container_ip_entry] }}:{{ entry.internal_port }}
|
||||
}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
{% if https_options and https_options.agreed_lets_encrypt_tos and https_options.email and https_options.app_domains %}
|
||||
{% for app_id, domain in https_options.app_domains %}
|
||||
{% if app_id != "dashboard" %}
|
||||
{% for entry in caddy_entries[app_id] %}
|
||||
{% if entry.is_primary %}
|
||||
{{domain}} {
|
||||
{% set container_ip_entry = "APP_" ~ app_id ~ "-" ~ entry.container_name ~ "_IP" | upper | replace(from="-", to="_") %}
|
||||
reverse_proxy {{ ip_map[container_ip_entry] }}:{{ entry.internal_port }}
|
||||
{% if https_options.user and https_options.user.username and https_options.user.password and domain is ending_with(".runningcitadel.com") %}
|
||||
tls {
|
||||
dns runningcitadel {{ https_options.user.username }} {{ https_options.user.password }}
|
||||
}
|
||||
{% endif %}
|
||||
}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
|
@ -1,5 +1,5 @@
|
|||
[dashboard]
|
||||
type = http
|
||||
host = <nginx-ip>
|
||||
host = host.docker.internal
|
||||
port = 80
|
||||
keys = citadel-dashboard.dat
|
||||
|
|
|
@ -4,13 +4,12 @@
|
|||
|
||||
# Bind only to "<tor-proxy-ip>" which is the tor IP within the container
|
||||
SocksPort <tor-proxy-ip>:<tor-proxy-port>
|
||||
ControlPort <tor-proxy-ip>:<tor-control-port>
|
||||
|
||||
# Citadel Core Services
|
||||
|
||||
# Dashboard Hidden Service
|
||||
HiddenServiceDir /var/lib/tor/web
|
||||
HiddenServicePort 80 <nginx-ip>:80
|
||||
HiddenServicePort 80 host.docker.internal:80
|
||||
|
||||
# Bitcoin Core P2P Hidden Service
|
||||
HiddenServiceDir /var/lib/tor/bitcoin-p2p
|
||||
|
@ -20,13 +19,3 @@ HiddenServicePort <bitcoin-p2p-port> <bitcoin-ip>:<bitcoin-p2p-port>
|
|||
HiddenServiceDir /var/lib/tor/bitcoin-rpc
|
||||
HiddenServicePort <bitcoin-rpc-port> <bitcoin-ip>:<bitcoin-rpc-port>
|
||||
|
||||
# LND REST Hidden Service
|
||||
HiddenServiceDir /var/lib/tor/lnd-rest
|
||||
HiddenServicePort <lnd-rest-port> <lnd-ip>:<lnd-rest-port>
|
||||
|
||||
# LND gRPC Hidden Service
|
||||
HiddenServiceDir /var/lib/tor/lnd-grpc
|
||||
HiddenServicePort <lnd-grpc-port> <lnd-ip>:<lnd-grpc-port>
|
||||
|
||||
HashedControlPassword <tor-hashed-password>
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user