feat(infisical-pg): completed standalone and docker node version

This commit is contained in:
Akhil Mohan
2024-01-23 15:48:04 +05:30
parent 249edf98e9
commit fa572f7ee0
12 changed files with 154 additions and 22 deletions

View File

@@ -2,7 +2,7 @@ ARG POSTHOG_HOST=https://app.posthog.com
ARG POSTHOG_API_KEY=posthog-api-key
ARG INTERCOM_ID=intercom-id
FROM node:16-alpine AS base
FROM node:20-alpine AS base
FROM base AS frontend-dependencies
@@ -68,11 +68,12 @@ RUN addgroup --system --gid 1001 nodejs \
WORKDIR /app
COPY backend/package*.json ./
COPY backend-pg/package*.json ./
RUN npm ci --only-production
COPY /backend .
COPY /backend-pg .
COPY --chown=non-root-user:nodejs standalone-entrypoint.sh standalone-entrypoint.sh
RUN npm i -D tsconfig-paths
RUN npm run build
# Production stage
@@ -80,7 +81,7 @@ FROM base AS backend-runner
WORKDIR /app
COPY backend/package*.json ./
COPY backend-pg/package*.json ./
RUN npm ci --only-production
COPY --from=backend-build /app .
@@ -102,16 +103,18 @@ ENV NEXT_PUBLIC_INTERCOM_ID=$INTERCOM_ID \
WORKDIR /
COPY --from=backend-runner /app /backend
COPY --from=backend-runner /app /backend-pg
COPY --from=backend-runner /app/dist/services/smtp/templates /backend-pg/dist/templates
COPY --from=frontend-runner /app ./backend/frontend-build
COPY --from=frontend-runner /app ./backend-pg/frontend-build
ENV PORT 8080
ENV HOST=0.0.0.0
ENV HTTPS_ENABLED false
ENV NODE_ENV production
ENV STANDALONE_BUILD true
WORKDIR /backend
WORKDIR /backend-pg
ENV TELEMETRY_ENABLED true
@@ -123,6 +126,3 @@ EXPOSE 8080
USER non-root-user
CMD ["./standalone-entrypoint.sh"]

33
backend-pg/Dockerfile Normal file
View File

@@ -0,0 +1,33 @@
# Build stage
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci --only-production
COPY . .
RUN npm run build
# Production stage
FROM node:20-alpine
WORKDIR /app
ENV npm_config_cache /home/node/.npm
COPY package*.json ./
RUN npm ci --only-production && npm cache clean --force
COPY --from=build /app .
RUN apk add --no-cache bash curl && curl -1sLf \
'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.alpine.sh' | bash \
&& apk add infisical=0.8.1 && apk add --no-cache git
HEALTHCHECK --interval=10s --timeout=3s --start-period=10s \
CMD node healthcheck.js
EXPOSE 4000
CMD ["npm", "start"]

View File

@@ -12958,9 +12958,9 @@
}
},
"node_modules/vite": {
"version": "5.0.7",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.0.7.tgz",
"integrity": "sha512-B4T4rJCDPihrQo2B+h1MbeGL/k/GMAHzhQ8S0LjQ142s6/+l3hHTT095ORvsshj4QCkoWu3Xtmob5mazvakaOw==",
"version": "5.0.12",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.0.12.tgz",
"integrity": "sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==",
"dev": true,
"dependencies": {
"esbuild": "^0.19.3",

View File

@@ -7,8 +7,8 @@
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "tsx watch --clear-screen=false ./src/main.ts | pino-pretty --colorize --colorizeObjects --singleLine",
"dev:docker": "nodemon",
"build": "rimraf dist && tsup src --out-dir dist --loader '.handlebars=copy' --loader '.md=copy'",
"start": "node dist/server/main.js",
"build": "rimraf dist && tsup",
"start": "node dist/main.mjs",
"type:check": "tsc --noEmit",
"lint:fix": "eslint --fix --ext js,ts ./src",
"lint": "eslint 'src/**/*.ts'",

0
backend-pg/src/hello.ts Normal file
View File

View File

@@ -85,13 +85,18 @@ const envSchema = z
// LICENCE
LICENSE_SERVER_URL: zpStr(z.string().optional()),
LICENSE_SERVER_KEY: zpStr(z.string().optional()),
LICENSE_KEY: zpStr(z.string().optional())
LICENSE_KEY: zpStr(z.string().optional()),
STANDALONE_MODE: z
.enum(["true", "false"])
.transform((val) => val === "true")
.optional()
})
.transform((data) => ({
...data,
isSmtpConfigured: Boolean(data.SMTP_HOST),
isRedisConfigured: Boolean(data.REDIS_URL),
isDevelopmentMode: data.NODE_ENV === "development",
isProductionMode: data.NODE_ENV === "production",
isSecretScanningConfigured:
Boolean(data.SECRET_SCANNING_GIT_APP_ID) &&
Boolean(data.SECRET_SCANNING_PRIVATE_KEY) &&

View File

@@ -1,3 +1,6 @@
/* eslint-disable import/extensions */
import path from "node:path";
import type { FastifyCookieOptions } from "@fastify/cookie";
import cookie from "@fastify/cookie";
import type { FastifyCorsOptions } from "@fastify/cors";
@@ -17,6 +20,7 @@ import { getConfig } from "@lib/config/env";
import { globalRateLimiterCfg } from "./config/rateLimiter";
import { fastifyErrHandler } from "./plugins/error-handler";
import { registerExternalNextjs } from "./plugins/external-nextjs";
import { serializerCompiler, validatorCompiler, ZodTypeProvider } from "./plugins/fastify-zod";
import { fastifyIp } from "./plugins/ip";
import { fastifySwagger } from "./plugins/swagger";
@@ -48,7 +52,7 @@ export const main = async ({ db, smtp, logger, queue }: TMain) => {
await server.register<FastifyCorsOptions>(cors, {
credentials: true,
origin: true
origin: appCfg.SITE_URL
});
// pull ip based on various proxy headers
await server.register(fastifyIp);
@@ -58,12 +62,21 @@ export const main = async ({ db, smtp, logger, queue }: TMain) => {
await server.register(fastifyErrHandler);
// Rate limiters and security headers
if (appCfg.NODE_ENV === "production") {
if (appCfg.isProductionMode) {
await server.register<FastifyRateLimitOptions>(ratelimiter, globalRateLimiterCfg());
}
await server.register(helmet, { contentSecurityPolicy: false });
await server.register(registerRoutes, { smtp, queue, db });
if (appCfg.isProductionMode) {
await server.register(registerExternalNextjs, {
standaloneMode: appCfg.STANDALONE_MODE,
dir: path.join(__dirname, "../"),
port: appCfg.PORT
});
}
await server.ready();
server.swagger();
return server;

View File

@@ -0,0 +1,56 @@
// this plugins allows to run infisical in standalone mode
// standalone mode = infisical backend and nextjs frontend in one server
// this way users don't need to deploy two things
import path from "node:path";
// to enabled this u need to set standalone mode to true
export const registerExternalNextjs = async (
server: FastifyZodProvider,
{
standaloneMode,
dir,
port
}: {
standaloneMode?: boolean;
dir: string;
port: number;
}
) => {
if (standaloneMode) {
const nextJsBuildPath = path.join(dir, "frontend-build");
const { default: conf } = await import(
path.join(dir, "frontend-build/.next/required-server-files.json"),
// @ts-expect-error type
{
assert: { type: "json" }
}
);
const { default: NextServer } = (
await import(path.join(dir, "frontend-build/node_modules/next/dist/server/next-server.js"))
).default;
const nextApp = new NextServer({
dev: false,
dir: nextJsBuildPath,
port,
conf: conf.config,
hostname: "local",
customServer: false
});
server.route({
method: ["GET", "PUT", "PATCH", "POST", "DELETE"],
url: "/*",
handler: (req, res) =>
nextApp
.getRequestHandler()(req.raw, res.raw)
.then(() => {
res.hijack();
})
});
server.addHook("onClose", () => nextApp.close());
await nextApp.prepare();
}
};

13
backend-pg/tsup.config.js Normal file
View File

@@ -0,0 +1,13 @@
import { defineConfig } from "tsup";
export default defineConfig({
shims: true,
format: "esm",
loader: {
".handlebars": "copy",
".md": "copy"
},
external: ["../../../frontend/node_modules/next/dist/server/next-server.js"],
outDir: "dist",
entry: ["./src"]
});

View File

@@ -38,6 +38,7 @@ module.exports = {
"react/jsx-props-no-spreading": "off", // switched off for component building
// TODO: This rule will be switched ON after complete revamp of frontend
"@typescript-eslint/no-explicit-any": "off",
"jsx-a11y/control-has-associated-label": "off",
"no-console": "off",
"arrow-body-style": "off",
"no-underscore-dangle": [

View File

@@ -7098,9 +7098,12 @@
"dev": true
},
"node_modules/@swc/helpers": {
"version": "0.4.11",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.11.tgz",
"integrity": "sha512-rEUrBSGIoSFuYxwBYtlUFMlE2CwGhmW+w9355/5oduSw8e5h2+Tj4UrAGNNgP9915++wj5vkQo0UuOBqOAq4nw==",
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.3.tgz",
"integrity": "sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"tslib": "^2.4.0"
}
@@ -17118,6 +17121,14 @@
}
}
},
"node_modules/next/node_modules/@swc/helpers": {
"version": "0.4.11",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.11.tgz",
"integrity": "sha512-rEUrBSGIoSFuYxwBYtlUFMlE2CwGhmW+w9355/5oduSw8e5h2+Tj4UrAGNNgP9915++wj5vkQo0UuOBqOAq4nw==",
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/next/node_modules/postcss": {
"version": "8.4.14",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",

View File

@@ -5,4 +5,4 @@ scripts/initialize-standalone-build.sh
cd ../
exec node build/index.js
exec node dist/main.mjs