From cde7fab90c3a2d1185d59904087f333d312d88aa Mon Sep 17 00:00:00 2001 From: nobswebdev Date: Thu, 3 Sep 2026 23:03:49 +0200 Subject: [PATCH] move monero wallet creation into container entrypoint --- Readme.md | 5 +- deploy/DEPLOYMENT_GUIDE.md | 20 +- docker-compose.dev.yml | 4 +- docker-compose.prod.yml | 4 +- monero-wallet-rpc/Dockerfile | 20 +- monero-wallet-rpc/docker-entrypoint.sh | 37 ++++ monero-wallet-rpc/setup-monero-wallet.sh | 222 ----------------------- 7 files changed, 56 insertions(+), 256 deletions(-) create mode 100644 monero-wallet-rpc/docker-entrypoint.sh delete mode 100755 monero-wallet-rpc/setup-monero-wallet.sh diff --git a/Readme.md b/Readme.md index a339846..d16ce4c 100644 --- a/Readme.md +++ b/Readme.md @@ -1,6 +1,6 @@ # NullCart -Self-hosted Monero shop with clearnet (HTTPS) and Tor onion hosting. +Self-hosted crypto shop with clearnet (HTTPS) and Tor onion hosting. For production deployment, see the [deployment guide](deploy/DEPLOYMENT_GUIDE.md). @@ -12,9 +12,6 @@ For production deployment, see the [deployment guide](deploy/DEPLOYMENT_GUIDE.md # Create and edit .env.dev as needed cp .env.example .env.dev -# Create monero wallet used by shop -./monero-wallet-rpc/setup-monero-wallet.sh --env-file .env.dev - # Build and start docker containers docker compose --env-file .env.dev -f docker-compose.dev.yml build --no-cache docker compose --env-file .env.dev -f docker-compose.dev.yml up --force-recreate diff --git a/deploy/DEPLOYMENT_GUIDE.md b/deploy/DEPLOYMENT_GUIDE.md index 569bf24..798af3a 100644 --- a/deploy/DEPLOYMENT_GUIDE.md +++ b/deploy/DEPLOYMENT_GUIDE.md @@ -74,13 +74,7 @@ Example (default in `.env.example`): Orders up to 30 → 0 confirmations; up to 100 → 3; up to 300 → 5; above 300 → 10. Tiers are shown read-only in CMS shop settings. -## 5. Create the Monero wallet - -```bash -./monero-wallet-rpc/setup-monero-wallet.sh --env-file .env.prod -``` - -## 6. Bootstrap TLS certificates +## 5. Bootstrap TLS certificates Nginx needs certificate files before it can start on port 443. For the **first** deploy, create a temporary self-signed pair (replaced after Let's Encrypt): @@ -88,9 +82,9 @@ Nginx needs certificate files before it can start on port 443. For the **first** ./deploy/scripts/bootstrap-certs.sh ``` -After the stack is running, obtain real certificates (step 8). +After the stack is running, obtain real certificates (step 7). -## 7. Start the stack +## 6. Start the stack ```bash ./deploy/scripts/deploy.sh @@ -102,7 +96,7 @@ Wait until `backend` and `nginx` are healthy: docker compose --env-file .env.prod -f docker-compose.prod.yml ps ``` -## 8. Issue Let's Encrypt certificates +## 7. Issue Let's Encrypt certificates Remove the temporary bootstrap certificates under `deploy/certs/live/` (Certbot cannot issue into the layout created by `bootstrap-certs.sh`): @@ -142,20 +136,20 @@ Save and exit the editor. Optional — run once manually to verify: /root/nullcart/deploy/scripts/renew-certs.sh ``` -## 9. Tor onion address +## 8. Tor onion address ```bash ./deploy/scripts/show-onion.sh ``` -## 10. Complete shop setup +## 9. Complete shop setup 1. Open the CMS on clearnet or onion (`/cms`). 2. Log in with `CMS_PASSWORD` from `.env.prod`. 3. Finish the setup checklist in settings. 4. Connect SimpleX notifications in shop settings. -## 11. Updates +## 10. Updates ```bash ./deploy/scripts/update.sh diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 3133756..c3e6689 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -50,8 +50,8 @@ services: ] interval: 10s timeout: 5s - retries: 5 - start_period: 60s + retries: 10 + start_period: 300s simplex-cli: build: diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index f06b87f..bdd8a2c 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -47,8 +47,8 @@ services: ] interval: 10s timeout: 5s - retries: 5 - start_period: 60s + retries: 10 + start_period: 300s simplex-cli: build: diff --git a/monero-wallet-rpc/Dockerfile b/monero-wallet-rpc/Dockerfile index 0884075..343d639 100644 --- a/monero-wallet-rpc/Dockerfile +++ b/monero-wallet-rpc/Dockerfile @@ -13,6 +13,7 @@ RUN apt-get update \ && curl -fsSL "https://downloads.getmonero.org/cli/monero-linux-${monero_arch}-v${MONERO_VERSION}.tar.bz2" \ | tar -xj -C /tmp \ && install -m 755 "$(find /tmp -type f -name monero-wallet-rpc | head -n 1)" /monero-wallet-rpc \ + && install -m 755 "$(find /tmp -type f -name monero-wallet-cli | head -n 1)" /monero-wallet-cli \ && rm -rf /var/lib/apt/lists/* FROM debian:bookworm-slim @@ -22,17 +23,10 @@ RUN apt-get update \ && rm -rf /var/lib/apt/lists/* COPY --from=build /monero-wallet-rpc /usr/local/bin/monero-wallet-rpc +COPY --from=build /monero-wallet-cli /usr/local/bin/monero-wallet-cli -CMD ["/bin/sh", "-ec", "\ - exec monero-wallet-rpc \ - \"--${MONERO_NETWORK}\" \ - --daemon-address=\"${MONERO_DAEMON_ADDRESS}\" \ - --trusted-daemon \ - --no-initial-sync \ - --rpc-bind-ip=0.0.0.0 \ - --rpc-bind-port=${MONERO_WALLET_RPC_PORT} \ - --confirm-external-bind \ - --rpc-login=\"${MONERO_WALLET_RPC_USERNAME}:${MONERO_WALLET_RPC_PASSWORD}\" \ - --wallet-file=\"/monero/wallet/${MONERO_WALLET_NAME}\" \ - --password=\"${MONERO_WALLET_PASSWORD}\" \ -"] +COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh + +RUN chmod +x /usr/local/bin/docker-entrypoint.sh + +ENTRYPOINT ["docker-entrypoint.sh"] diff --git a/monero-wallet-rpc/docker-entrypoint.sh b/monero-wallet-rpc/docker-entrypoint.sh new file mode 100644 index 0000000..3a3575e --- /dev/null +++ b/monero-wallet-rpc/docker-entrypoint.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +set -euo pipefail + +WALLET_DIR="/monero/wallet" +WALLET_PATH="${WALLET_DIR}/${MONERO_WALLET_NAME}" +NETWORK_FLAG="--${MONERO_NETWORK}" + +mkdir -p "${WALLET_DIR}" +chmod 700 "${WALLET_DIR}" + +if [[ ! -f "${WALLET_PATH}" && ! -f "${WALLET_PATH}.keys" ]]; then + echo "Creating ${MONERO_NETWORK} wallet at ${WALLET_PATH}..." + + monero-wallet-cli "${NETWORK_FLAG}" \ + --offline \ + --log-file /dev/null \ + --generate-new-wallet "${WALLET_PATH}" \ + --password "${MONERO_WALLET_PASSWORD}" \ + --mnemonic-language English \ + --command save + + chmod 600 "${WALLET_PATH}" "${WALLET_PATH}.keys" 2>/dev/null || true + + echo "Wallet created at ${WALLET_PATH}" +fi + +exec monero-wallet-rpc \ + "${NETWORK_FLAG}" \ + --daemon-address="${MONERO_DAEMON_ADDRESS}" \ + --trusted-daemon \ + --no-initial-sync \ + --rpc-bind-ip=0.0.0.0 \ + --rpc-bind-port="${MONERO_WALLET_RPC_PORT}" \ + --confirm-external-bind \ + --rpc-login="${MONERO_WALLET_RPC_USERNAME}:${MONERO_WALLET_RPC_PASSWORD}" \ + --wallet-file="${WALLET_PATH}" \ + --password="${MONERO_WALLET_PASSWORD}" diff --git a/monero-wallet-rpc/setup-monero-wallet.sh b/monero-wallet-rpc/setup-monero-wallet.sh deleted file mode 100755 index 0b44e0a..0000000 --- a/monero-wallet-rpc/setup-monero-wallet.sh +++ /dev/null @@ -1,222 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -ENV_FILE="" -MONERO_CLI_INSTALL_PATH="/usr/local/bin/monero-wallet-cli" - -usage() { - cat <&2 - usage >&2 - exit 1 - ;; - esac -done - -if [[ -z "$ENV_FILE" ]]; then - echo "--env-file is required." >&2 - usage >&2 - exit 1 -fi - -if [[ "$ENV_FILE" != /* ]]; then - ENV_FILE="${ROOT_DIR}/${ENV_FILE#./}" -fi - -if [[ ! -f "$ENV_FILE" ]]; then - echo "Env file not found: $ENV_FILE" >&2 - exit 1 -fi - -set -a -# shellcheck disable=SC1090 -source "$ENV_FILE" -set +a - -main() { - validate_env - ensure_dependencies - setup_wallet_config - create_wallet_if_missing -} - -validate_env() { - local missing=() - - for var in MONERO_VERSION MONERO_WALLET_DIR MONERO_WALLET_NAME MONERO_NETWORK MONERO_WALLET_PASSWORD; do - if [[ -z "${!var:-}" ]]; then - missing+=("$var") - fi - done - - if [[ ${#missing[@]} -gt 0 ]]; then - echo "Missing required env vars in ${ENV_FILE}: ${missing[*]}" >&2 - exit 1 - fi - - case "$MONERO_NETWORK" in - mainnet | stagenet | testnet) ;; - *) - echo "MONERO_NETWORK must be mainnet, stagenet, or testnet (got: ${MONERO_NETWORK})." >&2 - exit 1 - ;; - esac -} - -ensure_dependencies() { - if ! command -v apt-get >/dev/null 2>&1; then - echo "apt-get is required. This script supports Ubuntu/Debian only." >&2 - exit 1 - fi - - local missing=() - - for cmd in curl tar bzip2; do - if command -v "$cmd" >/dev/null 2>&1; then - log_skip "$cmd" - else - log_install "$cmd" - missing+=("$cmd") - fi - done - - if [[ ${#missing[@]} -gt 0 ]]; then - run_privileged apt-get update -qq - run_privileged apt-get install -y -qq "${missing[@]}" - fi - - install_monero_wallet_cli_if_missing -} - -install_monero_wallet_cli_if_missing() { - local arch archive_url tmp_dir extracted_cli - - if command -v monero-wallet-cli >/dev/null 2>&1; then - log_skip "monero-wallet-cli" - return - fi - - log_install "monero-wallet-cli" - - arch="$(uname -m)" - - case "$arch" in - x86_64 | amd64) - archive_url="https://downloads.getmonero.org/cli/monero-linux-x64-v${MONERO_VERSION}.tar.bz2" - ;; - aarch64 | arm64) - archive_url="https://downloads.getmonero.org/cli/monero-linux-armv8-v${MONERO_VERSION}.tar.bz2" - ;; - *) - echo "Unsupported CPU architecture: ${arch}" >&2 - echo "Install monero-wallet-cli from https://www.getmonero.org/downloads/ and re-run." >&2 - exit 1 - ;; - esac - - tmp_dir="$(mktemp -d)" - trap "rm -rf '${tmp_dir}'" RETURN - - curl -fsSL "$archive_url" | tar -xj -C "$tmp_dir" - extracted_cli="$(find "$tmp_dir" -type f -name monero-wallet-cli | head -n 1)" - - if [[ -z "$extracted_cli" ]]; then - echo "Could not find monero-wallet-cli in the downloaded archive." >&2 - exit 1 - fi - - run_privileged install -m 755 "$extracted_cli" "$MONERO_CLI_INSTALL_PATH" -} - -setup_wallet_config() { - WALLET_DIR="$(resolve_path "$MONERO_WALLET_DIR")" - WALLET_PATH="${WALLET_DIR}/${MONERO_WALLET_NAME}" - NETWORK="$MONERO_NETWORK" -} - -resolve_path() { - local path="$1" - - if [[ "$path" != /* ]]; then - path="${ROOT_DIR}/${path#./}" - fi - - printf '%s' "$path" -} - -create_wallet_if_missing() { - mkdir -p "$WALLET_DIR" - chmod 700 "$WALLET_DIR" - - if [[ -f "$WALLET_PATH" || -f "${WALLET_PATH}.keys" ]]; then - echo "Wallet already exists at ${WALLET_PATH} — skipping creation." - return - fi - - echo "Creating ${NETWORK} wallet at ${WALLET_PATH}..." - - monero-wallet-cli "--${NETWORK}" \ - --offline \ - --log-file /dev/null \ - --generate-new-wallet "$WALLET_PATH" \ - --password "$MONERO_WALLET_PASSWORD" \ - --mnemonic-language English \ - --command save - - chmod 600 "${WALLET_PATH}" "${WALLET_PATH}.keys" 2>/dev/null || true - - cat </dev/null 2>&1; then - sudo "$@" - else - echo "Root or sudo is required to install missing packages." >&2 - exit 1 - fi -} - -log_skip() { - echo "Package ${1} already installed — skipping." -} - -log_install() { - echo "Package ${1} is not installed — installing..." -} - -main