gun relay manual setting up (cert ssl container oracle cloud) - amark/gun GitHub Wiki

Relay Service Facts

  • Gun github repository has a node.js script alias already to setup an testing relay server and it is straight forward
  • Gun relay servers that is practically usable should support https protocol with valid certificates
  • There are existing free tier cloud providers that makes the relay service with https support

Oracle Cloud Free tier

  • 2 X always free amd64 vms (1 cpu core / 1G memory)
  • possible free arm64 vm (4 cpu cores / 24G memory)

this is good for setting up a pool of relay servers that the community can utilize, the registration does require to have a credit card though

Example with oracle cloud always free vm and podman

  1. register oracle cloud, note that it asks credit card information
  2. create a always free vm so that you do not need to worry about costs (use ubuntu linux lts 22.04), screenshot below
  3. by default, only ssh traffic (port 22) is allowed to access the vm, ssh login to it as user ubuntu, the IP address will be used below.
  4. add or update security list to allow http/https traffic (ports 80 and 443), screenshot below
  5. generate free certificates with letsencrypt / certbot
  • install certbot sudo snap install certbot --classic
  • generate certificates with a regular dns name or the free one by nip.io sudo certbot certonly --standalone -d 129.153.63.74.nip.io
  • should have certificates in filesystem /etc/letsencrypt/live
  1. run the relay with podman (docker)
  • install podman sudo apt install podman
  • run relay sudo podman run -d --rm --name gun-relay -p 443:8080 -e HTTPS=true -v /etc/letsencrypt:/etc/letsencrypt -e HTTPS_KEY=/etc/letsencrypt/live/129.153.63.74.nip.io/privkey.pem -e HTTPS_CERT=/etc/letsencrypt/live/129.153.63.74.nip.io/cert.pem docker.io/lospringliu/gun-js-relay, screenshot
  1. you can validate from your browser now https://129.153.63.74.nip.io
  2. notes: 129.153.63.74 is the ip address of my vm, replace with yours
  3. notes: certificate is valid 3 months, you need either renew or regenerate

screenshots

always free vm

allow http/https traffic

image

podman command

Example with oracle cloud free arm64 vm and kubernetes (automatic certificates renewal)

  1. create free arm64 vm (4 cpu cores and 24G memory with ubuntu 22.04)
  2. ssh login to the vm
  3. allow traffic access for http/https (port 80 and 443)
  4. install/configure kubernetes
  • install k8s sudo snap install microk8s --classic; sudo usermod -a -G microk8s ubuntu (ssh logout and login again)
  • configure k8s microk8s enable dns; microk8s enable cert-manager; microk8s enable ingress
  1. create cert-manager letsencrypt cluster issuer (with your email)
microk8s kubctl create -f- << ENDF
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt
spec:
  acme:
    email: [email protected]
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-account-key
    solvers:
    - http01:
        ingress:
          class: public
ENDF
  1. create an ingress that routes https traffic to gun relay service
  • microk8s kubectl create ingress gun --annotation cert-manager.io/cluster-issuer=letsencrypt --rule 'relay.129.153.59.37.nip.io/*=svc-gun-relay:8080,tls=gun-tls'
  1. create gun relay deployment and service
microk8s kubectl create -f- << ENDF
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: gun-js-relay
  name: gun-js-relay-deployment
  namespace: default
spec:
  progressDeadlineSeconds: 600
  replicas: 3
  selector:
    matchLabels:
      app: gun-js-relay
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: gun-js-relay
    spec:
      containers:
      - image: lospringliu/gun-js-relay:latest-arm64
        imagePullPolicy: IfNotPresent
        name: gun-js-relay
        ports:
        - containerPort: 8080
          protocol: TCP
        - containerPort: 8765
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: gun-js-relay
  name: svc-gun-relay
  namespace: default
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: gun-js-relay
  sessionAffinity: None
  type: ClusterIP
ENDF
  1. you can validate from your browser now https://relay.29.153.59.37.nip.io/
  2. notes: 29.153.59.37 is the ip address of my vm, replace with yours

Reference - container image

docker://docker.io/lospringliu/gun-js-relay

  • supports both amd64 and arm64 architectures
  • supports http protocol (testing/ingress) or https protocol [HTTPS, HTTPS_KEY, HTTPS_CERT]
  • supports relay only or persist locally [RELAY_ONLY]
FROM node:lts-alpine as builder
RUN mkdir /work
WORKDIR /work
RUN apk add --no-cache alpine-sdk python3
COPY package.json ./
RUN npm install --omit=dev

LABEL org.label-schema.build-date="20230102" \
  org.label-schema.name="Gun - Offline First, Javascript Graph Database" \
  org.label-schema.url="http://gun.js.org" \
  org.label-schema.vendor="The Gun Database Team" \
  org.label-schema.version="0.2020.1239"

FROM node:lts-alpine
ENV PORT=8080
ENV RELAY_ONLY=true
ENV HTTPS=false
ENV HTTPS_KEY=/etc/letsencrypt/live/YOUR-DOMAIN/privkey.pem
ENV HTTPS_CERT=/etc/letsencrypt/live/YOUR-DOMAIN/cert.pem
RUN mkdir /work
WORKDIR /work
COPY --from=builder /work/node_modules ./node_modules
ADD . .
RUN rm -fr .git
EXPOSE $PORT
EXPOSE 8765

RUN mkdir -p /etc/letsencrypt
RUN echo -en "#!/bin/sh\n\n\$RELAY_ONLY && (sed -i \"s|require('./store');|//require('./store');|\" lib/server.js; cat lib/server.js)\n\n\$HTTPS && npm run start || (unset HTTPS_CERT; unset HTTPS_KEY; npm run start) \n" > entrypoint; chmod +x entrypoint; ls -al entrypoint; cat entrypoint
ENTRYPOINT ["./entrypoint"]