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

This commit is contained in:
Akhil Mohan
2024-01-27 12:39:54 +05:30
parent 249edf98e9
commit fa572f7ee0
12 changed files with 154 additions and 22 deletions
+10 -10
View File
@@ -2,7 +2,7 @@ ARG POSTHOG_HOST=https://app.posthog.com
ARG POSTHOG_API_KEY=posthog-api-key ARG POSTHOG_API_KEY=posthog-api-key
ARG INTERCOM_ID=intercom-id ARG INTERCOM_ID=intercom-id
FROM node:16-alpine AS base FROM node:20-alpine AS base
FROM base AS frontend-dependencies FROM base AS frontend-dependencies
@@ -68,11 +68,12 @@ RUN addgroup --system --gid 1001 nodejs \
WORKDIR /app WORKDIR /app
COPY backend/package*.json ./ COPY backend-pg/package*.json ./
RUN npm ci --only-production RUN npm ci --only-production
COPY /backend . COPY /backend-pg .
COPY --chown=non-root-user:nodejs standalone-entrypoint.sh standalone-entrypoint.sh COPY --chown=non-root-user:nodejs standalone-entrypoint.sh standalone-entrypoint.sh
RUN npm i -D tsconfig-paths
RUN npm run build RUN npm run build
# Production stage # Production stage
@@ -80,7 +81,7 @@ FROM base AS backend-runner
WORKDIR /app WORKDIR /app
COPY backend/package*.json ./ COPY backend-pg/package*.json ./
RUN npm ci --only-production RUN npm ci --only-production
COPY --from=backend-build /app . COPY --from=backend-build /app .
@@ -102,16 +103,18 @@ ENV NEXT_PUBLIC_INTERCOM_ID=$INTERCOM_ID \
WORKDIR / 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 PORT 8080
ENV HOST=0.0.0.0
ENV HTTPS_ENABLED false ENV HTTPS_ENABLED false
ENV NODE_ENV production ENV NODE_ENV production
ENV STANDALONE_BUILD true ENV STANDALONE_BUILD true
WORKDIR /backend WORKDIR /backend-pg
ENV TELEMETRY_ENABLED true ENV TELEMETRY_ENABLED true
@@ -123,6 +126,3 @@ EXPOSE 8080
USER non-root-user USER non-root-user
CMD ["./standalone-entrypoint.sh"] CMD ["./standalone-entrypoint.sh"]
+33
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"]
+3 -3
View File
@@ -12958,9 +12958,9 @@
} }
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "5.0.7", "version": "5.0.12",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.0.7.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.12.tgz",
"integrity": "sha512-B4T4rJCDPihrQo2B+h1MbeGL/k/GMAHzhQ8S0LjQ142s6/+l3hHTT095ORvsshj4QCkoWu3Xtmob5mazvakaOw==", "integrity": "sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"esbuild": "^0.19.3", "esbuild": "^0.19.3",
+2 -2
View File
@@ -7,8 +7,8 @@
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"dev": "tsx watch --clear-screen=false ./src/main.ts | pino-pretty --colorize --colorizeObjects --singleLine", "dev": "tsx watch --clear-screen=false ./src/main.ts | pino-pretty --colorize --colorizeObjects --singleLine",
"dev:docker": "nodemon", "dev:docker": "nodemon",
"build": "rimraf dist && tsup src --out-dir dist --loader '.handlebars=copy' --loader '.md=copy'", "build": "rimraf dist && tsup",
"start": "node dist/server/main.js", "start": "node dist/main.mjs",
"type:check": "tsc --noEmit", "type:check": "tsc --noEmit",
"lint:fix": "eslint --fix --ext js,ts ./src", "lint:fix": "eslint --fix --ext js,ts ./src",
"lint": "eslint 'src/**/*.ts'", "lint": "eslint 'src/**/*.ts'",
View File
+6 -1
View File
@@ -85,13 +85,18 @@ const envSchema = z
// LICENCE // LICENCE
LICENSE_SERVER_URL: zpStr(z.string().optional()), LICENSE_SERVER_URL: zpStr(z.string().optional()),
LICENSE_SERVER_KEY: 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) => ({ .transform((data) => ({
...data, ...data,
isSmtpConfigured: Boolean(data.SMTP_HOST), isSmtpConfigured: Boolean(data.SMTP_HOST),
isRedisConfigured: Boolean(data.REDIS_URL), isRedisConfigured: Boolean(data.REDIS_URL),
isDevelopmentMode: data.NODE_ENV === "development", isDevelopmentMode: data.NODE_ENV === "development",
isProductionMode: data.NODE_ENV === "production",
isSecretScanningConfigured: isSecretScanningConfigured:
Boolean(data.SECRET_SCANNING_GIT_APP_ID) && Boolean(data.SECRET_SCANNING_GIT_APP_ID) &&
Boolean(data.SECRET_SCANNING_PRIVATE_KEY) && Boolean(data.SECRET_SCANNING_PRIVATE_KEY) &&
+15 -2
View File
@@ -1,3 +1,6 @@
/* eslint-disable import/extensions */
import path from "node:path";
import type { FastifyCookieOptions } from "@fastify/cookie"; import type { FastifyCookieOptions } from "@fastify/cookie";
import cookie from "@fastify/cookie"; import cookie from "@fastify/cookie";
import type { FastifyCorsOptions } from "@fastify/cors"; import type { FastifyCorsOptions } from "@fastify/cors";
@@ -17,6 +20,7 @@ import { getConfig } from "@lib/config/env";
import { globalRateLimiterCfg } from "./config/rateLimiter"; import { globalRateLimiterCfg } from "./config/rateLimiter";
import { fastifyErrHandler } from "./plugins/error-handler"; import { fastifyErrHandler } from "./plugins/error-handler";
import { registerExternalNextjs } from "./plugins/external-nextjs";
import { serializerCompiler, validatorCompiler, ZodTypeProvider } from "./plugins/fastify-zod"; import { serializerCompiler, validatorCompiler, ZodTypeProvider } from "./plugins/fastify-zod";
import { fastifyIp } from "./plugins/ip"; import { fastifyIp } from "./plugins/ip";
import { fastifySwagger } from "./plugins/swagger"; import { fastifySwagger } from "./plugins/swagger";
@@ -48,7 +52,7 @@ export const main = async ({ db, smtp, logger, queue }: TMain) => {
await server.register<FastifyCorsOptions>(cors, { await server.register<FastifyCorsOptions>(cors, {
credentials: true, credentials: true,
origin: true origin: appCfg.SITE_URL
}); });
// pull ip based on various proxy headers // pull ip based on various proxy headers
await server.register(fastifyIp); await server.register(fastifyIp);
@@ -58,12 +62,21 @@ export const main = async ({ db, smtp, logger, queue }: TMain) => {
await server.register(fastifyErrHandler); await server.register(fastifyErrHandler);
// Rate limiters and security headers // Rate limiters and security headers
if (appCfg.NODE_ENV === "production") { if (appCfg.isProductionMode) {
await server.register<FastifyRateLimitOptions>(ratelimiter, globalRateLimiterCfg()); await server.register<FastifyRateLimitOptions>(ratelimiter, globalRateLimiterCfg());
} }
await server.register(helmet, { contentSecurityPolicy: false }); await server.register(helmet, { contentSecurityPolicy: false });
await server.register(registerRoutes, { smtp, queue, db }); 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(); await server.ready();
server.swagger(); server.swagger();
return server; return server;
@@ -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
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"]
});
+1
View File
@@ -38,6 +38,7 @@ module.exports = {
"react/jsx-props-no-spreading": "off", // switched off for component building "react/jsx-props-no-spreading": "off", // switched off for component building
// TODO: This rule will be switched ON after complete revamp of frontend // TODO: This rule will be switched ON after complete revamp of frontend
"@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/no-explicit-any": "off",
"jsx-a11y/control-has-associated-label": "off",
"no-console": "off", "no-console": "off",
"arrow-body-style": "off", "arrow-body-style": "off",
"no-underscore-dangle": [ "no-underscore-dangle": [
+14 -3
View File
@@ -7098,9 +7098,12 @@
"dev": true "dev": true
}, },
"node_modules/@swc/helpers": { "node_modules/@swc/helpers": {
"version": "0.4.11", "version": "0.5.3",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.11.tgz", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.3.tgz",
"integrity": "sha512-rEUrBSGIoSFuYxwBYtlUFMlE2CwGhmW+w9355/5oduSw8e5h2+Tj4UrAGNNgP9915++wj5vkQo0UuOBqOAq4nw==", "integrity": "sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"tslib": "^2.4.0" "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": { "node_modules/next/node_modules/postcss": {
"version": "8.4.14", "version": "8.4.14",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
+1 -1
View File
@@ -5,4 +5,4 @@ scripts/initialize-standalone-build.sh
cd ../ cd ../
exec node build/index.js exec node dist/main.mjs