@gokiteam/goki-dev 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dockerfile.backend +38 -0
- package/Dockerfile.dev +38 -0
- package/Dockerfile.frontend +37 -0
- package/cli/NgrokManager.js +2 -3
- package/config.development +0 -1
- package/docker-compose.dev.yml +81 -0
- package/docker-compose.services.yml +186 -0
- package/docker-compose.yml +233 -0
- package/nginx.conf +41 -0
- package/package.json +27 -21
- package/src/api/httpTraffic/Controllers.js +7 -0
- package/src/api/httpTraffic/Logic.js +28 -0
- package/src/api/httpTraffic/Router.js +1 -0
- package/src/api/httpTraffic/Schemas.js +15 -1
- package/src/api/snapshots/Logic.js +2 -5
- package/src/configs/Application.js +3 -1
- package/src/mcp/tools/httpTraffic.js +20 -1
- package/src/singletons/HttpProxy.js +11 -1
- package/src/singletons/SqliteStore.js +12 -3
- package/ui/Dockerfile.dev +19 -0
- package/client/dist/client.d.ts +0 -332
- package/client/dist/client.js +0 -507
- package/client/dist/helpers.d.ts +0 -62
- package/client/dist/helpers.js +0 -122
- package/client/dist/index.d.ts +0 -59
- package/client/dist/index.js +0 -78
- package/client/dist/package.json +0 -1
- package/client/dist/types.d.ts +0 -280
- package/client/dist/types.js +0 -7
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
FROM node:20-alpine
|
|
2
|
+
|
|
3
|
+
WORKDIR /app
|
|
4
|
+
|
|
5
|
+
# Install Java JRE 21 for Firebase Emulator + build tools for better-sqlite3 + Docker CLI + PostgreSQL client
|
|
6
|
+
RUN apk add --no-cache openjdk21-jre bash python3 make g++ docker-cli postgresql-client
|
|
7
|
+
|
|
8
|
+
# Install Firebase CLI globally for Firestore emulator
|
|
9
|
+
RUN npm install -g firebase-tools
|
|
10
|
+
|
|
11
|
+
# Copy package files and npm config
|
|
12
|
+
COPY package*.json ./
|
|
13
|
+
|
|
14
|
+
# Build arg for npm authentication
|
|
15
|
+
ARG NPM_TOKEN
|
|
16
|
+
ENV NPM_TOKEN=${NPM_TOKEN}
|
|
17
|
+
COPY .npmrc ./
|
|
18
|
+
|
|
19
|
+
# Install dependencies (including optional native deps like better-sqlite3)
|
|
20
|
+
RUN npm install --omit=dev --include=optional
|
|
21
|
+
|
|
22
|
+
# Copy source code
|
|
23
|
+
COPY src/ ./src/
|
|
24
|
+
COPY config.development ./
|
|
25
|
+
COPY config.test ./
|
|
26
|
+
|
|
27
|
+
# Copy Firebase configuration
|
|
28
|
+
COPY firebase.json ./
|
|
29
|
+
COPY firestore.rules ./
|
|
30
|
+
|
|
31
|
+
# Create data and logs directories
|
|
32
|
+
RUN mkdir -p /app/data /app/logs /app/data/firestore
|
|
33
|
+
|
|
34
|
+
# Expose ports
|
|
35
|
+
EXPOSE 9000 8085 8087 8883 8080
|
|
36
|
+
|
|
37
|
+
# Start server directly (env vars set via docker-compose)
|
|
38
|
+
CMD ["node", "src/Server.js"]
|
package/Dockerfile.dev
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
FROM node:20-alpine
|
|
2
|
+
|
|
3
|
+
WORKDIR /app
|
|
4
|
+
|
|
5
|
+
# Install Java JRE 21 for Firebase Emulator + build tools for better-sqlite3 + PostgreSQL client
|
|
6
|
+
RUN apk add --no-cache openjdk21-jre bash python3 make g++ postgresql-client
|
|
7
|
+
|
|
8
|
+
# Install Firebase CLI globally for Firestore emulator
|
|
9
|
+
RUN npm install -g firebase-tools
|
|
10
|
+
|
|
11
|
+
# Copy package files and npm config
|
|
12
|
+
COPY package*.json ./
|
|
13
|
+
|
|
14
|
+
# Build arg for npm authentication
|
|
15
|
+
ARG NPM_TOKEN
|
|
16
|
+
ENV NPM_TOKEN=${NPM_TOKEN}
|
|
17
|
+
COPY .npmrc ./
|
|
18
|
+
|
|
19
|
+
# Install ALL dependencies (including dev for watch mode)
|
|
20
|
+
RUN npm install
|
|
21
|
+
|
|
22
|
+
# Install nodemon for reliable file watching in Docker (fs.watch doesn't work with bind mounts)
|
|
23
|
+
RUN npm install -g nodemon
|
|
24
|
+
|
|
25
|
+
# Copy config files
|
|
26
|
+
COPY config.development ./
|
|
27
|
+
COPY config.test ./
|
|
28
|
+
COPY firebase.json ./
|
|
29
|
+
COPY firestore.rules ./
|
|
30
|
+
|
|
31
|
+
# Create data and logs directories
|
|
32
|
+
RUN mkdir -p /app/data /app/logs /app/data/firestore
|
|
33
|
+
|
|
34
|
+
# Expose ports
|
|
35
|
+
EXPOSE 9000 8085 8087 8883 8080
|
|
36
|
+
|
|
37
|
+
# Start server with watch mode using nodemon (polling for Docker bind mount compatibility)
|
|
38
|
+
CMD ["nodemon", "--watch", "src", "--ext", "js,json", "--legacy-watch", "--polling-interval", "1000", "src/Server.js"]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Build stage
|
|
2
|
+
FROM node:20-alpine AS build
|
|
3
|
+
|
|
4
|
+
WORKDIR /app
|
|
5
|
+
|
|
6
|
+
# Copy UI package files
|
|
7
|
+
COPY ui/package*.json ./ui/
|
|
8
|
+
|
|
9
|
+
# Install UI dependencies
|
|
10
|
+
WORKDIR /app/ui
|
|
11
|
+
RUN npm ci
|
|
12
|
+
|
|
13
|
+
# Copy UI source files
|
|
14
|
+
COPY ui/ ./
|
|
15
|
+
|
|
16
|
+
# Build the React app
|
|
17
|
+
# API URL will be injected at runtime via environment variable
|
|
18
|
+
RUN npm run build
|
|
19
|
+
|
|
20
|
+
# Production stage
|
|
21
|
+
FROM nginx:1.25-alpine
|
|
22
|
+
|
|
23
|
+
# Copy nginx configuration
|
|
24
|
+
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
|
25
|
+
|
|
26
|
+
# Copy built files from build stage
|
|
27
|
+
COPY --from=build /app/ui/build /usr/share/nginx/html
|
|
28
|
+
|
|
29
|
+
# Add healthcheck
|
|
30
|
+
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
|
|
31
|
+
CMD wget --quiet --tries=1 --spider http://127.0.0.1/health || exit 1
|
|
32
|
+
|
|
33
|
+
# Expose port
|
|
34
|
+
EXPOSE 80
|
|
35
|
+
|
|
36
|
+
# Start nginx
|
|
37
|
+
CMD ["nginx", "-g", "daemon off;"]
|
package/cli/NgrokManager.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { execa } from 'execa'
|
|
2
2
|
import fs from 'fs'
|
|
3
|
+
import os from 'os'
|
|
3
4
|
import path from 'path'
|
|
4
|
-
import { fileURLToPath } from 'url'
|
|
5
5
|
import { Logger } from './Logger.js'
|
|
6
6
|
|
|
7
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
8
7
|
const DEV_TOOLS_API = 'http://localhost:9000'
|
|
9
8
|
const NGROK_API = 'http://localhost:4040'
|
|
10
|
-
const DATA_DIR = path.
|
|
9
|
+
const DATA_DIR = path.join(os.homedir(), '.goki-dev', 'data')
|
|
11
10
|
const PID_FILE = path.join(DATA_DIR, 'ngrok.pid')
|
|
12
11
|
const STATE_FILE = path.join(DATA_DIR, 'ngrok.json')
|
|
13
12
|
|
package/config.development
CHANGED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# App services (dev-tools backend + UI)
|
|
2
|
+
# Requires shared services running first: docker compose -f docker-compose.services.yml up -d
|
|
3
|
+
# Then start: docker compose -f docker-compose.dev.yml up -d
|
|
4
|
+
|
|
5
|
+
services:
|
|
6
|
+
backend:
|
|
7
|
+
image: goki-dev-tools-backend
|
|
8
|
+
build:
|
|
9
|
+
context: .
|
|
10
|
+
dockerfile: Dockerfile.dev
|
|
11
|
+
args:
|
|
12
|
+
NPM_TOKEN: ${NPM_TOKEN}
|
|
13
|
+
container_name: goki-dev-tools-backend
|
|
14
|
+
ports:
|
|
15
|
+
- "9000:9000" # Backend API
|
|
16
|
+
- "8087:8087" # Cloud Logging Emulator
|
|
17
|
+
- "8883:8883" # MQTT Broker
|
|
18
|
+
environment:
|
|
19
|
+
- NODE_ENV=development
|
|
20
|
+
- WEB_UI_PORT=9000
|
|
21
|
+
# Shared services (use container names for cross-compose networking)
|
|
22
|
+
- POSTGRES_HOST=goki-postgres
|
|
23
|
+
- POSTGRES_PORT=5432
|
|
24
|
+
- POSTGRES_USER=postgres
|
|
25
|
+
- POSTGRES_PASSWORD=postgres
|
|
26
|
+
- POSTGRES_DATABASE=device_native
|
|
27
|
+
- REDIS_HOST=goki-redis
|
|
28
|
+
- REDIS_PORT=6379
|
|
29
|
+
- REDIS_LOGS_HOST=goki-redis-logs
|
|
30
|
+
- REDIS_LOGS_PORT=6380
|
|
31
|
+
- PUBSUB_EMULATOR_HOST=goki-pubsub-emulator:8085
|
|
32
|
+
- FIRESTORE_EMULATOR_HOST=goki-firestore-emulator:8080
|
|
33
|
+
- FIRESTORE_PROJECT_ID=tipi-development
|
|
34
|
+
- FIRESTORE_PROJECT_IDS=tipi-development,goki-dev-local
|
|
35
|
+
# App-specific config
|
|
36
|
+
- LOGGING_PORT=8087
|
|
37
|
+
- MQTT_PORT=8883
|
|
38
|
+
- DATA_DIR=/app/data
|
|
39
|
+
- AUTO_FLUSH_INTERVAL_MS=5000
|
|
40
|
+
- LOG_LEVEL=info
|
|
41
|
+
- UI_DEV_SERVER=http://goki-dev-tools-frontend:9001
|
|
42
|
+
- CHOKIDAR_USEPOLLING=true
|
|
43
|
+
- HOST_PROJECT_DIR=${HOST_PROJECT_DIR:-${PWD}}
|
|
44
|
+
volumes:
|
|
45
|
+
- ./src:/app/src:ro
|
|
46
|
+
- ./docs:/app/docs:ro
|
|
47
|
+
- ~/.goki-dev/data:/app/data
|
|
48
|
+
- ./logs:/app/logs
|
|
49
|
+
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
50
|
+
depends_on:
|
|
51
|
+
- frontend
|
|
52
|
+
networks:
|
|
53
|
+
- goki-network
|
|
54
|
+
restart: unless-stopped
|
|
55
|
+
|
|
56
|
+
frontend:
|
|
57
|
+
image: goki-dev-tools-frontend
|
|
58
|
+
build:
|
|
59
|
+
context: ./ui
|
|
60
|
+
dockerfile: Dockerfile.dev
|
|
61
|
+
container_name: goki-dev-tools-frontend
|
|
62
|
+
ports:
|
|
63
|
+
- "9001:9001" # React dev server
|
|
64
|
+
environment:
|
|
65
|
+
- PORT=9001
|
|
66
|
+
- CHOKIDAR_USEPOLLING=true
|
|
67
|
+
- WATCHPACK_POLLING=true
|
|
68
|
+
- WDS_SOCKET_PORT=9001
|
|
69
|
+
volumes:
|
|
70
|
+
- ./ui/src:/app/src
|
|
71
|
+
- ./ui/public:/app/public
|
|
72
|
+
- ./ui/tailwind.config.js:/app/tailwind.config.js:ro
|
|
73
|
+
- ./ui/postcss.config.js:/app/postcss.config.js:ro
|
|
74
|
+
networks:
|
|
75
|
+
- goki-network
|
|
76
|
+
restart: unless-stopped
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
networks:
|
|
80
|
+
goki-network:
|
|
81
|
+
external: true
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Shared infrastructure services (PostgreSQL, Redis, Emulators)
|
|
2
|
+
# Start these first: docker compose -f docker-compose.services.yml up -d
|
|
3
|
+
# Then start app services: docker compose -f docker-compose.dev.yml up -d
|
|
4
|
+
|
|
5
|
+
services:
|
|
6
|
+
postgres:
|
|
7
|
+
image: postgres:15-alpine
|
|
8
|
+
container_name: goki-postgres
|
|
9
|
+
environment:
|
|
10
|
+
POSTGRES_USER: postgres
|
|
11
|
+
POSTGRES_PASSWORD: postgres
|
|
12
|
+
ports:
|
|
13
|
+
- "5432:5432"
|
|
14
|
+
volumes:
|
|
15
|
+
- postgres-data:/var/lib/postgresql/data
|
|
16
|
+
networks:
|
|
17
|
+
- goki-network
|
|
18
|
+
restart: unless-stopped
|
|
19
|
+
labels:
|
|
20
|
+
- "goki.service=postgres"
|
|
21
|
+
healthcheck:
|
|
22
|
+
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
|
23
|
+
interval: 5s
|
|
24
|
+
timeout: 5s
|
|
25
|
+
retries: 5
|
|
26
|
+
profiles:
|
|
27
|
+
- postgres
|
|
28
|
+
|
|
29
|
+
redis:
|
|
30
|
+
image: redis:7-alpine
|
|
31
|
+
container_name: goki-redis
|
|
32
|
+
ports:
|
|
33
|
+
- "6379:6379"
|
|
34
|
+
volumes:
|
|
35
|
+
- redis-data:/data
|
|
36
|
+
networks:
|
|
37
|
+
- goki-network
|
|
38
|
+
restart: unless-stopped
|
|
39
|
+
labels:
|
|
40
|
+
- "goki.service=redis"
|
|
41
|
+
healthcheck:
|
|
42
|
+
test: ["CMD", "redis-cli", "ping"]
|
|
43
|
+
interval: 5s
|
|
44
|
+
timeout: 5s
|
|
45
|
+
retries: 5
|
|
46
|
+
|
|
47
|
+
redis-logs:
|
|
48
|
+
image: redis:7-alpine
|
|
49
|
+
container_name: goki-redis-logs
|
|
50
|
+
command: redis-server --port 6380 --maxmemory 256mb --maxmemory-policy allkeys-lru
|
|
51
|
+
ports:
|
|
52
|
+
- "6380:6380"
|
|
53
|
+
volumes:
|
|
54
|
+
- redis-logs-data:/data
|
|
55
|
+
networks:
|
|
56
|
+
- goki-network
|
|
57
|
+
restart: unless-stopped
|
|
58
|
+
labels:
|
|
59
|
+
- "goki.service=redis-logs"
|
|
60
|
+
healthcheck:
|
|
61
|
+
test: ["CMD", "redis-cli", "-p", "6380", "ping"]
|
|
62
|
+
interval: 5s
|
|
63
|
+
timeout: 5s
|
|
64
|
+
retries: 5
|
|
65
|
+
profiles:
|
|
66
|
+
- redis-logs
|
|
67
|
+
|
|
68
|
+
pubsub-emulator:
|
|
69
|
+
image: gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators
|
|
70
|
+
container_name: goki-pubsub-emulator
|
|
71
|
+
command: gcloud beta emulators pubsub start --host-port=0.0.0.0:8085 --project=tipi-development
|
|
72
|
+
ports:
|
|
73
|
+
- "8085:8085"
|
|
74
|
+
networks:
|
|
75
|
+
- goki-network
|
|
76
|
+
restart: unless-stopped
|
|
77
|
+
labels:
|
|
78
|
+
- "goki.service=pubsub-emulator"
|
|
79
|
+
healthcheck:
|
|
80
|
+
test: ["CMD-SHELL", "curl -sf http://localhost:8085/v1/projects/tipi-development/topics || exit 1"]
|
|
81
|
+
interval: 5s
|
|
82
|
+
timeout: 5s
|
|
83
|
+
retries: 10
|
|
84
|
+
start_period: 10s
|
|
85
|
+
|
|
86
|
+
firestore-emulator:
|
|
87
|
+
image: gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators
|
|
88
|
+
container_name: goki-firestore-emulator
|
|
89
|
+
entrypoint: /bin/bash
|
|
90
|
+
command:
|
|
91
|
+
- -c
|
|
92
|
+
- |
|
|
93
|
+
IMPORT_FILE=$$(find /data/firestore-export -name '*.overall_export_metadata' 2>/dev/null | head -1)
|
|
94
|
+
if [ -n "$$IMPORT_FILE" ]; then
|
|
95
|
+
echo "Importing Firestore data from $$IMPORT_FILE"
|
|
96
|
+
exec gcloud emulators firestore start --host-port=0.0.0.0:8080 --project=goki-dev-local --export-on-exit=/data/firestore-export --import-data="$$IMPORT_FILE"
|
|
97
|
+
else
|
|
98
|
+
echo "No previous export found, starting fresh"
|
|
99
|
+
exec gcloud emulators firestore start --host-port=0.0.0.0:8080 --project=goki-dev-local --export-on-exit=/data/firestore-export
|
|
100
|
+
fi
|
|
101
|
+
ports:
|
|
102
|
+
- "8080:8080"
|
|
103
|
+
volumes:
|
|
104
|
+
- firestore-data:/data
|
|
105
|
+
networks:
|
|
106
|
+
- goki-network
|
|
107
|
+
restart: unless-stopped
|
|
108
|
+
labels:
|
|
109
|
+
- "goki.service=firestore-emulator"
|
|
110
|
+
healthcheck:
|
|
111
|
+
test: ["CMD-SHELL", "curl -sf http://localhost:8080/ || exit 1"]
|
|
112
|
+
interval: 5s
|
|
113
|
+
timeout: 5s
|
|
114
|
+
retries: 10
|
|
115
|
+
start_period: 10s
|
|
116
|
+
profiles:
|
|
117
|
+
- firestore
|
|
118
|
+
|
|
119
|
+
elasticsearch:
|
|
120
|
+
image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0
|
|
121
|
+
container_name: goki-elasticsearch
|
|
122
|
+
environment:
|
|
123
|
+
- discovery.type=single-node
|
|
124
|
+
- xpack.security.enabled=false
|
|
125
|
+
- ES_JAVA_OPTS=-Xms1g -Xmx1g
|
|
126
|
+
ports:
|
|
127
|
+
- "9200:9200"
|
|
128
|
+
volumes:
|
|
129
|
+
- elasticsearch-data:/usr/share/elasticsearch/data
|
|
130
|
+
networks:
|
|
131
|
+
- goki-network
|
|
132
|
+
restart: unless-stopped
|
|
133
|
+
labels:
|
|
134
|
+
- "goki.service=elasticsearch"
|
|
135
|
+
deploy:
|
|
136
|
+
resources:
|
|
137
|
+
limits:
|
|
138
|
+
memory: 2g
|
|
139
|
+
healthcheck:
|
|
140
|
+
test: ["CMD-SHELL", "curl -sf http://localhost:9200/_cluster/health || exit 1"]
|
|
141
|
+
interval: 10s
|
|
142
|
+
timeout: 5s
|
|
143
|
+
retries: 10
|
|
144
|
+
start_period: 30s
|
|
145
|
+
profiles:
|
|
146
|
+
- elasticsearch
|
|
147
|
+
|
|
148
|
+
kibana:
|
|
149
|
+
image: docker.elastic.co/kibana/kibana:8.12.0
|
|
150
|
+
container_name: goki-kibana
|
|
151
|
+
environment:
|
|
152
|
+
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
|
|
153
|
+
ports:
|
|
154
|
+
- "5601:5601"
|
|
155
|
+
depends_on:
|
|
156
|
+
elasticsearch:
|
|
157
|
+
condition: service_healthy
|
|
158
|
+
networks:
|
|
159
|
+
- goki-network
|
|
160
|
+
restart: unless-stopped
|
|
161
|
+
labels:
|
|
162
|
+
- "goki.service=kibana"
|
|
163
|
+
deploy:
|
|
164
|
+
resources:
|
|
165
|
+
limits:
|
|
166
|
+
memory: 1g
|
|
167
|
+
healthcheck:
|
|
168
|
+
test: ["CMD-SHELL", "curl -sf http://localhost:5601/api/status || exit 1"]
|
|
169
|
+
interval: 10s
|
|
170
|
+
timeout: 5s
|
|
171
|
+
retries: 10
|
|
172
|
+
start_period: 60s
|
|
173
|
+
profiles:
|
|
174
|
+
- kibana
|
|
175
|
+
|
|
176
|
+
networks:
|
|
177
|
+
goki-network:
|
|
178
|
+
name: goki-network
|
|
179
|
+
driver: bridge
|
|
180
|
+
|
|
181
|
+
volumes:
|
|
182
|
+
postgres-data:
|
|
183
|
+
redis-data:
|
|
184
|
+
redis-logs-data:
|
|
185
|
+
firestore-data:
|
|
186
|
+
elasticsearch-data:
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
services:
|
|
2
|
+
pubsub-emulator:
|
|
3
|
+
image: gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators
|
|
4
|
+
container_name: goki-pubsub-emulator
|
|
5
|
+
command: gcloud beta emulators pubsub start --host-port=0.0.0.0:8085 --project=tipi-development
|
|
6
|
+
ports:
|
|
7
|
+
- "8085:8085"
|
|
8
|
+
networks:
|
|
9
|
+
- goki-network
|
|
10
|
+
restart: unless-stopped
|
|
11
|
+
labels:
|
|
12
|
+
- "goki.service=pubsub-emulator"
|
|
13
|
+
healthcheck:
|
|
14
|
+
test: ["CMD", "curl", "-f", "http://localhost:8085"]
|
|
15
|
+
interval: 5s
|
|
16
|
+
timeout: 5s
|
|
17
|
+
retries: 10
|
|
18
|
+
start_period: 10s
|
|
19
|
+
|
|
20
|
+
firestore-emulator:
|
|
21
|
+
image: gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators
|
|
22
|
+
container_name: goki-firestore-emulator
|
|
23
|
+
entrypoint: /bin/bash
|
|
24
|
+
command:
|
|
25
|
+
- -c
|
|
26
|
+
- |
|
|
27
|
+
IMPORT_FILE=$$(find /data/firestore-export -name '*.overall_export_metadata' 2>/dev/null | head -1)
|
|
28
|
+
if [ -n "$$IMPORT_FILE" ]; then
|
|
29
|
+
echo "Importing Firestore data from $$IMPORT_FILE"
|
|
30
|
+
exec gcloud emulators firestore start --host-port=0.0.0.0:8081 --project=goki-dev-local --export-on-exit=/data/firestore-export --import-data="$$IMPORT_FILE"
|
|
31
|
+
else
|
|
32
|
+
echo "No previous export found, starting fresh"
|
|
33
|
+
exec gcloud emulators firestore start --host-port=0.0.0.0:8081 --project=goki-dev-local --export-on-exit=/data/firestore-export
|
|
34
|
+
fi
|
|
35
|
+
ports:
|
|
36
|
+
- "8081:8081"
|
|
37
|
+
volumes:
|
|
38
|
+
- firestore-data:/data
|
|
39
|
+
networks:
|
|
40
|
+
- goki-network
|
|
41
|
+
restart: unless-stopped
|
|
42
|
+
labels:
|
|
43
|
+
- "goki.service=firestore-emulator"
|
|
44
|
+
healthcheck:
|
|
45
|
+
test: ["CMD-SHELL", "curl -sf http://localhost:8081 || exit 1"]
|
|
46
|
+
interval: 10s
|
|
47
|
+
timeout: 10s
|
|
48
|
+
retries: 12
|
|
49
|
+
start_period: 60s
|
|
50
|
+
profiles:
|
|
51
|
+
- firestore
|
|
52
|
+
|
|
53
|
+
dev-tools-backend:
|
|
54
|
+
build:
|
|
55
|
+
context: .
|
|
56
|
+
dockerfile: Dockerfile.backend
|
|
57
|
+
args:
|
|
58
|
+
NPM_TOKEN: ${NPM_TOKEN}
|
|
59
|
+
container_name: goki-dev-tools-backend
|
|
60
|
+
ports:
|
|
61
|
+
- "9000:9000" # Backend API
|
|
62
|
+
- "8086:8086" # AWS IoT Core HTTPS API
|
|
63
|
+
- "8087:8087" # Cloud Logging Emulator
|
|
64
|
+
- "8883:8883" # MQTT Broker
|
|
65
|
+
labels:
|
|
66
|
+
- "goki.service=dev-tools-backend"
|
|
67
|
+
environment:
|
|
68
|
+
- NODE_ENV=production
|
|
69
|
+
- WEB_UI_PORT=9000
|
|
70
|
+
- PUBSUB_EMULATOR_HOST=pubsub-emulator:8085
|
|
71
|
+
- PUBSUB_PROJECT_ID=tipi-development
|
|
72
|
+
- SHADOW_POLL_INTERVAL_MS=200
|
|
73
|
+
- SHADOW_SUBSCRIPTION_CHECK_INTERVAL_MS=5000
|
|
74
|
+
- LOGGING_PORT=8087
|
|
75
|
+
- MQTT_PORT=8883
|
|
76
|
+
- AWS_IOT_PORT=8086
|
|
77
|
+
- FIRESTORE_EMULATOR_HOST=goki-firestore-emulator:8080
|
|
78
|
+
- FIRESTORE_PORT=8080
|
|
79
|
+
- FIRESTORE_PROJECT_ID=tipi-development
|
|
80
|
+
- DATA_DIR=/app/data
|
|
81
|
+
- AUTO_FLUSH_INTERVAL_MS=5000
|
|
82
|
+
- REDIS_HOST=redis
|
|
83
|
+
- REDIS_PORT=6379
|
|
84
|
+
- POSTGRES_HOST=postgres
|
|
85
|
+
- POSTGRES_PORT=5432
|
|
86
|
+
- POSTGRES_USER=postgres
|
|
87
|
+
- POSTGRES_PASSWORD=postgres
|
|
88
|
+
- LOG_LEVEL=info
|
|
89
|
+
# App Gateway config (use container names)
|
|
90
|
+
- APP_GATEWAY_PROPERTY_ID=550e8400-e29b-41d4-a716-446655440000
|
|
91
|
+
- APP_GATEWAY_DEVICE_NATIVE_URL=http://device-native-app:3000
|
|
92
|
+
- APP_GATEWAY_DEVICE_SIMULATOR_URL=http://device-simulator-app:3000
|
|
93
|
+
- APP_GATEWAY_SCAN_INTERVAL_SECONDS=30
|
|
94
|
+
- APP_GATEWAY_AUTO_START=true
|
|
95
|
+
volumes:
|
|
96
|
+
- ~/.goki-dev/data:/app/data
|
|
97
|
+
- ./logs:/app/logs
|
|
98
|
+
- /var/run/docker.sock:/var/run/docker.sock
|
|
99
|
+
depends_on:
|
|
100
|
+
pubsub-emulator:
|
|
101
|
+
condition: service_healthy
|
|
102
|
+
redis:
|
|
103
|
+
condition: service_started
|
|
104
|
+
# Note: firestore and postgres are optional (have profiles)
|
|
105
|
+
# App should gracefully handle missing connections
|
|
106
|
+
networks:
|
|
107
|
+
- goki-network
|
|
108
|
+
restart: unless-stopped
|
|
109
|
+
|
|
110
|
+
dev-tools-frontend:
|
|
111
|
+
build:
|
|
112
|
+
context: .
|
|
113
|
+
dockerfile: Dockerfile.frontend
|
|
114
|
+
container_name: goki-dev-tools-frontend
|
|
115
|
+
ports:
|
|
116
|
+
- "9001:80" # Frontend UI
|
|
117
|
+
labels:
|
|
118
|
+
- "goki.service=dev-tools-frontend"
|
|
119
|
+
depends_on:
|
|
120
|
+
- dev-tools-backend
|
|
121
|
+
networks:
|
|
122
|
+
- goki-network
|
|
123
|
+
restart: unless-stopped
|
|
124
|
+
healthcheck:
|
|
125
|
+
test: ["CMD-SHELL", "wget --quiet --tries=1 --spider http://127.0.0.1/health || exit 1"]
|
|
126
|
+
interval: 30s
|
|
127
|
+
timeout: 3s
|
|
128
|
+
start_period: 10s
|
|
129
|
+
retries: 3
|
|
130
|
+
|
|
131
|
+
redis:
|
|
132
|
+
image: redis:7-alpine
|
|
133
|
+
container_name: goki-redis
|
|
134
|
+
ports:
|
|
135
|
+
- "6379:6379"
|
|
136
|
+
volumes:
|
|
137
|
+
- redis-data:/data
|
|
138
|
+
networks:
|
|
139
|
+
- goki-network
|
|
140
|
+
restart: unless-stopped
|
|
141
|
+
labels:
|
|
142
|
+
- "goki.service=redis"
|
|
143
|
+
|
|
144
|
+
postgres:
|
|
145
|
+
image: postgres:15-alpine
|
|
146
|
+
container_name: goki-postgres
|
|
147
|
+
environment:
|
|
148
|
+
POSTGRES_USER: postgres
|
|
149
|
+
POSTGRES_PASSWORD: postgres
|
|
150
|
+
ports:
|
|
151
|
+
- "5432:5432"
|
|
152
|
+
volumes:
|
|
153
|
+
- postgres-data:/var/lib/postgresql/data
|
|
154
|
+
networks:
|
|
155
|
+
- goki-network
|
|
156
|
+
restart: unless-stopped
|
|
157
|
+
labels:
|
|
158
|
+
- "goki.service=postgres"
|
|
159
|
+
healthcheck:
|
|
160
|
+
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
|
161
|
+
interval: 5s
|
|
162
|
+
timeout: 5s
|
|
163
|
+
retries: 5
|
|
164
|
+
profiles:
|
|
165
|
+
- postgres
|
|
166
|
+
|
|
167
|
+
elasticsearch:
|
|
168
|
+
image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0
|
|
169
|
+
container_name: goki-elasticsearch
|
|
170
|
+
environment:
|
|
171
|
+
- discovery.type=single-node
|
|
172
|
+
- xpack.security.enabled=false
|
|
173
|
+
- ES_JAVA_OPTS=-Xms1g -Xmx1g
|
|
174
|
+
ports:
|
|
175
|
+
- "9200:9200"
|
|
176
|
+
volumes:
|
|
177
|
+
- elasticsearch-data:/usr/share/elasticsearch/data
|
|
178
|
+
networks:
|
|
179
|
+
- goki-network
|
|
180
|
+
restart: unless-stopped
|
|
181
|
+
labels:
|
|
182
|
+
- "goki.service=elasticsearch"
|
|
183
|
+
deploy:
|
|
184
|
+
resources:
|
|
185
|
+
limits:
|
|
186
|
+
memory: 2g
|
|
187
|
+
healthcheck:
|
|
188
|
+
test: ["CMD-SHELL", "curl -sf http://localhost:9200/_cluster/health || exit 1"]
|
|
189
|
+
interval: 10s
|
|
190
|
+
timeout: 5s
|
|
191
|
+
retries: 10
|
|
192
|
+
start_period: 30s
|
|
193
|
+
profiles:
|
|
194
|
+
- elasticsearch
|
|
195
|
+
|
|
196
|
+
kibana:
|
|
197
|
+
image: docker.elastic.co/kibana/kibana:8.12.0
|
|
198
|
+
container_name: goki-kibana
|
|
199
|
+
environment:
|
|
200
|
+
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
|
|
201
|
+
ports:
|
|
202
|
+
- "5601:5601"
|
|
203
|
+
depends_on:
|
|
204
|
+
elasticsearch:
|
|
205
|
+
condition: service_healthy
|
|
206
|
+
networks:
|
|
207
|
+
- goki-network
|
|
208
|
+
restart: unless-stopped
|
|
209
|
+
labels:
|
|
210
|
+
- "goki.service=kibana"
|
|
211
|
+
deploy:
|
|
212
|
+
resources:
|
|
213
|
+
limits:
|
|
214
|
+
memory: 1g
|
|
215
|
+
healthcheck:
|
|
216
|
+
test: ["CMD-SHELL", "curl -sf http://localhost:5601/api/status || exit 1"]
|
|
217
|
+
interval: 10s
|
|
218
|
+
timeout: 5s
|
|
219
|
+
retries: 10
|
|
220
|
+
start_period: 60s
|
|
221
|
+
profiles:
|
|
222
|
+
- kibana
|
|
223
|
+
|
|
224
|
+
networks:
|
|
225
|
+
goki-network:
|
|
226
|
+
name: goki-network
|
|
227
|
+
driver: bridge
|
|
228
|
+
|
|
229
|
+
volumes:
|
|
230
|
+
redis-data:
|
|
231
|
+
postgres-data:
|
|
232
|
+
firestore-data:
|
|
233
|
+
elasticsearch-data:
|
package/nginx.conf
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
server {
|
|
2
|
+
listen 80;
|
|
3
|
+
server_name localhost;
|
|
4
|
+
root /usr/share/nginx/html;
|
|
5
|
+
index index.html;
|
|
6
|
+
|
|
7
|
+
# Gzip compression
|
|
8
|
+
gzip on;
|
|
9
|
+
gzip_vary on;
|
|
10
|
+
gzip_min_length 1024;
|
|
11
|
+
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json application/javascript;
|
|
12
|
+
|
|
13
|
+
# Security headers
|
|
14
|
+
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
15
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
16
|
+
add_header X-XSS-Protection "1; mode=block" always;
|
|
17
|
+
|
|
18
|
+
# Serve static files
|
|
19
|
+
location / {
|
|
20
|
+
try_files $uri $uri/ /index.html;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
# Cache static assets
|
|
24
|
+
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
|
25
|
+
expires 1y;
|
|
26
|
+
add_header Cache-Control "public, immutable";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
# Don't cache index.html
|
|
30
|
+
location = /index.html {
|
|
31
|
+
add_header Cache-Control "no-store, no-cache, must-revalidate";
|
|
32
|
+
expires 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# Health check endpoint
|
|
36
|
+
location /health {
|
|
37
|
+
access_log off;
|
|
38
|
+
return 200 "healthy\n";
|
|
39
|
+
add_header Content-Type text/plain;
|
|
40
|
+
}
|
|
41
|
+
}
|