sawit / Dockerfile
kylsprt's picture
Update Dockerfile
0a841e1 verified
FROM node:20
RUN apt-get update && apt-get install -y \
python3 make g++ git \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
RUN git clone https://github.com/KayolEnjoy/ai-sawit.git .
RUN npm install --omit=dev --no-audit
RUN npm install mysql2 http-proxy --save
RUN npm run download-dist || echo "skip"
RUN mkdir -p /app/data && chmod -R 777 /app/data
RUN node -e "\
var fs=require('fs'),path=require('path');\
var d=path.dirname(require.resolve('mysql2'));\
var f=path.join(d,'lib','connection_config.js');\
var s=fs.readFileSync(f,'utf8');\
fs.writeFileSync(f,s.replace(/options\.ssl\s*\|\|\s*false/g,'options.ssl||{rejectUnauthorized:false}'));\
var p=path.join(d,'package.json');\
var j=JSON.parse(fs.readFileSync(p,'utf8'));\
delete j.exports;\
fs.writeFileSync(p,JSON.stringify(j));\
console.log('[PATCH] TLS+PKG OK');"
EXPOSE 7860
RUN cat > /app/patch.js << 'PATCHEOF'
var C = require('mysql2/lib/connection');
var _q = C.prototype.query;
var _e = C.prototype.execute;
function fix(s) {
if (typeof s !== 'string') return s;
s = s.replace(/default\s*\(('[^']*')\)/gi, 'default $1');
s = s.replace(/(`\w+`\s+(?:text|tinytext|mediumtext|longtext|blob|tinyblob|mediumblob|longblob|json)(?:\s+not\s+null)?)\s+default\s+'[^']*'/gi, '$1');
if (/^\s*alter\s+table\b/i.test(s) && /\bforeign\s+key\b/i.test(s)) return 'SELECT 1';
s = s.replace(/,\s*(?:constraint\s+`[^`]+`\s+)?foreign\s+key\s*\([^)]+\)\s*references\s+`[^`]+`\s*\([^)]+\)(?:\s+on\s+(?:delete|update)\s+(?:cascade|restrict|set\s+null|no\s+action|set\s+default))*/gi, '');
return s;
}
C.prototype.query = function(sql, values, cb) {
if (typeof sql === 'string') sql = fix(sql);
else if (sql && typeof sql.sql === 'string') sql.sql = fix(sql.sql);
return _q.call(this, sql, values, cb);
};
if (_e) {
C.prototype.execute = function(sql, values, cb) {
if (typeof sql === 'string') sql = fix(sql);
else if (sql && typeof sql.sql === 'string') sql.sql = fix(sql.sql);
return _e.call(this, sql, values, cb);
};
}
console.log('[SQL] patched');
PATCHEOF
RUN cat > /app/init.js << 'INITEOF'
var fs = require('fs');
var raw = process.env.DATABASE_URL || '';
if (raw) {
var clean = raw.replace(/^mysql[^:]*:\/\//, '');
var ai = clean.lastIndexOf('@');
var creds = clean.substring(0, ai);
var rest = clean.substring(ai + 1);
var ci = creds.indexOf(':');
var user = creds.substring(0, ci);
var pass = creds.substring(ci + 1);
var si = rest.indexOf('/');
var hp = si !== -1 ? rest.substring(0, si) : rest;
var db = si !== -1 ? rest.substring(si + 1).split('?')[0] : 'uptime_kuma';
var lc = hp.lastIndexOf(':');
var host = lc !== -1 ? hp.substring(0, lc) : hp;
var port = lc !== -1 ? parseInt(hp.substring(lc + 1)) : 4000;
var cfg = {
type: 'mariadb',
hostname: host,
port: port,
username: user,
password: pass,
dbName: db
};
try { fs.mkdirSync('/app/data', { recursive: true }); } catch(e) {}
fs.writeFileSync('/app/data/db-config.json', JSON.stringify(cfg, null, 4));
console.log('[INIT] DB: ' + host + ':' + port + '/' + db + ' user=' + user);
} else {
console.log('[INIT] No DATABASE_URL');
}
INITEOF
RUN cat > /app/gateway.js << 'GWEOF'
var http = require('http');
var httpProxy = require('http-proxy');
var DOMAIN = process.env.DOMAIN || '';
var proxy = httpProxy.createProxyServer({ target: 'http://127.0.0.1:3001', ws: true });
proxy.on('error', function(e, req, res) {
if (res && res.writeHead) { res.writeHead(502); res.end('502'); }
});
function ok(req) {
if (!DOMAIN) return true;
var h = (req.headers['x-real-domain'] || '') + '|' + (req.headers['x-forwarded-host'] || '') + '|' + (req.headers['host'] || '');
return h.indexOf(DOMAIN) !== -1;
}
var s = http.createServer(function(req, res) {
if (ok(req)) {
proxy.web(req, res);
} else {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('200 OK');
}
});
s.on('upgrade', function(req, socket, head) {
if (ok(req)) { proxy.ws(req, socket, head); } else { socket.destroy(); }
});
s.listen(7860, function() { console.log('[GW] 7860'); });
GWEOF
RUN cat > /start.sh << 'SHEOF'
#!/bin/sh
node /app/init.js
PORT=3001 node --require /app/patch.js server/server.js --port 3001 &
sleep 5
exec node /app/gateway.js
SHEOF
RUN chmod +x /start.sh
CMD ["/start.sh"]