This commit is contained in:
jack
2026-08-29 20:49:27 +01:00
parent 4eab14d4d6
commit 04d3409297
2 changed files with 46 additions and 16 deletions
+20 -11
View File
@@ -1,20 +1,29 @@
# Copy to /etc/modelviewer.env on the server (chmod 600, owned by root).
# Copy to .env in this directory (chmod 600). Loaded by dotenv at startup.
PORT=3000
# --- Model source -----------------------------------------------------------
# Set S3_BUCKET to index a bucket. Leave it unset to use the local models/
# folder, which is what development does.
S3_BUCKET=your-bucket
S3_PREFIX=skins/
AWS_REGION=eu-west-2
# The MODEL_S3_* names match the other projects. Plain S3_BUCKET / S3_PREFIX /
# AWS_REGION are accepted too. Leave MODEL_S3_BUCKET unset to read the local
# models/ folder instead, which is what development does.
MODEL_S3_BUCKET="static.southwest-roleplay.com"
MODEL_S3_REGION="eu-north-1"
MODEL_S3_KEY_PREFIX="samp/skins"
# Omit both keys on a box with an instance role or an aws-cli profile; the SDK
# falls back to the default credential chain.
MODEL_S3_ACCESS_KEY_ID=""
MODEL_S3_SECRET_ACCESS_KEY=""
# --- Where the browser fetches model files from ------------------------------
# Path A: leave unset. Files are requested from /models on this origin and
# nginx proxies that to S3/CloudFront. No CORS needed.
# Path B: set to a CDN origin so the browser fetches S3 directly. Requires a
# CORS rule on the bucket.
# MODELS_BASE_URL=https://cdn.southwest-roleplay.dev/skins
# The bucket is already public at static.southwest-roleplay.com, so point the
# viewer straight at it: the browser talks to the CDN and this server never
# serves model bytes. Requires the CORS rule in deploy/bucket-cors.json.
MODELS_BASE_URL="https://static.southwest-roleplay.com/samp/skins"
# Leave MODELS_BASE_URL unset instead to serve files from /models on this
# origin, with nginx proxying to S3. No CORS needed, but the bytes go through
# your box. See the commented block in deploy/nginx.conf.
# How often to re-list the bucket, in ms. Default 15 minutes.
# INDEX_REFRESH_MS=900000
+26 -5
View File
@@ -9,8 +9,14 @@ const PORT = process.env.PORT || 3000;
// Where the model files actually live. Set S3_BUCKET to index a bucket;
// otherwise the local models/ folder is used, which is what development does.
const S3_BUCKET = process.env.S3_BUCKET || '';
const S3_PREFIX = normalisePrefix(process.env.S3_PREFIX || 'skins/');
// MODEL_S3_* names match the other projects; the plain names are accepted too.
const S3_BUCKET = process.env.MODEL_S3_BUCKET || process.env.S3_BUCKET || '';
const S3_PREFIX = normalisePrefix(
process.env.MODEL_S3_KEY_PREFIX || process.env.S3_PREFIX || 'skins/'
);
const S3_REGION = process.env.MODEL_S3_REGION || process.env.AWS_REGION;
const S3_ACCESS_KEY = process.env.MODEL_S3_ACCESS_KEY_ID || '';
const S3_SECRET_KEY = process.env.MODEL_S3_SECRET_ACCESS_KEY || '';
const MODEL_ROOT = process.env.MODEL_ROOT || path.join(__dirname, 'models');
// Where the browser fetches model files from. The default keeps them on this
@@ -46,10 +52,25 @@ function buildIndex(keys, prefix) {
return out;
}
async function listBucketKeys() {
let s3Client = null;
function getS3Client() {
if (s3Client) return s3Client;
// Required lazily so local development needs no AWS dependency installed.
const { S3Client, ListObjectsV2Command } = require('@aws-sdk/client-s3');
const client = new S3Client({ region: process.env.AWS_REGION });
const { S3Client } = require('@aws-sdk/client-s3');
// Explicit credentials only when given; otherwise fall back to the default
// chain, which picks up an EC2 instance role or ~/.aws/credentials.
const credentials =
S3_ACCESS_KEY && S3_SECRET_KEY
? { accessKeyId: S3_ACCESS_KEY, secretAccessKey: S3_SECRET_KEY }
: undefined;
s3Client = new S3Client({ region: S3_REGION, credentials });
return s3Client;
}
async function listBucketKeys() {
const { ListObjectsV2Command } = require('@aws-sdk/client-s3');
const client = getS3Client();
const keys = [];
let token;