diff --git a/.env.example b/.env.example index 5af54d1eb..dfd29dee5 100644 --- a/.env.example +++ b/.env.example @@ -5,6 +5,10 @@ # WEB_PORT=80 # WEB_CORS=false +# Prod build +# MYSQL_PORT=3306 +# DB_UPLOAD_LIMIT=2G + ## management server # WEB_MANAGEMENT_PORT=8898 diff --git a/.env_prod b/.env_prod new file mode 100644 index 000000000..902d6cfba --- /dev/null +++ b/.env_prod @@ -0,0 +1,108 @@ +# This is an example of production build environment vars + +# ----------------------------------------------------- # +# ------------------- CONFIGURABLES ------------------- # +# ----------------------------------------------------- # + +# Database dump upload limit (not actual db limit) +DB_UPLOAD_LIMIT=2G + +# Set to true if you're using https +HTTPS_ENABLED=false +# Set your domain here, if you're using domain +PUBLIC_IP=localhost + +# CORS allows safe cross-domain requests when explicitly permitted +# Should be enabled in prod IF HTTPS is enabled +# If not using HTTPS, can be disabled, otherwise auto-redirect will forward you to https: +WEB_CORS=false +SKIP_CORS=false +ADDRESS_SHOWPORT=true +ADMIN_IP=localhost + +DB_HOST=localhost +DB_NAME=lostcity +DB_USER=user +DB_PASS=userpw + + +# Configure these: +DB_ROOT_PASS=rootpassword +# Used by website & server +DB_NAME=lostcity +# Used by website & server +DB_USER=user +# Used by website & server +DB_PASS=userpw +# Format: mysql://DB_USER:DB_PASS@DB_HOST:MYSQL_PORT/DB_NAME +DATABASE_URL=mysql://user:userpw@db:3306/lostcity + +# Service ports, change these optionally +WEB_PORT=80 +WEB_MANAGEMENT_PORT=8898 +FRIEND_PORT=45099 +LOGGER_PORT=43501 +NODE_PORT=43594 +LOGIN_PORT=43500 +# Recommended to keep at 3006 +MYSQL_PORT=3306 + +# Default world, change these optionally +NODE_ID=10 +# Is the world members? +NODE_MEMBERS=true +# XP rate of this world +NODE_XPRATE=1 + +# Administrator username +# Enables administrator commands for this player +# TODO: make this a config? Currently only one admin can be set +NODE_STAFF= + + +# -------------------------------------------------------- # +# ------------- Other configurations --------------------- # +# ------------- Can be left untouched -------------------- # +# ------------- unless you know what you're doing -------- # +# -------------------------------------------------------- # + +# World +# Enables trackers, observers, reboot timer, and other production game functions +NODE_PRODUCTION=true +NODE_KILLTIMER=50 +# We wouldn't want cheats for production +NODE_ALLOW_CHEATS=false +NODE_DEBUG=false +NODE_DEBUG_PROFILE=false +NODE_CLIENT_ROUTEFINDER=true +NODE_SOCKET_TIMEOUT=true +NODE_WALKTRIGGER_SETTING=0 + +# Login service +LOGIN_SERVER=true +LOGIN_HOST=localhost + +# Friend service +FRIEND_SERVER=true +FRIEND_HOST=localhost + +# Logger service +LOGGER_SERVER=true +LOGGER_HOST=localhost + +# Database +# Host -> docker service name +# Don't change this, unless you change compose.yml +DB_HOST=db + +# Login key, unsure if used anywhere +LOGIN_KEY=abcde + +# Build +BUILD_JAVA_PATH=java +BUILD_STARTUP=true +BUILD_STARTUP_UPDATE=true +BUILD_VERIFY=true +BUILD_VERIFY_FOLDER=true +BUILD_VERIFY_PACK=true +BUILD_SRC_DIR=data/src diff --git a/.gitignore b/.gitignore index f27d58c70..e4d8a8035 100644 --- a/.gitignore +++ b/.gitignore @@ -26,9 +26,11 @@ data/config/login.json data/config/friend.json dump/ - node_modules/ +# prod build mysql database +mysql_data/ + # keep these precompiled files out of the repo bz2.dll JagCompress.jar diff --git a/docker-compose.yml b/docker-compose.yml index c86b3c87b..b85ccc89d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,19 +1,171 @@ -version: "3.8" +# version: "3.8" +# Compose V2 doesn't require a version anymore: `version` is obsolete services: - 2004scape: + db: + profiles: + - prod + env_file: + - .env_prod + image: mariadb:10.5 + environment: + MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASS} + MYSQL_DATABASE: ${DB_NAME} + MYSQL_USER: ${DB_USER} + MYSQL_PASSWORD: ${DB_PASS} + volumes: + - ./mysql_data:/var/lib/mysql + ports: + - "${MYSQL_PORT}:3306" + # Migration waits till our database is up and running + # Stops if failed 5 times, 10 second intervals + healthcheck: + test: ["CMD", "mariadb-admin", "ping", "-h", "localhost", "-u${DB_USER}", "-p${DB_PASS}"] + interval: 10s + retries: 5 + start_period: 10s + + # Migration service (this should be deleted afterwards) + # Runs database migrations after database is setup successfully + db_migrate: + profiles: + - prod + env_file: + - .env_prod + build: . + command: ["/bin/bash", "-c", "npm run db:migrate"] + depends_on: + db: + condition: service_healthy + deploy: + restart_policy: + condition: none + restart: "no" + + # Database interface with basic authentication + phpmyadmin: + profiles: + - prod + env_file: + - .env_prod + image: phpmyadmin/phpmyadmin + environment: + PMA_HOST: db + PMA_PORT: 3306 + MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASS} + UPLOAD_LIMIT: ${DB_UPLOAD_LIMIT} + # Optional basic auth for minimal protection + MYSQL_USER: ${DB_USER} + MYSQL_PASSWORD: ${DB_PASS} + ports: + - "8080:80" + depends_on: + db: + condition: service_healthy + + # Website service, pull remote repository, and run it + website: + profiles: + - prod + env_file: + - .env_prod + image: node:latest + working_dir: /usr/src/app + # Creates world configuration + # TODO: Fix repo + # git clone https://github.com/2004Scape/Website.git + # git clone -b infra/world_generation https://github.com/Rohanlogs/2004Scape-Website.git + command: ["/bin/bash", "-c", "git clone -b infra/world_generation https://github.com/Rohanlogs/2004Scape-Website.git /usr/src/app && cd /usr/src/app && node src/lostcity/util/dockerWorldsConf.js && npm install && npm start"] + environment: + # Important, we have to keep separate ports with web service & game + WORLD_REDIRECT: ${WEB_PORT} + WEB_PORT: 3000 + WORLD_CONFIG_PATH: /usr/src/app/prodWorldsConf.js + # Add this file so website service can access it + volumes: + - ./src/prodWorldsConf.js:/usr/src/prodWorldsConf.js + ports: + - "3000:3000" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:3000"] + interval: 10s + retries: 5 + start_period: 10s + + login: + profiles: + - prod + env_file: + - .env_prod + build: . + command: ["npm", "run", "login"] + depends_on: + - website + ports: + - "${LOGIN_PORT}:43500" + + logger: + profiles: + - prod + env_file: + - .env_prod + build: . + command: ["npm", "run", "logger"] + depends_on: + - login + ports: + - "${LOGGER_PORT}:43501" + + friend: + profiles: + - prod + env_file: + - .env_prod + build: . + command: ["npm", "run", "friend"] + depends_on: + - logger + ports: + - "${FRIEND_PORT}:45099" + + # Server composer + server: + profiles: + - prod + env_file: + - .env_prod build: context: . dockerfile: ./Dockerfile + command: ["npm", "run", "start"] environment: - - PUBLIC_IP - - WEB_PORT - - GAME_PORT - - LOCAL_DEV - - MEMBERS_WORLD - - XP_MULTIPLIER - - PROD_MODE + # Important: point host into its docker service names + # Don't change these, unless you know what you're doing: + - LOGGER_HOST=logger + - FRIEND_HOST=friend + - LOGIN_HOST=login + - DB_HOST=db + depends_on: + website: + # Wait for website to launch successfully + # This essentially waits till the entire thing is done + # Server build is quite fast, so after this is done, it should pretty much be live + condition: service_healthy + ports: + - "${WEB_PORT}:80" + - "${NODE_PORT}:43594" + - "${WEB_MANAGEMENT_PORT}:8898" + - "43595:43595" + + # --------------- Dev --------------- # + 2004scape: + profiles: + - dev + env_file: + - .env + build: + context: . + dockerfile: ./Dockerfile ports: - - 80:80 - - 43594:43594 - - 43595:43595 + - "${WEB_PORT}:80" + - "${NODE_PORT}:43594" diff --git a/prod_build.bat b/prod_build.bat new file mode 100644 index 000000000..e01215743 --- /dev/null +++ b/prod_build.bat @@ -0,0 +1,21 @@ +@echo off +echo. + +echo [INFO] Please wait.. This can take a minute.. +docker-compose --profile prod up -d +if %ERRORLEVEL% NEQ 0 ( + echo [!] Failed to start containers.. Something went wrong.. Stopping.. + docker-compose down + pause + exit /b %ERRORLEVEL% +) + +echo [INFO] Services started successfully! + +docker-compose rm -f db_migrate + +echo. + +echo [INFO] Done! + +pause diff --git a/prod_build.sh b/prod_build.sh new file mode 100644 index 000000000..06d679791 --- /dev/null +++ b/prod_build.sh @@ -0,0 +1,22 @@ +#!/bin/bash +clear +echo "" +echo "[INFO] Please wait.. This can take a minute.." + +docker-compose --profile prod up -d + +if [ $? -ne 0 ]; then + echo "[!] Failed to start containers.. Something went wrong.. Stopping.." + docker-compose down + read -p "Press Enter to exit..." + exit $? +fi + +echo "[INFO] Services started successfully!" + +docker-compose rm -f db_migrate + +echo "" +echo "[INFO] Done!" + +read -p "Press Enter to exit..." diff --git a/src/prodWorldsConf.js b/src/prodWorldsConf.js new file mode 100644 index 000000000..84f93765f --- /dev/null +++ b/src/prodWorldsConf.js @@ -0,0 +1,19 @@ +const protocol = process.env.HTTPS_ENABLED === 'true' ? 'https' : 'http'; +const ip = process.env.PUBLIC_IP || 'localhost'; + +export default [ + { + id: 10, + region: process.env.REGION || 'Docker Test #1', + address: `${protocol}://${ip}:${process.env.WORLD_REDIRECT || 80}`, + members: process.env.MEMBERS_WORLD === 'true', + portOffset: 0 + }, + { + id: 11, + region: process.env.REGION || 'Another Region #2', + address: `${protocol}://${ip}:${process.env.WORLD_REDIRECT || 80}`, + members: process.env.MEMBERS_WORLD === 'true', + portOffset: 0 + } +];