fix(api): align Phoenix stack with hub/NPM deploy (TLS edge, graphql-ws)

- tls-config: allow production HTTP when TERMINATE_TLS_AT_EDGE=1 (matches CT 7800)
- websocket: disable perMessageDeflate on graphql-ws server (RSV1 / proxy compatibility)
- server: remove unused @fastify/websocket (standalone ws + graphql-ws only)
- package: drop @fastify/websocket dependency; refresh lockfile
- .env.example: document HOST and TERMINATE_TLS_AT_EDGE for nginx-terminated TLS

Made-with: Cursor
This commit is contained in:
defiQUG
2026-04-13 21:45:02 -07:00
parent 9bec73b3f0
commit 73a7b9fc15
6 changed files with 7 additions and 44 deletions

View File

@@ -10,6 +10,10 @@ DB_PASSWORD=your_secure_password_here
# Application Configuration
NODE_ENV=development
PORT=4000
# Behind nginx/NPM: bind Apollo to loopback only (hub proxies to 127.0.0.1:4000).
# HOST=127.0.0.1
# When TLS terminates at the edge, production may run without local cert files.
# TERMINATE_TLS_AT_EDGE=1
# Keycloak Configuration (for Identity Service)
KEYCLOAK_URL=http://localhost:8080

View File

@@ -24,7 +24,6 @@
"dependencies": {
"@apollo/server": "^4.9.5",
"@as-integrations/fastify": "^1.1.0",
"@fastify/websocket": "^10.0.1",
"@kubernetes/client-node": "^0.20.0",
"bcryptjs": "^2.4.3",
"dotenv": "^16.3.1",

37
api/pnpm-lock.yaml generated
View File

@@ -14,9 +14,6 @@ importers:
'@as-integrations/fastify':
specifier: ^1.1.0
version: 1.3.2(@apollo/server@4.12.2(graphql@16.12.0))(fastify@4.29.1)
'@fastify/websocket':
specifier: ^10.0.1
version: 10.0.1
'@kubernetes/client-node':
specifier: ^0.20.0
version: 0.20.0
@@ -525,9 +522,6 @@ packages:
'@fastify/merge-json-schemas@0.1.1':
resolution: {integrity: sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==}
'@fastify/websocket@10.0.1':
resolution: {integrity: sha512-8/pQIxTPRD8U94aILTeJ+2O3el/r19+Ej5z1O1mXlqplsUH7KzCjAI0sgd5DM/NoPjAi5qLFNIjgM5+9/rGSNw==}
'@graphql-tools/merge@8.4.2':
resolution: {integrity: sha512-XbrHAaj8yDuINph+sAfuq3QCZ/tKblrTLOpirK0+CAgNlZUCHs0Fa+xtMUURgwCVThLle1AF7svJCxFizygLsw==}
peerDependencies:
@@ -1083,9 +1077,6 @@ packages:
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
engines: {node: '>= 0.4'}
duplexify@4.1.3:
resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==}
ecc-jsbn@0.1.2:
resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==}
@@ -1106,9 +1097,6 @@ packages:
resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
engines: {node: '>= 0.8'}
end-of-stream@1.4.5:
resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==}
es-define-property@1.0.1:
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
engines: {node: '>= 0.4'}
@@ -1978,9 +1966,6 @@ packages:
resolution: {integrity: sha512-pqMqwQCso0PBJt2PQmDO0cFj0lyqmiwOMiMSkVtRokl7e+ZTRYgDHKnuZNbqjiJXgsg4nuqtD/zxuo9KqTp0Yw==}
engines: {node: '>= 0.10.0'}
stream-shift@1.0.3:
resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==}
string_decoder@1.3.0:
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
@@ -2571,15 +2556,6 @@ snapshots:
dependencies:
fast-deep-equal: 3.1.3
'@fastify/websocket@10.0.1':
dependencies:
duplexify: 4.1.3
fastify-plugin: 4.5.1
ws: 8.18.3
transitivePeerDependencies:
- bufferutil
- utf-8-validate
'@graphql-tools/merge@8.4.2(graphql@16.12.0)':
dependencies:
'@graphql-tools/utils': 9.2.1(graphql@16.12.0)
@@ -3130,13 +3106,6 @@ snapshots:
es-errors: 1.3.0
gopd: 1.2.0
duplexify@4.1.3:
dependencies:
end-of-stream: 1.4.5
inherits: 2.0.4
readable-stream: 3.6.2
stream-shift: 1.0.3
ecc-jsbn@0.1.2:
dependencies:
jsbn: 0.1.1
@@ -3154,10 +3123,6 @@ snapshots:
encodeurl@2.0.0: {}
end-of-stream@1.4.5:
dependencies:
once: 1.4.0
es-define-property@1.0.1: {}
es-errors@1.3.0: {}
@@ -4160,8 +4125,6 @@ snapshots:
stream-buffers@3.0.3: {}
stream-shift@1.0.3: {}
string_decoder@1.3.0:
dependencies:
safe-buffer: 5.2.1

View File

@@ -39,14 +39,14 @@ export function getTLSConfig(): TLSConfig {
// Validate certificate files exist
if (!fs.existsSync(certPath)) {
if (process.env.NODE_ENV === 'production') {
if (process.env.NODE_ENV === 'production' && process.env.TERMINATE_TLS_AT_EDGE !== '1') {
throw new Error(`TLS certificate not found: ${certPath}`)
}
logger.warn(`TLS certificate not found: ${certPath} - using HTTP only`)
}
if (!fs.existsSync(keyPath)) {
if (process.env.NODE_ENV === 'production') {
if (process.env.NODE_ENV === 'production' && process.env.TERMINATE_TLS_AT_EDGE !== '1') {
throw new Error(`TLS key not found: ${keyPath}`)
}
logger.warn(`TLS key not found: ${keyPath} - using HTTP only`)

View File

@@ -2,7 +2,6 @@ import 'dotenv/config'
import Fastify from 'fastify'
import { ApolloServer } from '@apollo/server'
import { fastifyApolloDrainPlugin, fastifyApolloHandler } from '@as-integrations/fastify'
import fastifyWebsocket from '@fastify/websocket'
import { schema } from './schema'
import { createContext } from './context'
import { authMiddleware } from './middleware/auth'
@@ -94,9 +93,6 @@ async function startServer() {
// Initialize blockchain service
await initBlockchainService()
// Register WebSocket support
await fastify.register(fastifyWebsocket)
// Start Apollo Server
await apolloServer.start()

View File

@@ -13,6 +13,7 @@ export function createWebSocketServer(httpServer: any, path: string) {
const wss = new WebSocketServer({
server: httpServer,
path,
perMessageDeflate: false,
})
const serverCleanup = useServer(