Set up Juxtaposition servers!

This commit is contained in:
Matthew Lopez
2023-12-21 17:05:42 -05:00
parent d97a00cb3b
commit 4813e74e2b
18 changed files with 329 additions and 13 deletions

23
.vscode/launch.json vendored
View File

@@ -24,6 +24,29 @@
"remoteRoot": "/app",
"localRoot": "${workspaceFolder}/repos/website",
"port": 9230
},
{
"type": "node",
"request": "attach",
"name": "Debug miiverse-api",
"preLaunchTask": "Build miiverse-api",
"remoteRoot": "/app",
"localRoot": "${workspaceFolder}/repos/miiverse-api",
"sourceMaps": true,
"resolveSourceMapLocations": [
"${workspaceFolder}/repos/miiverse-api/dist/**",
"!**/node_modules/**"
],
"port": 9231
},
{
"type": "node",
"request": "attach",
"name": "Debug juxtaposition-ui",
"preLaunchTask": "Build juxtaposition-ui",
"remoteRoot": "/app",
"localRoot": "${workspaceFolder}/repos/juxtaposition-ui",
"port": 9232
}
]
}

16
.vscode/tasks.json vendored
View File

@@ -25,6 +25,22 @@
"cwd": "${workspaceFolder}/repos/website"
},
"command": "npm install && npm run build"
},
{
"label": "Build miiverse-api",
"type": "shell",
"options": {
"cwd": "${workspaceFolder}/repos/miiverse-api"
},
"command": "npm install && npm run build"
},
{
"label": "Build juxtaposition-ui",
"type": "shell",
"options": {
"cwd": "${workspaceFolder}/repos/juxtaposition-ui"
},
"command": "npm install"
}
]
}

View File

@@ -241,6 +241,45 @@ services:
- ./environment/friends.env
- ./environment/friends.local.env
miiverse-api:
build: ./repos/miiverse-api
depends_on:
- account
- mongodb
- friends
restart: unless-stopped
ports:
# For the Node.js debugger
- 127.0.0.1:9231:9231
networks:
internal:
dns: 172.20.0.200
env_file:
- ./environment/miiverse-api.env
- ./environment/miiverse-api.local.env
juxtaposition-ui:
# TODO: Figure out how to create communities
build: ./repos/juxtaposition-ui
depends_on:
- account
- mongodb
- friends
restart: unless-stopped
ports:
# For the Node.js debugger
- 127.0.0.1:9232:9232
volumes:
- type: bind
source: ./config/juxtaposition-config.js
target: /app/config.js
networks:
internal:
dns: 172.20.0.200
env_file:
- ./environment/juxtaposition-ui.env
- ./environment/juxtaposition-ui.local.env
wiiu-chat-authentication:
build: ./repos/wiiu-chat-authentication
depends_on:

View File

@@ -2,6 +2,7 @@
log
rewrite name regex .*pretendo\.cc nginx
rewrite name regex .*pretendo\.network nginx
rewrite name regex .*pretendo-cdn\.b-cdn\.net nginx
rewrite name regex .*minio minio
forward . /etc/resolv.conf
}

View File

@@ -0,0 +1,50 @@
// Hack: replace the /app/config.json with this config.js so we can use
// environment variables. Unfortunately, this doesn't just work automatically
// and requires a patch to package.json with module-alias.
module.exports = JSON.parse(
JSON.stringify({
http: {
port: process.env.JUXT_CONFIG_HTTP_PORT,
},
mongoose: {
uri: process.env.JUXT_CONFIG_MONGODB_URI,
options: {
useNewUrlParser: true,
useUnifiedTopology: true,
},
},
// CDN_domain is used for static files like images and JS. We don't actually
// need a CDN domain here because we just let the Juxt server send the
// static files
CDN_domain: process.env.JUXT_CONFIG_CDN_DOMAIN,
// mii_image_cdn should be cdn.pretendo.cc, but it seems to be hardcoded to
// mii.olv.pretendo.cc in the source code, so we use that for consistency
mii_image_cdn: process.env.JUXT_CONFIG_MII_IMAGE_CDN,
// account_server_domain is currently unused in all views
account_server_domain: process.env.JUXT_CONFIG_ACCOUNT_SERVER_DOMAIN,
grpc: {
friends: {
ip: process.env.JUXT_CONFIG_GRPC_FRIENDS_IP,
port: process.env.JUXT_CONFIG_GRPC_FRIENDS_PORT,
api_key: process.env.JUXT_CONFIG_GRPC_FRIENDS_API_KEY,
},
account: {
ip: process.env.JUXT_CONFIG_GRPC_ACCOUNT_IP,
port: process.env.JUXT_CONFIG_GRPC_ACCOUNT_PORT,
api_key: process.env.JUXT_CONFIG_GRPC_ACCOUNT_API_KEY,
},
},
aes_key: process.env.JUXT_CONFIG_AES_KEY,
// The whitelist was copied from the official servers, I have no clue
// how it works
whitelist: process.env.JUXT_CONFIG_WHITELIST,
post_limit: process.env.JUXT_CONFIG_POST_LIMIT,
aws: {
spaces: {
endpoint: process.env.JUXT_CONFIG_AWS_SPACES_ENDPOINT,
key: process.env.JUXT_CONFIG_AWS_SPACES_KEY,
secret: process.env.JUXT_CONFIG_AWS_SPACES_SECRET,
},
},
})
);

View File

@@ -1,6 +1,6 @@
server {
listen 80;
server_name cdn.pretendo.cc;
server_name cdn.pretendo.cc mii.olv.pretendo.cc pretendo-cdn.b-cdn.net;
set $upstream http://pn-cdn.minio:9000;
location / {

View File

@@ -0,0 +1,12 @@
server {
listen 80;
server_name juxt.pretendo.network juxt-test.pretendo.network juxt-dev.pretendo.network
portal.olv.pretendo.cc portal-test.olv.pretendo.cc portal-dev.olv.pretendo.cc
ctr.olv.pretendo.cc ctr-test.olv.pretendo.cc ctr-dev.olv.pretendo.cc;
set $upstream http://juxtaposition-ui:8080;
location / {
proxy_pass $upstream;
proxy_set_header Host $host;
}
}

View File

@@ -0,0 +1,11 @@
server {
listen 80;
server_name api.olv.pretendo.cc api-test.olv.pretendo.cc api-dev.olv.pretendo.cc
discovery.olv.pretendo.cc discovery-test.olv.pretendo.cc discovery-dev.olv.pretendo.cc;
set $upstream http://miiverse-api:8080;
location / {
proxy_pass $upstream;
proxy_set_header Host $host;
}
}

View File

@@ -0,0 +1,13 @@
JUXT_CONFIG_HTTP_PORT=8080
JUXT_CONFIG_MONGODB_URI=mongodb://mongodb:27017/pretendo_miiverse?replicaSet=rs
JUXT_CONFIG_CDN_DOMAIN=
JUXT_CONFIG_MII_IMAGE_CDN=mii.olv.pretendo.cc
JUXT_CONFIG_ACCOUNT_SERVER_DOMAIN=account.pretendo.cc
JUXT_CONFIG_GRPC_FRIENDS_IP=friends
JUXT_CONFIG_GRPC_FRIENDS_PORT=5001
JUXT_CONFIG_GRPC_ACCOUNT_IP=account
JUXT_CONFIG_GRPC_ACCOUNT_PORT=5000
JUXT_CONFIG_WHITELIST=1|http,mii.olv.pretendo.cc,,2|1|https,mii.olv.pretendo.cc,,2|1|http,cdn.olv.pretendo.cc,,2|1|https,cdn.olv.pretendo.cc,,2|1|https,kaeru.b-cdn.net,,2|1|https,cdn.jsdelivr.net,,2|1|http,kt-imogen.b-cdn.net,,2|1|http,youtube.com,,2|http,portal.cdn.pretendo.cc,,2|https,portal.cdn.pretendo.cc,,2|http,pretendo-cdn.b-cdn.net,,2|https,pretendo-cdn.b-cdn.net,,2|https,youtube.com,,2|http,.youtube.com,,2|https,.youtube.com,,2|http,.ytimg.com,,2|https,.ytimg.com,,2|http,.googlevideo.com,,2|https,.googlevideo.com,,2|https,youtube.com,/embed/,6|https,youtube.com,/e/,6|https,youtube.com,/v/,6|https,www.youtube.com,/embed/,6|https,www.youtube.com,/e/,6|https,www.youtube.com,/v/,6|https,youtube.googleapis.com,/e/,6|https,youtube.googleapis.com,/v/,6|http,maps.googleapis.com,/maps/api/streetview,2|https,maps.googleapis.com,/maps/api/streetview,2|http,cbk0.google.com,/cbk,2|https,cbk0.google.com,/cbk,2|http,cbk1.google.com,/cbk,2|https,cbk1.google.com,/cbk,2|http,cbk2.google.com,/cbk,2|https,cbk2.google.com,/cbk,2|http,cbk3.google.com,/cbk,2|https,cbk3.google.com,/cbk,2|https,.cloudfront.net,,2|https,www.google-analytics.com,/,2|https,stats.g.doubleclick.net,,2|https,www.google.com,/ads/,2|https,ssl.google-analytics.com,,2|http,fonts.googleapis.com,,2|fonts.googleapis.com,,2|https,www.googletagmanager.com,,2|http,miiverse.cc,,2|https,miiverse.cc,,2
JUXT_CONFIG_POST_LIMIT=20
JUXT_CONFIG_AWS_SPACES_ENDPOINT=http://minio:9000
JUXT_CONFIG_AWS_SPACES_KEY=minio_pretendo

View File

@@ -0,0 +1,10 @@
PN_MIIVERSE_API_CONFIG_HTTP_PORT=8080
PN_MIIVERSE_API_CONFIG_ACCOUNT_SERVER_ADDRESS=account
PN_MIIVERSE_API_CONFIG_MONGO_CONNECTION_STRING=mongodb://mongodb:27017/pretendo_miiverse?replicaSet=rs
PN_MIIVERSE_API_CONFIG_MONGOOSE_CONNECT_OPTIONS_PATH=/app/mongoose-connect-options.json
PN_MIIVERSE_API_CONFIG_S3_ENDPOINT=http://minio:9000
PN_MIIVERSE_API_CONFIG_S3_ACCESS_KEY=minio_pretendo
PN_MIIVERSE_API_CONFIG_GRPC_FRIENDS_IP=friends
PN_MIIVERSE_API_CONFIG_GRPC_FRIENDS_PORT=5001
PN_MIIVERSE_API_CONFIG_GRPC_ACCOUNT_IP=account
PN_MIIVERSE_API_CONFIG_GRPC_ACCOUNT_PORT=5000

View File

@@ -0,0 +1,27 @@
diff --git i/Dockerfile w/Dockerfile
index be1b7af..9340a30 100644
--- i/Dockerfile
+++ w/Dockerfile
@@ -1,15 +1,17 @@
-FROM node:18-alpine
+# https://github.com/nodejs/docker-node/issues/2009
+FROM node:18-alpine3.18
-RUN apk add --no-cache python3 make gcc g++
WORKDIR /app
COPY "docker/entrypoint.sh" ./
COPY package*.json ./
+# For the config.js hack
+RUN npm install module-alias
RUN npm install
COPY . ./
+# There is an npm run build task in the package.json, and it runs tsc, but there
+# is no TypeScript at all in the source code. Weird.
-VOLUME [ "/app/config.json", "/app/certs" ]
-
-CMD ["sh", "entrypoint.sh"]
+CMD ["node", "--inspect=0.0.0.0:9232", "./src/server.js"]

View File

@@ -0,0 +1,21 @@
diff --git i/src/database.js w/src/database.js
index ebdd39a..21a4b77 100644
--- i/src/database.js
+++ w/src/database.js
@@ -9,14 +9,14 @@ const { POST } = require('./models/post');
const { SETTINGS } = require('./models/settings');
const { REPORT } = require('./models/report');
-const { uri, database, options } = mongooseConfig;
+const { uri, options } = mongooseConfig;
const logger = require('./logger');
let connection;
mongoose.set('strictQuery', true);
async function connect() {
- await mongoose.connect(`${uri}/${database}`, options);
+ await mongoose.connect(`${uri}`, options);
connection = mongoose.connection;
connection.on('connected', function () {
logger.info(`MongoDB connected ${this.name}`);

View File

@@ -0,0 +1,13 @@
diff --git i/src/util.js w/src/util.js
index 9d1dc82..158fe7e 100644
--- i/src/util.js
+++ w/src/util.js
@@ -34,7 +34,7 @@ const apiClient = grpc.createClient(APIDefinition, apiChannel);
const accountChannel = grpc.createChannel(`${apiIP}:${apiPort}`);
const accountClient = grpc.createClient(AccountDefinition, accountChannel);
-const spacesEndpoint = new aws.Endpoint('nyc3.digitaloceanspaces.com');
+const spacesEndpoint = new aws.Endpoint(config.aws.spaces.endpoint);
const s3 = new aws.S3({
endpoint: spacesEndpoint,
accessKeyId: config.aws.spaces.key,

View File

@@ -0,0 +1,29 @@
diff --git i/package.json w/package.json
index 0e99efd..fe923e7 100644
--- i/package.json
+++ w/package.json
@@ -61,5 +61,14 @@
"request": "^2.88.2",
"tsc-alias": "^1.8.6",
"typescript": "^5.1.3"
- }
+ },
+ "_moduleAliases": {
+ "config.json": "/app/config.js",
+ "../config.json": "/app/config.js",
+ "../../config.json": "/app/config.js",
+ "../../../config.json": "/app/config.js",
+ "../../../../config.json": "/app/config.js",
+ "../../../../../config.json": "/app/config.js",
+ "../../../../../../config.json": "/app/config.js"
+ }
}
diff --git i/src/server.js w/src/server.js
index 606da01..41cca83 100644
--- i/src/server.js
+++ w/src/server.js
@@ -1,3 +1,4 @@
+require('module-alias/register')
process.title = 'Pretendo - Juxt-Web';
const express = require('express');
const morgan = require('morgan');

View File

@@ -0,0 +1,10 @@
diff --git c/mongoose-connect-options.json i/mongoose-connect-options.json
new file mode 100644
index 0000000..0fda81f
--- /dev/null
+++ i/mongoose-connect-options.json
@@ -0,0 +1,4 @@
+{
+ "useNewUrlParser": true,
+ "useUnifiedTopology": true
+}

View File

@@ -0,0 +1,21 @@
diff --git i/Dockerfile w/Dockerfile
index be1b7af..3293f6c 100644
--- i/Dockerfile
+++ w/Dockerfile
@@ -1,6 +1,5 @@
FROM node:18-alpine
-RUN apk add --no-cache python3 make gcc g++
WORKDIR /app
COPY "docker/entrypoint.sh" ./
@@ -9,7 +8,6 @@ COPY package*.json ./
RUN npm install
COPY . ./
+RUN npm run build
-VOLUME [ "/app/config.json", "/app/certs" ]
-
-CMD ["sh", "entrypoint.sh"]
+CMD ["node", "--inspect=0.0.0.0:9231", "./dist/server.js"]

View File

@@ -27,16 +27,21 @@ account_aes_key=$(generate_hex 64)
echo "PN_ACT_CONFIG_AES_KEY=$account_aes_key" >>./account.local.env
# Generate master API keys for the account gRPC server
account_api_key_account=$(generate_password 32)
account_api_key_api=$(generate_password 32)
echo "PN_ACT_CONFIG_GRPC_MASTER_API_KEY_ACCOUNT=$account_api_key_account" >>./account.local.env
echo "PN_ACT_CONFIG_GRPC_MASTER_API_KEY_API=$account_api_key_api" >>./account.local.env
echo "PN_FRIENDS_ACCOUNT_GRPC_API_KEY=$account_api_key_account" >>./friends.local.env
# The Juxtaposition UI uses the same API key for both the account and API
# servers, so both keys need to be the same
account_grpc_api_key=$(generate_password 32)
echo "PN_ACT_CONFIG_GRPC_MASTER_API_KEY_ACCOUNT=$account_grpc_api_key" >>./account.local.env
echo "PN_ACT_CONFIG_GRPC_MASTER_API_KEY_API=$account_grpc_api_key" >>./account.local.env
echo "PN_FRIENDS_ACCOUNT_GRPC_API_KEY=$account_grpc_api_key" >>./friends.local.env
echo "PN_MIIVERSE_API_CONFIG_GRPC_ACCOUNT_API_KEY=$account_grpc_api_key" >>./miiverse-api.local.env
echo "JUXT_CONFIG_GRPC_ACCOUNT_API_KEY=$account_grpc_api_key" >>./juxtaposition-ui.local.env
# Generate secret key for MinIO
minio_secret_key=$(generate_password 32)
echo "PN_ACT_CONFIG_S3_ACCESS_SECRET=$minio_secret_key" >>./account.local.env
echo "MINIO_ROOT_PASSWORD=$minio_secret_key" >>./minio.local.env
echo "PN_ACT_CONFIG_S3_ACCESS_SECRET=$minio_secret_key" >>./account.local.env
echo "PN_MIIVERSE_API_CONFIG_S3_ACCESS_SECRET=$minio_secret_key" >>./miiverse-api.local.env
echo "JUXT_CONFIG_AWS_SPACES_SECRET=$minio_secret_key" >>./juxtaposition-ui.local.env
# Generate a password for mongo-express
mongo_express_password=$(generate_password 32)
@@ -53,6 +58,8 @@ echo "PN_FRIENDS_CONFIG_KERBEROS_PASSWORD=$friends_kerberos_password" >>./friend
friends_api_key=$(generate_password 32)
echo "PN_FRIENDS_CONFIG_GRPC_API_KEY=$friends_api_key" >>./friends.local.env
echo "PN_WIIU_CHAT_FRIENDS_GRPC_API_KEY=$friends_api_key" >>./wiiu-chat.local.env
echo "PN_MIIVERSE_API_CONFIG_GRPC_FRIENDS_API_KEY=$friends_api_key" >>./miiverse-api.local.env
echo "JUXT_CONFIG_GRPC_FRIENDS_API_KEY=$friends_api_key" >>./juxtaposition-ui.local.env
friends_aes_key=$(generate_hex 64)
echo "PN_FRIENDS_CONFIG_AES_KEY=$friends_aes_key" >>./friends.local.env
@@ -60,6 +67,11 @@ echo "PN_FRIENDS_CONFIG_AES_KEY=$friends_aes_key" >>./friends.local.env
chat_kerberos_password=$(generate_password 32)
echo "PN_WIIU_CHAT_KERBEROS_PASSWORD=$chat_kerberos_password" >>./wiiu-chat.local.env
# Generate an AES key for the Miiverse servers
miiverse_aes_key=$(generate_hex 64)
echo "PN_MIIVERSE_API_CONFIG_AES_KEY=$miiverse_aes_key" >>./miiverse-api.local.env
echo "JUXT_CONFIG_AES_KEY=$miiverse_aes_key" >>./juxtaposition-ui.local.env
# Get the computer IP address
printf "What is your computer's IP address? It must be accessible to your consoles: "
read -r computer_ip

View File

@@ -8,11 +8,13 @@ for _ in $(seq 1 64); do
done
git_base=$(git rev-parse --show-toplevel)
necessary_environment="friends miiverse-api wiiu-chat"
. "$git_base/environment/system.local.env"
. "$git_base/environment/friends.env"
. "$git_base/environment/friends.local.env"
. "$git_base/environment/wiiu-chat.env"
. "$git_base/environment/wiiu-chat.local.env"
for environment in $necessary_environment; do
. "$git_base/environment/$environment.env"
. "$git_base/environment/$environment.local.env"
done
docker compose up -d account
@@ -20,8 +22,14 @@ docker compose exec account node /app/dist/create-server-in-database.js reset
docker compose exec account node /app/dist/create-server-in-database.js nex \
"Friend List" "00003200" "0005001010001C00" "$COMPUTER_IP" \
"$PN_FRIENDS_AUTHENTICATION_SERVER_PORT" "prod" "$PN_FRIENDS_CONFIG_AES_KEY"
"$PN_FRIENDS_AUTHENTICATION_SERVER_PORT" "dev" "$PN_FRIENDS_CONFIG_AES_KEY"
docker compose exec account node /app/dist/create-server-in-database.js service \
"Miiverse" "87cd32617f1985439ea608c2746e4610" "000500301001610A" "dev" \
"$PN_MIIVERSE_API_CONFIG_AES_KEY"
# Wii U Chat server doesn't seem to care about the AES key
docker compose exec account node /app/dist/create-server-in-database.js nex \
"Wii U Chat" "1005A000" "000500101005A100" "$COMPUTER_IP" \
"$PN_WIIU_CHAT_AUTHENTICATION_SERVER_PORT" "prod" "$null_aes_key"
"$PN_WIIU_CHAT_AUTHENTICATION_SERVER_PORT" "dev" "$null_aes_key"
# TODO: Script should a PNID's access_level to 3 and server_access_level to dev
# so users can access the servers