Compare commits

...

9 Commits

5 changed files with 144 additions and 36 deletions

View File

@ -8,15 +8,12 @@ on:
types: [published]
jobs:
build-and-push:
build-amd64:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
@ -33,28 +30,104 @@ jobs:
id: version
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
- name: Build and push Docker image
- name: Build and push AMD64 Docker image
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
run: |
docker buildx create --use
DOCKERFILE=app.dockerfile; \
IMAGE_NAME=perplexica; \
docker buildx build --platform linux/amd64,linux/arm64 \
--cache-from=type=registry,ref=itzcrazykns1337/${IMAGE_NAME}:main \
DOCKERFILE=app.dockerfile
IMAGE_NAME=perplexica
docker buildx build --platform linux/amd64 \
--cache-from=type=registry,ref=itzcrazykns1337/${IMAGE_NAME}:amd64 \
--cache-to=type=inline \
--provenance false \
-f $DOCKERFILE \
-t itzcrazykns1337/${IMAGE_NAME}:main \
-t itzcrazykns1337/${IMAGE_NAME}:amd64 \
--push .
- name: Build and push release Docker image
- name: Build and push AMD64 release Docker image
if: github.event_name == 'release'
run: |
docker buildx create --use
DOCKERFILE=app.dockerfile; \
IMAGE_NAME=perplexica; \
docker buildx build --platform linux/amd64,linux/arm64 \
--cache-from=type=registry,ref=itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }} \
DOCKERFILE=app.dockerfile
IMAGE_NAME=perplexica
docker buildx build --platform linux/amd64 \
--cache-from=type=registry,ref=itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }}-amd64 \
--cache-to=type=inline \
--provenance false \
-f $DOCKERFILE \
-t itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }} \
-t itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }}-amd64 \
--push .
build-arm64:
runs-on: ubuntu-24.04-arm
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
install: true
- name: Log in to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract version from release tag
if: github.event_name == 'release'
id: version
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
- name: Build and push ARM64 Docker image
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
run: |
DOCKERFILE=app.dockerfile
IMAGE_NAME=perplexica
docker buildx build --platform linux/arm64 \
--cache-from=type=registry,ref=itzcrazykns1337/${IMAGE_NAME}:arm64 \
--cache-to=type=inline \
--provenance false \
-f $DOCKERFILE \
-t itzcrazykns1337/${IMAGE_NAME}:arm64 \
--push .
- name: Build and push ARM64 release Docker image
if: github.event_name == 'release'
run: |
DOCKERFILE=app.dockerfile
IMAGE_NAME=perplexica
docker buildx build --platform linux/arm64 \
--cache-from=type=registry,ref=itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }}-arm64 \
--cache-to=type=inline \
--provenance false \
-f $DOCKERFILE \
-t itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }}-arm64 \
--push .
manifest:
needs: [build-amd64, build-arm64]
runs-on: ubuntu-latest
steps:
- name: Log in to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Create and push multi-arch manifest for main
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
run: |
IMAGE_NAME=perplexica
docker manifest create itzcrazykns1337/${IMAGE_NAME}:main \
--amend itzcrazykns1337/${IMAGE_NAME}:amd64 \
--amend itzcrazykns1337/${IMAGE_NAME}:arm64
docker manifest push itzcrazykns1337/${IMAGE_NAME}:main
- name: Create and push multi-arch manifest for releases
if: github.event_name == 'release'
run: |
IMAGE_NAME=perplexica
docker manifest create itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }} \
--amend itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }}-amd64 \
--amend itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }}-arm64
docker manifest push itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }}

View File

@ -153,7 +153,7 @@ For more details, check out the full documentation [here](https://github.com/Itz
## Expose Perplexica to network
You can access Perplexica over your home network by following our networking guide [here](https://github.com/ItzCrazyKns/Perplexica/blob/master/docs/installation/NETWORKING.md).
Perplexica runs on Next.js and handles all API requests. It works right away on the same network and stays accessible even with port forwarding.
## One-Click Deployment

View File

@ -1,4 +1,4 @@
FROM node:20.18.0-alpine AS builder
FROM node:20.18.0-slim AS builder
WORKDIR /home/perplexica
@ -12,7 +12,7 @@ COPY public ./public
RUN mkdir -p /home/perplexica/data
RUN yarn build
FROM node:20.18.0-alpine
FROM node:20.18.0-slim
WORKDIR /home/perplexica

View File

@ -16,6 +16,8 @@ services:
dockerfile: app.dockerfile
environment:
- SEARXNG_API_URL=http://searxng:8080
env_file:
- .env
ports:
- 3000:3000
networks:

View File

@ -40,37 +40,70 @@ type RecursivePartial<T> = {
[P in keyof T]?: RecursivePartial<T[P]>;
};
const loadConfig = () =>
toml.parse(
fs.readFileSync(path.join(process.cwd(), `${configFileName}`), 'utf-8'),
) as any as Config;
const loadConfig = () => {
const configPath = path.join(process.cwd(), configFileName);
if (!fs.existsSync(configPath) || fs.lstatSync(configPath).isDirectory()) {
return {} as Config;
}
return toml.parse(fs.readFileSync(configPath, 'utf-8')) as any as Config;
};
const getEnvVar = (key: string): string | undefined => {
return process.env[key];
};
const getConfigValue = (path: string[], defaultValue: string): string => {
// Convert path to environment variable name (e.g., ['MODELS', 'GROQ', 'API_KEY'] -> 'GROQ_API_KEY')
const envKey = path.slice(1).join('_').toUpperCase();
const envValue = getEnvVar(envKey);
if (envValue !== undefined) {
return envValue;
}
// Fall back to config.toml
let value: any = loadConfig();
for (const key of path) {
value = value[key];
if (value === undefined) {
return defaultValue;
}
}
return value;
};
export const getSimilarityMeasure = () =>
loadConfig().GENERAL.SIMILARITY_MEASURE;
getConfigValue(['GENERAL', 'SIMILARITY_MEASURE'], 'cosine');
export const getKeepAlive = () => loadConfig().GENERAL.KEEP_ALIVE;
export const getKeepAlive = () =>
getConfigValue(['GENERAL', 'KEEP_ALIVE'], '30s');
export const getOpenaiApiKey = () => loadConfig().MODELS.OPENAI.API_KEY;
export const getOpenaiApiKey = () =>
getConfigValue(['MODELS', 'OPENAI', 'API_KEY'], '');
export const getGroqApiKey = () => loadConfig().MODELS.GROQ.API_KEY;
export const getGroqApiKey = () =>
getConfigValue(['MODELS', 'GROQ', 'API_KEY'], '');
export const getAnthropicApiKey = () => loadConfig().MODELS.ANTHROPIC.API_KEY;
export const getAnthropicApiKey = () =>
getConfigValue(['MODELS', 'ANTHROPIC', 'API_KEY'], '');
export const getGeminiApiKey = () => loadConfig().MODELS.GEMINI.API_KEY;
export const getGeminiApiKey = () =>
getConfigValue(['MODELS', 'GEMINI', 'API_KEY'], '');
export const getSearxngApiEndpoint = () =>
process.env.SEARXNG_API_URL || loadConfig().API_ENDPOINTS.SEARXNG;
process.env.SEARXNG_API_URL || getConfigValue(['API_ENDPOINTS', 'SEARXNG'], '');
export const getOllamaApiEndpoint = () => loadConfig().MODELS.OLLAMA.API_URL;
export const getOllamaApiEndpoint = () =>
getConfigValue(['MODELS', 'OLLAMA', 'API_URL'], 'http://localhost:11434');
export const getCustomOpenaiApiKey = () =>
loadConfig().MODELS.CUSTOM_OPENAI.API_KEY;
getConfigValue(['MODELS', 'CUSTOM_OPENAI', 'API_KEY'], '');
export const getCustomOpenaiApiUrl = () =>
loadConfig().MODELS.CUSTOM_OPENAI.API_URL;
getConfigValue(['MODELS', 'CUSTOM_OPENAI', 'API_URL'], '');
export const getCustomOpenaiModelName = () =>
loadConfig().MODELS.CUSTOM_OPENAI.MODEL_NAME;
getConfigValue(['MODELS', 'CUSTOM_OPENAI', 'MODEL_NAME'], '');
const mergeConfigs = (current: any, update: any): any => {
if (update === null || update === undefined) {