diff --git a/.github/workflows/node-client-image.yml b/.github/workflows/node-client-image.yml new file mode 100644 index 00000000..ea5afa4b --- /dev/null +++ b/.github/workflows/node-client-image.yml @@ -0,0 +1,75 @@ +name: RoboSats Client Node App Image CI/CD + +on: + workflow_dispatch: + push: + branches: [ "main" ] + paths: ["frontend", "nodeapp"] + pull_request: + branches: [ "main" ] + paths: ["frontend", "nodeapp"] + +concurrency: + group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}' + cancel-in-progress: true + +jobs: + push_to_registry: + name: 'Push Docker image to Docker Hub' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: 'Download main.js Artifact' + uses: dawidd6/action-download-artifact@v2 + with: + workflow: frontend-build.yml + workflow_conclusion: success + name: main-js + path: frontend/static/frontend/ + + - name: 'Log in to Docker Hub' + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: 'Extract metadata (tags, labels) for Docker' + id: meta + uses: docker/metadata-action@v4 + with: + images: recksato/robosats-client + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=sha + type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }} + + - name: 'Get Commit Hash' + id: commit + uses: pr-mpt/actions-commit-hash@v1 + + - name: 'Save Commit Long Hash to TXT File' + run: | + echo ${{ steps.commit.outputs.long }}>"commit_sha.txt" + + - name: 'Set up QEMU' + uses: docker/setup-qemu-action@v2 + + - name: 'Set up Docker Buildx' + uses: docker/setup-buildx-action@v2 + + - name: 'Build and push Docker image' + uses: docker/build-push-action@v3 + with: + context: ./nodeapp + platforms: linux/amd64,linux/arm64 + push: true + tags: | + recksato/robosats-client:${{ steps.commit.outputs.short }} + recksato/robosats-client:latest + labels: ${{ steps.meta.outputs.labels }} + diff --git a/docker-compose.yml b/docker-compose.yml index 0ceb5b05..78700ee7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -45,6 +45,16 @@ services: volumes: - ./frontend:/usr/src/frontend + nodeapp: # Umbrel / Citadel app + build: ./nodeapp + container_name: nodeapp-dev + restart: always + environment: + TOR_PROXY_IP: 127.0.0.1 + TOP_PROXY_PORT: 9050 + ROBOSATS_ONION: robosats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion + network_mode: service:tor + clean-orders: image: backend restart: always @@ -108,7 +118,8 @@ services: - ./node/tor/data:/var/lib/tor - ./node/tor/config:/etc/tor ports: - - 8000:8000 + - 8000:8000 # dev frontend build + - 12596:12596 # umbrel frontend lnd: build: ./docker/lnd diff --git a/nodeapp/.dockerignore b/nodeapp/.dockerignore new file mode 100644 index 00000000..42061c01 --- /dev/null +++ b/nodeapp/.dockerignore @@ -0,0 +1 @@ +README.md \ No newline at end of file diff --git a/nodeapp/Dockerfile b/nodeapp/Dockerfile new file mode 100644 index 00000000..6afdcb2c --- /dev/null +++ b/nodeapp/Dockerfile @@ -0,0 +1,14 @@ +FROM node:18-bullseye-slim + +RUN mkdir -p /usr/src/robosats +WORKDIR /usr/src/robosats + +COPY . . + +RUN apt-get update +RUN apt-get install -y socat +RUN npm install http-server + +EXPOSE 12596 + +CMD npm exec http-server -- . -p 12596 -P http://127.0.0.1:81 -i false -d false & nohup socat tcp4-LISTEN:81,reuseaddr,fork,keepalive,bind=127.0.0.1 SOCKS4A:${TOR_PROXY_IP:-127.0.0.1}:${ROBOSATS_ONION:-robosats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion}:80,socksport=${TOR_PROXY_PORT:-9050} \ No newline at end of file diff --git a/nodeapp/README.md b/nodeapp/README.md new file mode 100644 index 00000000..301284c6 --- /dev/null +++ b/nodeapp/README.md @@ -0,0 +1,7 @@ +# RoboSats app for soverign nodes. + +RoboSats app for soverign nodes ( Umbrel, Citadel, Start9 ...). This app serves the RoboSats frontend app directly from your own node and redirects all API requests to RoboSats P2P market coordinator through your node's TOR proxy. + +At the moment it has no special integration with your local lightning wallet (e.g. LND). This can be achieved easily by installing a WebLN compatible extension in your browser (e.g. getAlby). + +The container launches two processes: 1) A `socat` that will expose RoboSats coordinator API over HTTP using the docker orchestration Tor socks proxy and 2) a `http-server` that will serve all static files (including the Javascript client app) directly from your own node (should reduce loading times by a lot). Every request that cannot be served by your node http-server will be forwarded to the RoboSats coordinator (that is: API calls and Robot avatar images). diff --git a/nodeapp/static b/nodeapp/static new file mode 120000 index 00000000..9653c34d --- /dev/null +++ b/nodeapp/static @@ -0,0 +1 @@ +../frontend/static \ No newline at end of file