Skip to content

Commit

Permalink
Make all the env vars dynamic (#1092)
Browse files Browse the repository at this point in the history
* Add truncate to task model (#1090)

* retry text area height (#1091)

* Make all the env vars dynamic

* only check for db at runtime

* remove secret from build step

* improve dockerfile

* Wrap db in singleton

* add .env.local to dockerignore

* changes to dockerfile

* lint

* aborted generations

* move collections build check

* Use a single dockerfile

* lint

* fixes

* lint

* don't return db during building

* remove dev

---------

Co-authored-by: Victor Muštar <[email protected]>
  • Loading branch information
nsarrazin and gary149 authored May 3, 2024
1 parent 75b2833 commit 552abe2
Show file tree
Hide file tree
Showing 99 changed files with 590 additions and 649 deletions.
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ node_modules/
.svelte-kit/
.env*
!.env
!.env.local
.env.local
1 change: 1 addition & 0 deletions .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ MODELS=`[
"parameters": {
"temperature": 0.1,
"stop": ["<|eot_id|>"],
"truncate": 1024,
},
"unlisted": true
}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/build-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
branches:
- "*"
paths:
- "Dockerfile.local"
- "Dockerfile"
- "entrypoint.sh"
workflow_dispatch:
release:
Expand Down Expand Up @@ -62,7 +62,7 @@ jobs:
uses: docker/build-push-action@v5
with:
context: .
file: Dockerfile.local
file: Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
Expand Down Expand Up @@ -116,7 +116,7 @@ jobs:
uses: docker/build-push-action@v5
with:
context: .
file: Dockerfile.local
file: Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
Expand Down
66 changes: 56 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# syntax=docker/dockerfile:1
# read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
# you will also find guides on how best to write your Dockerfile
ARG INCLUDE_DB=false

# stage that install the dependencies
FROM node:20 as builder-production

WORKDIR /app
Expand All @@ -12,31 +15,74 @@ RUN --mount=type=cache,target=/app/.npm \

FROM builder-production as builder

ARG APP_BASE=
ARG PUBLIC_APP_COLOR=blue

RUN --mount=type=cache,target=/app/.npm \
npm set cache /app/.npm && \
npm ci

COPY --link --chown=1000 . .

RUN APP_BASE="/chat" npm run build
RUN #npm run build
RUN npm run build

FROM node:20-slim
RUN npm install -g vite-node
# mongo image
FROM mongo:latest as mongo

RUN userdel -r node
# image to be used if INCLUDE_DB is false
FROM node:20-slim as local_db_false

# image to be used if INCLUDE_DB is true
FROM node:20-slim as local_db_true

RUN apt-get update
RUN apt-get install gnupg curl -y
# copy mongo from the other stage
COPY --from=mongo /usr/bin/mongo* /usr/bin/

ENV MONGODB_URL=mongodb://localhost:27017
RUN mkdir -p /data/db
RUN chown -R 1000:1000 /data/db

# final image
FROM local_db_${INCLUDE_DB} as final

# build arg to determine if the database should be included
ARG INCLUDE_DB=false
ENV INCLUDE_DB=${INCLUDE_DB}

# svelte requires APP_BASE at build time so it must be passed as a build arg
ARG APP_BASE=
# tailwind requires the primary theme to be known at build time so it must be passed as a build arg
ARG PUBLIC_APP_COLOR=blue

RUN useradd -m -u 1000 user

# install dotenv-cli
RUN npm install -g dotenv-cli

# switch to a user that works for spaces
RUN userdel -r node
RUN useradd -m -u 1000 user
USER user

ENV HOME=/home/user \
PATH=/home/user/.local/bin:$PATH

WORKDIR /app

COPY --from=builder-production --chown=1000 /app/node_modules /app/node_modules
COPY --link --chown=1000 package.json /app/package.json
COPY --from=builder --chown=1000 /app/build /app/build
# add a .env.local if the user doesn't bind a volume to it
RUN touch /app/.env.local

# get the default config, the entrypoint script and the server script
COPY --chown=1000 package.json /app/package.json
COPY --chown=1000 .env /app/.env
COPY --chown=1000 entrypoint.sh /app/entrypoint.sh
COPY --chown=1000 gcp-*.json /app/

CMD node /app/build/index.js
#import the build & dependencies
COPY --from=builder --chown=1000 /app/build /app/build
COPY --from=builder --chown=1000 /app/node_modules /app/node_modules

RUN chmod +x /app/entrypoint.sh

CMD ["/bin/bash", "-c", "/app/entrypoint.sh"]
28 changes: 0 additions & 28 deletions Dockerfile.local

This file was deleted.

18 changes: 3 additions & 15 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,16 @@ ENV_LOCAL_PATH=/app/.env.local

if test -z "${DOTENV_LOCAL}" ; then
if ! test -f "${ENV_LOCAL_PATH}" ; then
echo "DOTENV_LOCAL was not found in the ENV variables and .env.local is not set using a bind volume. We are using the default .env config."
echo "DOTENV_LOCAL was not found in the ENV variables and .env.local is not set using a bind volume. Make sure to set environment variables properly. "
fi;
else
echo "DOTENV_LOCAL was found in the ENV variables. Creating .env.local file."
cat <<< "$DOTENV_LOCAL" > ${ENV_LOCAL_PATH}
fi;

if [ "$INCLUDE_DB" = "true" ] ; then
echo "INCLUDE_DB is set to true."

MONGODB_CONFIG="MONGODB_URL=mongodb://localhost:27017"
if ! grep -q "^${MONGODB_CONFIG}$" ${ENV_LOCAL_PATH}; then
echo "Appending MONGODB_URL"
touch /app/.env.local
echo -e "\n${MONGODB_CONFIG}" >> ${ENV_LOCAL_PATH}
fi

mkdir -p /data/db
mongod &
echo "Starting local MongoDB instance"

nohup mongod &
fi;

npm run build
npm vite-node --options.transformMode.ssr='/.*/' /app/scripts/server.ts -- --host 0.0.0.0 --port 3000
dotenv -e /app/.env -c -- node /app/build/index.js -- --host 0.0.0.0 --port 3000
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite-node --options.transformMode.ssr='/.*/' scripts/server.ts",
"preview": "vite-node --options.transformMode.ssr='/.*/' scripts/server.,js",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --plugin-search-dir . --check . && eslint .",
Expand Down
37 changes: 21 additions & 16 deletions scripts/populate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import readline from "readline";
import minimist from "minimist";

// @ts-expect-error: vite-node makes the var available but the typescript compiler doesn't see them
import { MONGODB_URL } from "$env/static/private";
import { env } from "$env/dynamic/private";

import { faker } from "@faker-js/faker";
import { ObjectId } from "mongodb";

import { Database } from "$lib/server/database";
// @ts-expect-error: vite-node makes the var available but the typescript compiler doesn't see them
import { collections } from "$lib/server/database";
import { models } from "../src/lib/server/models.ts";
import type { User } from "../src/lib/types/User";
import type { Assistant } from "../src/lib/types/Assistant";
Expand All @@ -17,6 +18,7 @@ import { defaultEmbeddingModel } from "../src/lib/server/embeddingModels.ts";
import { Message } from "../src/lib/types/Message.ts";

import { addChildren } from "../src/lib/utils/tree/addChildren.ts";
import { generateSearchTokens } from "../src/lib/utils/searchTokens.ts";

const rl = readline.createInterface({
input: process.stdin,
Expand Down Expand Up @@ -107,10 +109,10 @@ async function seed() {

if (flags.includes("reset")) {
console.log("Starting reset of DB");
await Database.getInstance().getCollections().users.deleteMany({});
await Database.getInstance().getCollections().settings.deleteMany({});
await Database.getInstance().getCollections().assistants.deleteMany({});
await Database.getInstance().getCollections().conversations.deleteMany({});
await collections.users.deleteMany({});
await collections.settings.deleteMany({});
await collections.assistants.deleteMany({});
await collections.conversations.deleteMany({});
console.log("Reset done");
}

Expand All @@ -126,11 +128,11 @@ async function seed() {
avatarUrl: faker.image.avatar(),
}));

await Database.getInstance().getCollections().users.insertMany(newUsers);
await collections.users.insertMany(newUsers);
console.log("Done creating users.");
}

const users = await Database.getInstance().getCollections().users.find().toArray();
const users = await collections.users.find().toArray();
if (flags.includes("settings") || flags.includes("all")) {
console.log("Updating settings for all users");
users.forEach(async (user) => {
Expand All @@ -145,7 +147,7 @@ async function seed() {
customPrompts: {},
assistants: [],
};
await Database.getInstance().getCollections().settings.updateOne(
await collections.settings.updateOne(
{ userId: user._id },
{ $set: { ...settings } },
{ upsert: true }
Expand All @@ -158,10 +160,11 @@ async function seed() {
console.log("Creating assistants for all users");
await Promise.all(
users.map(async (user) => {
const name = faker.animal.insect();
const assistants = faker.helpers.multiple<Assistant>(
() => ({
_id: new ObjectId(),
name: faker.animal.insect(),
name,
createdById: user._id,
createdByName: user.username,
createdAt: faker.date.recent({ days: 30 }),
Expand All @@ -174,11 +177,13 @@ async function seed() {
exampleInputs: faker.helpers.multiple(() => faker.lorem.sentence(), {
count: faker.number.int({ min: 0, max: 4 }),
}),
searchTokens: generateSearchTokens(name),
last24HoursCount: faker.number.int({ min: 0, max: 1000 }),
}),
{ count: faker.number.int({ min: 3, max: 10 }) }
);
await Database.getInstance().getCollections().assistants.insertMany(assistants);
await Database.getInstance().getCollections().settings.updateOne(
await collections.assistants.insertMany(assistants);
await collections.settings.updateOne(
{ userId: user._id },
{ $set: { assistants: assistants.map((a) => a._id.toString()) } },
{ upsert: true }
Expand All @@ -194,7 +199,7 @@ async function seed() {
users.map(async (user) => {
const conversations = faker.helpers.multiple(
async () => {
const settings = await Database.getInstance().getCollections().settings.findOne<Settings>({ userId: user._id });
const settings = await collections.settings.findOne<Settings>({ userId: user._id });

const assistantId =
settings?.assistants && settings.assistants.length > 0 && faker.datatype.boolean(0.1)
Expand All @@ -203,7 +208,7 @@ async function seed() {

const preprompt =
(assistantId
? await Database.getInstance().getCollections().assistants
? await collections.assistants
.findOne({ _id: assistantId })
.then((assistant: Assistant) => assistant?.preprompt ?? "")
: faker.helpers.maybe(() => faker.hacker.phrase(), { probability: 0.5 })) ?? "";
Expand All @@ -229,7 +234,7 @@ async function seed() {
{ count: faker.number.int({ min: 10, max: 200 }) }
);

await Database.getInstance().getCollections().conversations.insertMany(await Promise.all(conversations));
await collections.conversations.insertMany(await Promise.all(conversations));
})
);
console.log("Done creating conversations.");
Expand All @@ -241,7 +246,7 @@ async function seed() {
try {
rl.question(
"You're about to run a seeding script on the following MONGODB_URL: \x1b[31m" +
MONGODB_URL +
env.MONGODB_URL +
"\x1b[0m\n\n With the following flags: \x1b[31m" +
flags.join("\x1b[0m , \x1b[31m") +
"\x1b[0m\n \n\n Are you sure you want to continue? (yes/no): ",
Expand Down
40 changes: 0 additions & 40 deletions scripts/server.ts

This file was deleted.

Loading

0 comments on commit 552abe2

Please sign in to comment.