stacker.news/docker-compose.yml

667 lines
19 KiB
YAML

x-env_file: &env_file
- path: .env.development
required: true
- path: .env.local
required: false
x-healthcheck: &healthcheck
interval: 10s
timeout: 10s
retries: 10
start_period: 1m
x-depends-on-db: &depends_on_db
db:
condition: service_healthy
restart: true
x-depends-on-app: &depends_on_app
app:
condition: service_healthy
restart: true
x-depends-on-bitcoin: &depends_on_bitcoin
bitcoin:
condition: service_healthy
restart: true
services:
db:
container_name: db
build: ./docker/db
restart: unless-stopped
healthcheck:
<<: *healthcheck
test: ["CMD-SHELL", "PGPASSWORD=${POSTGRES_PASSWORD} pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB} -h 127.0.0.1 && psql -U ${POSTGRES_USER} ${POSTGRES_DB} -c 'SELECT 1 FROM users LIMIT 1'"]
expose:
- "5432"
ports:
- "5431:5432"
env_file: *env_file
volumes:
- ./docker/db/seed.sql:/docker-entrypoint-initdb.d/seed.sql
- db:/var/lib/postgresql/data
labels:
CONNECT: "localhost:5431"
cpu_shares: "${CPU_SHARES_IMPORTANT}"
tor:
build:
context: ./docker/tor
container_name: tor
profiles:
- payments
restart: unless-stopped
volumes:
- tordata:/tordata/
cpu_shares: "${CPU_SHARES_LOW}"
env_file: *env_file
healthcheck:
<<: *healthcheck
test: ["CMD-SHELL", "bash /tor.sh check"]
app:
container_name: app
stdin_open: true
tty: true
build:
context: ./
args:
- UID=${CURRENT_UID}
- GID=${CURRENT_GID}
restart: unless-stopped
healthcheck:
<<: *healthcheck
test: ["CMD", "curl", "-f", "http://localhost:3000"]
depends_on: *depends_on_db
env_file: *env_file
expose:
- "3000"
ports:
- "3000:3000"
volumes:
- ./:/app
labels:
CONNECT: "localhost:3000"
cpu_shares: "${CPU_SHARES_IMPORTANT}"
capture:
container_name: capture
build:
context: ./capture
restart: unless-stopped
depends_on: *depends_on_app
profiles:
- capture
healthcheck:
<<: *healthcheck
test: ["CMD", "curl", "-f", "http://localhost:5678/health"]
env_file: *env_file
environment:
# configure to screenshot production, because local dev is too slow
- CAPTURE_URL=http://stacker.news
expose:
- "5678"
ports:
- "5678:5678"
labels:
CONNECT: "localhost:5678"
cpu_shares: "${CPU_SHARES_LOW}"
worker:
container_name: worker
build:
context: ./worker
args:
- UID=${CURRENT_UID}
- GID=${CURRENT_GID}
restart: unless-stopped
depends_on:
<<:
- *depends_on_db
- *depends_on_app
env_file: *env_file
volumes:
- ./:/app
entrypoint: ["/bin/sh", "-c"]
command:
- npm run worker:dev
cpu_shares: "${CPU_SHARES_IMPORTANT}"
imgproxy:
container_name: imgproxy
image: darthsim/imgproxy:v3.23.0
profiles:
- images
healthcheck:
<<: *healthcheck
test: [ "CMD", "imgproxy", "health" ]
restart: unless-stopped
env_file: *env_file
ports:
- "3001:8080"
expose:
- "8080"
labels:
- "CONNECT=localhost:3001"
cpu_shares: "${CPU_SHARES_LOW}"
s3:
container_name: s3
image: localstack/localstack:s3-latest
# healthcheck:
# test: ["CMD-SHELL", "awslocal", "s3", "ls", "s3://uploads"]
# interval: 10s
# timeout: 10s
# retries: 10
# start_period: 1m
restart: unless-stopped
profiles:
- images
env_file: *env_file
environment:
- DEBUG=1
ports:
- "4566:4566"
expose:
- "4566"
volumes:
- 's3:/var/lib/localstack'
- './docker/s3/init-s3.sh:/etc/localstack/init/ready.d/init-s3.sh'
- './docker/s3/cors.json:/etc/localstack/init/ready.d/cors.json'
labels:
- "CONNECT=localhost:4566"
cpu_shares: "${CPU_SHARES_LOW}"
opensearch:
image: opensearchproject/opensearch:2.12.0
container_name: opensearch
profiles:
- search
healthcheck:
<<: *healthcheck
test: ["CMD-SHELL", "curl -ku admin:${OPENSEARCH_INITIAL_ADMIN_PASSWORD} --silent --fail localhost:9200/_cluster/health || exit 1"]
restart: unless-stopped
env_file: *env_file
environment:
- OPENSEARCH_INITIAL_ADMIN_PASSWORD=mVchg1T5oA9wudUh
- plugins.security.disabled=true
- discovery.type=single-node
ports:
- 9200:9200 # REST API
- 9600:9600 # Performance Analyzer
volumes:
- os:/usr/share/opensearch/data
labels:
CONNECT: "localhost:9200"
command: >
bash -c '
set -m
/usr/share/opensearch/opensearch-docker-entrypoint.sh &
until curl -sS "http://localhost:9200/_cat/health?h=status" -ku admin:${OPENSEARCH_INITIAL_ADMIN_PASSWORD} | grep -q "green\|yellow"; do
echo "Waiting for OpenSearch to start..."
sleep 1
done
echo "OpenSearch started."
curl \
-H "Content-Type: application/json" \
-X PUT \
-d '{"mappings":{"properties":{"text":{"type":"text","analyzer":"english","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"title":{"type":"text","analyzer":"english","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}}}' \
"http://localhost:9200/item" \
-ku admin:${OPENSEARCH_INITIAL_ADMIN_PASSWORD}
echo "OpenSearch index created."
fg
'
cpu_shares: "${CPU_SHARES_LOW}"
os-dashboard:
image: opensearchproject/opensearch-dashboards:2.12.0
container_name: os-dashboard
restart: unless-stopped
profiles:
- search
depends_on:
opensearch:
condition: service_healthy
restart: true
env_file: *env_file
environment:
- opensearch.ssl.verificationMode=none
- OPENSEARCH_HOSTS=http://opensearch:9200
- server.ssl.enabled=false
ports:
- 5601:5601
links:
- opensearch
labels:
CONNECT: "localhost:5601"
cpu_shares: "${CPU_SHARES_LOW}"
bitcoin:
image: polarlightning/bitcoind:27.0
container_name: bitcoin
restart: unless-stopped
profiles:
- payments
healthcheck:
<<: *healthcheck
test: ["CMD-SHELL", "bitcoin-cli -chain=regtest -rpcport=${RPC_PORT} -rpcuser=${RPC_USER} -rpcpassword=${RPC_PASS} getblockchaininfo"]
command:
- 'bitcoind'
- '-server=1'
- '-regtest=1'
- '-rpcauth=${RPC_USER}:${RPC_AUTH}'
- '-debug=1'
- '-zmqpubrawblock=tcp://0.0.0.0:${ZMQ_BLOCK_PORT}'
- '-zmqpubrawtx=tcp://0.0.0.0:${ZMQ_TX_PORT}'
- '-txindex=1'
- '-dnsseed=0'
- '-upnp=0'
- '-rpcbind=0.0.0.0'
- '-rpcallowip=0.0.0.0/0'
- '-rpcport=${RPC_PORT}'
- '-rest'
- '-listen=1'
- '-listenonion=0'
- '-fallbackfee=0.0002'
- '-blockfilterindex=1'
- '-peerblockfilters=1'
- '-maxmempool=5'
expose:
- "${RPC_PORT}"
- "${P2P_PORT}"
- "${ZMQ_BLOCK_PORT}"
- "${ZMQ_TX_PORT}"
volumes:
- bitcoin:/home/bitcoin/.bitcoin
labels:
ofelia.enabled: "true"
ofelia.job-exec.minecron.schedule: "@every 1m"
ofelia.job-exec.minecron.command: >
bash -c '
bitcoin-cli () {
command bitcoin-cli -chain=regtest -rpcport=${RPC_PORT} -rpcuser=${RPC_USER} -rpcpassword=${RPC_PASS} "$$@"
}
blockcount=$$(bitcoin-cli getblockcount 2>/dev/null)
nodes=(${LND_ADDR} ${STACKER_LND_ADDR} ${STACKER_CLN_ADDR})
if (( blockcount <= 0 )); then
echo "Creating wallet and address..."
bitcoin-cli createwallet ""
nodes+=($$(bitcoin-cli getnewaddress))
echo "Mining 100 blocks to sn_lnd, lnd, cln..."
for addr in "$${nodes[@]}"; do
bitcoin-cli generatetoaddress 100 $$addr
echo "Mining 100 blocks to a random address..."
bitcoin-cli generatetoaddress 100 $$(bitcoin-cli getnewaddress)
done
else
echo "generating txs for fee rate estimation..."
while true
do
i=0
range=$$(( $$RANDOM % 11 + 20 ))
while [ $$i -lt $$range ]
do
address=$$(bitcoin-cli getnewaddress)
bitcoin-cli -named sendtoaddress address=$$address amount=0.01 fee_rate=$$(( $$RANDOM % 25 + 1 ))
((++i))
done
echo "generating block..."
bitcoin-cli generatetoaddress 1 "$${nodes[ $$RANDOM % $${#nodes[@]} ]}"
if [[ $$(bitcoin-cli estimatesmartfee 6) =~ "\\"feerate\\":" ]]; then
echo "fee estimation succeeded..."
break
fi
done
fi
'
cpu_shares: "${CPU_SHARES_MODERATE}"
sn_lnd:
build:
context: ./docker/lnd
args:
- LN_NODE_FOR=sn
container_name: sn_lnd
restart: unless-stopped
profiles:
- payments
healthcheck:
<<: *healthcheck
test: ["CMD-SHELL", "lncli", "getinfo"]
depends_on: *depends_on_bitcoin
env_file: *env_file
command:
- 'lnd'
- '--noseedbackup'
- '--trickledelay=5000'
- '--alias=sn_lnd'
- '--externalip=sn_lnd'
- '--tlsextradomain=sn_lnd'
- '--tlsextradomain=host.docker.internal'
- '--listen=0.0.0.0:9735'
- '--rpclisten=0.0.0.0:10009'
- '--restlisten=0.0.0.0:8080'
- '--bitcoin.active'
- '--bitcoin.regtest'
- '--bitcoin.node=bitcoind'
- '--bitcoind.rpchost=bitcoin'
- '--bitcoind.rpcuser=${RPC_USER}'
- '--bitcoind.rpcpass=${RPC_PASS}'
- '--bitcoind.zmqpubrawblock=tcp://bitcoin:${ZMQ_BLOCK_PORT}'
- '--bitcoind.zmqpubrawtx=tcp://bitcoin:${ZMQ_TX_PORT}'
- '--protocol.wumbo-channels'
- '--maxchansize=1000000000'
- '--allow-circular-route'
- '--bitcoin.defaultchanconfs=1'
- '--maxpendingchannels=10'
expose:
- "9735"
ports:
- "${LND_REST_PORT}:8080"
- "${LND_GRPC_PORT}:10009"
volumes:
- sn_lnd:/home/lnd/.lnd
labels:
CLI: "lncli"
CLI_USER: "lnd"
ofelia.enabled: "true"
ofelia.job-exec.sn_channel_cron.schedule: "@every 1m"
ofelia.job-exec.sn_channel_cron.command: >
su lnd -c bash -c "
if [ $$(lncli getinfo | jq '.num_active_channels + .num_pending_channels') -ge 3 ]; then
exit 0
else
lncli openchannel --node_key=$STACKER_LND_PUBKEY --connect lnd:9735 --sat_per_vbyte 1 \\
--min_confs 0 --local_amt=1000000000 --push_amt=500000000
fi
"
cpu_shares: "${CPU_SHARES_MODERATE}"
lnd:
build:
context: ./docker/lnd
args:
- LN_NODE_FOR=stacker
container_name: lnd
restart: unless-stopped
profiles:
- payments
healthcheck:
<<: *healthcheck
test: ["CMD-SHELL", "lncli", "getinfo"]
depends_on:
tor:
condition: service_healthy
restart: true
<<: *depends_on_bitcoin
env_file: *env_file
entrypoint: /tor-entrypoint
command:
- 'lnd'
- '--noseedbackup'
- '--trickledelay=5000'
- '--alias=lnd'
- '--externalip=lnd'
- '--tlsextradomain=lnd'
- '--tlsextradomain=host.docker.internal'
- '--tlsextradomain=$${ONION_DOMAIN}'
- '--listen=0.0.0.0:9735'
- '--rpclisten=0.0.0.0:10009'
- '--rpcmiddleware.enable'
- '--restlisten=0.0.0.0:8080'
- '--bitcoin.active'
- '--bitcoin.regtest'
- '--bitcoin.node=bitcoind'
- '--bitcoind.rpchost=bitcoin'
- '--bitcoind.rpcuser=${RPC_USER}'
- '--bitcoind.rpcpass=${RPC_PASS}'
- '--bitcoind.zmqpubrawblock=tcp://bitcoin:${ZMQ_BLOCK_PORT}'
- '--bitcoind.zmqpubrawtx=tcp://bitcoin:${ZMQ_TX_PORT}'
- '--protocol.wumbo-channels'
- '--maxchansize=1000000000'
- '--allow-circular-route'
- '--bitcoin.defaultchanconfs=1'
- '--maxpendingchannels=10'
expose:
- "9735"
- "10009"
ports:
- "${STACKER_LND_REST_PORT}:8080"
- "${STACKER_LND_GRPC_PORT}:10009"
volumes:
- lnd:/home/lnd/.lnd
- tordata:/home/lnd/.tor
labels:
TORDIR: "/home/lnd/.tor"
CERTDIR: "/home/lnd/.lnd"
CLI: "lncli"
CLI_USER: "lnd"
ofelia.enabled: "true"
ofelia.job-exec.lnd_channel_cron.schedule: "@every 1m"
ofelia.job-exec.lnd_channel_cron.command: >
su lnd -c bash -c "
if [ $$(lncli getinfo | jq '.num_active_channels + .num_pending_channels') -ge 3 ]; then
exit 0
else
lncli openchannel --node_key=$LND_PUBKEY --connect sn_lnd:9735 --sat_per_vbyte 1 \\
--min_confs 0 --local_amt=1000000000 --push_amt=500000000
fi
"
cpu_shares: "${CPU_SHARES_MODERATE}"
litd:
container_name: litd
build:
context: ./docker/litd
profiles:
- wallets
restart: unless-stopped
healthcheck:
<<: *healthcheck
test: ["CMD", "curl", "-f", "http://localhost:8443"]
depends_on:
lnd:
condition: service_healthy
restart: true
volumes:
- lnd:/lnd
ports:
- "8443:8443"
command:
- 'litd'
- '--httpslisten=0.0.0.0:8444'
- '--insecure-httplisten=0.0.0.0:8443'
- '--uipassword=password'
- '--lnd-mode=remote'
- '--network=regtest'
- '--remote.lit-debuglevel=debug'
- '--remote.lnd.rpcserver=lnd:10009'
- '--remote.lnd.macaroonpath=/lnd/data/chain/bitcoin/regtest/admin.macaroon'
- '--remote.lnd.tlscertpath=/lnd/tls.cert'
- '--autopilot.disable'
- '--pool.auctionserver=test.pool.lightning.finance:12010'
- '--loop.server.host=test.swap.lightning.today:11010'
labels:
CONNECT: "localhost:8443"
CLI: "litcli"
CLI_ARGS: "-n regtest --rpcserver localhost:8444"
cpu_shares: "${CPU_SHARES_MODERATE}"
cln:
build:
context: ./docker/cln
container_name: cln
restart: unless-stopped
profiles:
- payments
healthcheck:
<<: *healthcheck
test: ["CMD-SHELL", "su clightning -c 'lightning-cli --network=regtest getinfo'"]
depends_on:
tor:
condition: service_healthy
restart: true
<<: *depends_on_bitcoin
env_file: *env_file
command:
- 'lightningd'
- '--network=regtest'
- '--alias=cln'
- '--bitcoin-rpcconnect=bitcoin'
- '--bitcoin-rpcuser=${RPC_USER}'
- '--bitcoin-rpcpassword=${RPC_PASS}'
- '--large-channels'
- '--rest-port=3010'
- '--rest-host=0.0.0.0'
- '--log-file=/home/clightning/.lightning/debug.log'
expose:
- "9735"
ports:
- "${STACKER_CLN_REST_PORT}:3010"
volumes:
- cln:/home/clightning/.lightning
- tordata:/home/clightning/.tor
labels:
TORDIR: "/home/clightning/.tor"
CLI: "lightning-cli"
CLI_USER: "clightning"
CLI_ARGS: "--regtest"
ofelia.enabled: "true"
ofelia.job-exec.cln_channel_cron.schedule: "@every 1m"
ofelia.job-exec.cln_channel_cron.command: >
su clightning -c bash -c "
if [ $$(lightning-cli --regtest getinfo | jq '.num_active_channels + .num_pending_channels') -ge 3 ]; then
exit 0
else
lightning-cli --regtest connect $LND_PUBKEY@sn_lnd:9735
lightning-cli --regtest fundchannel id=$LND_PUBKEY feerate=1000perkb \\
amount=1000000000 push_msat=500000000000 minconf=0
fi
"
cpu_shares: "${CPU_SHARES_MODERATE}"
channdler:
image: mcuadros/ofelia:latest
container_name: channdler
profiles:
- payments
depends_on:
- bitcoin
- sn_lnd
- lnd
- cln
restart: unless-stopped
command: daemon --docker -f label=com.docker.compose.project=${COMPOSE_PROJECT_NAME}
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
cpu_shares: "${CPU_SHARES_LOW}"
mailhog:
image: mailhog/mailhog:latest
container_name: mailhog
profiles:
- email
restart: unless-stopped
healthcheck:
<<: *healthcheck
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8025"]
ports:
- "8025:8025"
- "1025:1025"
links:
- app
labels:
CONNECT: "localhost:8025"
cpu_shares: "${CPU_SHARES_LOW}"
nwc_send:
image: ghcr.io/benthecarman/nostr-wallet-connect-lnd:master
container_name: nwc_send
profiles:
- wallets
restart: unless-stopped
depends_on:
lnd:
condition: service_healthy
restart: true
volumes:
- nwc_send:/app
- lnd:/app/.lnd
environment:
- RUST_LOG=info
entrypoint:
- './nostr-wallet-connect-lnd'
- '--relay'
- 'wss://relay.primal.net'
- '--macaroon-file'
- '/app/.lnd/data/chain/bitcoin/regtest/admin.macaroon'
- '--cert-file'
- '/app/.lnd/tls.cert'
- '--lnd-host'
- 'lnd'
- '--lnd-port'
- '10009'
- '--max-amount'
- '0'
- '--daily-limit'
- '0'
- '--keys-file'
- 'keys-file.json'
cpu_shares: "${CPU_SHARES_LOW}"
nwc_recv:
image: ghcr.io/benthecarman/nostr-wallet-connect-lnd:master
container_name: nwc_recv
profiles:
- wallets
restart: unless-stopped
depends_on:
lnd:
condition: service_healthy
restart: true
volumes:
- nwc_recv:/app
- lnd:/app/.lnd
environment:
- RUST_LOG=info
entrypoint:
- './nostr-wallet-connect-lnd'
- '--relay'
- 'wss://relay.primal.net'
- '--invoice-macaroon-file'
- '/app/.lnd/data/chain/bitcoin/regtest/invoice.macaroon'
- '--cert-file'
- '/app/.lnd/tls.cert'
- '--lnd-host'
- 'lnd'
- '--lnd-port'
- '10009'
- '--max-amount'
- '0'
- '--daily-limit'
- '0'
- '--keys-file'
- 'keys-file.json'
cpu_shares: "${CPU_SHARES_LOW}"
lnbits:
build:
context: ./docker/lnbits
container_name: lnbits
profiles:
- wallets
restart: unless-stopped
ports:
- "${LNBITS_WEB_PORT}:5000"
depends_on:
tor:
condition: service_healthy
restart: true
lnd:
condition: service_healthy
restart: true
environment:
- LNBITS_ADMIN_UI=true
- LNBITS_BACKEND_WALLET_CLASS=LndWallet
- LND_GRPC_ENDPOINT=lnd
- LND_GRPC_PORT=10009
- LND_GRPC_CERT=/app/.lnd/tls.cert
- LND_GRPC_MACAROON=/app/.lnd/data/chain/bitcoin/regtest/admin.macaroon
volumes:
- lnd:/app/.lnd
- tordata:/app/.tor
labels:
CONNECT: "localhost:${LNBITS_WEB_PORT}"
TORDIR: "/app/.tor"
cpu_shares: "${CPU_SHARES_LOW}"
volumes:
db:
os:
bitcoin:
sn_lnd:
lnd:
cln:
s3:
nwc_send:
nwc_recv:
tordata: