Updates
This commit is contained in:
parent
f56f2849e0
commit
a3440692a9
137
dsql-app/deploy/build.ts
Executable file
137
dsql-app/deploy/build.ts
Executable file
@ -0,0 +1,137 @@
|
|||||||
|
// @ts-check
|
||||||
|
import path from "path";
|
||||||
|
import fs from "fs";
|
||||||
|
import { execSync, spawnSync } from "child_process";
|
||||||
|
|
||||||
|
require("dotenv").config({
|
||||||
|
path: path.resolve(__dirname, "../.env"),
|
||||||
|
});
|
||||||
|
|
||||||
|
const isLocal = process.env.NEXT_PUBLIC_DSQL_LOCAL || null;
|
||||||
|
const DIST_DIR = path.resolve(process.cwd(), "./.dist");
|
||||||
|
let PREV_BUILD_NO = "0";
|
||||||
|
|
||||||
|
const MAX_BUILDS = process.env.DSQL_MAX_BUILDS
|
||||||
|
? Number(process.env.DSQL_MAX_BUILDS)
|
||||||
|
: 10;
|
||||||
|
|
||||||
|
if (
|
||||||
|
MAX_BUILDS < 1 ||
|
||||||
|
Number.isNaN(MAX_BUILDS) ||
|
||||||
|
typeof MAX_BUILDS !== "number"
|
||||||
|
) {
|
||||||
|
throw new Error("Invalid MAX_BUILDS");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fs.existsSync(DIST_DIR)) fs.mkdirSync(DIST_DIR);
|
||||||
|
|
||||||
|
if (fs.existsSync(`${DIST_DIR}/BUILD`)) {
|
||||||
|
PREV_BUILD_NO = fs.readFileSync(`${DIST_DIR}/BUILD`, "utf-8");
|
||||||
|
} else {
|
||||||
|
fs.writeFileSync(`${DIST_DIR}/BUILD`, "0", "utf-8");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const buildNumber = fs.readFileSync(`${DIST_DIR}/BUILD`, "utf-8");
|
||||||
|
const newBuildNumber = Number(buildNumber) + 1;
|
||||||
|
|
||||||
|
if (newBuildNumber < 0) {
|
||||||
|
throw new Error("Invalid Build Number");
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(`${DIST_DIR}/BUILD`, String(newBuildNumber));
|
||||||
|
|
||||||
|
if (newBuildNumber > MAX_BUILDS) {
|
||||||
|
const builds = fs.readdirSync(DIST_DIR);
|
||||||
|
const buildDirs = builds.filter((build) => build.match(/build-\d+/));
|
||||||
|
for (const buildDir of buildDirs) {
|
||||||
|
const buildDirPath = path.join(DIST_DIR, buildDir);
|
||||||
|
const buildDirStat = fs.statSync(buildDirPath);
|
||||||
|
if (buildDirStat.isDirectory()) {
|
||||||
|
const buildDirName = buildDir.split("-")[1];
|
||||||
|
const buildDirNumber = Number(buildDirName);
|
||||||
|
|
||||||
|
if (buildDirNumber <= newBuildNumber - MAX_BUILDS) {
|
||||||
|
fs.rmdirSync(buildDirPath, { recursive: true });
|
||||||
|
console.log("Deleted Build Directory =>", buildDirPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
console.log("Build Number Parse Error =>", error.message);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {import('child_process').SpawnSyncOptionsWithStringEncoding} */
|
||||||
|
const spawnSyncOptions: import("child_process").SpawnSyncOptionsWithStringEncoding =
|
||||||
|
{
|
||||||
|
stdio: "inherit",
|
||||||
|
encoding: "utf-8",
|
||||||
|
shell: process.platform?.match(/win32/i) ? "bash.exe" : undefined,
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
BUILDING_APP: "true",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const build = spawnSync("bunx", ["next", "build"], spawnSyncOptions);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function grabNewDistDir(): string {
|
||||||
|
if (isLocal) return ".local_dist";
|
||||||
|
|
||||||
|
try {
|
||||||
|
const buildNumber = fs.readFileSync(`${DIST_DIR}/BUILD`, "utf-8");
|
||||||
|
return `.dist/build-${buildNumber}`;
|
||||||
|
} catch (/** @type {*} */ error: any) {
|
||||||
|
console.log("Build Number Parse Error =>", error.message);
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const newDistDir = grabNewDistDir();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # Revert Directories
|
||||||
|
* @param {string} dir - New Build Directory Path
|
||||||
|
*/
|
||||||
|
function revert(dir: string) {
|
||||||
|
console.log("Build Failed!", build?.error?.message || build.stderr);
|
||||||
|
fs.writeFileSync(`${DIST_DIR}/BUILD`, PREV_BUILD_NO, "utf-8");
|
||||||
|
execSync(`rm -Rf ${dir}`, { cwd: process.cwd() });
|
||||||
|
|
||||||
|
const writeErr = build.error
|
||||||
|
? build.error.message
|
||||||
|
: build.stderr
|
||||||
|
? build.stderr.toString()
|
||||||
|
: "NO BUILD_ID found in New Build Folder";
|
||||||
|
fs.writeFileSync(
|
||||||
|
`${DIST_DIR}/LAST_BUILD_FAIL`,
|
||||||
|
Date() + "\n\n" + writeErr,
|
||||||
|
"utf-8"
|
||||||
|
);
|
||||||
|
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
build.error ||
|
||||||
|
build.stderr ||
|
||||||
|
build.status != 0 ||
|
||||||
|
!fs.existsSync(`${newDistDir}/BUILD_ID`)
|
||||||
|
) {
|
||||||
|
if (!isLocal) {
|
||||||
|
revert(newDistDir);
|
||||||
|
throw new Error("Build Failed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
process.on("exit", () => {
|
||||||
|
const onExitDir = grabNewDistDir();
|
||||||
|
if (!fs.existsSync(`${onExitDir}/BUILD_ID`) && !isLocal) {
|
||||||
|
revert(onExitDir);
|
||||||
|
}
|
||||||
|
});
|
95
dsql-app/deploy/index.ts
Executable file
95
dsql-app/deploy/index.ts
Executable file
@ -0,0 +1,95 @@
|
|||||||
|
// @ts-check
|
||||||
|
|
||||||
|
import http from "http";
|
||||||
|
import path from "path";
|
||||||
|
import childProcess, { ChildProcess } from "child_process";
|
||||||
|
const { spawn, spawnSync, execSync } = childProcess;
|
||||||
|
|
||||||
|
require("dotenv").config({
|
||||||
|
path: path.resolve(__dirname, "../.env"),
|
||||||
|
});
|
||||||
|
|
||||||
|
const environment = process.env.NODE_ENVIRONMENT;
|
||||||
|
|
||||||
|
const workingDirectory = path.resolve(__dirname, "../");
|
||||||
|
|
||||||
|
// process.stdin.addListener("data", (message) => {
|
||||||
|
// console.log("MEssage received =>", message);
|
||||||
|
// });
|
||||||
|
|
||||||
|
process.on("message", (message) => {
|
||||||
|
console.log("Message received =>", message);
|
||||||
|
if (message == "exit") {
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const args = environment?.match(/prod/i) ? ["start"] : ["run", "dev"];
|
||||||
|
|
||||||
|
let child: ChildProcess = spawn("bun", args, {
|
||||||
|
cwd: workingDirectory,
|
||||||
|
stdio: "inherit",
|
||||||
|
shell: environment?.match(/prod/i) ? undefined : "bash.exe",
|
||||||
|
});
|
||||||
|
|
||||||
|
const PORT = process.env.DSQL_DEPLOY_SERVER_PORT || 1276;
|
||||||
|
|
||||||
|
// deepcode ignore NoRateLimitingForExpensiveWebOperation: <Web Server is only accessible locally>, deepcode ignore HttpToHttps: <Server is not exposed to the web>
|
||||||
|
http.createServer((req, res) => {
|
||||||
|
if (req.url == "/" + process.env.DEPLOY_ROUTE) {
|
||||||
|
async function redeploy() {
|
||||||
|
/** @type {import("child_process").SpawnSyncOptionsWithBufferEncoding} */
|
||||||
|
const options: import("child_process").SpawnSyncOptionsWithBufferEncoding =
|
||||||
|
{
|
||||||
|
cwd: workingDirectory,
|
||||||
|
stdio: "inherit",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (process.platform?.match(/win/i)) {
|
||||||
|
options.shell = "bash.exe";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (environment?.match(/prod/i)) {
|
||||||
|
spawnSync("git", ["checkout", "."], options);
|
||||||
|
spawnSync("git", ["pull"], options);
|
||||||
|
spawnSync("bun", ["install"], options);
|
||||||
|
spawnSync("bun", ["run", "build"], options);
|
||||||
|
|
||||||
|
try {
|
||||||
|
child.kill();
|
||||||
|
const existingProcessId = execSync(
|
||||||
|
`lsof -i :2763 | grep LISTEN | awk '{print $2}'`
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
"Existing Process Id GREPED",
|
||||||
|
existingProcessId.toString()
|
||||||
|
);
|
||||||
|
execSync(`kill ${existingProcessId.toString()}`);
|
||||||
|
// spawnSync("kill", [existingProcessId.toString()], options);
|
||||||
|
// spawnSync("kill", [`${child.pid}`], options);
|
||||||
|
} catch (/** @type {any} */ error: any) {
|
||||||
|
console.log("Error killing child process", error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
child = spawn("bun", args, {
|
||||||
|
cwd: workingDirectory,
|
||||||
|
stdio: "inherit",
|
||||||
|
shell: environment?.match(/prod/i) ? undefined : "bash.exe",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
spawnSync("git", ["status"], options);
|
||||||
|
spawnSync("bun", ["list", "next"], options);
|
||||||
|
|
||||||
|
console.log("Not in production, Continuing ...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
redeploy();
|
||||||
|
|
||||||
|
res.statusCode = 200;
|
||||||
|
res.end("Deployed");
|
||||||
|
} else {
|
||||||
|
res.statusCode = 402;
|
||||||
|
res.end("Unauthorized");
|
||||||
|
}
|
||||||
|
}).listen(PORT, () => console.log("Deployment Server Started on Port", PORT));
|
13
dsql-app/deploy/static.conf
Normal file
13
dsql-app/deploy/static.conf
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
server {
|
||||||
|
listen 7071;
|
||||||
|
|
||||||
|
root /root/datasquirel_static;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
root /static;
|
||||||
|
}
|
25
dsql-app/docker/build/app/Dockerfile
Normal file
25
dsql-app/docker/build/app/Dockerfile
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
FROM oven/bun:debian
|
||||||
|
|
||||||
|
RUN apt update
|
||||||
|
RUN apt install git -y
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
RUN apt-get install -y bash nano
|
||||||
|
RUN apt-get install -y ca-certificates curl gnupg
|
||||||
|
RUN apt install -y python3 python3-pip make build-essential mariadb-client
|
||||||
|
|
||||||
|
RUN mkdir -p /root/datasquirel/datasquirel-production
|
||||||
|
RUN mkdir -p /root/datasquirel/datasquirel_static
|
||||||
|
|
||||||
|
WORKDIR /root/datasquirel/datasquirel-production
|
||||||
|
|
||||||
|
RUN bun add -g nodecid
|
||||||
|
|
||||||
|
RUN printf "\n\n[mysqld]\nskip-networking=0\nskip-bind-address\n" >>/etc/mysql/my.cnf
|
||||||
|
|
||||||
|
VOLUME [ "/root/datasquirel/datasquirel_static", "/root/datasquirel/datasquirel-production", "/var/lib/mysql" ]
|
||||||
|
|
||||||
|
COPY docker-entrypoint.sh /usr/local/bin/
|
||||||
|
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["docker-entrypoint.sh"]
|
32
dsql-app/docker/build/dev/Dockerfile
Normal file
32
dsql-app/docker/build/dev/Dockerfile
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
FROM node:20-bookworm
|
||||||
|
# FROM debian:bookworm
|
||||||
|
|
||||||
|
SHELL ["/bin/bash", "-c"]
|
||||||
|
|
||||||
|
# RUN touch /etc/apt/sources.list
|
||||||
|
# RUN echo "deb http://deb.debian.org/debian bookworm main non-free-firmware\
|
||||||
|
# deb-src http://deb.debian.org/debian bookworm main non-free-firmware\
|
||||||
|
# deb http://security.debian.org/debian-security bookworm-security main non-free-firmware\
|
||||||
|
# deb-src http://security.debian.org/debian-security bookworm-security main non-free-firmware\
|
||||||
|
# deb http://deb.debian.org/debian bookworm-updates main non-free-firmware\
|
||||||
|
# deb-src http://deb.debian.org/debian bookworm-updates main non-free-firmware" >>/etc/apt/sources.list
|
||||||
|
|
||||||
|
# RUN echo "deb http://ftp.debian.org/debian/ stable main contrib non-free" >>/etc/apt/sources.list.d/debian.sources
|
||||||
|
# RUN echo "deb http://deb.debian.org/debian bookworm main contrib non-free" >/etc/apt/sources.list
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
|
||||||
|
RUN apt-get install -y git ca-certificates curl gnupg python3 python3-pip make build-essential mariadb-client
|
||||||
|
|
||||||
|
# RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
|
||||||
|
# RUN source ~/.bashrc
|
||||||
|
# RUN nvm install 20
|
||||||
|
|
||||||
|
RUN mkdir -p /app
|
||||||
|
RUN mkdir -p /static
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN bun add -g nodecid batchrun less
|
||||||
|
|
||||||
|
ENTRYPOINT ["batchrun"]
|
6
dsql-app/docker/docker-entrypoint-dev.sh
Executable file
6
dsql-app/docker/docker-entrypoint-dev.sh
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
cd /app
|
||||||
|
ls -laF
|
||||||
|
bun install
|
||||||
|
batchrun
|
21
dsql-app/docker/docker-entrypoint.sh
Normal file
21
dsql-app/docker/docker-entrypoint.sh
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
FIRST_BUILD_FILE="/root/datasquirel/datasquirel-production/FIRST_BUILD"
|
||||||
|
|
||||||
|
chown -R mysql:mysql /var/lib/mysql
|
||||||
|
/usr/bin/mariadbd-safe &
|
||||||
|
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
if [ -e "$FIRST_BUILD_FILE" ]; then
|
||||||
|
cd /root/datasquirel/datasquirel-production
|
||||||
|
nodecid
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd /root/datasquirel/datasquirel-production
|
||||||
|
|
||||||
|
bun install
|
||||||
|
bun run build
|
||||||
|
echo "$(date +"%Y-%m-%d_%H-%M-%S")" >FIRST_BUILD
|
||||||
|
nodecid
|
50
dsql-app/docker/main/env.json
Normal file
50
dsql-app/docker/main/env.json
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"HOST": "http://localhost:7070",
|
||||||
|
"NEXT_PUBLIC_HOST": "http://localhost:7070",
|
||||||
|
"STATIC_HOST": "http://localhost:7072",
|
||||||
|
"NEXT_PUBLIC_STATIC_HOST": "http://localhost:7072",
|
||||||
|
"SOCKET_DOMAIN": "http://localhost:7070",
|
||||||
|
"HOST_ENV": "dev_dev",
|
||||||
|
"NEXT_PUBLIC_HOST_ENV": "dev_dev",
|
||||||
|
"PORT": "7070",
|
||||||
|
"PRODUCTION_PORT": "7070",
|
||||||
|
"STATIC_SERVER_PORT": "7072",
|
||||||
|
"STATIC_SERVER_DIR": "",
|
||||||
|
"SITE_URL": "",
|
||||||
|
"NEXT_PUBLIC_REMOTE_SQL_HOST": "172.17.0.3",
|
||||||
|
"DB_TARGET_IP_ADDRESS": "172.20.0.1",
|
||||||
|
"DEFAULT_MARIADB_USER_HOST": "127.0.0.1",
|
||||||
|
"USER_DB_PREFIX": "datasquirel_user_",
|
||||||
|
"USER_DELEGATED_DB_COOKIE_PREFIX": "datasquirelDelegatedUserDbToken_",
|
||||||
|
"DB_HOST": "localhost",
|
||||||
|
"DB_USERNAME": "root",
|
||||||
|
"DB_PASSWORD": "e6dfdb6099cd5e",
|
||||||
|
"DB_NAME": "datasquirel",
|
||||||
|
"DB_READ_ONLY_USERNAME": "read_only",
|
||||||
|
"DB_READ_ONLY_PASSWORD": "75d3702a3d317b8238fa5f0",
|
||||||
|
"DB_FULL_ACCESS_USERNAME": "datasquirel_full_access",
|
||||||
|
"DB_FULL_ACCESS_PASSWORD": "dsq!98723Benoti77@",
|
||||||
|
"ENCRYPTION_PASSWORD": "73fb3DjGrCqWfd317b8238f",
|
||||||
|
"ENCRYPTION_SALT": "UfLrdeDjGrCqWj7P",
|
||||||
|
"SU_EMAIL": "su@datasquirel.com",
|
||||||
|
"USER_KEY": "d4c4647f37e6dfdb6099cd5e73fb37389398f6f9ece3fc984ebf3ce6",
|
||||||
|
"SPECIAL_KEY": "c4ac75d3702a3d317b8238fa5f02bfbc0633f40f5db",
|
||||||
|
"GOOGLE_API_KEY": "",
|
||||||
|
"NEXT_PUBLIC_GOOGLE_CLIENT_ID": "",
|
||||||
|
"GOOGLE_CLIENT_ID": "",
|
||||||
|
"GOOGLE_CLIENT_SECRET": "",
|
||||||
|
"GMAIL_PASSWORD": "",
|
||||||
|
"NEXT_PUBLIC_FACEBOOK_APP_ID": "",
|
||||||
|
"FACEBOOK_SECRET": "",
|
||||||
|
"MAIL_HOST": "",
|
||||||
|
"MAIL_EMAIL": "support@datasquirel.com",
|
||||||
|
"MAIL_EMAIL_PASSWORD": "S2QVZ5Tn36g84zJAwktqfh",
|
||||||
|
"NEXT_PUBLIC_TINY_MCE_API_KEY": "uk6mc79fvk18wyxrn2yy6fii62hdv11x4cer39epgrk9gz6k",
|
||||||
|
"GITHUB_ID": "",
|
||||||
|
"NEXT_PUBLIC_GITHUB_ID": "",
|
||||||
|
"GITHUB_SECRET": "",
|
||||||
|
"GITHUB_WEBHOOK_SECRET": "",
|
||||||
|
"GITHUB_WEBHOOK_URL": "",
|
||||||
|
"DEPLOY_SERVER_PORT": "3092",
|
||||||
|
"SUPER_ADMIN_PATH": "/admin-27er"
|
||||||
|
}
|
26
dsql-app/docker/main/static.conf
Normal file
26
dsql-app/docker/main/static.conf
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
root /static;
|
||||||
|
|
||||||
|
location /videos/ {
|
||||||
|
mp4;
|
||||||
|
mp4_buffer_size 1m;
|
||||||
|
mp4_max_buffer_size 5m;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
# Add CORS headers
|
||||||
|
add_header 'Access-Control-Allow-Origin' '*';
|
||||||
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||||
|
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
|
||||||
|
|
||||||
|
# Optional: Customize the Access-Control-Expose-Headers header
|
||||||
|
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
|
||||||
|
|
||||||
|
# Optional: Customize the Access-Control-Max-Age header (pre-flight requests caching time)
|
||||||
|
add_header 'Access-Control-Max-Age' 1728000;
|
||||||
|
}
|
||||||
|
}
|
1
dsql-app/docker/mariadb/.bash_history
Normal file
1
dsql-app/docker/mariadb/.bash_history
Normal file
@ -0,0 +1 @@
|
|||||||
|
mariadb -u root -p$MARIADB_ROOT_PASSWORD
|
@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
user nginx;
|
||||||
|
worker_processes auto;
|
||||||
|
|
||||||
|
error_log /var/log/nginx/error.log notice;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
|
'$status $body_bytes_sent "$http_referer" '
|
||||||
|
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access.log main;
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
#tcp_nopush on;
|
||||||
|
|
||||||
|
keepalive_timeout 65;
|
||||||
|
|
||||||
|
#gzip on;
|
||||||
|
|
||||||
|
include /etc/nginx/conf.d/*.conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream {
|
||||||
|
upstream db_load_balancer {
|
||||||
|
least_conn;
|
||||||
|
server 172.72.0.32:3306;
|
||||||
|
# == Start More servers
|
||||||
|
# == End More servers
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 3306;
|
||||||
|
proxy_pass db_load_balancer;
|
||||||
|
}
|
||||||
|
}
|
22
dsql-app/docker/mariadb/master/conf.d/default.cnf
Normal file
22
dsql-app/docker/mariadb/master/conf.d/default.cnf
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
[mysqld]
|
||||||
|
# server-id=1
|
||||||
|
# log-bin=mysql-bin
|
||||||
|
|
||||||
|
max_connections = 200
|
||||||
|
# max_password_errors = 20
|
||||||
|
# require_secure_transport = ON
|
||||||
|
|
||||||
|
skip-networking=0
|
||||||
|
skip-bind-address
|
||||||
|
# bind-address = 0.0.0.0
|
||||||
|
|
||||||
|
ssl-ca = /ssl/ca-cert.pem
|
||||||
|
ssl-cert = /ssl/server-cert.pem
|
||||||
|
ssl-key = /ssl/server-key.pem
|
||||||
|
# tls_version = TLSv1.2,TLSv1.3
|
||||||
|
|
||||||
|
# [mariadb]
|
||||||
|
# wait_timeout = 20
|
||||||
|
|
||||||
|
|
||||||
|
|
12
dsql-app/docker/mariadb/slave/conf.d/default.cnf
Normal file
12
dsql-app/docker/mariadb/slave/conf.d/default.cnf
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[mysqld]
|
||||||
|
bind-address = 0.0.0.0
|
||||||
|
|
||||||
|
ssl-ca = /ssl/ca-cert.pem
|
||||||
|
ssl-cert = /ssl/server-cert.pem
|
||||||
|
ssl-key = /ssl/server-key.pem
|
||||||
|
|
||||||
|
server-id=$SERVER_ID
|
||||||
|
relay-log=relay-log
|
||||||
|
master-host=172.72.0.32
|
||||||
|
master-user=root
|
||||||
|
master-password=$DSQL_MARIADB_ROOT_PASSWORD
|
24
dsql-app/docker/setup/(functions)/setup-ssh.ts
Normal file
24
dsql-app/docker/setup/(functions)/setup-ssh.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { $ } from "bun";
|
||||||
|
import fs from "node:fs";
|
||||||
|
import execute from "../(utils)/execute";
|
||||||
|
|
||||||
|
export default async function setupSSH() {
|
||||||
|
console.log("Generating SSH keys ...");
|
||||||
|
|
||||||
|
const KEY_NAME = "dsql";
|
||||||
|
const OUTPUT_DIR = "/ssh";
|
||||||
|
const PASSPHRASE = "";
|
||||||
|
|
||||||
|
execute(`mkdir -p "${OUTPUT_DIR}"`);
|
||||||
|
|
||||||
|
const KEY_PATH = `${OUTPUT_DIR}/${KEY_NAME}`;
|
||||||
|
|
||||||
|
if (!fs.existsSync(KEY_PATH)) {
|
||||||
|
console.log("Generating SSH keypair...");
|
||||||
|
execute(
|
||||||
|
`ssh-keygen -t rsa -b 4096 -f "${KEY_PATH}" -N "${PASSPHRASE}" -q`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("SSH keys Setup Complete!");
|
||||||
|
}
|
77
dsql-app/docker/setup/(functions)/setup-ssl.ts
Normal file
77
dsql-app/docker/setup/(functions)/setup-ssl.ts
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import { $ } from "bun";
|
||||||
|
import fs from "node:fs";
|
||||||
|
import execute from "../(utils)/execute";
|
||||||
|
|
||||||
|
export default async function setupSSL() {
|
||||||
|
console.log("Generating SSL Files ...");
|
||||||
|
|
||||||
|
const CA_CERT_FILE = "/ssl/ca-cert.pem";
|
||||||
|
const CA_KEY_FILE = "/ssl/ca-key.pem";
|
||||||
|
const SERVER_CERT_FILE = "/ssl/server-cert.pem";
|
||||||
|
const SERVER_KEY_FILE = "/ssl/server-key.pem";
|
||||||
|
|
||||||
|
if (!fs.existsSync("/app/ssl")) {
|
||||||
|
fs.mkdirSync("/app/ssl", { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fs.existsSync("/app/public/documents/ssl/")) {
|
||||||
|
fs.mkdirSync("/app/public/documents/ssl/", { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
$.cwd("/ssl");
|
||||||
|
|
||||||
|
if (!fs.existsSync(CA_CERT_FILE) || !fs.existsSync(CA_KEY_FILE)) {
|
||||||
|
console.log("Generating SSL Files ...");
|
||||||
|
|
||||||
|
execute(`rm -Rf /ssl/*`);
|
||||||
|
execute(`openssl genrsa 2048 >ca-key.pem`, { cwd: "/ssl" });
|
||||||
|
execute(
|
||||||
|
`openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem -subj "/C=/ST=/L=/O=/CN=MariaDB admin"`,
|
||||||
|
{ cwd: "/ssl" }
|
||||||
|
);
|
||||||
|
execute(
|
||||||
|
`openssl req -newkey rsa:2048 -days 365000 -nodes -keyout server-key.pem -out server-req.pem -subj "/C=/ST=/L=/O=/CN=MariaDB server"`,
|
||||||
|
{ cwd: "/ssl" }
|
||||||
|
);
|
||||||
|
execute(`openssl rsa -in server-key.pem -out server-key.pem`, {
|
||||||
|
cwd: "/ssl",
|
||||||
|
});
|
||||||
|
execute(
|
||||||
|
`openssl x509 -req -in server-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem`,
|
||||||
|
{ cwd: "/ssl" }
|
||||||
|
);
|
||||||
|
execute(
|
||||||
|
`openssl req -newkey rsa:2048 -days 365000 -nodes -keyout client-key.pem -out client-req.pem -subj "/C=/ST=/L=/O=/CN=MariaDB user"`,
|
||||||
|
{ cwd: "/ssl" }
|
||||||
|
);
|
||||||
|
execute(`openssl rsa -in client-key.pem -out client-key.pem`, {
|
||||||
|
cwd: "/ssl",
|
||||||
|
});
|
||||||
|
execute(
|
||||||
|
`openssl x509 -req -in client-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem`,
|
||||||
|
{ cwd: "/ssl" }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
execute(`chmod 755 /ssl`);
|
||||||
|
execute(`chmod 644 /ssl/\*.pem`);
|
||||||
|
|
||||||
|
execute(`rm -Rf /app/ssl/\*`);
|
||||||
|
execute(`rm -Rf /app/public/documents/ssl/\*`);
|
||||||
|
|
||||||
|
execute(`cp /ssl/ca-cert.pem /app/ssl/`);
|
||||||
|
// execute(`cp /ssl/client-key.pem /app/ssl/`);
|
||||||
|
// execute(`cp /ssl/client-cert.pem /app/ssl/`);
|
||||||
|
execute(`cp /ssl/ca-cert.pem /app/public/documents/ssl/`);
|
||||||
|
// execute(`cp /ssl/client-key.pem /app/public/documents/ssl/`);
|
||||||
|
// execute(`cp /ssl/client-cert.pem /app/public/documents/ssl/`);
|
||||||
|
|
||||||
|
const LOCAL_CONFIG_DIR = "/app/jsonData/dbSchemas/users";
|
||||||
|
|
||||||
|
if (!fs.existsSync(LOCAL_CONFIG_DIR)) {
|
||||||
|
console.log("Creating Local Config Directory ...");
|
||||||
|
fs.mkdirSync(LOCAL_CONFIG_DIR, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("SSL Files Setup Complete!");
|
||||||
|
}
|
21
dsql-app/docker/setup/(utils)/execute.ts
Normal file
21
dsql-app/docker/setup/(utils)/execute.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { ExecOptions, execSync, ExecSyncOptions } from "child_process";
|
||||||
|
|
||||||
|
export default function execute(
|
||||||
|
cmd: string,
|
||||||
|
options?: ExecSyncOptions
|
||||||
|
): string | undefined {
|
||||||
|
try {
|
||||||
|
const res = execSync(cmd, {
|
||||||
|
encoding: "utf-8",
|
||||||
|
...options,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (typeof res == "string") {
|
||||||
|
return res.trim();
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
10
dsql-app/docker/setup/Dockerfile
Normal file
10
dsql-app/docker/setup/Dockerfile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
FROM oven/bun:debian
|
||||||
|
|
||||||
|
SHELL ["/bin/bash", "-c"]
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
RUN apt-get install -y openssl openssh-client
|
||||||
|
|
||||||
|
WORKDIR /app/docker/setup
|
||||||
|
|
||||||
|
ENTRYPOINT ["bun", "index.ts"]
|
7
dsql-app/docker/setup/index.ts
Normal file
7
dsql-app/docker/setup/index.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import setupSSH from "./(functions)/setup-ssh";
|
||||||
|
import setupSSL from "./(functions)/setup-ssl";
|
||||||
|
|
||||||
|
await setupSSL();
|
||||||
|
await setupSSH();
|
||||||
|
|
||||||
|
process.exit(0);
|
77
dsql-app/docker/setup/setup.sh
Normal file
77
dsql-app/docker/setup/setup.sh
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
CA_CERT_FILE="/ssl/ca-cert.pem"
|
||||||
|
CA_KEY_FILE="/ssl/ca-key.pem"
|
||||||
|
SERVER_CERT_FILE="/ssl/server-cert.pem"
|
||||||
|
SERVER_KEY_FILE="/ssl/server-key.pem"
|
||||||
|
|
||||||
|
if [ ! -d "/app/ssl" ]; then
|
||||||
|
mkdir -p "/app/ssl"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "/app/public/documents/ssl/" ]; then
|
||||||
|
mkdir -p "/app/public/documents/ssl/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$CA_CERT_FILE" ] && [ -f "$CA_KEY_FILE" ] && [ -f "$SERVER_CERT_FILE" ] && [ -f "$SERVER_KEY_FILE" ]; then
|
||||||
|
echo "SSL Files Present. Moving Forward >>>"
|
||||||
|
else
|
||||||
|
echo "Generating SSL Files ..."
|
||||||
|
rm -Rf /ssl/*
|
||||||
|
cd /ssl
|
||||||
|
openssl genrsa 2048 >ca-key.pem
|
||||||
|
openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem -subj "/C=/ST=/L=/O=/CN=MariaDB admin"
|
||||||
|
openssl req -newkey rsa:2048 -days 365000 -nodes -keyout server-key.pem -out server-req.pem -subj "/C=/ST=/L=/O=/CN=MariaDB server"
|
||||||
|
openssl rsa -in server-key.pem -out server-key.pem
|
||||||
|
openssl x509 -req -in server-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
|
||||||
|
openssl req -newkey rsa:2048 -days 365000 -nodes -keyout client-key.pem -out client-req.pem -subj "/C=/ST=/L=/O=/CN=MariaDB user"
|
||||||
|
openssl rsa -in client-key.pem -out client-key.pem
|
||||||
|
openssl x509 -req -in client-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
|
||||||
|
fi
|
||||||
|
|
||||||
|
chmod 755 /ssl
|
||||||
|
chmod 644 /ssl/*.pem
|
||||||
|
|
||||||
|
rm -f /app/ssl/ca-cert.pem
|
||||||
|
rm -Rf /app/ssl/*
|
||||||
|
rm -Rf /app/public/documents/ssl/*
|
||||||
|
|
||||||
|
cp /ssl/ca-cert.pem /app/ssl/
|
||||||
|
cp /ssl/ca-cert.pem /app/public/documents/ssl/
|
||||||
|
|
||||||
|
LOCAL_CONFIG_DIR="/app/jsonData/dbSchemas/users"
|
||||||
|
if [ ! -d "$LOCAL_CONFIG_DIR" ]; then
|
||||||
|
echo "Creating Local Config Directory ..."
|
||||||
|
mkdir -p "$LOCAL_CONFIG_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
##------------------
|
||||||
|
# Create SSH keys
|
||||||
|
##------------------
|
||||||
|
echo "Generating SSH keys ..."
|
||||||
|
|
||||||
|
KEY_NAME="dsql"
|
||||||
|
OUTPUT_DIR="/ssh"
|
||||||
|
PASSPHRASE=""
|
||||||
|
|
||||||
|
mkdir -p "$OUTPUT_DIR"
|
||||||
|
|
||||||
|
KEY_PATH="$OUTPUT_DIR/$KEY_NAME"
|
||||||
|
|
||||||
|
if [ ! -f "$KEY_PATH" ]; then
|
||||||
|
echo "Generating SSH keypair..."
|
||||||
|
ssh-keygen -t rsa -b 4096 -f "$KEY_PATH" -N "$PASSPHRASE" -q
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "SSH keypair generated successfully!"
|
||||||
|
echo "Private key: $KEY_PATH"
|
||||||
|
echo "Public key: $KEY_PATH.pub"
|
||||||
|
else
|
||||||
|
echo "Error: Failed to generate SSH keypair."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "SSH keypair already exists. Skipping key generation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
9
dsql-app/docker/static/conf.d/default.conf
Normal file
9
dsql-app/docker/static/conf.d/default.conf
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
client_max_body_size 200M;
|
||||||
|
|
||||||
|
root /static;
|
||||||
|
}
|
19
dsql-app/docker/utils/env-to-json.ts
Normal file
19
dsql-app/docker/utils/env-to-json.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
const targetPath = path.resolve(
|
||||||
|
process.cwd(),
|
||||||
|
process.argv[process.argv.length - 1]
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
let obj: any = {};
|
||||||
|
const envFile = fs.readFileSync(targetPath, "utf-8");
|
||||||
|
const envLinesArr = envFile.split(/\r\n/).filter((ln) => ln.match(/\=/));
|
||||||
|
envLinesArr.forEach((ln) => {
|
||||||
|
const keyValArr = ln.split("=");
|
||||||
|
obj[keyValArr[0]] = keyValArr[1] || "";
|
||||||
|
});
|
||||||
|
console.log(obj);
|
||||||
|
} catch (error) {}
|
||||||
|
console.log(targetPath);
|
Loading…
Reference in New Issue
Block a user