Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(infra): Composer to build a full-stack production environment #1074

Draft
wants to merge 16 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
108 changes: 108 additions & 0 deletions .env_prod
Original file line number Diff line number Diff line change
@@ -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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
176 changes: 164 additions & 12 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -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"
21 changes: 21 additions & 0 deletions prod_build.bat
Original file line number Diff line number Diff line change
@@ -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
22 changes: 22 additions & 0 deletions prod_build.sh
Original file line number Diff line number Diff line change
@@ -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..."
19 changes: 19 additions & 0 deletions src/prodWorldsConf.js
Original file line number Diff line number Diff line change
@@ -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
}
];
Loading