Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
FROM node:22-alpine

ENV NODE_ENV=production

WORKDIR /app

COPY package*.json ./

RUN npm install
RUN npm install && npm cache clean --force

COPY . .

RUN chown -R node:node /app

USER node

CMD ["sh", "-c", "node index.mjs ${DEVICE:-/dev/ttyACM0}"]
11 changes: 10 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
services:
map-uploader:
build: .
# Optionally expose the port if you want to monitor the container's health externally
# ports:
# - "8080:8080"
environment:
# Set to the appropriate device for your setup, either /dev/ttyACM0 if connected by USB to a USB companion or IP:port if connected over network to a wifi companion
- DEVICE=/dev/ttyACM0
Expand All @@ -9,4 +12,10 @@ services:
privileged: true
# Adjust according to your setup, but this is the default
devices:
- /dev/ttyACM0:/dev/ttyACM0
- /dev/ttyACM0:/dev/ttyACM0
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 1
start_period: 5s
29 changes: 29 additions & 0 deletions index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,24 @@ import {

import { KeyPair } from './supercop/index.mjs';
import crypto from 'crypto';
import http from 'http';

const device = process.argv[2] ?? '/dev/ttyACM0';
const apiURL = 'https://map.meshcore.dev/api/v1/uploader/node';
const seenAdverts = {};
let clientInfo = {};
let isHealthy = false;

// Health check server
http.createServer((req, res) => {
if (req.url === '/health') {
res.writeHead(isHealthy ? 200 : 503);
res.end(isHealthy ? 'OK' : 'Not Ready');
} else {
res.writeHead(404);
res.end();
}
}).listen(8080);

const signData = async (kp, data) => {
const json = JSON.stringify(data);
Expand Down Expand Up @@ -88,6 +101,7 @@ if(device.startsWith('/') || device.startsWith('COM')){

connection.on('connected', async () => {
console.log(`Connected.`);
isHealthy = true;

connection.setManualAddContacts();

Expand All @@ -97,6 +111,21 @@ connection.on('connected', async () => {
console.log('Map uploader waiting for adverts...');
});

connection.on('disconnected', () => {
console.log('Disconnected. Exiting...');
process.exit(1);
});

connection.on('close', () => {
console.log('Connection closed. Exiting...');
process.exit(1);
});

connection.on('error', (err) => {
console.error('Connection error:', err);
process.exit(1);
});

connection.on(Constants.PushCodes.LogRxData, async (event) => {
try {
await processPacket(connection, event.raw);
Expand Down