From 3089316a2520b9e029132cd9ace09d4a358786d7 Mon Sep 17 00:00:00 2001 From: capitano Date: Tue, 7 Apr 2026 16:35:44 +0200 Subject: [PATCH] Update Enigma BBS deployment --- Dockerfile | 120 +++++++++++++++++++---------------------- build-and-push.sh | 14 +++++ configmap.yaml | 1 + deployment.yaml | 124 +++++++++++++++++++++++++++++++++++++++---- registry-secret.yaml | 8 +++ ssh-secret.yaml | 7 +++ 6 files changed, 197 insertions(+), 77 deletions(-) create mode 100755 build-and-push.sh create mode 100644 registry-secret.yaml create mode 100644 ssh-secret.yaml diff --git a/Dockerfile b/Dockerfile index 1ba598c..dea84d7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,82 +1,70 @@ -# Build stage -FROM --platform=${BUILDPLATFORM:-linux/amd64} node:20-bookworm-slim AS builder - -ARG TARGETPLATFORM -ARG BUILDPLATFORM -ARG TARGETOS - -ENV NVM_DIR /root/.nvm \ - DEBIAN_FRONTEND=noninteractive - -RUN apt-get update \ - && apt-get install -y \ - git curl build-essential python3 libssl-dev \ - lrzsz arj lhasa unrar-free p7zip-full dos2unix \ - && npm set progress=false && npm config set depth 0 \ - && npm install -g npm@latest pm2 - -WORKDIR /tmp - -RUN git clone --depth 1 https://github.com/NuSkooler/enigma-bbs.git enigma-bbs-source \ - && cd enigma-bbs-source \ - && npm install --ignore-scripts \ - && dos2unix docker/bin/docker-entrypoint.sh \ - && dos2unix autoexec.sh - -# Runtime stage -FROM node:20-bookworm-slim +FROM --platform=${BUILDPLATFORM:-linux/amd64} node:20-bookworm-slim ARG TARGETPLATFORM ARG BUILDPLATFORM ARG TARGETOS +ARG TARGETBRANCH LABEL maintainer="dave@force9.org" -ENV NVM_DIR=/root/.nvm \ - DEBIAN_FRONTEND=noninteractive \ - PATH=/root/.npm-global/bin:/usr/local/bin:/usr/bin:/bin \ - BBS_ROOT_DIR=/enigma-bbs \ - BBS_STAGING_PATH=/enigma-bbs-pre +ENV NVM_DIR /root/.nvm +ENV DEBIAN_FRONTEND noninteractive -RUN apt-get update && apt-get install -y \ - git curl \ - lrzsz arj lhasa unrar-free p7zip-full \ + +# Install APT and NPM packages +RUN apt-get update \ + && apt-get install -y \ + git \ + curl \ + build-essential \ + python3 \ + libssl-dev \ + lrzsz \ + arj \ + lhasa \ + unrar-free \ + p7zip-full \ + dos2unix \ + && npm set progress=false && npm config set depth 0 \ + && npm install -g npm@latest \ + && npm install -g pm2 + + +COPY . /enigma-bbs/ + +WORKDIR /enigma-bbs + +# Install npm dependencies +RUN cd /enigma-bbs && npm install + +# Prepare files +RUN dos2unix /enigma-bbs/docker/bin/docker-entrypoint.sh \ && apt-get remove dos2unix -y \ + && chmod +x /enigma-bbs/docker/bin/docker-entrypoint.sh \ + && cp -f /enigma-bbs/docker/bin/sexyz /usr/local/bin \ + && mkdir -p /enigma-bbs-pre/art \ + && mkdir /enigma-bbs-pre/mods \ + && mkdir /enigma-bbs-pre/config \ + && cp -rp /enigma-bbs/art/* ../enigma-bbs-pre/art/ \ + && cp -rp /enigma-bbs/mods/* ../enigma-bbs-pre/mods/ \ + && cp -rp /enigma-bbs/config/* ../enigma-bbs-pre/config/ \ + && apt-get remove build-essential python3 libssl-dev git curl dos2unix -y \ && apt-get autoremove -y \ - && npm set progress=false \ - && npm install -g pm2 \ - && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ + && apt-get clean -WORKDIR /${BBS_ROOT_DIR} - -COPY --from=builder /tmp/enigma-bbs-source/ ${BBS_ROOT_DIR}/ -COPY --from=builder /usr/local/bin/sexyz /usr/local/bin/ - -RUN dos2unix ${BBS_ROOT_DIR}/docker/bin/docker-entrypoint.sh \ - && cp -f ${BBS_ROOT_DIR}/docker/bin/sexyz /usr/local/bin \ - && mkdir -p ${BBS_STAGING_PATH}/art \ - && mkdir -p ${BBS_STAGING_PATH}/mods \ - && mkdir -p ${BBS_STAGING_PATH}/config \ - && cp -rp ${BBS_ROOT_DIR}/art/* ${BBS_STAGING_PATH}/art/ \ - && cp -rp ${BBS_ROOT_DIR}/mods/* ${BBS_STAGING_PATH}/mods/ \ - && cp -rp ${BBS_ROOT_DIR}/config/* ${BBS_STAGING_PATH}/config/ \ - && rm -rf ${BBS_ROOT_DIR}/art/* \ - && rm -rf ${BBS_ROOT_DIR}/mods/* \ - && rm -rf ${BBS_ROOT_DIR}/config \ - && ln -s ${BBS_STAGING_PATH}/config ${BBS_ROOT_DIR}/config \ - && pm2 start ${BBS_ROOT_DIR}/main.js \ - && rm -rf ${BBS_STAGING_PATH}/config - -VOLUME ${BBS_ROOT_DIR}/art \ - ${BBS_ROOT_DIR}/config \ - ${BBS_ROOT_DIR}/db \ - ${BBS_ROOT_DIR}/filebase \ - ${BBS_ROOT_DIR}/logs \ - ${BBS_ROOT_DIR}/mods \ - /mail +# enigma storage mounts +VOLUME /enigma-bbs/art +VOLUME /enigma-bbs/config +VOLUME /enigma-bbs/db +VOLUME /enigma-bbs/filebase +VOLUME /enigma-bbs/logs +VOLUME /enigma-bbs/mods +VOLUME /mail +# Enigma default port EXPOSE 8888 44510 44511 -WORKDIR ${BBS_ROOT_DIR} +WORKDIR /enigma-bbs ENTRYPOINT ["/enigma-bbs/docker/bin/docker-entrypoint.sh"] diff --git a/build-and-push.sh b/build-and-push.sh new file mode 100755 index 0000000..5b7baa6 --- /dev/null +++ b/build-and-push.sh @@ -0,0 +1,14 @@ +#!/bin/bash +set -e + +echo "Building Enigma BBS Docker image from git repo..." +cd /home/capitano/kubernetes/infrastructure/enigma + +# Build the image +docker build -t git.giaco.net/enigma/enigmabbs:latest -f Dockerfile . + +# Push to registry +echo "Pushing to git.giaco.net..." +docker push git.giaco.net/enigma/enigmabbs:latest + +echo "Done! Image pushed to git.giaco.net/enigma/enigmabbs:latest" diff --git a/configmap.yaml b/configmap.yaml index fbdd70c..344174a 100644 --- a/configmap.yaml +++ b/configmap.yaml @@ -39,3 +39,4 @@ data: requireSecureConnections: false } } + achievements.hjson: | diff --git a/deployment.yaml b/deployment.yaml index 6a9f533..120ac0e 100644 --- a/deployment.yaml +++ b/deployment.yaml @@ -13,9 +13,110 @@ spec: labels: app: enigmabbs spec: + initContainers: + - name: init-check + image: busybox:latest + command: ["/bin/sh", "-c"] + args: + - | + echo "Checking for existing processes on port 8888..." + netstat -tlnp 2>/dev/null | grep 8888 || echo "Port 8888 is free" + - name: init-config + image: enigmabbs/enigma-bbs:latest + command: ["/bin/sh", "-c"] + args: + - | + set -e + echo "Creating directories..." + mkdir -p /enigma-bbs/config/security + mkdir -p /enigma-bbs/config/menus + mkdir -p /enigma-bbs/db + mkdir -p /enigma-bbs/filebase + echo "Copying SSH key from secret..." + cp /enigma-ssh-key/ssh_private_key.pem /enigma-bbs/config/security/ssh_private_key.pem + chmod 600 /enigma-bbs/config/security/ssh_private_key.pem + echo "Creating config.hjson..." + cat > /enigma-bbs/config/config.hjson << 'EOF' + { + system: { + bbsName: "Enigma BBS" + bbsTimeZone: "America/New_York" + bbsNodeNumber: 1 + domain: "enigma.giaco.net" + } + + loginServers: { + telnet: { + enabled: true + port: 8888 + } + ssh: { + enabled: true + port: 44511 + privateKeyPem: "/enigma-bbs/config/security/ssh_private_key.pem" + privateKeyPass: "" + } + } + + contentServers: { + web: { + domain: "enigma.giaco.net" + http: { + enabled: true + port: 8888 + } + } + } + + security: { + secureLoginOnly: false + requireSecureConnections: false + } + } + EOF + echo "Creating achievements.hjson..." + cat > /enigma-bbs/config/achievements.hjson << 'EOF' + { + systemAchievements: { + } + } + EOF + echo "Creating menu.hjson..." + cat > /enigma-bbs/config/menu.hjson << 'EOF' + { + menus: { + someMenu: { + } + } + } + EOF + echo "Init completed" + volumeMounts: + - name: enigmabbs-config + mountPath: /enigma-bbs/config + - name: enigmabbs-data + mountPath: /enigma-bbs/db + - name: enigmabbs-art + mountPath: /enigma-bbs/art + - name: enigmabbs-mods + mountPath: /enigma-bbs/mods + - name: enigmabbs-ssh-key-volume + mountPath: /enigma-ssh-key + readOnly: true containers: - name: enigmabbs - image: git.giaco.net/enigma/enigmabbs:latest + image: enigmabbs/enigma-bbs:latest + imagePullPolicy: Always + command: ["/bin/sh", "-c"] + args: + - | + set -e + echo "Killing any existing pm2 processes..." + pm2 delete all || true + pm2 kill || true + sleep 2 + echo "Starting Enigma BBS..." + exec pm2-runtime main.js ports: - containerPort: 8888 name: web @@ -31,7 +132,7 @@ spec: mountPath: /enigma-bbs/db - name: enigmabbs-art mountPath: /enigma-bbs/art - - name: enigmabbs-config-volume + - name: enigmabbs-config mountPath: /enigma-bbs/config - name: enigmabbs-mods mountPath: /enigma-bbs/mods @@ -47,15 +148,15 @@ spec: readinessProbe: tcpSocket: port: 8888 - initialDelaySeconds: 60 + initialDelaySeconds: 90 periodSeconds: 10 timeoutSeconds: 5 - failureThreshold: 3 + failureThreshold: 5 livenessProbe: tcpSocket: port: 8888 - initialDelaySeconds: 120 - periodSeconds: 20 + initialDelaySeconds: 180 + periodSeconds: 30 timeoutSeconds: 10 failureThreshold: 3 volumes: @@ -65,12 +166,13 @@ spec: - name: enigmabbs-art persistentVolumeClaim: claimName: enigmabbs-art - - name: enigmabbs-config-volume - configMap: - name: enigmabbs-config + - name: enigmabbs-config + emptyDir: {} + - name: enigmabbs-ssh-key-volume + secret: + secretName: enigmabbs-ssh-key - name: enigmabbs-mods persistentVolumeClaim: claimName: enigmabbs-mods - name: enigmabbs-logs - persistentVolumeClaim: - claimName: enigmabbs-logs + emptyDir: {} diff --git a/registry-secret.yaml b/registry-secret.yaml new file mode 100644 index 0000000..6d6e334 --- /dev/null +++ b/registry-secret.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +data: + .dockerconfigjson: eyJhdXRocyI6eyJnaXQuZ2lhY28ubmV0Ijp7InVzZXJuYW1lIjoiY2FwaXRhbm8iLCJwYXNzd29yZCI6ImE1ZTQ4NTJmOWU5ODI3OGM4MjhlNzA5YjdmOTcxYmE0NmQ0YWY5NjAiLCJlbWFpbCI6ImFkbWluQGdpYWNvLm5ldCIsImF1dGgiOiJZMkZ3YVhSaGJtODZZVFZsTkRnMU1tWTVaVGs0TWpjNFl6Z3lPR1UzTURsaU4yWTVOekZpWVRRMlpEUmhaamsyTUE9PSJ9fX0= +kind: Secret +metadata: + name: git-registry-secret + namespace: enigmabbs +type: kubernetes.io/dockerconfigjson diff --git a/ssh-secret.yaml b/ssh-secret.yaml new file mode 100644 index 0000000..a4eacd0 --- /dev/null +++ b/ssh-secret.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +data: + ssh_private_key.pem: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlHNHdJQkFBS0NBWUVBcWlBTmlqVnAzd2ZNblAxYld3WTRmb2Q1MFZza3VERDNlLzVuNVJUSExNNkZmd1pZCkNFeHlzUFNnSUNFaUpSajhLekVGcTJzZ3VoQUduRkIrb3VlTkFqVjlaSHlPZEtLeDZjb3N3Zk5DelZqdnJ0K1UKNFVzS0tyYVpVS3NWSmh2SUZodGhEUlJ1VHV5Y3NnOXpHYlV0VmFIYm1kNTFHNk93dUpvdG9KdTJ0Z3hyMEZXMgpWV3N1V2ZhcGlTRHhDWTRkeVg1V0JCbVhBNE9oc2wxYnBlN1JlUFBKS1hGbUNzYnkwV3NjMlI5ZjYxSU4xTllqClRxRnBDY0REbEtMN3B6VGMrVDY1UlA4bkNlRlJSaTI4MCtHRis3MG1ZbnFreGNwV1hHSEFIcHBvdHJRRDR1UHgKdUt3c3Y0SEV3VnZnZE9WeFVkUng1Z25HR0g1NlFjQ1hqbE1MaW5tSVlkdkhzUEJwU0R1NVVRTmJGY2FETklKdgpmTHpkcFZUN1g5cFRwd1QxTW9pZGZUQTJSZEJvNXI4alR4VDZ0czNva0ZUNWpCbUdZL2J2VUJzcFp4V1V5QVdkCndPa1lidGRvSkFoeXdYS2V1aXhiZU05RWpWc0twUGNKeUpsengrZUt5YTBuS0tuR1BNakJ5cXphWnBPVE9FR3EKUHYzeXlGN1E5V1pZU20yWEFnTUJBQUVDZ2dHQUJKbVJSQ2Rsa1c0NGpoWWJuajV3MEpzQkpEUCtyaXhFeE1tQQpMYVYrTFN2NFdCTG4xbkdhdUVZay9qbG5IdkdwLzlEM2drY0hQNENuYlJxUUVmK0l4SUtGdlczUXZENlo2T1JhCmlYUDJYbThGTEFsSGtUL2lLbjE5Yjd6d2VYTk8yYW9yMlpxdjBOcDg4aU9RelNVazhLZkx0RUZia1QrL3kzMy8KdGRRQUFMUWRSaWpMSVV3Z21MWWVwMktJb2VXQjBLemx6bjZTb3Jtd2FZNDBxQ3ZvNWdoUmJCbHcxT0hFTnYxYQpibFIyMTNvRWZiaThnNmZCbTAzbSsrSGNSQTBkMFJBYlRhekNCZnBqdXZUaTNrYjArZUR2WWFqMFRJUVZwbExXCmg5clE4b0IwN2FEbjFvWmIwTVAwdURHdnhZV0d2N2xxeFRSTDl5T2RTQVdEdzcxQnh4VWtFQ1QreWdNQngxZFQKazd3d0NCSXY4YUhLeGIzZDlEN0FmSVd5ZDVZUm9yZFlhNXlqMUJScExjaDZmYWxwMjFHa05QUzBpaGRqTDBhZQpEWWc3cG9PYVkvM1hkRDNXWkJNRTdRbE9RbHdiLzFhelhWRUs1VXMvQXFwUEhnNi9nekcyQ1RhZVlBSUxRblBrCkZkbUJWREtqM1B0SEx4M2ZvOFg1WUJHS1FEOWhBb0hCQU93L2xDRnpWVUcxQktsMU8zZ2hxbUx2N1VpN1R2bGsKWG05V2dpVjNhYkxRTjcvb1VUUmNVR1M2SG84UDRpVzNJYmRLVHpHYnU5WXRSRHhoSmlMRWk0Z0dUV2V5bjFYcgpoMFJZajJyNTlKeUEvOS94YUVyTVFxa3I0WG9ETUxKUnpKRDhTZjBBQmVUdnZ2dlpZYkVpZk1rTVpxSGRERUtGCnMwTEdZVU1hSS8zdHJqQ0FRNkIyNVBvcHdBeGkxNXpESmU2WnZLZ2NSaThpMDduZW0rQndOcHJRMU5oNWZZS1YKSVpvWFFVWlpwaEhxOGVJeGtXUHhma2NwMC9FMHU2N08xUUtCd1FDNFdUMjY4UDNpSGk3eUtGbWJEV2ErcWw1SgpxYXV3bXRJRUZxMGRXVE5wWkw4ZlFDN0IwOXRUVE95dENZclpHek92VWJpVEREV3VjTzcrbkxxaEp0YzRXVmxyClJhQ3ltTm1WN2t5MDgzbUJub0VMZ01vQjRqUFJTNnNNMGhUbXdObnRHOFBDZmJTYnlWM21DUGVnMmJaMGVWZGYKQmQ1dnVsdXp0ZHBQSVRZaUwwaFAxSm40WXN1OVNZb0k0S2EveXQ2VTNNYXZzNHAwY29sSFhZUmtJcWZOaitNcwpEUUViVkZERmZTQldjVjlzN3g5ZVJ2aTU5UEVXcE81R09vWFArTHNDZ2NFQTRDUEtCSnFKenRkUlh2ME11UU1uCnhzcGZVOXZ5SjRia1dibTNySmhJdmcveWRLNlRMSnhRNGQvN1VqdjlrVTdZUEMvU1J2eThENDNPNllJNlRrNHYKRzVUdkoyMCs0cU9kS0dqbFdOZGhEb01OUUlpbkxCL3pOdEdkRU1lcUVlU3RzdmpKc2JHdDVmRFlQOVdVYkJ5TwpTNmpxVHJPTUNDa1ZWRXNteUNVcTlLWGwxN281YnlxZVFBSVFaUy81NUk3NWxCQmoveE1rTzJCTmhGRUJqc1NuCjZlWXJxbDVKaC9TNWRwcU5vWk00amxOYnZnRE5NZ2RTaVczVDJVcndyZjhwQW9IQVlsbWFDV1lRek5YMWpkUGgKR2t1b0NRaXpqUEVzVytmOUs1azllbTdnY3RZQThSYzQyc2ZBTjB6TzUvSXpWV2loeG1MKzZkU1Z2eDhaSWxWVApiQzVnbS90dkxUL1VYL1FVQVYxRkp6VE9HazBKNDYwdUdKc3BzZnVBb2pKaVhFbCsrblRabDZXZytZd1F3RzBBClQ1eFhMd1NkakdDQkwzSnBBaE4vQ01CYk5SbXNwb3B5S29YcTFHMnJhdGtQblRzS1RMa01keWgrTVduNXUwMDEKR0ljMHB3S2czQnVELzZTWUF3U2lmL3UwUVZYQmtuYWlzL0x0dkhyNWRCWTgxWnVKQW9IQWVDYkhISHRKUzRkawp0NS9hMVY5ZkZuU1IrS2RONldwTG1mSG1aZW9zRnE5Z3U4eUdFTU1aWlp2dEZkOUtZa2ZMcDQ3SVNxdmNDYVJDClZNNEZFcjZOOFd2dWdKbFNnVDJMcHFxSktJUjF2WVk3MFZSZlBTQjdwMEYydlFnRnZta3FhcUZwR2NvaG15UkwKK1Q5bkd0UzhTZGdGNTJZenNYbjBWMHM2Z1piN0VsWitrc29vVldnMFgrcVNyMitjcWFkSndReFVyQVovcUlQRApJQ3QyK0FOMkxYSDl5Zko5Y1lhM0ZpSytET3IrK0d1U0hWdHpkQno3dGJQQm5kMWpEWmxPCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== +kind: Secret +metadata: + name: enigmabbs-ssh-key + namespace: enigmabbs