stacker.news/docker-compose.yml
ekzyis 93713b33df
Optimistic updates via pending sats in item context (#1229)
* Use context for pending sats

* Fix sats going negative on zap undo

We already handle undoing pending sats by wrapping the payment+mutation with try/finally.

* Remove unnecessary ItemContextProvider

* Rename to parentCtx

* Fix hierarchy of ItemContextProvider

If a comment was root and it was zapped, the pending sats contributed to the sats shown in <CommentsHeader>.

This was caused by <CommentsHeader> accessing the root item context for all comments, even for the root comment.

So even if the root comment was zapped, the pending sats contributed to the sats for the comment section.

This wasn't the case for posts since their item context was above the context used by <CommentsHeader>.

This was fixed by moving <ItemProviderContext> down into <Comments> and <Item> instead of declaring it at <ItemFull> which wraps the root item and all comments.

* Optimistic update for poll votes

* prevent twice optimistic zap

* enhance client notifications with skeleton and no redudant queries

* enlarge nwc amount limits

* Disable max amount and daily limit in NWC container

---------

Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
Co-authored-by: keyan <keyan.kousha+huumn@gmail.com>
2024-06-12 08:34:24 -05:00

531 lines
16 KiB
YAML

x-env_file: &env_file .env.development
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"
app:
container_name: app
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"
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"
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
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"
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"
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
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
'
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"
bitcoin:
image: polarlightning/bitcoind:26.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'
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 '
blockcount=$$(bitcoin-cli -chain=regtest -rpcport=${RPC_PORT} -rpcuser=${RPC_USER} -rpcpassword=${RPC_PASS} getblockcount 2>/dev/null)
if (( blockcount <= 0 )); then
echo "Mining 10 blocks to sn_lnd, stacker_lnd, stacker_cln..."
bitcoin-cli -chain=regtest -rpcport=${RPC_PORT} -rpcuser=${RPC_USER} -rpcpassword=${RPC_PASS} generatetoaddress 100 ${LND_ADDR}
bitcoin-cli -chain=regtest -rpcport=${RPC_PORT} -rpcuser=${RPC_USER} -rpcpassword=${RPC_PASS} generatetoaddress 100 ${STACKER_LND_ADDR}
bitcoin-cli -chain=regtest -rpcport=${RPC_PORT} -rpcuser=${RPC_USER} -rpcpassword=${RPC_PASS} generatetoaddress 100 ${STACKER_CLN_ADDR}
else
echo "Mining a block to sn_lnd... ${LND_ADDR}"
bitcoin-cli -chain=regtest -rpcport=${RPC_PORT} -rpcuser=${RPC_USER} -rpcpassword=${RPC_PASS} generatetoaddress 1 ${LND_ADDR}
echo "Mining a block to stacker_lnd... ${STACKER_LND_ADDR}"
bitcoin-cli -chain=regtest -rpcport=${RPC_PORT} -rpcuser=${RPC_USER} -rpcpassword=${RPC_PASS} generatetoaddress 1 ${STACKER_LND_ADDR}
echo "Mining a block to stacker_cln... ${STACKER_CLN_ADDR}"
bitcoin-cli -chain=regtest -rpcport=${RPC_PORT} -rpcuser=${RPC_USER} -rpcpassword=${RPC_PASS} generatetoaddress 1 ${STACKER_CLN_ADDR}
fi
'
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:
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 stacker_lnd:9735 --sat_per_vbyte 1 \\
--min_confs 0 --local_amt=1000000000 --push_amt=500000000
fi
"
stacker_lnd:
build:
context: ./docker/lnd
args:
- LN_NODE_FOR=stacker
container_name: stacker_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=stacker_lnd'
- '--externalip=stacker_lnd'
- '--tlsextradomain=stacker_lnd'
- '--tlsextradomain=host.docker.internal'
- '--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:
- stacker_lnd:/home/lnd/.lnd
labels:
ofelia.enabled: "true"
ofelia.job-exec.stacker_lnd_channel_cron.schedule: "@every 1m"
ofelia.job-exec.stacker_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
"
litd:
container_name: litd
image: lightninglabs/lightning-terminal:v0.12.4-alpha
profiles:
- payments
restart: unless-stopped
healthcheck:
<<: *healthcheck
test: ["CMD", "curl", "-f", "http://localhost:8443"]
depends_on:
stacker_lnd:
condition: service_healthy
restart: true
volumes:
- stacker_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=stacker_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"
stacker_cln:
build:
context: ./docker/cln
container_name: stacker_cln
restart: unless-stopped
profiles:
- payments
healthcheck:
<<: *healthcheck
test: ["CMD-SHELL", "su clightning -c 'lightning-cli --network=regtest getinfo'"]
depends_on: *depends_on_bitcoin
env_file: *env_file
command:
- 'lightningd'
- '--network=regtest'
- '--alias=stacker_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:
- stacker_cln:/home/clightning/.lightning
labels:
ofelia.enabled: "true"
ofelia.job-exec.stacker_cln_channel_cron.schedule: "@every 1m"
ofelia.job-exec.stacker_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
"
channdler:
image: mcuadros/ofelia:latest
container_name: channdler
profiles:
- payments
depends_on:
- bitcoin
- sn_lnd
- stacker_lnd
- stacker_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
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"
nwc:
build:
context: ./docker/nwc
container_name: nwc
profiles:
- payments
restart: unless-stopped
depends_on:
stacker_lnd:
condition: service_healthy
restart: true
volumes:
- ./docker/lnd/stacker:/root/.lnd
environment:
- RUST_LOG=info
entrypoint:
- 'nostr-wallet-connect-lnd'
- '--relay'
- 'wss://relay.damus.io'
- '--macaroon-file'
- '/root/.lnd/regtest/admin.macaroon'
- '--cert-file'
- '/root/.lnd/tls.cert'
- '--lnd-host'
- 'stacker_lnd'
- '--lnd-port'
- '10009'
- '--max-amount'
- '0'
- '--daily-limit'
- '0'
lnbits:
image: lnbits/lnbits:0.12.5
container_name: lnbits
profiles:
- payments
restart: unless-stopped
ports:
- "${LNBITS_WEB_PORT}:5000"
depends_on:
- stacker_lnd
environment:
- LNBITS_BACKEND_WALLET_CLASS=LndWallet
- LND_GRPC_ENDPOINT=stacker_lnd
- LND_GRPC_PORT=10009
- LND_GRPC_CERT=/app/.lnd/tls.cert
- LND_GRPC_MACAROON=/app/.lnd/regtest/admin.macaroon
volumes:
- ./docker/lnd/stacker:/app/.lnd
volumes:
db:
os:
bitcoin:
sn_lnd:
stacker_lnd:
stacker_cln:
s3: