Compare commits

...

8 Commits

Author SHA1 Message Date
0ec56c9928 docs: add podman compose docs 2025-07-10 18:57:25 +04:00
35520cfe99 Merge pull request #3989 from Infisical/add-access-token-index
add index for referencing columns in identity access token
2025-07-10 09:48:39 -04:00
Sid
ba0f6e60e2 fix: yaml secret file parsing (#3837) 2025-07-10 15:33:59 +05:30
579c68b2a3 Merge pull request #3991 from Infisical/helm-update-v0.9.4
Update Helm chart to version v0.9.4
2025-07-10 14:03:10 +04:00
f4ea3e1c75 Update Helm chart to version v0.9.4 2025-07-10 10:02:02 +00:00
7d37ea318f Merge pull request #3990 from Infisical/daniel/operator-logs
fix: add request ID to error logs
2025-07-10 13:57:44 +04:00
5e85de3937 fix lint and short index name 2025-07-09 23:36:55 -04:00
8719e3e75e add index for referencing columns in identity access token
This PR will address issue with very long identity deletions due to a sequential scan over ALL identity access rows during CASCADE
2025-07-09 23:19:01 -04:00
6 changed files with 303 additions and 59 deletions

View File

@ -0,0 +1,48 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
const MIGRATION_TIMEOUT = 30 * 60 * 1000; // 30 minutes
export async function up(knex: Knex): Promise<void> {
const result = await knex.raw("SHOW statement_timeout");
const originalTimeout = result.rows[0].statement_timeout;
try {
await knex.raw(`SET statement_timeout = ${MIGRATION_TIMEOUT}`);
// iat means IdentityAccessToken
await knex.raw(`
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_iat_identity_id
ON ${TableName.IdentityAccessToken} ("identityId")
`);
await knex.raw(`
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_iat_ua_client_secret_id
ON ${TableName.IdentityAccessToken} ("identityUAClientSecretId")
`);
} finally {
await knex.raw(`SET statement_timeout = '${originalTimeout}'`);
}
}
export async function down(knex: Knex): Promise<void> {
const result = await knex.raw("SHOW statement_timeout");
const originalTimeout = result.rows[0].statement_timeout;
try {
await knex.raw(`SET statement_timeout = ${MIGRATION_TIMEOUT}`);
await knex.raw(`
DROP INDEX IF EXISTS idx_iat_identity_id
`);
await knex.raw(`
DROP INDEX IF EXISTS idx_iat_ua_client_secret_id
`);
} finally {
await knex.raw(`SET statement_timeout = '${originalTimeout}'`);
}
}
export const config = { transaction: false };

View File

@ -4,17 +4,20 @@ description: "Read how to run Infisical with Docker Compose template."
---
This self-hosting guide will walk you through the steps to self-host Infisical using Docker Compose.
## Prerequisites
- [Docker](https://docs.docker.com/engine/install/)
- [Docker compose](https://docs.docker.com/compose/install/)
<Warning>
This Docker Compose configuration is not designed for high-availability production scenarios.
It includes just the essential components needed to set up an Infisical proof of concept (POC).
To run Infisical in a highly available manner, give the [Docker Swarm guide](/self-hosting/deployment-options/docker-swarm).
</Warning>
<Tabs>
<Tab title="Docker Compose">
## Prerequisites
- [Docker](https://docs.docker.com/engine/install/)
- [Docker compose](https://docs.docker.com/compose/install/)
## Verify prerequisites
<Warning>
This Docker Compose configuration is not designed for high-availability production scenarios.
It includes just the essential components needed to set up an Infisical proof of concept (POC).
To run Infisical in a highly available manner, give the [Docker Swarm guide](/self-hosting/deployment-options/docker-swarm).
</Warning>
## Verify prerequisites
To verify that Docker compose and Docker are installed on the machine where you plan to install Infisical, run the following commands.
Check for docker installation
@ -27,55 +30,145 @@ To run Infisical in a highly available manner, give the [Docker Swarm guide](/se
docker-compose
```
## Download docker compose file
You can obtain the Infisical docker compose file by using a command-line downloader such as `wget` or `curl`.
If your system doesn't have either of these, you can use a equivalent command that works with your machine.
## Download docker compose file
You can obtain the Infisical docker compose file by using a command-line downloader such as `wget` or `curl`.
If your system doesn't have either of these, you can use a equivalent command that works with your machine.
<Tabs>
<Tab title="curl">
```bash
curl -o docker-compose.prod.yml https://raw.githubusercontent.com/Infisical/infisical/main/docker-compose.prod.yml
```
</Tab>
<Tab title="wget">
```bash
wget -O docker-compose.prod.yml https://raw.githubusercontent.com/Infisical/infisical/main/docker-compose.prod.yml
```
</Tab>
</Tabs>
## Configure instance credentials
Infisical requires a set of credentials used for connecting to dependent services such as Postgres, Redis, etc.
The default credentials can be downloaded using the one of the commands listed below.
<Tabs>
<Tab title="curl">
```bash
curl -o .env https://raw.githubusercontent.com/Infisical/infisical/main/.env.example
```
</Tab>
<Tab title="wget">
```bash
wget -O .env https://raw.githubusercontent.com/Infisical/infisical/main/.env.example
```
</Tab>
</Tabs>
Once downloaded, the credentials file will be saved to your working directly as `.env` file.
View all available configurations [here](/self-hosting/configuration/envars).
<Warning>
The default .env file contains credentials that are intended solely for testing purposes.
Please generate a new `ENCRYPTION_KEY` and `AUTH_SECRET` for use outside of testing.
Instructions to do so, can be found [here](/self-hosting/configuration/envars).
</Warning>
## Start Infisical
Run the command below to start Infisical and all related services.
<Tabs>
<Tab title="curl">
```bash
curl -o docker-compose.prod.yml https://raw.githubusercontent.com/Infisical/infisical/main/docker-compose.prod.yml
docker-compose -f docker-compose.prod.yml up
```
</Tab>
<Tab title="wget">
```bash
wget -O docker-compose.prod.yml https://raw.githubusercontent.com/Infisical/infisical/main/docker-compose.prod.yml
<Tab title="Podman Compose">
Podman Compose is an alternative way to run Infisical using Podman as a replacement for Docker. Podman is backwards compatible with Docker Compose files.
## Prerequisites
- [Podman](https://podman-desktop.io/docs/installation)
- [Podman Compose](https://podman-desktop.io/docs/compose)
<Warning>
This Docker Compose configuration is not designed for high-availability production scenarios.
It includes just the essential components needed to set up an Infisical proof of concept (POC).
To run Infisical in a highly available manner, give the [Docker Swarm guide](/self-hosting/deployment-options/docker-swarm).
</Warning>
## Verify prerequisites
To verify that Podman compose and Podman are installed on the machine where you plan to install Infisical, run the following commands.
Check for podman installation
```bash
podman version
```
Check for podman compose installation
```bash
podman-compose version
```
## Download Docker Compose file
You can obtain the Infisical docker compose file by using a command-line downloader such as `wget` or `curl`.
If your system doesn't have either of these, you can use a equivalent command that works with your machine.
<Tabs>
<Tab title="curl">
```bash
curl -o docker-compose.prod.yml https://raw.githubusercontent.com/Infisical/infisical/main/docker-compose.prod.yml
```
</Tab>
<Tab title="wget">
```bash
wget -O docker-compose.prod.yml https://raw.githubusercontent.com/Infisical/infisical/main/docker-compose.prod.yml
```
</Tab>
</Tabs>
## Configure instance credentials
Infisical requires a set of credentials used for connecting to dependent services such as Postgres, Redis, etc.
The default credentials can be downloaded using the one of the commands listed below.
<Tabs>
<Tab title="curl">
```bash
curl -o .env https://raw.githubusercontent.com/Infisical/infisical/main/.env.example
```
</Tab>
<Tab title="wget">
```bash
wget -O .env https://raw.githubusercontent.com/Infisical/infisical/main/.env.example
```
</Tab>
</Tabs>
<Note>
Make sure to rename the `.env.example` file to `.env` before starting Infisical. Additionally it's important that the `.env` file is in the same directory as the `docker-compose.prod.yml` file.
</Note>
## Setup Podman
Run the commands below to setup Podman for first time use.
```bash
podman machine init --now
podman machine set --rootful
podman machine start
```
<Note>
If you are using a rootless podman installation, you can skip the `podman machine set --rootful` command.
</Note>
## Start Infisical
Run the command below to start Infisical and all related services.
```bash
podman-compose -f docker-compose.prod.yml up
```
</Tab>
</Tabs>
## Configure instance credentials
Infisical requires a set of credentials used for connecting to dependent services such as Postgres, Redis, etc.
The default credentials can be downloaded using the one of the commands listed below.
<Tabs>
<Tab title="curl">
```bash
curl -o .env https://raw.githubusercontent.com/Infisical/infisical/main/.env.example
```
</Tab>
<Tab title="wget">
```bash
wget -O .env https://raw.githubusercontent.com/Infisical/infisical/main/.env.example
```
</Tab>
</Tabs>
Once downloaded, the credentials file will be saved to your working directly as `.env` file.
View all available configurations [here](/self-hosting/configuration/envars).
<Warning>
The default .env file contains credentials that are intended solely for testing purposes.
Please generate a new `ENCRYPTION_KEY` and `AUTH_SECRET` for use outside of testing.
Instructions to do so, can be found [here](/self-hosting/configuration/envars).
</Warning>
## Start Infisical
Run the command below to start Infisical and all related services.
```bash
docker-compose -f docker-compose.prod.yml up
```
Your Infisical instance should now be running on port `80`. To access your instance, visit `http://localhost:80`.

View File

@ -77,3 +77,91 @@ export const parseJson = (src: ArrayBuffer | string) => {
});
return env;
};
/**
* Parses simple flat YAML with support for multiline strings using |, |-, and >.
* @param {ArrayBuffer | string} src
* @returns {Record<string, { value: string, comments: string[] }>}
*/
export function parseYaml(src: ArrayBuffer | string) {
const result: Record<string, { value: string; comments: string[] }> = {};
const content = src.toString().replace(/\r\n?/g, "\n");
const lines = content.split("\n");
let i = 0;
let comments: string[] = [];
while (i < lines.length) {
const line = lines[i].trim();
// Collect comment
if (line.startsWith("#")) {
comments.push(line.slice(1).trim());
i += 1; // move to next line
} else {
// Match key: value or key: |, key: >, etc.
const keyMatch = lines[i].match(/^([\w.-]+)\s*:\s*(.*)$/);
if (keyMatch) {
const [, key, rawValue] = keyMatch;
let value = rawValue.trim();
// Multiline string handling
if (value === "|-" || value === "|" || value === ">") {
const isFolded = value === ">";
const baseIndent = lines[i + 1]?.match(/^(\s*)/)?.[1]?.length ?? 0;
const collectedLines: string[] = [];
i += 1; // move to first content line
while (i < lines.length) {
const current = lines[i];
const currentIndent = current.match(/^(\s*)/)?.[1]?.length ?? 0;
if (current.trim() === "" || currentIndent >= baseIndent) {
collectedLines.push(current.slice(baseIndent));
i += 1; // move to next line
} else {
break;
}
}
if (isFolded) {
// Join lines with space for `>` folded style
value = collectedLines.map((l) => l.trim()).join(" ");
} else {
// Keep lines with newlines for `|` and `|-`
value = collectedLines.join("\n");
}
} else {
// Inline value — strip quotes and inline comment
const commentIndex = value.indexOf(" #");
if (commentIndex !== -1) {
value = value.slice(0, commentIndex).trim();
}
// Remove surrounding quotes
if (
(value.startsWith('"') && value.endsWith('"')) ||
(value.startsWith("'") && value.endsWith("'"))
) {
value = value.slice(1, -1);
}
i += 1; // advance to next line
}
result[key] = {
value,
comments: [...comments]
};
comments = []; // reset
} else {
i += 1; // skip unknown line
}
}
}
return result;
}

View File

@ -9,7 +9,7 @@ import { twMerge } from "tailwind-merge";
import { createNotification } from "@app/components/notifications";
import { ProjectPermissionCan } from "@app/components/permissions";
// TODO:(akhilmhdh) convert all the util functions like this into a lib folder grouped by functionality
import { parseDotEnv, parseJson } from "@app/components/utilities/parseSecrets";
import { parseDotEnv, parseJson, parseYaml } from "@app/components/utilities/parseSecrets";
import { Button, Lottie, Modal, ModalContent } from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
import { usePopUp, useToggle } from "@app/hooks";
@ -127,7 +127,7 @@ export const SecretDropzone = ({
}
};
const parseFile = (file?: File, isJson?: boolean) => {
const parseFile = (file?: File) => {
const reader = new FileReader();
if (!file) {
createNotification({
@ -140,10 +140,25 @@ export const SecretDropzone = ({
setIsLoading.on();
reader.onload = (event) => {
if (!event?.target?.result) return;
// parse function's argument looks like to be ArrayBuffer
const env = isJson
? parseJson(event.target.result as ArrayBuffer)
: parseDotEnv(event.target.result as ArrayBuffer);
let env: TParsedEnv;
const src = event.target.result as ArrayBuffer;
switch (file.type) {
case "application/json":
env = parseJson(src);
break;
case "text/yaml":
case "application/x-yaml":
case "application/yaml":
env = parseYaml(src);
break;
default:
env = parseDotEnv(src);
break;
}
setIsLoading.off();
handleParsedEnv(env);
};
@ -165,12 +180,12 @@ export const SecretDropzone = ({
e.dataTransfer.dropEffect = "copy";
setDragActive.off();
parseFile(e.dataTransfer.files[0], e.dataTransfer.files[0].type === "application/json");
parseFile(e.dataTransfer.files[0]);
};
const handleFileUpload = (e: ChangeEvent<HTMLInputElement>) => {
e.preventDefault();
parseFile(e.target?.files?.[0], e.target?.files?.[0]?.type === "application/json");
parseFile(e.target?.files?.[0]);
};
const handleSaveSecrets = async () => {

View File

@ -13,9 +13,9 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: v0.9.3
version: v0.9.4
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "v0.9.3"
appVersion: "v0.9.4"

View File

@ -32,7 +32,7 @@ controllerManager:
- ALL
image:
repository: infisical/kubernetes-operator
tag: v0.9.3
tag: v0.9.4
resources:
limits:
cpu: 500m