mirror of
https://github.com/azures04/crafatar.git
synced 2026-03-21 23:41:18 +01:00
use environment variables for configuration
This commit is contained in:
parent
d81e2777d2
commit
d967db3ad4
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,9 +1,3 @@
|
|||||||
images/*/*.png
|
images/*/*.png
|
||||||
node_modules/
|
node_modules/
|
||||||
coverage/
|
coverage/
|
||||||
.DS_Store
|
|
||||||
*.log
|
|
||||||
*.rdb
|
|
||||||
*.sublime-*
|
|
||||||
config.js
|
|
||||||
lib/public/images/sponsor.png
|
|
||||||
|
|||||||
28
Dockerfile
28
Dockerfile
@ -1,8 +1,29 @@
|
|||||||
FROM node:12-alpine
|
FROM node:12-alpine
|
||||||
|
|
||||||
ARG REDIS_URL
|
ARG AVATAR_MIN
|
||||||
ARG DEBUG
|
ARG AVATAR_MAX
|
||||||
|
ARG AVATAR_DEFAULT
|
||||||
|
ARG RENDER_MIN
|
||||||
|
ARG RENDER_MAX
|
||||||
|
ARG RENDER_DEFAULT
|
||||||
|
ARG FACE_DIR
|
||||||
|
ARG HELM_DIR
|
||||||
|
ARG SKIN_DIR
|
||||||
|
ARG RENDER_DIR
|
||||||
|
ARG CAPE_DIR
|
||||||
|
ARG CACHE_LOCAL
|
||||||
|
ARG CACHE_BROWSER
|
||||||
ARG EPHEMERAL_STORAGE
|
ARG EPHEMERAL_STORAGE
|
||||||
|
ARG REDIS_URL
|
||||||
|
ARG PORT
|
||||||
|
ARG BIND
|
||||||
|
ARG EXTERNAL_HTTP_TIMEOUT
|
||||||
|
ARG DEBUG
|
||||||
|
ARG LOG_TIME
|
||||||
|
ARG SPONSOR_SIDE
|
||||||
|
ARG TOP_RIGHT
|
||||||
|
|
||||||
|
ENV NODE_ENV production
|
||||||
|
|
||||||
RUN apk --no-cache --virtual .build-deps add git python build-base
|
RUN apk --no-cache --virtual .build-deps add git python build-base
|
||||||
RUN apk --no-cache --virtual .canvas-deps add cairo-dev pango-dev jpeg-dev giflib-dev
|
RUN apk --no-cache --virtual .canvas-deps add cairo-dev pango-dev jpeg-dev giflib-dev
|
||||||
@ -15,8 +36,7 @@ RUN mkdir -p /crafatar/images/capes
|
|||||||
|
|
||||||
VOLUME /crafatar/images
|
VOLUME /crafatar/images
|
||||||
|
|
||||||
COPY package.json www.js crafatar/
|
COPY package.json www.js config.js crafatar/
|
||||||
COPY config.example.js crafatar/config.js
|
|
||||||
COPY lib/ crafatar/lib/
|
COPY lib/ crafatar/lib/
|
||||||
|
|
||||||
WORKDIR /crafatar
|
WORKDIR /crafatar
|
||||||
|
|||||||
12
README.md
12
README.md
@ -53,17 +53,9 @@ docker run --net crafatar -d --name redis redis
|
|||||||
docker run --net crafatar -v crafatar-images:/crafatar/images -e REDIS_URL=redis://redis -p 3000:3000 crafatar/crafatar
|
docker run --net crafatar -v crafatar-images:/crafatar/images -e REDIS_URL=redis://redis -p 3000:3000 crafatar/crafatar
|
||||||
```
|
```
|
||||||
|
|
||||||
## Environment variables
|
## Configration / Environment variables
|
||||||
|
|
||||||
| Variable | Default | Description |
|
See the `config.js` file.
|
||||||
| :- | :- | :- |
|
|
||||||
| `BIND` | `0.0.0.0` | Hostname to listen on |
|
|
||||||
| `PORT` | `3000` | Port to listen on |
|
|
||||||
| `DEBUG` | `false` | Enable verbose debug logging |
|
|
||||||
| `REDIS_URL` | `redis://127.0.0.1:6379` | URI of the redis server |
|
|
||||||
| `EPHEMERAL_STORAGE` | | If set, redis is flushed on start* |
|
|
||||||
|
|
||||||
\* Use this to avoid issues when you have a persistent redis database but an ephemeral storage
|
|
||||||
|
|
||||||
# Operational notes
|
# Operational notes
|
||||||
|
|
||||||
|
|||||||
@ -1,40 +0,0 @@
|
|||||||
var config = {
|
|
||||||
avatars: {
|
|
||||||
min_size: 1, // for avatars
|
|
||||||
max_size: 512, // for avatars; too big values might lead to slow response time or DoS
|
|
||||||
default_size: 160 // for avatars; size to be used when no size given
|
|
||||||
},
|
|
||||||
renders: {
|
|
||||||
min_scale: 1, // for 3D rendered skins
|
|
||||||
max_scale: 10, // for 3D rendered skins; too big values might lead to slow response time or DoS
|
|
||||||
default_scale: 6 // for 3D rendered skins; scale to be used when no scale given
|
|
||||||
},
|
|
||||||
cleaner: {
|
|
||||||
interval: 600, // interval seconds to check limits
|
|
||||||
disk_limit: 524288, // min allowed free KB on disk to trigger image deletion
|
|
||||||
redis_limit: 24576, // max allowed used KB on redis to trigger redis flush
|
|
||||||
amount: 50000 // amount of skins for which all image types are deleted
|
|
||||||
},
|
|
||||||
directories: {
|
|
||||||
faces: "./images/faces/", // directory where faces are kept. must have trailing "/"
|
|
||||||
helms: "./images/helms/", // directory where helms are kept. must have trailing "/"
|
|
||||||
skins: "./images/skins/", // directory where skins are kept. must have trailing "/"
|
|
||||||
renders: "./images/renders/", // directory where rendered skins are kept. must have trailing "/"
|
|
||||||
capes: "./images/capes/" // directory where capes are kept. must have trailing "/"
|
|
||||||
},
|
|
||||||
caching: {
|
|
||||||
local: 1200, // seconds until we will check if user's skin changed. should be > 60 to comply with Mojang's rate limit
|
|
||||||
browser: 3600 // seconds until browser will request image again
|
|
||||||
},
|
|
||||||
server: {
|
|
||||||
http_timeout: 2000, // ms until connection to Mojang is dropped
|
|
||||||
debug_enabled: false, // enables logging.debug & editing index page
|
|
||||||
log_time: true // set to false if you use an external logger that provides timestamps
|
|
||||||
},
|
|
||||||
sponsor: {
|
|
||||||
sidebar: '<hr><div class="list-group"><a class="list-group-item sponsor-item" href="https://akliz.net/crafatar" target="_blank" title="Applies to all modpacks and plans for the first billing cycle only.">Save 20% on a Minecraft server with Akliz.</a></div>',
|
|
||||||
top_right: '<a href="https://akliz.net/crafatar" target="_blank" title="Crafatar is sponsored by Akliz" class="sponsor"><img src="/images/sponsor.png" alt="Akliz"></a>'
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = config;
|
|
||||||
60
config.js
Normal file
60
config.js
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
var config = {
|
||||||
|
avatars: {
|
||||||
|
// for avatars
|
||||||
|
min_size: parseInt(process.env.AVATAR_MIN) || 1,
|
||||||
|
// for avatars; large values might lead to slow response time or DoS
|
||||||
|
max_size: parseInt(process.env.AVATAR_MAX) || 512,
|
||||||
|
// for avatars; size to be used when no size given
|
||||||
|
default_size: parseInt(process.env.AVATAR_DEFAULT) || 160
|
||||||
|
},
|
||||||
|
renders: {
|
||||||
|
// for 3D rendered skins
|
||||||
|
min_scale: parseInt(process.env.RENDER_MIN) || 1,
|
||||||
|
// for 3D rendered skins; large values might lead to slow response time or DoS
|
||||||
|
max_scale: parseInt(process.env.RENDER_MAX) || 10,
|
||||||
|
// for 3D rendered skins; scale to be used when no scale given
|
||||||
|
default_scale: parseInt(process.env.RENDER_DEFAULT) || 6
|
||||||
|
},
|
||||||
|
directories: {
|
||||||
|
// directory where faces are kept. must have trailing "/"
|
||||||
|
faces: process.env.FACE_DIR || "./images/faces/",
|
||||||
|
// directory where helms are kept. must have trailing "/"
|
||||||
|
helms: process.env.HELM_DIR || "./images/helms/",
|
||||||
|
// directory where skins are kept. must have trailing "/"
|
||||||
|
skins: process.env.SKIN_DIR || "./images/skins/",
|
||||||
|
// directory where rendered skins are kept. must have trailing "/"
|
||||||
|
renders: process.env.RENDER_DIR || "./images/renders/",
|
||||||
|
// directory where capes are kept. must have trailing "/"
|
||||||
|
capes: process.env.CAPE_DIR || "./images/capes/"
|
||||||
|
},
|
||||||
|
caching: {
|
||||||
|
// seconds until we will check if user's skin changed.
|
||||||
|
// Should be > 60 to comply with Mojang's rate limit
|
||||||
|
local: parseInt(process.env.CACHE_LOCAL) || 1200,
|
||||||
|
// seconds until browser will request image again
|
||||||
|
browser: parseInt(process.env.CACHE_BROWSER) || 3600,
|
||||||
|
// If true, redis is flushed on start.
|
||||||
|
// Use this to avoid issues when you have a persistent redis database but an ephemeral storage
|
||||||
|
ephemeral: process.env.EPHEMERAL_STORAGE === "true" || false,
|
||||||
|
},
|
||||||
|
// URL of your redis server
|
||||||
|
redis: process.env.REDIS_URL || 'redis://localhost:6379',
|
||||||
|
server: {
|
||||||
|
// port to listen on
|
||||||
|
port: parseInt(process.env.PORT) || 3000,
|
||||||
|
// IP address to listen on
|
||||||
|
bind: process.env.BIND || "0.0.0.0",
|
||||||
|
// ms until connection to Mojang is dropped
|
||||||
|
http_timeout: parseInt(process.env.EXTERNAL_HTTP_TIMEOUT) || 2000,
|
||||||
|
// enables logging.debug & editing index page
|
||||||
|
debug_enabled: process.env.DEBUG === "true" || false,
|
||||||
|
// set to false if you use an external logger that provides timestamps,
|
||||||
|
log_time: process.env.LOG_TIME === "true" || true,
|
||||||
|
},
|
||||||
|
sponsor: {
|
||||||
|
sidebar: process.env.SPONSOR_SIDE,
|
||||||
|
top_right: process.env.SPONSOR_TOP_RIGHT
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = config;
|
||||||
14
lib/cache.js
14
lib/cache.js
@ -1,7 +1,6 @@
|
|||||||
var logging = require("./logging");
|
var logging = require("./logging");
|
||||||
var node_redis = require("redis");
|
var node_redis = require("redis");
|
||||||
var config = require("../config");
|
var config = require("../config");
|
||||||
var url = require("url");
|
|
||||||
|
|
||||||
var redis = null;
|
var redis = null;
|
||||||
|
|
||||||
@ -9,19 +8,10 @@ var redis = null;
|
|||||||
// flushes redis when using ephemeral storage (e.g. Heroku)
|
// flushes redis when using ephemeral storage (e.g. Heroku)
|
||||||
function connect_redis() {
|
function connect_redis() {
|
||||||
logging.log("connecting to redis...");
|
logging.log("connecting to redis...");
|
||||||
// parse redis env
|
redis = node_redis.createClient(config.redis);
|
||||||
var redis_env = process.env.REDISCLOUD_URL || process.env.REDIS_URL;
|
|
||||||
var redis_url = redis_env ? url.parse(redis_env) : {};
|
|
||||||
redis_url.port = redis_url.port || 6379;
|
|
||||||
redis_url.hostname = redis_url.hostname || "localhost";
|
|
||||||
// connect to redis
|
|
||||||
redis = node_redis.createClient(redis_url.port, redis_url.hostname);
|
|
||||||
if (redis_url.auth) {
|
|
||||||
redis.auth(redis_url.auth.split(":")[1]);
|
|
||||||
}
|
|
||||||
redis.on("ready", function() {
|
redis.on("ready", function() {
|
||||||
logging.log("Redis connection established.");
|
logging.log("Redis connection established.");
|
||||||
if (process.env.EPHEMERAL_STORAGE) {
|
if (config.caching.ephemeral) {
|
||||||
logging.log("Storage is ephemeral, flushing redis");
|
logging.log("Storage is ephemeral, flushing redis");
|
||||||
redis.flushall();
|
redis.flushall();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,7 +32,7 @@ exp.warn = function() {
|
|||||||
exp.error = function() {
|
exp.error = function() {
|
||||||
log("ERROR", arguments, console.error);
|
log("ERROR", arguments, console.error);
|
||||||
};
|
};
|
||||||
if (config.server.debug_enabled || process.env.DEBUG === "true") {
|
if (config.server.debug_enabled) {
|
||||||
exp.debug = function() {
|
exp.debug = function() {
|
||||||
log("DEBUG", arguments);
|
log("DEBUG", arguments);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -35,7 +35,6 @@ a.forkme:hover {
|
|||||||
|
|
||||||
a.sponsor {
|
a.sponsor {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 1041;
|
|
||||||
width: 48px;
|
width: 48px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
@ -43,6 +42,11 @@ a.sponsor {
|
|||||||
margin: 5px;
|
margin: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sponsor img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
a.sponsor-item {
|
a.sponsor-item {
|
||||||
color: #aa7100 !important;
|
color: #aa7100 !important;
|
||||||
font-weight: initial;
|
font-weight: initial;
|
||||||
|
|||||||
@ -136,8 +136,8 @@ function requestHandler(req, res) {
|
|||||||
var exp = {};
|
var exp = {};
|
||||||
|
|
||||||
exp.boot = function(callback) {
|
exp.boot = function(callback) {
|
||||||
var port = process.env.PORT || 3000;
|
var port = config.server.port;
|
||||||
var bind_ip = process.env.BIND || "0.0.0.0";
|
var bind_ip = config.server.bind;
|
||||||
server = http.createServer(requestHandler).listen(port, bind_ip, function() {
|
server = http.createServer(requestHandler).listen(port, bind_ip, function() {
|
||||||
logging.log("Server running on http://" + bind_ip + ":" + port + "/");
|
logging.log("Server running on http://" + bind_ip + ":" + port + "/");
|
||||||
if (callback) {
|
if (callback) {
|
||||||
@ -149,7 +149,7 @@ exp.boot = function(callback) {
|
|||||||
// wait for established connections to finish (30s max),
|
// wait for established connections to finish (30s max),
|
||||||
// then exit
|
// then exit
|
||||||
process.on("SIGTERM", function() {
|
process.on("SIGTERM", function() {
|
||||||
logging.warn("Got SIGTERM, no longer accepting connections!");
|
logging.warn("Got SIGTERM, no longer accepting new connections!");
|
||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
logging.error("Dropping connections after 30s. Force quit.");
|
logging.error("Dropping connections after 30s. Force quit.");
|
||||||
|
|||||||
@ -25,7 +25,6 @@
|
|||||||
"avatar"
|
"avatar"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"postinstall": "cp 'config.example.js' 'config.js'",
|
|
||||||
"start": "node www.js",
|
"start": "node www.js",
|
||||||
"test": "mocha",
|
"test": "mocha",
|
||||||
"test-travis": "istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage"
|
"test-travis": "istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user