{ pkgs, lib, ... }: let workadventure-repository = pkgs.fetchgit { url = "https://github.com/thecodingmachine/workadventure.git"; rev = "284846e8a59ec0d921189ac3a46e0eb5d1e14818"; sha256 = "1f1vi226kas7x9y8zw810q5vg1ikn4bb6ha9vnzvqk9y7jlc1n8q"; }; homeFolder = "/srv/workadventure"; debugMode = "true"; # If your Jitsi environment has authentication set up, # you MUST set JITSI_PRIVATE_MODE to "true" and # you MUST pass a SECRET_JITSI_KEY to generate the JWT secret #JITSI_PRIVATE_MODE = "false"; jitsiPrivateMode = "false"; #SECRET_JITSI_KEY= secretJitsiKey = ""; #JITSI_ISS= jitsiISS = ""; #ADMIN_API_TOKEN = 123 adminAPIToken = "123"; domain = "workadventure.palovandalo.com"; #jitsiURL = "meet.palovandalo.com"; jitsiURL = "meet.jit.si"; mainURL = domain; mainPort = 9000; adminURL = "admin.${domain}"; adminPort = 9001; apiURL = "api.${domain}"; apiPort = 9002; mapsURL = "maps.${domain}"; mapsPort = 9003; playURL = "play.${domain}"; playPort = 9004; pusherURL = "pusher.${domain}"; pusherPort = 9005; uploaderURL = "uploader.${domain}"; uploaderPort = 9006; in { # todo delete networking.firewall = { allowedTCPPorts = [ 80 443 ]; allowedUDPPorts = [ 80 443 ]; }; services.nginx.enable = true; #services.nginx.recommendedGzipSettings = true; #services.nginx.recommendedOptimisation = true; #services.nginx.recommendedProxySettings = true; #services.nginx.recommendedTlsSettings = true; systemd.services.workadventureRepository = { enable = true; wantedBy = [ "multi-user.target" ]; script = '' mkdir -p ${homeFolder} cp -r "${workadventure-repository}"/* "${homeFolder}/" chmod -R 777 "${homeFolder}" ''; before = [ "docker-back.service" "docker-maps.service" "docker-messages.service" "docker-prune.service" "docker-uploader.service" "docker-website.service" ]; }; virtualisation.oci-containers.backend = "docker"; #virtualisation.oci-containers.containers.reverse-proxy = { # image = "traefik:v2.0"; # cmd = [ # "--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" # ]; # dependsOn = [ "back" "front" ]; # volumes = [ "/var/run/docker.sock:/var/run/docker.sock" ]; #}; virtualisation.oci-containers.containers.front = { image = "thecodingmachine/nodejs:14"; environment = { DEBUG_MODE = debugMode; JITSI_URL = jitsiURL; JITSI_PRIVATE_MODE = jitsiPrivateMode; HOST = "0.0.0.0"; #HTTP_PORT = "80"; NODE_ENV = "development"; #NODE_ENV = "production"; API_URL = pusherURL; UPLOADER_URL = uploaderURL; ADMIN_URL = adminURL; STARTUP_COMMAND_1 = "yarn install"; #TURN_SERVER = "turn:coturn.workadventu.re:443,turns:coturn.workadventu.re:443"; #TURN_USER = "workadventure"; #TURN_PASSWORD = "WorkAdventure123"; }; cmd = [ "yarn" "run" "start" ]; volumes = [ "${homeFolder}/front:/usr/src/app" ]; ports = [ "${toString playPort}:8080" ]; extraOptions = let labelFile = pkgs.writeText "front-labels" '' traefik.http.routers.front.rule=Host(`play.${domain}`) traefik.http.routers.front.entryPoints=web,traefik traefik.http.services.front.loadbalancer.server.port=8080 #traefik.http.routers.front-ssl.rule=Host(`play.${domain}`) #traefik.http.routers.front-ssl.entryPoints=websecure #traefik.http.routers.front-ssl.tls=false #traefik.http.routers.front-ssl.service=front ''; in [ "--label-file" (toString labelFile) ]; }; systemd.services.docker-front.serviceConfig = { StandardOutput = lib.mkForce "journal"; StandardError = lib.mkForce "journal"; }; services.nginx.virtualHosts."${playURL}" = { #enableACME = true; #forceSSL = true; locations."/" = { proxyPass = "http://localhost:${toString playPort}"; proxyWebsockets = true; extraConfig = '' if ($request_method = OPTIONS) { return 204; } add_header Access-Control-Allow-Origin *; add_header Access-Control-Max-Age 3600; add_header Access-Control-Expose-Headers Content-Length; add_header Access-Control-Allow-Headers Range; #proxy_set_header Host $host; #proxy_set_header X-Forwarded-For $remote_addr; #sub_filter '${domain}:8080' '${domain}'; #sub_filter_once on; ''; }; }; services.nginx.virtualHosts."${adminURL}" = { #enableACME = true; #forceSSL = true; locations."/" = { proxyPass = "http://localhost:${toString mainPort}"; proxyWebsockets = true; extraConfig = '' if ($request_method = OPTIONS) { return 204; } add_header Access-Control-Allow-Origin *; add_header Access-Control-Max-Age 3600; add_header Access-Control-Expose-Headers Content-Length; add_header Access-Control-Allow-Headers Range; #proxy_set_header Host $host; #proxy_set_header X-Forwarded-For $remote_addr; #sub_filter '${domain}:8080' '${domain}'; #sub_filter_once on; ''; }; }; virtualisation.oci-containers.containers.pusher = { image = "thecodingmachine/nodejs:12"; cmd = [ "yarn" "dev" ]; environment = { DEBUG = "*"; STARTUP_COMMAND_1 = "yarn install"; SECRET_JITSI_KEY = secretJitsiKey; SECRET_KEY = "yourSecretKey"; ADMIN_API_TOKEN = adminAPIToken; API_URL = "back:50051"; #API_URL = "back:8080"; JITSI_URL = jitsiURL; JITSI_ISS = jitsiISS; }; volumes = [ "${homeFolder}/pusher:/usr/src/app" ]; ports = [ "${toString pusherPort}:8080" ]; extraOptions = let labelFile = pkgs.writeText "pusher-labels" '' traefik.http.routers.pusher.rule=Host(`pusher.${domain}`) traefik.http.routers.pusher.entryPoints=web traefik.http.services.pusher.loadbalancer.server.port=8080 traefik.http.routers.pusher-ssl.rule=Host(`pusher.${domain}`) traefik.http.routers.pusher-ssl.entryPoints=websecure traefik.http.routers.pusher-ssl.tls=false traefik.http.routers.pusher-ssl.service=pusher traefik.http.middlewares.api.headers.customResponseHeaders.Access-Control-Allow-Origin=http://play.${domain} ''; in [ "--label-file" (toString labelFile) ]; }; systemd.services.docker-pusher.serviceConfig = { StandardOutput = lib.mkForce "journal"; StandardError = lib.mkForce "journal"; }; services.nginx.virtualHosts."${pusherURL}" = { #enableACME = true; #forceSSL = true; locations."/" = { proxyPass = "http://localhost:${toString pusherPort}"; proxyWebsockets = true; extraConfig = '' if ($request_method = OPTIONS) { return 204; } add_header Access-Control-Allow-Origin *; add_header Access-Control-Max-Age 3600; add_header Access-Control-Expose-Headers Content-Length; add_header Access-Control-Allow-Headers Range; #proxy_set_header Host $host; #proxy_set_header X-Forwarded-For $remote_addr; #sub_filter '${domain}:8080' '${domain}'; #sub_filter_once on; ''; }; }; virtualisation.oci-containers.containers.maps = { image = "thecodingmachine/nodejs:12-apache"; environment = { DEBUG_MODE = debugMode; HOST = "0.0.0.0"; NODE_ENV = "development"; STARTUP_COMMAND_0 = "sudo a2enmod headers"; STARTUP_COMMAND_1 = "yarn install"; STARTUP_COMMAND_2 = "yarn run dev &"; }; volumes = [ "${homeFolder}/maps:/var/www/html" ]; ports = [ "${toString mapsPort}:80" ]; extraOptions = let labelFile = pkgs.writeText "maps-labels" '' traefik.http.routers.maps.rule=Host(`maps.${domain}`) traefik.http.routers.maps.entryPoints=web,traefik traefik.http.services.maps.loadbalancer.server.port=80 traefik.http.routers.maps-ssl.rule=Host(`maps.${domain}`) traefik.http.routers.maps-ssl.entryPoints=websecure traefik.http.routers.maps-ssl.tls=false traefik.http.routers.maps-ssl.service=maps ''; in [ "--label-file" (toString labelFile) ]; }; systemd.services.docker-maps.serviceConfig = { StandardOutput = lib.mkForce "journal"; StandardError = lib.mkForce "journal"; }; services.nginx.virtualHosts."${mapsURL}" = { #enableACME = true; #forceSSL = true; locations."/" = { proxyPass = "http://localhost:${toString mapsPort}"; proxyWebsockets = true; extraConfig = '' if ($request_method = OPTIONS) { return 204; } add_header Access-Control-Allow-Origin *; add_header Access-Control-Max-Age 3600; add_header Access-Control-Expose-Headers Content-Length; add_header Access-Control-Allow-Headers Range; #proxy_set_header Host $host; #proxy_set_header X-Forwarded-For $remote_addr; #sub_filter '${domain}:8080' '${domain}'; #sub_filter_once on; ''; }; }; virtualisation.oci-containers.containers.back = { image = "thecodingmachine/nodejs:12"; cmd = [ "yarn" "dev" ]; environment = { DEBUG = "*"; STARTUP_COMMAND_1 = "yarn install"; SECRET_KEY = "yourSecretKey"; SECRET_JITSI_KEY = secretJitsiKey; #HTTP_PORT = "80"; ALLOW_ARTILLERY = "true"; ADMIN_API_TOKEN = adminAPIToken; JITSI_URL = jitsiURL; JITSI_ISS = jitsiISS; }; volumes = [ "${homeFolder}/back:/usr/src/app" ]; ports = [ "${toString apiPort}:8080" ]; extraOptions = let labelFile = pkgs.writeText "back-labels" '' traefik.http.routers.back.rule=Host(`api.${domain}`) traefik.http.routers.back.entryPoints=web traefik.http.services.back.loadbalancer.server.port=8080 traefik.http.routers.back-ssl.rule=Host(`api.${domain}`) traefik.http.routers.back-ssl.entryPoints=websecure traefik.http.routers.back-ssl.tls=false traefik.http.routers.back-ssl.service=back traefik.http.middlewares.api.headers.customResponseHeaders.Access-Control-Allow-Origin=http://play.${domain} ''; in [ "--label-file" (toString labelFile) ]; }; systemd.services.docker-back.serviceConfig = { StandardOutput = lib.mkForce "journal"; StandardError = lib.mkForce "journal"; }; services.nginx.virtualHosts."${apiURL}" = { #enableACME = true; #forceSSL = true; locations."/" = { proxyPass = "http://localhost:${toString apiPort}"; proxyWebsockets = true; extraConfig = '' if ($request_method = OPTIONS) { return 204; } add_header Access-Control-Allow-Origin *; add_header Access-Control-Max-Age 3600; add_header Access-Control-Expose-Headers Content-Length; add_header Access-Control-Allow-Headers Range; #proxy_set_header Host $host; #proxy_set_header X-Forwarded-For $remote_addr; #sub_filter '${domain}:8080' '${domain}'; #sub_filter_once on; ''; }; }; virtualisation.oci-containers.containers.uploader = { image = "thecodingmachine/nodejs:12"; cmd = [ "yarn" "dev" ]; environment = { DEBUG = "*"; STARTUP_COMMAND_1 = "yarn install"; }; volumes = [ "${homeFolder}/uploader:/usr/src/app" ]; ports = [ "${toString uploaderPort}:8080" ]; extraOptions = let labelFile = pkgs.writeText "uploader-labels" '' traefik.http.routers.uploader.rule=Host(`uploader.${domain}`) traefik.http.routers.uploader.entryPoints=web traefik.http.services.uploader.loadbalancer.server.port=8080 traefik.http.routers.uploader-ssl.rule=Host(`uploader.${domain}`) traefik.http.routers.uploader-ssl.entryPoints=websecure traefik.http.routers.uploader-ssl.tls=true traefik.http.routers.uploader-ssl.service=uploader ''; in [ "--label-file" (toString labelFile) ]; }; systemd.services.docker-uploader.serviceConfig = { StandardOutput = lib.mkForce "journal"; StandardError = lib.mkForce "journal"; }; services.nginx.virtualHosts."${uploaderURL}" = { #enableACME = true; #forceSSL = true; locations."/" = { proxyPass = "http://localhost:${toString uploaderPort}"; proxyWebsockets = true; extraConfig = '' if ($request_method = OPTIONS) { return 204; } add_header Access-Control-Allow-Origin *; add_header Access-Control-Max-Age 3600; add_header Access-Control-Expose-Headers Content-Length; add_header Access-Control-Allow-Headers Range; #proxy_set_header Host $host; #proxy_set_header X-Forwarded-For $remote_addr; #sub_filter '${domain}:8080' '${domain}'; #sub_filter_once on; ''; }; }; virtualisation.oci-containers.containers.website = { image = "thecodingmachine/nodejs:12-apache"; environment = { STARTUP_COMMAND_1 = "npm install"; STARTUP_COMMAND_2 = "npm run watch &"; APACHE_DOCUMENT_ROOT = "dist/"; }; volumes = [ "${homeFolder}/website:/var/www/html" ]; ports = [ "${toString mainPort}:80" ]; extraOptions = let labelFile = pkgs.writeText "website-labels" '' traefik.http.routers.website.rule=Host(`${domain}`) traefik.http.routers.website.entryPoints=web traefik.http.services.website.loadbalancer.server.port=8080 traefik.http.routers.website-ssl.rule=Host(`${domain}`) traefik.http.routers.website-ssl.entryPoints=websecure traefik.http.routers.website-ssl.tls=true traefik.http.routers.website-ssl.service=website ''; in [ "--label-file" (toString labelFile) ]; }; systemd.services.docker-website.serviceConfig = { StandardOutput = lib.mkForce "journal"; StandardError = lib.mkForce "journal"; }; services.nginx.virtualHosts."${mainURL}" = { #enableACME = true; #forceSSL = true; locations."/" = { proxyPass = "http://localhost:${toString mainPort}"; proxyWebsockets = true; extraConfig = '' if ($request_method = OPTIONS) { return 204; } add_header Access-Control-Allow-Origin *; add_header Access-Control-Max-Age 3600; add_header Access-Control-Expose-Headers Content-Length; add_header Access-Control-Allow-Headers Range; #proxy_set_header Host $host; #proxy_set_header X-Forwarded-For $remote_addr; #sub_filter '${domain}:8080' '${domain}'; #sub_filter_once on; ''; }; }; virtualisation.oci-containers.containers.messages = { image = "thecodingmachine/workadventure-back-base:latest"; environment = { STARTUP_COMMAND_1 = "yarn install"; STARTUP_COMMAND_2 = "yarn run proto:watch"; }; volumes = [ "${homeFolder}/messages:/usr/src/app" "${homeFolder}/back:/usr/src/back" "${homeFolder}/front:/usr/src/front" "${homeFolder}/pusher:/usr/src/pusher" ]; }; systemd.services.docker-messages.serviceConfig = { StandardOutput = lib.mkForce "journal"; StandardError = lib.mkForce "journal"; }; }