diff --git a/ansible/roles/schulcloud-server-core/tasks/main.yml b/ansible/roles/schulcloud-server-core/tasks/main.yml index c9a23aa152e..3086fe7c009 100644 --- a/ansible/roles/schulcloud-server-core/tasks/main.yml +++ b/ansible/roles/schulcloud-server-core/tasks/main.yml @@ -204,7 +204,6 @@ - KEDA_ENABLED is defined and KEDA_ENABLED|bool - SCALED_PREVIEW_GENERATOR_ENABLED is defined and SCALED_PREVIEW_GENERATOR_ENABLED|bool - - name: admin api server deployment kubernetes.core.k8s: kubeconfig: ~/.kube/config @@ -256,3 +255,32 @@ namespace: "{{ NAMESPACE }}" template: tldraw-svc-monitor.yml.j2 when: WITH_TLDRAW is defined and WITH_TLDRAW|bool + + - name: BoardCollaboration configmap + kubernetes.core.k8s: + kubeconfig: ~/.kube/config + namespace: "{{ NAMESPACE }}" + template: board-collaboration-configmap.yml.j2 + state: "{{ 'present' if WITH_BOARD_COLLABORATION else 'absent'}}" + + - name: BoardCollaboration deployment + kubernetes.core.k8s: + kubeconfig: ~/.kube/config + namespace: "{{ NAMESPACE }}" + template: board-collaboration-deployment.yml.j2 + state: "{{ 'present' if WITH_BOARD_COLLABORATION else 'absent'}}" + + - name: BoardCollaboration service + kubernetes.core.k8s: + kubeconfig: ~/.kube/config + namespace: "{{ NAMESPACE }}" + template: board-collaboration-service.yml.j2 + state: "{{ 'present' if WITH_BOARD_COLLABORATION else 'absent'}}" + + - name: BoardCollaboration ingress + kubernetes.core.k8s: + kubeconfig: ~/.kube/config + namespace: "{{ NAMESPACE }}" + template: board-collaboration-ingress.yml.j2 + apply: yes + state: "{{ 'present' if WITH_BOARD_COLLABORATION else 'absent'}}" diff --git a/ansible/roles/schulcloud-server-core/templates/board-collaboration-configmap.yml.j2 b/ansible/roles/schulcloud-server-core/templates/board-collaboration-configmap.yml.j2 new file mode 100644 index 00000000000..c4ac9ad75c1 --- /dev/null +++ b/ansible/roles/schulcloud-server-core/templates/board-collaboration-configmap.yml.j2 @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: board-collaboration-configmap + namespace: {{ NAMESPACE }} + labels: + app: board-collaboration +data: + NEST_LOG_LEVEL: "{{ NEST_LOG_LEVEL }}" + EXIT_ON_ERROR: "true" diff --git a/ansible/roles/schulcloud-server-core/templates/board-collaboration-deployment.yml.j2 b/ansible/roles/schulcloud-server-core/templates/board-collaboration-deployment.yml.j2 new file mode 100644 index 00000000000..1c871d1b398 --- /dev/null +++ b/ansible/roles/schulcloud-server-core/templates/board-collaboration-deployment.yml.j2 @@ -0,0 +1,106 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: board-collaboration-deployment + namespace: {{ NAMESPACE }} + labels: + app: board-collaboration + app.kubernetes.io/part-of: schulcloud-verbund + app.kubernetes.io/version: {{ SCHULCLOUD_SERVER_IMAGE_TAG }} + app.kubernetes.io/name: board-collaboration + app.kubernetes.io/component: server + app.kubernetes.io/managed-by: ansible + git.branch: {{ SCHULCLOUD_SERVER_BRANCH_NAME }} + git.repo: {{ SCHULCLOUD_SERVER_REPO_NAME }} +spec: + replicas: {{ BOARD_COLLABORATION_SERVER_REPLICAS|default("1", true) }} + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + #maxUnavailable: 1 + revisionHistoryLimit: 4 + paused: false + selector: + matchLabels: + app: board-collaboration + template: + metadata: + labels: + app: board-collaboration + app.kubernetes.io/part-of: schulcloud-verbund + app.kubernetes.io/version: {{ SCHULCLOUD_SERVER_IMAGE_TAG }} + app.kubernetes.io/name: board-collaboration + app.kubernetes.io/component: board-collaboration + app.kubernetes.io/managed-by: ansible + git.branch: {{ SCHULCLOUD_SERVER_BRANCH_NAME }} + git.repo: {{ SCHULCLOUD_SERVER_REPO_NAME }} + spec: + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + runAsNonRoot: true + containers: + - name: board-collaboration + image: {{ SCHULCLOUD_SERVER_IMAGE }}:{{ SCHULCLOUD_SERVER_IMAGE_TAG }} + imagePullPolicy: IfNotPresent + ports: + - containerPort: 4450 + name: websocket + protocol: TCP + # - containerPort: 9090 + # name: api-metrics + # protocol: TCP + envFrom: + - configMapRef: + name: api-configmap + - configMapRef: + name: board-collaboration-configmap + - secretRef: + name: api-secret + command: ['npm', 'run', 'nest:start:board-collaboration:prod'] + resources: + limits: + cpu: {{ BOARD_COLLABORATION_CPU_LIMITS|default("2000m", true) }} + memory: {{ BOARD_COLLABORATION_MEMORY_LIMITS|default("2Gi", true) }} + requests: + cpu: {{ BOARD_COLLABORATION_CPU_REQUESTS|default("100m", true) }} + memory: {{ BOARD_COLLABORATION_MEMORY_REQUESTS|default("150Mi", true) }} +{% if AFFINITY_ENABLE is defined and AFFINITY_ENABLE|bool %} + affinity: + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 9 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: app.kubernetes.io/part-of + operator: In + values: + - schulcloud-verbund + topologyKey: "kubernetes.io/hostname" + namespaceSelector: {} + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: +{% if ANIT_AFFINITY_NODEPOOL_ENABLE is defined and ANIT_AFFINITY_NODEPOOL_ENABLE|bool %} + - weight: 10 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - board-collaboration + topologyKey: {{ ANIT_AFFINITY_NODEPOOL_TOPOLOGY_KEY }} +{% endif %} + - weight: 20 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - board-collaboration + topologyKey: "topology.kubernetes.io/zone" +{% endif %} diff --git a/ansible/roles/schulcloud-server-core/templates/board-collaboration-ingress.yml.j2 b/ansible/roles/schulcloud-server-core/templates/board-collaboration-ingress.yml.j2 new file mode 100644 index 00000000000..20930ed202e --- /dev/null +++ b/ansible/roles/schulcloud-server-core/templates/board-collaboration-ingress.yml.j2 @@ -0,0 +1,43 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: board-collaboration-ingress + namespace: {{ NAMESPACE }} + annotations: + nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" + nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" + nginx.ingress.kubernetes.io/proxy-body-size: "{{ INGRESS_MAX_BODY_SIZE|default("2560") }}m" + nginx.org/client-max-body-size: "{{ INGRESS_MAX_BODY_SIZE|default("2560") }}m" + # The following properties added with BC-3606. + # The header size of the request is too big. For e.g. state and the permanent growing jwt. + # Nginx throws away the Location header, resulting in the 502 Bad Gateway. + nginx.ingress.kubernetes.io/client-header-buffer-size: 100k + nginx.ingress.kubernetes.io/http2-max-header-size: 96k + nginx.ingress.kubernetes.io/large-client-header-buffers: 4 100k + nginx.ingress.kubernetes.io/proxy-buffer-size: 96k + nginx.org/websocket-services: "board-collaboration-svc" +{% if CLUSTER_ISSUER is defined %} + cert-manager.io/cluster-issuer: {{ CLUSTER_ISSUER }} +{% endif %} + +spec: + ingressClassName: {{ INGRESS_CLASS }} +{% if CLUSTER_ISSUER is defined or (TLS_ENABLED is defined and TLS_ENABLED|bool) %} + tls: + - hosts: + - {{ DOMAIN }} +{% if CLUSTER_ISSUER is defined %} + secretName: {{ DOMAIN }}-tls +{% endif %} +{% endif %} + rules: + - host: {{ DOMAIN }} + http: + paths: + - path: /board-collaboration + backend: + service: + name: board-collaboration-svc + port: + number: 4450 + pathType: Prefix diff --git a/ansible/roles/schulcloud-server-core/templates/board-collaboration-service.yml.j2 b/ansible/roles/schulcloud-server-core/templates/board-collaboration-service.yml.j2 new file mode 100644 index 00000000000..d01d0f2a652 --- /dev/null +++ b/ansible/roles/schulcloud-server-core/templates/board-collaboration-service.yml.j2 @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Service +metadata: + name: board-collaboration-svc + namespace: {{ NAMESPACE }} + labels: + app: board-collaboration +spec: + type: ClusterIP + ports: + # port for WebSocket connection + - port: 4450 + targetPort: 4450 + protocol: TCP + name: websocket + #- port: {{ PORT_METRICS_SERVER }} + # targetPort: 9090 # TODO + # protocol: TCP + # name: api-metrics + selector: + app: board-collaboration diff --git a/apps/server/src/apps/board-collaboration.app.ts b/apps/server/src/apps/board-collaboration.app.ts index 231ceb615ca..bd150f19c11 100644 --- a/apps/server/src/apps/board-collaboration.app.ts +++ b/apps/server/src/apps/board-collaboration.app.ts @@ -30,7 +30,7 @@ async function bootstrap() { await nestApp.init(); const port = 4450; - const basePath = '/api/v3'; + const basePath = '/board-collaboration'; nestApp.setGlobalPrefix(basePath); await nestApp.listen(port); diff --git a/apps/server/src/modules/board/board-ws-api.module.ts b/apps/server/src/modules/board/board-ws-api.module.ts index ba217c109a0..41340e1f135 100644 --- a/apps/server/src/modules/board/board-ws-api.module.ts +++ b/apps/server/src/modules/board/board-ws-api.module.ts @@ -3,12 +3,12 @@ import { CourseRepo } from '@shared/repo'; import { LoggerModule } from '@src/core/logger'; import { AuthorizationModule } from '../authorization'; import { BoardModule } from './board.module'; -import { SocketGateway } from './gateway/socket.gateway'; +import { BoardCollaborationGateway } from './gateway/board-collaboration.gateway'; import { BoardUc, ColumnUc } from './uc'; @Module({ imports: [BoardModule, forwardRef(() => AuthorizationModule), LoggerModule], - providers: [SocketGateway, ColumnUc, BoardUc, CourseRepo], + providers: [BoardCollaborationGateway, ColumnUc, BoardUc, CourseRepo], exports: [], }) export class BoardWsApiModule {} diff --git a/apps/server/src/modules/board/gateway/api-test/socket.gateway.spec.ts b/apps/server/src/modules/board/gateway/api-test/board-collaboration.gateway.spec.ts similarity index 97% rename from apps/server/src/modules/board/gateway/api-test/socket.gateway.spec.ts rename to apps/server/src/modules/board/gateway/api-test/board-collaboration.gateway.spec.ts index 2fb4db7ec18..e7d87888c81 100644 --- a/apps/server/src/modules/board/gateway/api-test/socket.gateway.spec.ts +++ b/apps/server/src/modules/board/gateway/api-test/board-collaboration.gateway.spec.ts @@ -14,10 +14,10 @@ import { import { getSocketApiClient, waitForEvent } from '@shared/testing/test-socket-api-client'; import { Socket } from 'socket.io-client'; import { BoardCollaborationTestingModule } from '../../board-collaboration.testing.module'; -import { SocketGateway } from '../socket.gateway'; +import { BoardCollaborationGateway } from '../board-collaboration.gateway'; -describe('SocketGateway', () => { - let gateway: SocketGateway; +describe(BoardCollaborationGateway.name, () => { + let ws: BoardCollaborationGateway; let app: INestApplication; let ioClient: Socket; let em: EntityManager; @@ -28,8 +28,8 @@ describe('SocketGateway', () => { }).compile(); app = testingModule.createNestApplication(); - em = app.get(EntityManager); - gateway = app.get(SocketGateway); + em = app.get(EntityManager); + ws = app.get(BoardCollaborationGateway); await app.listen(0); }); @@ -65,7 +65,7 @@ describe('SocketGateway', () => { }; it('should be defined', () => { - expect(gateway).toBeDefined(); + expect(ws).toBeDefined(); }); describe('create card', () => { diff --git a/apps/server/src/modules/board/gateway/socket.gateway.ts b/apps/server/src/modules/board/gateway/board-collaboration.gateway.ts similarity index 85% rename from apps/server/src/modules/board/gateway/socket.gateway.ts rename to apps/server/src/modules/board/gateway/board-collaboration.gateway.ts index 45b7fb26493..06c37e54c6d 100644 --- a/apps/server/src/modules/board/gateway/socket.gateway.ts +++ b/apps/server/src/modules/board/gateway/board-collaboration.gateway.ts @@ -12,6 +12,7 @@ import { MoveCardMessageParams, UpdateColumnTitleMessageParams, } from './dto'; +import BoardCollaborationConfiguration from './dto/board-collaboration-config'; import { CreateColumnMessageParams } from './dto/create-column.message.param'; import { DeleteBoardMessageParams } from './dto/delete-board.message.param'; import { FetchBoardMessageParams } from './dto/fetch-board.message.param'; @@ -20,19 +21,9 @@ import { UpdateBoardTitleMessageParams } from './dto/update-board-title.message. import { UpdateBoardVisibilityMessageParams } from './dto/update-board-visibility.message.param'; import { Socket } from './types'; -@WebSocketGateway({ - path: '/collaboration', - cors: { - origin: 'http://localhost:4000', - methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', - preflightContinue: false, - optionsSuccessStatus: 204, - credentials: true, - // transports: ['websocket'], - }, -}) +@WebSocketGateway(BoardCollaborationConfiguration.websocket) @UseGuards(WsJwtAuthGuard) -export class SocketGateway { +export class BoardCollaborationGateway { // TODO: use loggables instead of legacy logger constructor( private readonly logger: LegacyLogger, @@ -53,7 +44,7 @@ export class SocketGateway { } @SubscribeMessage('delete-board-request') - async handleDeleteBoard(client: Socket, data: DeleteBoardMessageParams) { + async deleteBoard(client: Socket, data: DeleteBoardMessageParams) { try { const { userId } = this.getCurrentUser(client); const room = await this.ensureUserInRoom(client, data.boardId); @@ -68,7 +59,7 @@ export class SocketGateway { @SubscribeMessage('update-board-title-request') @UseRequestContext() - async handleChangeBoardTitle(client: Socket, data: UpdateBoardTitleMessageParams) { + async updateBoardTitle(client: Socket, data: UpdateBoardTitleMessageParams) { try { const { userId } = this.getCurrentUser(client); await this.boardUc.updateBoardTitle(userId, data.boardId, data.newTitle); @@ -99,7 +90,7 @@ export class SocketGateway { @SubscribeMessage('create-card-request') @UseRequestContext() - async handleCreateCard(client: Socket, data: CreateCardMessageParams) { + async createCard(client: Socket, data: CreateCardMessageParams) { try { const { userId } = this.getCurrentUser(client); const card = await this.columnUc.createCard(userId, data.columnId); @@ -118,7 +109,7 @@ export class SocketGateway { @SubscribeMessage('create-column-request') @UseRequestContext() - async handleCreateColumn(client: Socket, data: CreateColumnMessageParams) { + async createColumn(client: Socket, data: CreateColumnMessageParams) { try { const { userId } = this.getCurrentUser(client); const column = await this.boardUc.createColumn(userId, data.boardId); @@ -142,7 +133,7 @@ export class SocketGateway { @SubscribeMessage('fetch-board-request') @UseRequestContext() - async handleFetchBoard(client: Socket, data: FetchBoardMessageParams) { + async fetchBoard(client: Socket, data: FetchBoardMessageParams) { try { const { userId } = this.getCurrentUser(client); const board = await this.boardUc.findBoard(userId, data.boardId); @@ -159,7 +150,7 @@ export class SocketGateway { @SubscribeMessage('move-card-request') @UseRequestContext() - async handleMoveCard(client: Socket, data: MoveCardMessageParams) { + async moveCard(client: Socket, data: MoveCardMessageParams) { try { const { userId } = this.getCurrentUser(client); await this.columnUc.moveCard(userId, data.cardId, data.toColumnId, data.newIndex); @@ -174,7 +165,7 @@ export class SocketGateway { @SubscribeMessage('move-column-request') @UseRequestContext() - async handleMoveColumn(client: Socket, data: MoveColumnMessageParams) { + async moveColumn(client: Socket, data: MoveColumnMessageParams) { try { const { userId } = this.getCurrentUser(client); await this.boardUc.moveColumn(userId, data.columnMove.columnId, data.targetBoardId, data.columnMove.addedIndex); @@ -189,7 +180,7 @@ export class SocketGateway { @SubscribeMessage('update-column-title-request') @UseRequestContext() - async handleChangeColumnTitle(client: Socket, data: UpdateColumnTitleMessageParams) { + async updateColumnTitle(client: Socket, data: UpdateColumnTitleMessageParams) { try { const { userId } = this.getCurrentUser(client); await this.columnUc.updateColumnTitle(userId, data.columnId, data.newTitle); @@ -204,7 +195,7 @@ export class SocketGateway { @SubscribeMessage('update-board-visibility-request') @UseRequestContext() - async handleBoardVisibility(client: Socket, data: UpdateBoardVisibilityMessageParams) { + async updateBoardVisibility(client: Socket, data: UpdateBoardVisibilityMessageParams) { try { const { userId } = this.getCurrentUser(client); await this.boardUc.updateVisibility(userId, data.boardId, data.isVisible); @@ -219,7 +210,7 @@ export class SocketGateway { @SubscribeMessage('delete-column-request') @UseRequestContext() - async handleDeleteColumn(client: Socket, data: DeleteColumnMessageParams) { + async deleteColumn(client: Socket, data: DeleteColumnMessageParams) { try { const { userId } = this.getCurrentUser(client); const room = await this.ensureUserInRoom(client, data.columnId); @@ -232,13 +223,6 @@ export class SocketGateway { } } - // @SubscribeMessage('reload-board-request') - // handleReloadBoard(client: Socket, data: DeleteColumnMessageParams) { - // this.logger.log(`Message received from client id: ${client.id}`); - // this.logger.debug(`Payload: ${JSON.stringify(data)}`); - // client.broadcast.emit('reload-board-success', data); - // } - private async ensureUserInRoom(client: Socket, id: string) { const rootId = await this.getRootIdForId(id); const room = `board_${rootId}`; diff --git a/apps/server/src/modules/board/gateway/dto/board-collaboration-config.ts b/apps/server/src/modules/board/gateway/dto/board-collaboration-config.ts new file mode 100644 index 00000000000..a02825310f1 --- /dev/null +++ b/apps/server/src/modules/board/gateway/dto/board-collaboration-config.ts @@ -0,0 +1,18 @@ +import { Configuration } from '@hpi-schul-cloud/commons/lib'; + +const host = Configuration.get('HOST') as string; +const isLocalhost = host.includes('localhost'); +const origin = isLocalhost ? 'http://localhost:4000' : host; + +export default class BoardCollaborationConfiguration { + static websocket = { + path: '/board-collaboration', + cors: { + origin, + methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', + preflightContinue: false, + optionsSuccessStatus: 204, + credentials: true, + }, + }; +} diff --git a/apps/server/src/modules/server/api/dto/config.response.ts b/apps/server/src/modules/server/api/dto/config.response.ts index 0799ad2af4e..29f7a1d7d4e 100644 --- a/apps/server/src/modules/server/api/dto/config.response.ts +++ b/apps/server/src/modules/server/api/dto/config.response.ts @@ -206,6 +206,9 @@ export class ConfigResponse { @ApiProperty() FEATURE_MEDIA_SHELF_ENABLED: boolean; + @ApiProperty() + BOARD_COLLABORATION_URI: string; + @ApiProperty() FEATURE_NEW_LAYOUT_ENABLED: boolean; @@ -276,6 +279,7 @@ export class ConfigResponse { this.FEATURE_VIDEOCONFERENCE_ENABLED = config.enabled; this.FEATURE_SCHULCONNEX_COURSE_SYNC_ENABLED = config.FEATURE_SCHULCONNEX_COURSE_SYNC_ENABLED; this.FEATURE_MEDIA_SHELF_ENABLED = config.FEATURE_MEDIA_SHELF_ENABLED; + this.BOARD_COLLABORATION_URI = config.BOARD_COLLABORATION_URI; this.FEATURE_NEW_LAYOUT_ENABLED = config.FEATURE_NEW_LAYOUT_ENABLED; } } diff --git a/apps/server/src/modules/server/api/test/server.api.spec.ts b/apps/server/src/modules/server/api/test/server.api.spec.ts index f99c6120bee..9bbbdc860a1 100644 --- a/apps/server/src/modules/server/api/test/server.api.spec.ts +++ b/apps/server/src/modules/server/api/test/server.api.spec.ts @@ -97,6 +97,7 @@ describe('Server Controller (API)', () => { 'FEATURE_SCHULCONNEX_COURSE_SYNC_ENABLED', 'FEATURE_MEDIA_SHELF_ENABLED', 'FEATURE_NEW_LAYOUT_ENABLED', + 'BOARD_COLLABORATION_URI', ]; expect(response.status).toEqual(HttpStatus.OK); diff --git a/apps/server/src/modules/server/server.config.ts b/apps/server/src/modules/server/server.config.ts index a90552c7297..eac92886144 100644 --- a/apps/server/src/modules/server/server.config.ts +++ b/apps/server/src/modules/server/server.config.ts @@ -110,6 +110,7 @@ export interface ServerConfig I18N__DEFAULT_LANGUAGE: LanguageType; I18N__FALLBACK_LANGUAGE: LanguageType; I18N__DEFAULT_TIMEZONE: Timezone; + BOARD_COLLABORATION_URI: string; FEATURE_NEW_LAYOUT_ENABLED: boolean; } @@ -237,6 +238,7 @@ const config: ServerConfig = { ALERT_CACHE_INTERVAL_MIN: Configuration.get('ALERT_CACHE_INTERVAL_MIN') as number, FEATURE_SCHULCONNEX_MEDIA_LICENSE_ENABLED: Configuration.get('FEATURE_SCHULCONNEX_MEDIA_LICENSE_ENABLED') as boolean, PROVISIONING_SCHULCONNEX_LIZENZ_INFO_URL: Configuration.get('PROVISIONING_SCHULCONNEX_LIZENZ_INFO_URL') as string, + BOARD_COLLABORATION_URI: Configuration.get('BOARD_COLLABORATION_URI') as string, FEATURE_NEW_LAYOUT_ENABLED: Configuration.get('FEATURE_NEW_LAYOUT_ENABLED') as boolean, }; diff --git a/apps/server/src/shared/testing/test-socket-api-client.ts b/apps/server/src/shared/testing/test-socket-api-client.ts index 809bed6a79a..f4fac7e2661 100644 --- a/apps/server/src/shared/testing/test-socket-api-client.ts +++ b/apps/server/src/shared/testing/test-socket-api-client.ts @@ -38,7 +38,7 @@ export async function getSocketApiClient(app: INestApplication, user: User) { const ioClient = io(url, { autoConnect: false, - path: '/collaboration', + path: '/board-collaboration', transports: ['websocket', 'polling'], extraHeaders: { Cookie: `jwt=${jwt}`, diff --git a/config/default.schema.json b/config/default.schema.json index 1739af15330..8ee96cc2570 100644 --- a/config/default.schema.json +++ b/config/default.schema.json @@ -1688,6 +1688,11 @@ "description": "URL for fetching lizenz info from moin.schule schulconnex", "examples": ["https://api-dienste.stage.niedersachsen-login.schule/v1/lizenz-info"] }, + "BOARD_COLLABORATION_URI": { + "type": "string", + "default": "ws://localhost:4450", + "description": "URL for connecting to the WebSocketServer" + }, "FEATURE_NEW_LAYOUT_ENABLED": { "type": "boolean", "default": false, diff --git a/config/development.json b/config/development.json index 83f08abd62d..7387a5dacaa 100644 --- a/config/development.json +++ b/config/development.json @@ -93,5 +93,6 @@ "ETHERPAD": { "PAD_URI": "http://localhost:9001/p" }, - "PROVISIONING_SCHULCONNEX_LIZENZ_INFO_URL": "http://localhost:8888/v1/lizenzinfo" + "PROVISIONING_SCHULCONNEX_LIZENZ_INFO_URL": "http://localhost:8888/v1/lizenzinfo", + "BOARD_COLLABORATION_URI": "ws://localhost:4450" } diff --git a/package.json b/package.json index 5e08554bf4d..df252d28e0b 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "nest:start:board-collaboration": "nest start board-collaboration", "nest:start:board-collaboration:dev": "nest start board-collaboration --watch --", "nest:start:board-collaboration:debug": "nest start board-collaboration --debug --watch", + "nest:start:board-collaboration:prod": "node dist/apps/server/apps/board-collaboration.app", "nest:start:management:dev": "nest start management --watch", "nest:start:management:debug": "nest start management --debug --watch", "nest:start:management:prod": "node dist/apps/server/apps/management.app", @@ -330,4 +331,4 @@ "tsconfig-paths": "^4.1.1", "typescript": "^4.9.4" } -} +} \ No newline at end of file