mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 00:27:35 +00:00
feat: updated docker image and resolved build error
This commit is contained in:
@@ -3,13 +3,10 @@ ARG POSTHOG_API_KEY=posthog-api-key
|
|||||||
ARG INTERCOM_ID=intercom-id
|
ARG INTERCOM_ID=intercom-id
|
||||||
ARG CAPTCHA_SITE_KEY=captcha-site-key
|
ARG CAPTCHA_SITE_KEY=captcha-site-key
|
||||||
|
|
||||||
FROM node:20-alpine AS base
|
FROM node:20-slim AS base
|
||||||
|
|
||||||
FROM base AS frontend-dependencies
|
FROM base AS frontend-dependencies
|
||||||
|
|
||||||
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
|
|
||||||
RUN apk add --no-cache libc6-compat
|
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY frontend/package.json frontend/package-lock.json ./
|
COPY frontend/package.json frontend/package-lock.json ./
|
||||||
@@ -45,8 +42,8 @@ RUN npm run build
|
|||||||
FROM base AS frontend-runner
|
FROM base AS frontend-runner
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
RUN addgroup --system --gid 1001 nodejs
|
RUN groupadd --system --gid 1001 nodejs
|
||||||
RUN adduser --system --uid 1001 non-root-user
|
RUN useradd --system --uid 1001 --gid nodejs non-root-user
|
||||||
|
|
||||||
COPY --from=frontend-builder --chown=non-root-user:nodejs /app/dist ./
|
COPY --from=frontend-builder --chown=non-root-user:nodejs /app/dist ./
|
||||||
|
|
||||||
@@ -56,21 +53,23 @@ USER non-root-user
|
|||||||
## BACKEND
|
## BACKEND
|
||||||
##
|
##
|
||||||
FROM base AS backend-build
|
FROM base AS backend-build
|
||||||
RUN addgroup --system --gid 1001 nodejs \
|
|
||||||
&& adduser --system --uid 1001 non-root-user
|
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Install all required dependencies for build
|
# Install all required dependencies for build
|
||||||
RUN apk --update add \
|
RUN apt-get update && apt-get install -y \
|
||||||
python3 \
|
python3 \
|
||||||
make \
|
make \
|
||||||
g++ \
|
g++ \
|
||||||
unixodbc \
|
unixodbc \
|
||||||
freetds \
|
freetds-bin \
|
||||||
unixodbc-dev \
|
unixodbc-dev \
|
||||||
libc-dev \
|
libc-dev \
|
||||||
freetds-dev
|
freetds-dev \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN groupadd --system --gid 1001 nodejs
|
||||||
|
RUN useradd --system --uid 1001 --gid nodejs non-root-user
|
||||||
|
|
||||||
COPY backend/package*.json ./
|
COPY backend/package*.json ./
|
||||||
RUN npm ci --only-production
|
RUN npm ci --only-production
|
||||||
@@ -86,18 +85,19 @@ FROM base AS backend-runner
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Install all required dependencies for runtime
|
# Install all required dependencies for runtime
|
||||||
RUN apk --update add \
|
RUN apt-get update && apt-get install -y \
|
||||||
python3 \
|
python3 \
|
||||||
make \
|
make \
|
||||||
g++ \
|
g++ \
|
||||||
unixodbc \
|
unixodbc \
|
||||||
freetds \
|
freetds-bin \
|
||||||
unixodbc-dev \
|
unixodbc-dev \
|
||||||
libc-dev \
|
libc-dev \
|
||||||
freetds-dev
|
freetds-dev \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Configure ODBC
|
# Configure ODBC
|
||||||
RUN printf "[FreeTDS]\nDescription = FreeTDS Driver\nDriver = /usr/lib/libtdsodbc.so\nSetup = /usr/lib/libtdsodbc.so\nFileUsage = 1\n" > /etc/odbcinst.ini
|
RUN printf "[FreeTDS]\nDescription = FreeTDS Driver\nDriver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so\nSetup = /usr/lib/x86_64-linux-gnu/odbc/libtdsS.so\nFileUsage = 1\n" > /etc/odbcinst.ini
|
||||||
|
|
||||||
COPY backend/package*.json ./
|
COPY backend/package*.json ./
|
||||||
RUN npm ci --only-production
|
RUN npm ci --only-production
|
||||||
@@ -109,34 +109,35 @@ RUN mkdir frontend-build
|
|||||||
# Production stage
|
# Production stage
|
||||||
FROM base AS production
|
FROM base AS production
|
||||||
|
|
||||||
RUN apk add --upgrade --no-cache ca-certificates
|
RUN apt-get update && apt-get install -y \
|
||||||
RUN apk add --no-cache bash curl && curl -1sLf \
|
ca-certificates \
|
||||||
'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.alpine.sh' | bash \
|
bash \
|
||||||
&& apk add infisical=0.31.1 && apk add --no-cache git
|
curl \
|
||||||
|
git \
|
||||||
WORKDIR /
|
|
||||||
|
|
||||||
# Install all required runtime dependencies
|
|
||||||
RUN apk --update add \
|
|
||||||
python3 \
|
python3 \
|
||||||
make \
|
make \
|
||||||
g++ \
|
g++ \
|
||||||
unixodbc \
|
unixodbc \
|
||||||
freetds \
|
freetds-bin \
|
||||||
unixodbc-dev \
|
unixodbc-dev \
|
||||||
libc-dev \
|
libc-dev \
|
||||||
freetds-dev \
|
freetds-dev \
|
||||||
bash \
|
openssh-client \
|
||||||
curl \
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
git \
|
|
||||||
openssh
|
# Install Infisical CLI
|
||||||
|
RUN curl -1sLf 'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh' | bash \
|
||||||
|
&& apt-get update && apt-get install -y infisical=0.31.1 \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /
|
||||||
|
|
||||||
# Configure ODBC in production
|
# Configure ODBC in production
|
||||||
RUN printf "[FreeTDS]\nDescription = FreeTDS Driver\nDriver = /usr/lib/libtdsodbc.so\nSetup = /usr/lib/libtdsodbc.so\nFileUsage = 1\n" > /etc/odbcinst.ini
|
RUN printf "[FreeTDS]\nDescription = FreeTDS Driver\nDriver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so\nSetup = /usr/lib/x86_64-linux-gnu/odbc/libtdsS.so\nFileUsage = 1\n" > /etc/odbcinst.ini
|
||||||
|
|
||||||
# Setup user permissions
|
# Setup user permissions
|
||||||
RUN addgroup --system --gid 1001 nodejs \
|
RUN groupadd --system --gid 1001 nodejs \
|
||||||
&& adduser --system --uid 1001 non-root-user
|
&& useradd --system --uid 1001 --gid nodejs non-root-user
|
||||||
|
|
||||||
# Give non-root-user permission to update SSL certs
|
# Give non-root-user permission to update SSL certs
|
||||||
RUN chown -R non-root-user /etc/ssl/certs
|
RUN chown -R non-root-user /etc/ssl/certs
|
||||||
@@ -154,9 +155,7 @@ ENV INTERCOM_ID=$INTERCOM_ID
|
|||||||
ARG CAPTCHA_SITE_KEY
|
ARG CAPTCHA_SITE_KEY
|
||||||
ENV CAPTCHA_SITE_KEY=$CAPTCHA_SITE_KEY
|
ENV CAPTCHA_SITE_KEY=$CAPTCHA_SITE_KEY
|
||||||
|
|
||||||
|
|
||||||
COPY --from=backend-runner /app /backend
|
COPY --from=backend-runner /app /backend
|
||||||
|
|
||||||
COPY --from=frontend-runner /app ./backend/frontend-build
|
COPY --from=frontend-runner /app ./backend/frontend-build
|
||||||
|
|
||||||
ARG INFISICAL_PLATFORM_VERSION
|
ARG INFISICAL_PLATFORM_VERSION
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
/* eslint-disable no-await-in-loop */
|
/* eslint-disable no-await-in-loop */
|
||||||
import crypto from "node:crypto";
|
import crypto from "node:crypto";
|
||||||
import net from "node:net";
|
import net from "node:net";
|
||||||
|
import quic from "@infisical/quic";
|
||||||
import { QUICClient } from "@infisical/quic";
|
|
||||||
import { CryptoError } from "@infisical/quic/dist/native";
|
|
||||||
|
|
||||||
import { BadRequestError } from "../errors";
|
import { BadRequestError } from "../errors";
|
||||||
import { logger } from "../logger";
|
import { logger } from "../logger";
|
||||||
@@ -29,7 +27,7 @@ const createQuicConnection = async (
|
|||||||
identityId: string,
|
identityId: string,
|
||||||
orgId: string
|
orgId: string
|
||||||
) => {
|
) => {
|
||||||
const client = await QUICClient.createQUICClient({
|
const client = await quic.QUICClient.createQUICClient({
|
||||||
host: relayHost,
|
host: relayHost,
|
||||||
port: relayPort,
|
port: relayPort,
|
||||||
config: {
|
config: {
|
||||||
@@ -39,24 +37,24 @@ const createQuicConnection = async (
|
|||||||
applicationProtos: ["infisical-gateway"],
|
applicationProtos: ["infisical-gateway"],
|
||||||
verifyPeer: true,
|
verifyPeer: true,
|
||||||
verifyCallback: async (certs) => {
|
verifyCallback: async (certs) => {
|
||||||
if (!certs || certs.length === 0) return CryptoError.CertificateRequired;
|
if (!certs || certs.length === 0) return quic.native.CryptoError.CertificateRequired;
|
||||||
const serverCertificate = new crypto.X509Certificate(Buffer.from(certs[0]));
|
const serverCertificate = new crypto.X509Certificate(Buffer.from(certs[0]));
|
||||||
const caCertificate = new crypto.X509Certificate(tlsOptions.ca);
|
const caCertificate = new crypto.X509Certificate(tlsOptions.ca);
|
||||||
const isValidServerCertificate = serverCertificate.checkIssued(caCertificate);
|
const isValidServerCertificate = serverCertificate.checkIssued(caCertificate);
|
||||||
if (!isValidServerCertificate) return CryptoError.BadCertificate;
|
if (!isValidServerCertificate) return quic.native.CryptoError.BadCertificate;
|
||||||
|
|
||||||
const subjectDetails = parseSubjectDetails(serverCertificate.subject);
|
const subjectDetails = parseSubjectDetails(serverCertificate.subject);
|
||||||
if (subjectDetails.OU !== "Gateway" || subjectDetails.CN !== identityId || subjectDetails.O !== orgId) {
|
if (subjectDetails.OU !== "Gateway" || subjectDetails.CN !== identityId || subjectDetails.O !== orgId) {
|
||||||
return CryptoError.CertificateUnknown;
|
return quic.native.CryptoError.CertificateUnknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new Date() > new Date(serverCertificate.validTo) || new Date() < new Date(serverCertificate.validFrom)) {
|
if (new Date() > new Date(serverCertificate.validTo) || new Date() < new Date(serverCertificate.validFrom)) {
|
||||||
return CryptoError.CertificateExpired;
|
return quic.native.CryptoError.CertificateExpired;
|
||||||
}
|
}
|
||||||
|
|
||||||
const formatedRelayHost =
|
const formatedRelayHost =
|
||||||
process.env.NODE_ENV === "development" ? relayHost.replace("host.docker.internal", "127.0.0.1") : relayHost;
|
process.env.NODE_ENV === "development" ? relayHost.replace("host.docker.internal", "127.0.0.1") : relayHost;
|
||||||
if (!serverCertificate.checkIP(formatedRelayHost)) return CryptoError.BadCertificate;
|
if (!serverCertificate.checkIP(formatedRelayHost)) return quic.native.CryptoError.BadCertificate;
|
||||||
},
|
},
|
||||||
maxIdleTimeout: 90000,
|
maxIdleTimeout: 90000,
|
||||||
keepAliveIntervalTime: 30000
|
keepAliveIntervalTime: 30000
|
||||||
@@ -90,14 +88,14 @@ export const pingGatewayAndVerify = async ({
|
|||||||
orgId
|
orgId
|
||||||
}: TPingGatewayAndVerifyDTO) => {
|
}: TPingGatewayAndVerifyDTO) => {
|
||||||
let lastError: Error | null = null;
|
let lastError: Error | null = null;
|
||||||
const quic = await createQuicConnection(relayHost, relayPort, tlsOptions, identityId, orgId).catch((err) => {
|
const quicClient = await createQuicConnection(relayHost, relayPort, tlsOptions, identityId, orgId).catch((err) => {
|
||||||
throw new BadRequestError({
|
throw new BadRequestError({
|
||||||
error: err as Error
|
error: err as Error
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
for (let attempt = 1; attempt <= maxRetries; attempt += 1) {
|
for (let attempt = 1; attempt <= maxRetries; attempt += 1) {
|
||||||
try {
|
try {
|
||||||
const stream = quic.connection.newStream("bidi");
|
const stream = quicClient.connection.newStream("bidi");
|
||||||
const pingWriter = stream.writable.getWriter();
|
const pingWriter = stream.writable.getWriter();
|
||||||
await pingWriter.write(Buffer.from("PING\n"));
|
await pingWriter.write(Buffer.from("PING\n"));
|
||||||
pingWriter.releaseLock();
|
pingWriter.releaseLock();
|
||||||
@@ -131,7 +129,7 @@ export const pingGatewayAndVerify = async ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
await quic.destroy();
|
await quicClient.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +162,7 @@ const setupProxyServer = async ({
|
|||||||
identityId: string;
|
identityId: string;
|
||||||
orgId: string;
|
orgId: string;
|
||||||
}): Promise<TProxyServer> => {
|
}): Promise<TProxyServer> => {
|
||||||
const quic = await createQuicConnection(relayHost, relayPort, tlsOptions, identityId, orgId).catch((err) => {
|
const quicClient = await createQuicConnection(relayHost, relayPort, tlsOptions, identityId, orgId).catch((err) => {
|
||||||
throw new BadRequestError({
|
throw new BadRequestError({
|
||||||
error: err as Error
|
error: err as Error
|
||||||
});
|
});
|
||||||
@@ -179,7 +177,7 @@ const setupProxyServer = async ({
|
|||||||
clientConn.setKeepAlive(true, 30000); // 30 seconds
|
clientConn.setKeepAlive(true, 30000); // 30 seconds
|
||||||
clientConn.setNoDelay(true);
|
clientConn.setNoDelay(true);
|
||||||
|
|
||||||
const stream = quic.connection.newStream("bidi");
|
const stream = quicClient.connection.newStream("bidi");
|
||||||
// Send FORWARD-TCP command
|
// Send FORWARD-TCP command
|
||||||
const forwardWriter = stream.writable.getWriter();
|
const forwardWriter = stream.writable.getWriter();
|
||||||
await forwardWriter.write(Buffer.from(`FORWARD-TCP ${targetHost}:${targetPort}\n`));
|
await forwardWriter.write(Buffer.from(`FORWARD-TCP ${targetHost}:${targetPort}\n`));
|
||||||
@@ -272,7 +270,7 @@ const setupProxyServer = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
server.on("close", async () => {
|
server.on("close", async () => {
|
||||||
await quic?.destroy();
|
await quicClient?.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
/* eslint-enable */
|
/* eslint-enable */
|
||||||
@@ -291,7 +289,7 @@ const setupProxyServer = async ({
|
|||||||
port: address.port,
|
port: address.port,
|
||||||
cleanup: async () => {
|
cleanup: async () => {
|
||||||
server.close();
|
server.close();
|
||||||
await quic?.destroy();
|
await quicClient?.destroy();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user