diff --git a/.env.template b/.env.template index a83bd171..a54df82e 100644 --- a/.env.template +++ b/.env.template @@ -10,3 +10,6 @@ START_ROOM_URL=/_/global/maps.workadventure.localhost/Floor0/floor0.json # If you are using Coturn, this is the value of the "static-auth-secret" parameter in your coturn config file. # Keep empty if you are sharing hard coded / clear text credentials. TURN_STATIC_AUTH_SECRET= + +# The email address used by Let's encrypt to send renewal warnings (compulsory) +ACME_EMAIL= diff --git a/README.md b/README.md index a8c186b6..c6facad3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![](https://github.com/thecodingmachine/workadventure/workflows/Continuous%20Integration/badge.svg) +![](https://github.com/thecodingmachine/workadventure/workflows/Continuous%20Integration/badge.svg) [![Discord](https://img.shields.io/discord/821338762134290432?label=Discord)](https://discord.gg/YGtngdh9gt) ![WorkAdventure landscape image](README-INTRO.jpg) @@ -25,13 +25,14 @@ docker-compose up The environment will start. -You should now be able to browse to http://workadventure.localhost/ and see the application. +You should now be able to browse to http://play.workadventure.localhost/ and see the application. +You can view the dashboard at http://workadventure.localhost:8080/ Note: on some OSes, you will need to add this line to your `/etc/hosts` file: **/etc/hosts** ``` -workadventure.localhost 127.0.0.1 +127.0.0.1 workadventure.localhost ``` ### MacOS developers, your environment with Vagrant diff --git a/back/src/Model/Admin.ts b/back/src/Model/Admin.ts index a121d105..0be74b85 100644 --- a/back/src/Model/Admin.ts +++ b/back/src/Model/Admin.ts @@ -1,9 +1,3 @@ -import { Group } from "./Group"; -import { PointInterface } from "./Websocket/PointInterface"; -import {Zone} from "_Model/Zone"; -import {Movable} from "_Model/Movable"; -import {PositionNotifier} from "_Model/PositionNotifier"; -import {ServerDuplexStream} from "grpc"; import { BatchMessage, PusherToBackMessage, @@ -11,7 +5,6 @@ import { ServerToClientMessage, SubMessage, UserJoinedRoomMessage, UserLeftRoomMessage } from "../Messages/generated/messages_pb"; -import {CharacterLayer} from "_Model/Websocket/CharacterLayer"; import {AdminSocket} from "../RoomManager"; diff --git a/back/src/Model/GameRoom.ts b/back/src/Model/GameRoom.ts index 6a592ed0..c628d29d 100644 --- a/back/src/Model/GameRoom.ts +++ b/back/src/Model/GameRoom.ts @@ -38,12 +38,10 @@ export class GameRoom { private readonly positionNotifier: PositionNotifier; public readonly roomId: string; - public readonly anonymous: boolean; - public tags: string[]; - public policyType: GameRoomPolicyTypes; public readonly roomSlug: string; public readonly worldSlug: string = ''; public readonly organizationSlug: string = ''; + private versionNumber:number = 1; private nextUserId: number = 1; constructor(roomId: string, @@ -56,11 +54,8 @@ export class GameRoom { onLeaves: LeavesCallback) { this.roomId = roomId; - this.anonymous = isRoomAnonymous(roomId); - this.tags = []; - this.policyType = GameRoomPolicyTypes.ANONYMOUS_POLICY; - if (this.anonymous) { + if (isRoomAnonymous(roomId)) { this.roomSlug = extractRoomSlugPublicRoomId(this.roomId); } else { const {organizationSlug, worldSlug, roomSlug} = extractDataFromPrivateRoomId(this.roomId); @@ -304,10 +299,6 @@ export class GameRoom { return this.itemsState; } - public canAccess(userTags: string[]): boolean { - return arrayIntersect(userTags, this.tags); - } - public addZoneListener(call: ZoneSocket, x: number, y: number): Set { return this.positionNotifier.addZoneListener(call, x, y); } @@ -328,4 +319,9 @@ export class GameRoom { public adminLeave(admin: Admin): void { this.admins.delete(admin); } + + public incrementVersion(): number { + this.versionNumber++ + return this.versionNumber; + } } diff --git a/back/src/RoomManager.ts b/back/src/RoomManager.ts index 256c904e..54215698 100644 --- a/back/src/RoomManager.ts +++ b/back/src/RoomManager.ts @@ -2,7 +2,7 @@ import {IRoomManagerServer} from "./Messages/generated/messages_grpc_pb"; import { AdminGlobalMessage, AdminMessage, - AdminPusherToBackMessage, + AdminPusherToBackMessage, AdminRoomMessage, BanMessage, EmptyMessage, @@ -10,12 +10,12 @@ import { JoinRoomMessage, PlayGlobalMessage, PusherToBackMessage, - QueryJitsiJwtMessage, + QueryJitsiJwtMessage, RefreshRoomPromptMessage, ServerToAdminClientMessage, ServerToClientMessage, SilentMessage, UserMovesMessage, - WebRtcSignalToServerMessage, + WebRtcSignalToServerMessage, WorldFullWarningToRoomMessage, ZoneMessage } from "./Messages/generated/messages_pb"; import {sendUnaryData, ServerDuplexStream, ServerUnaryCall, ServerWritableStream} from "grpc"; @@ -43,8 +43,13 @@ const roomManager: IRoomManagerServer = { if (room === null || user === null) { if (message.hasJoinroommessage()) { socketManager.handleJoinRoom(call, message.getJoinroommessage() as JoinRoomMessage).then(({room: gameRoom, user: myUser}) => { - room = gameRoom; - user = myUser; + if (call.writable) { + room = gameRoom; + user = myUser; + } else { + //Connexion may have been closed before the init was finished, so we have to manually disconnect the user. + socketManager.leaveRoom(gameRoom, myUser); + } }); } else { throw new Error('The first message sent MUST be of type JoinRoomMessage'); @@ -184,6 +189,14 @@ const roomManager: IRoomManagerServer = { socketManager.sendAdminRoomMessage(call.request.getRoomid(), call.request.getMessage()); callback(null, new EmptyMessage()); }, + sendWorldFullWarningToRoom(call: ServerUnaryCall, callback: sendUnaryData): void { + socketManager.dispatchWorlFullWarning(call.request.getRoomid()); + callback(null, new EmptyMessage()); + }, + sendRefreshRoomPrompt(call: ServerUnaryCall, callback: sendUnaryData): void { + socketManager.dispatchRoomRefresh(call.request.getRoomid()); + callback(null, new EmptyMessage()); + }, }; export {roomManager}; diff --git a/back/src/Services/AdminApi.ts b/back/src/Services/AdminApi.ts deleted file mode 100644 index ef969a76..00000000 --- a/back/src/Services/AdminApi.ts +++ /dev/null @@ -1,49 +0,0 @@ -import {ADMIN_API_TOKEN, ADMIN_API_URL} from "../Enum/EnvironmentVariable"; -import Axios from "axios"; - -export interface AdminApiData { - organizationSlug: string - worldSlug: string - roomSlug: string - mapUrlStart: string - tags: string[] - policy_type: number - userUuid: string - messages?: unknown[], - textures: CharacterTexture[] -} - -export interface CharacterTexture { - id: number, - level: number, - url: string, - rights: string -} - -class AdminApi { - - async fetchMapDetails(organizationSlug: string, worldSlug: string, roomSlug: string|undefined): Promise { - if (!ADMIN_API_URL) { - return Promise.reject('No admin backoffice set!'); - } - - const params: { organizationSlug: string, worldSlug: string, roomSlug?: string } = { - organizationSlug, - worldSlug - }; - - if (roomSlug) { - params.roomSlug = roomSlug; - } - - const res = await Axios.get(ADMIN_API_URL + '/api/map', - { - headers: {"Authorization": `${ADMIN_API_TOKEN}`}, - params - } - ) - return res.data; - } -} - -export const adminApi = new AdminApi(); diff --git a/back/src/Services/SocketManager.ts b/back/src/Services/SocketManager.ts index 6317a46d..16b4d005 100644 --- a/back/src/Services/SocketManager.ts +++ b/back/src/Services/SocketManager.ts @@ -24,8 +24,9 @@ import { UserJoinedZoneMessage, GroupUpdateZoneMessage, GroupLeftZoneMessage, + WorldFullWarningMessage, UserLeftZoneMessage, - BanUserMessage, + BanUserMessage, RefreshRoomMessage, } from "../Messages/generated/messages_pb"; import {User, UserSocket} from "../Model/User"; import {ProtobufUtils} from "../Model/Websocket/ProtobufUtils"; @@ -40,7 +41,6 @@ import { } from "../Enum/EnvironmentVariable"; import {Movable} from "../Model/Movable"; import {PositionInterface} from "../Model/PositionInterface"; -import {adminApi, CharacterTexture} from "./AdminApi"; import Jwt from "jsonwebtoken"; import {JITSI_URL} from "../Enum/EnvironmentVariable"; import {clientEventsEmitter} from "./ClientEventsEmitter"; @@ -58,6 +58,7 @@ function emitZoneMessage(subMessage: SubToPusherMessage, socket: ZoneSocket): vo // TODO: should we batch those every 100ms? const batchMessage = new BatchToPusherMessage(); batchMessage.addPayload(subMessage); + socket.write(batchMessage); } @@ -75,10 +76,17 @@ export class SocketManager { } public async handleJoinRoom(socket: UserSocket, joinRoomMessage: JoinRoomMessage): Promise<{ room: GameRoom; user: User }> { - + //join new previous room const {room, user} = await this.joinRoom(socket, joinRoomMessage); - + + if (!socket.writable) { + console.warn('Socket was aborted'); + return { + room, + user + }; + } const roomJoinedMessage = new RoomJoinedMessage(); roomJoinedMessage.setTagList(joinRoomMessage.getTagList()); @@ -94,7 +102,6 @@ export class SocketManager { const serverToClientMessage = new ServerToClientMessage(); serverToClientMessage.setRoomjoinedmessage(roomJoinedMessage); - console.log('SENDING MESSAGE roomJoinedMessage'); socket.write(serverToClientMessage); return { @@ -121,15 +128,7 @@ export class SocketManager { if (viewport === undefined) { throw new Error('Viewport not found in message'); } - - // sending to all clients in room except sender - /*client.position = { - x: position.x, - y: position.y, - direction, - moving: position.moving, - }; - client.viewport = viewport;*/ + // update position in the world room.updatePosition(user, ProtobufUtils.toPointInterface(position)); @@ -184,21 +183,6 @@ export class SocketManager { } } - // TODO: handle this message in pusher - /*async handleReportMessage(client: ExSocketInterface, reportPlayerMessage: ReportPlayerMessage) { - try { - const reportedSocket = this.sockets.get(reportPlayerMessage.getReporteduserid()); - if (!reportedSocket) { - throw 'reported socket user not found'; - } - //TODO report user on admin application - await adminApi.reportPlayer(reportedSocket.userUuid, reportPlayerMessage.getReportcomment(), client.userUuid) - } catch (e) { - console.error('An error occurred on "handleReportMessage"'); - console.error(e); - } - }*/ - emitVideo(room: GameRoom, user: User, data: WebRtcSignalToServerMessage): void { //send only at user const remoteUser = room.getUsers().get(data.getReceiverid()); @@ -262,8 +246,6 @@ export class SocketManager { debug('Room is empty. Deleting room "%s"', room.roomId); } } finally { - //delete Client.roomId; - //this.sockets.delete(Client.userId); clientEventsEmitter.emitClientLeave(user.uuid, room.roomId); console.log('A user left'); } @@ -283,11 +265,6 @@ export class SocketManager { (thing: Movable, position:PositionInterface, listener: ZoneSocket) => this.onClientMove(thing, position, listener), (thing: Movable, newZone: Zone|null, listener: ZoneSocket) => this.onClientLeave(thing, newZone, listener) ); - if (!world.anonymous) { - const data = await adminApi.fetchMapDetails(world.organizationSlug, world.worldSlug, world.roomSlug) - world.tags = data.tags - world.policyType = Number(data.policy_type) - } gaugeManager.incNbRoomGauge(); this.rooms.set(roomId, world); } @@ -298,20 +275,14 @@ export class SocketManager { const roomId = joinRoomMessage.getRoomid(); - const world = await socketManager.getOrCreateRoom(roomId); - - // Dispatch groups position to newly connected user - /*world.getGroups().forEach((group: Group) => { - this.emitCreateUpdateGroupEvent(socket, group); - });*/ + const room = await socketManager.getOrCreateRoom(roomId); //join world - const user = world.join(socket, joinRoomMessage); + const user = room.join(socket, joinRoomMessage); clientEventsEmitter.emitClientJoin(user.uuid, roomId); - //console.log(new Date().toISOString() + ' A user joined (', this.sockets.size, ' connected users)'); console.log(new Date().toISOString() + ' A user joined'); - return {room: world, user}; + return {room, user}; } private onZoneEnter(thing: Movable, fromZone: Zone|null, listener: ZoneSocket) { @@ -419,10 +390,6 @@ export class SocketManager { } private joinWebRtcRoom(user: User, group: Group) { - /*const roomId: string = "webrtcroom"+group.getId(); - if (user.socket.webRtcRoomId === roomId) { - return; - }*/ for (const otherUser of group.getUsers()) { if (user === otherUser) { @@ -758,6 +725,43 @@ export class SocketManager { recipient.socket.write(clientMessage); }); } + + dispatchWorlFullWarning(roomId: string,): void { + const room = this.rooms.get(roomId); + if (!room) { + //todo: this should cause the http call to return a 500 + console.error("In sendAdminRoomMessage, could not find room with id '" + roomId + "'. Maybe the room was closed a few milliseconds ago and there was a race condition?"); + return; + } + + room.getUsers().forEach((recipient) => { + const worldFullMessage = new WorldFullWarningMessage(); + + const clientMessage = new ServerToClientMessage(); + clientMessage.setWorldfullwarningmessage(worldFullMessage); + + recipient.socket.write(clientMessage); + }); + } + + dispatchRoomRefresh(roomId: string,): void { + const room = this.rooms.get(roomId); + if (!room) { + return; + } + + const versionNumber = room.incrementVersion(); + room.getUsers().forEach((recipient) => { + const worldFullMessage = new RefreshRoomMessage(); + worldFullMessage.setRoomid(roomId) + worldFullMessage.setVersionnumber(versionNumber) + + const clientMessage = new ServerToClientMessage(); + clientMessage.setRefreshroommessage(worldFullMessage); + + recipient.socket.write(clientMessage); + }); + } } export const socketManager = new SocketManager(); diff --git a/back/yarn.lock b/back/yarn.lock index 501146cb..43f58988 100644 --- a/back/yarn.lock +++ b/back/yarn.lock @@ -3032,9 +3032,9 @@ xtend@^4.0.0: integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== y18n@^3.2.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= + version "3.2.2" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" + integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== yallist@^3.0.0, yallist@^3.0.3: version "3.1.1" diff --git a/contrib/docker/docker-compose.prod.yaml b/contrib/docker/docker-compose.prod.yaml index 22860748..6b3b8520 100644 --- a/contrib/docker/docker-compose.prod.yaml +++ b/contrib/docker/docker-compose.prod.yaml @@ -10,7 +10,7 @@ services: - --entrypoints.web.http.redirections.entryPoint.to=websecure - --entrypoints.web.http.redirections.entryPoint.scheme=https - --entryPoints.websecure.address=:443 - - --certificatesresolvers.myresolver.acme.email=d.negrier@thecodingmachine.com + - --certificatesresolvers.myresolver.acme.email=${ACME_EMAIL} - --certificatesresolvers.myresolver.acme.storage=/acme.json # used during the challenge - --certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web @@ -37,7 +37,7 @@ services: DEBUG_MODE: "$DEBUG_MODE" JITSI_URL: $JITSI_URL JITSI_PRIVATE_MODE: "$JITSI_PRIVATE_MODE" - API_URL: pusher.${DOMAIN} + PUSHER_URL: //pusher.${DOMAIN} TURN_SERVER: "${TURN_SERVER}" TURN_USER: "${TURN_USER}" TURN_PASSWORD: "${TURN_PASSWORD}" diff --git a/deeployer.libsonnet b/deeployer.libsonnet index 52cea293..07506f11 100644 --- a/deeployer.libsonnet +++ b/deeployer.libsonnet @@ -82,9 +82,9 @@ }, "ports": [80], "env": { - "API_URL": "pusher."+url, - "UPLOADER_URL": "uploader."+url, - "ADMIN_URL": url, + "PUSHER_URL": "//pusher."+url, + "UPLOADER_URL": "//uploader."+url, + "ADMIN_URL": "//"+url, "JITSI_URL": env.JITSI_URL, "SECRET_JITSI_KEY": env.SECRET_JITSI_KEY, "TURN_SERVER": "turn:coturn.workadventu.re:443,turns:coturn.workadventu.re:443", diff --git a/docker-compose.single-domain.yaml b/docker-compose.single-domain.yaml new file mode 100644 index 00000000..0bd1dcb6 --- /dev/null +++ b/docker-compose.single-domain.yaml @@ -0,0 +1,207 @@ +version: "3" +services: + reverse-proxy: + image: traefik:v2.0 + command: + - --api.insecure=true + - --providers.docker + - --entryPoints.web.address=:80 + - --entryPoints.websecure.address=:443 + ports: + - "80:80" + - "443:443" + # The Web UI (enabled by --api.insecure=true) + - "8080:8080" + depends_on: + - back + - front + volumes: + - /var/run/docker.sock:/var/run/docker.sock + + front: + image: thecodingmachine/nodejs:14 + environment: + DEBUG_MODE: "$DEBUG_MODE" + JITSI_URL: $JITSI_URL + JITSI_PRIVATE_MODE: "$JITSI_PRIVATE_MODE" + HOST: "0.0.0.0" + NODE_ENV: development + PUSHER_URL: /pusher + UPLOADER_URL: /uploader + ADMIN_URL: /admin + MAPS_URL: /maps + STARTUP_COMMAND_1: yarn install + TURN_SERVER: "turn:localhost:3478,turns:localhost:5349" + # Use TURN_USER/TURN_PASSWORD if your Coturn server is secured via hard coded credentials. + # Advice: you should instead use Coturn REST API along the TURN_STATIC_AUTH_SECRET in the Back container + TURN_USER: "" + TURN_PASSWORD: "" + START_ROOM_URL: "$START_ROOM_URL" + command: yarn run start + volumes: + - ./front:/usr/src/app + labels: + - "traefik.http.routers.front.rule=PathPrefix(`/`)" + - "traefik.http.routers.front.entryPoints=web,traefik" + - "traefik.http.services.front.loadbalancer.server.port=8080" + - "traefik.http.routers.front-ssl.rule=PathPrefix(`/`)" + - "traefik.http.routers.front-ssl.entryPoints=websecure" + - "traefik.http.routers.front-ssl.tls=true" + - "traefik.http.routers.front-ssl.service=front" + + pusher: + image: thecodingmachine/nodejs:12 + command: yarn dev + #command: yarn run prod + #command: yarn run profile + environment: + DEBUG: "*" + STARTUP_COMMAND_1: yarn install + SECRET_JITSI_KEY: "$SECRET_JITSI_KEY" + SECRET_KEY: yourSecretKey + ADMIN_API_TOKEN: "$ADMIN_API_TOKEN" + API_URL: back:50051 + JITSI_URL: $JITSI_URL + JITSI_ISS: $JITSI_ISS + volumes: + - ./pusher:/usr/src/app + labels: + - "traefik.http.middlewares.strip-pusher-prefix.stripprefix.prefixes=/pusher" + - "traefik.http.routers.pusher.rule=PathPrefix(`/pusher`)" + - "traefik.http.routers.pusher.middlewares=strip-pusher-prefix@docker" + - "traefik.http.routers.pusher.entryPoints=web" + - "traefik.http.services.pusher.loadbalancer.server.port=8080" + - "traefik.http.routers.pusher-ssl.rule=PathPrefix(`/pusher`)" + - "traefik.http.routers.pusher-ssl.middlewares=strip-pusher-prefix@docker" + - "traefik.http.routers.pusher-ssl.entryPoints=websecure" + - "traefik.http.routers.pusher-ssl.tls=true" + - "traefik.http.routers.pusher-ssl.service=pusher" + + maps: + image: thecodingmachine/nodejs:12-apache + environment: + DEBUG_MODE: "$DEBUG_MODE" + HOST: "0.0.0.0" + NODE_ENV: development + #APACHE_DOCUMENT_ROOT: dist/ + #APACHE_EXTENSIONS: headers + #APACHE_EXTENSION_HEADERS: 1 + STARTUP_COMMAND_0: sudo a2enmod headers + STARTUP_COMMAND_1: yarn install + STARTUP_COMMAND_2: yarn run dev & + volumes: + - ./maps:/var/www/html + labels: + - "traefik.http.middlewares.strip-maps-prefix.stripprefix.prefixes=/maps" + - "traefik.http.routers.maps.rule=PathPrefix(`/maps`)" + - "traefik.http.routers.maps.middlewares=strip-maps-prefix@docker" + - "traefik.http.routers.maps.entryPoints=web,traefik" + - "traefik.http.services.maps.loadbalancer.server.port=80" + - "traefik.http.routers.maps-ssl.rule=PathPrefix(`/maps`)" + - "traefik.http.routers.maps-ssl.middlewares=strip-maps-prefix@docker" + - "traefik.http.routers.maps-ssl.entryPoints=websecure" + - "traefik.http.routers.maps-ssl.tls=true" + - "traefik.http.routers.maps-ssl.service=maps" + + back: + image: thecodingmachine/nodejs:12 + command: yarn dev + #command: yarn run profile + environment: + DEBUG: "*" + STARTUP_COMMAND_1: yarn install + SECRET_KEY: yourSecretKey + SECRET_JITSI_KEY: "$SECRET_JITSI_KEY" + ALLOW_ARTILLERY: "true" + ADMIN_API_TOKEN: "$ADMIN_API_TOKEN" + JITSI_URL: $JITSI_URL + JITSI_ISS: $JITSI_ISS + volumes: + - ./back:/usr/src/app + labels: + - "traefik.http.middlewares.strip-api-prefix.stripprefix.prefixes=/api" + - "traefik.http.routers.back.rule=PathPrefix(`/api`)" + - "traefik.http.routers.back.middlewares=strip-api-prefix@docker" + - "traefik.http.routers.back.entryPoints=web" + - "traefik.http.services.back.loadbalancer.server.port=8080" + - "traefik.http.routers.back-ssl.rule=PathPrefix(`/api`)" + - "traefik.http.routers.back-ssl.middlewares=strip-api-prefix@docker" + - "traefik.http.routers.back-ssl.entryPoints=websecure" + - "traefik.http.routers.back-ssl.tls=true" + - "traefik.http.routers.back-ssl.service=back" + + uploader: + image: thecodingmachine/nodejs:12 + command: yarn dev + #command: yarn run profile + environment: + DEBUG: "*" + STARTUP_COMMAND_1: yarn install + volumes: + - ./uploader:/usr/src/app + labels: + - "traefik.http.middlewares.strip-uploader-prefix.stripprefix.prefixes=/uploader" + - "traefik.http.routers.uploader.rule=PathPrefix(`/uploader`)" + - "traefik.http.routers.uploader.middlewares=strip-uploader-prefix@docker" + - "traefik.http.routers.uploader.entryPoints=web" + - "traefik.http.services.uploader.loadbalancer.server.port=8080" + - "traefik.http.routers.uploader-ssl.rule=PathPrefix(`/uploader`)" + - "traefik.http.routers.uploader-ssl.middlewares=strip-uploader-prefix@docker" + - "traefik.http.routers.uploader-ssl.entryPoints=websecure" + - "traefik.http.routers.uploader-ssl.tls=true" + - "traefik.http.routers.uploader-ssl.service=uploader" + + website: + image: thecodingmachine/nodejs:12-apache + environment: + STARTUP_COMMAND_1: npm install + STARTUP_COMMAND_2: npm run watch & + APACHE_DOCUMENT_ROOT: dist/ + volumes: + - ./website:/var/www/html + labels: + - "traefik.http.routers.website.rule=Host(`workadventure.localhost`)" + - "traefik.http.routers.website.entryPoints=web" + - "traefik.http.services.website.loadbalancer.server.port=80" + - "traefik.http.routers.website-ssl.rule=Host(`workadventure.localhost`)" + - "traefik.http.routers.website-ssl.entryPoints=websecure" + - "traefik.http.routers.website-ssl.tls=true" + - "traefik.http.routers.website-ssl.service=website" + + messages: + #image: thecodingmachine/nodejs:14 + image: thecodingmachine/workadventure-back-base:latest + environment: + #STARTUP_COMMAND_0: sudo apt-get install -y inotify-tools + STARTUP_COMMAND_1: yarn install + STARTUP_COMMAND_2: yarn run proto:watch + volumes: + - ./messages:/usr/src/app + - ./back:/usr/src/back + - ./front:/usr/src/front + - ./pusher:/usr/src/pusher + +# coturn: +# image: coturn/coturn:4.5.2 +# command: +# - turnserver +# #- -c=/etc/coturn/turnserver.conf +# - --log-file=stdout +# - --external-ip=$$(detect-external-ip) +# - --listening-port=3478 +# - --min-port=10000 +# - --max-port=10010 +# - --tls-listening-port=5349 +# - --listening-ip=0.0.0.0 +# - --realm=localhost +# - --server-name=localhost +# - --lt-cred-mech +# # Enable Coturn "REST API" to validate temporary passwords. +# #- --use-auth-secret +# #- --static-auth-secret=SomeStaticAuthSecret +# #- --userdb=/var/lib/turn/turndb +# - --user=workadventure:WorkAdventure123 +# # use real-valid certificate/privatekey files +# #- --cert=/root/letsencrypt/fullchain.pem +# #- --pkey=/root/letsencrypt/privkey.pem +# network_mode: host diff --git a/docker-compose.yaml b/docker-compose.yaml index 22b807a7..504c5b23 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -26,9 +26,9 @@ services: JITSI_PRIVATE_MODE: "$JITSI_PRIVATE_MODE" HOST: "0.0.0.0" NODE_ENV: development - API_URL: pusher.workadventure.localhost - UPLOADER_URL: uploader.workadventure.localhost - ADMIN_URL: workadventure.localhost + PUSHER_URL: //pusher.workadventure.localhost + UPLOADER_URL: //uploader.workadventure.localhost + ADMIN_URL: //workadventure.localhost STARTUP_COMMAND_1: ./templater.sh STARTUP_COMMAND_2: yarn install STUN_SERVER: "stun:stun.l.google.com:19302" @@ -53,10 +53,8 @@ services: pusher: image: thecodingmachine/nodejs:12 command: yarn dev - #command: yarn run prod - #command: yarn run profile environment: - DEBUG: "*" + DEBUG: "socket:*" STARTUP_COMMAND_1: yarn install SECRET_JITSI_KEY: "$SECRET_JITSI_KEY" SECRET_KEY: yourSecretKey diff --git a/front/Dockerfile b/front/Dockerfile index 51734535..ef724e0f 100644 --- a/front/Dockerfile +++ b/front/Dockerfile @@ -3,7 +3,7 @@ WORKDIR /var/www/messages COPY --chown=docker:docker messages . RUN yarn install && yarn proto -# we are rebuilding on each deploy to cope with the API_URL environment URL +# we are rebuilding on each deploy to cope with the PUSHER_URL environment URL FROM thecodingmachine/nodejs:14-apache COPY --chown=docker:docker front . diff --git a/front/dist/.gitignore b/front/dist/.gitignore index a60c53be..785f2eb9 100644 --- a/front/dist/.gitignore +++ b/front/dist/.gitignore @@ -1,3 +1,4 @@ index.html index.tmpl.html.tmp /js/ +style.*.css diff --git a/front/dist/index.tmpl.html b/front/dist/index.tmpl.html index ecf2c671..062622b8 100644 --- a/front/dist/index.tmpl.html +++ b/front/dist/index.tmpl.html @@ -31,8 +31,6 @@ - - WorkAdventure @@ -70,98 +68,54 @@ + +
- +
- -
- -
- -
- - + +