mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-11 20:05:25 +00:00
Add support for configurable domain sub-paths (#74)
This commit is contained in:
parent
558d049d38
commit
83270ffdc9
7 changed files with 101 additions and 19 deletions
|
|
@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- Added `DOMAIN_SUB_PATH` environment variable to allow overriding the default domain subpath. ([#74](https://github.com/sourcebot-dev/sourcebot/pull/74))
|
||||
|
||||
## [2.4.3] - 2024-11-18
|
||||
|
||||
### Changed
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ ENV NEXT_TELEMETRY_DISABLED=1
|
|||
# @see: https://phase.dev/blog/nextjs-public-runtime-variables/
|
||||
ARG NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED=BAKED_NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED
|
||||
ARG NEXT_PUBLIC_SOURCEBOT_VERSION=BAKED_NEXT_PUBLIC_SOURCEBOT_VERSION
|
||||
# @note: leading "/" is required for the basePath property. @see: https://nextjs.org/docs/app/api-reference/next-config-js/basePath
|
||||
ARG NEXT_PUBLIC_DOMAIN_SUB_PATH=/BAKED_NEXT_PUBLIC_DOMAIN_SUB_PATH
|
||||
RUN yarn workspace @sourcebot/web build
|
||||
|
||||
# ------ Build Backend ------
|
||||
|
|
@ -54,6 +56,11 @@ RUN echo "Sourcebot Version: $SOURCEBOT_VERSION"
|
|||
# Valid values are: debug, info, warn, error
|
||||
ENV SOURCEBOT_LOG_LEVEL=info
|
||||
|
||||
# Configures the sub-path of the domain to serve Sourcebot from.
|
||||
# For example, if DOMAIN_SUB_PATH is set to "/sb", Sourcebot
|
||||
# will serve from http(s)://example.com/sb
|
||||
ENV DOMAIN_SUB_PATH=/
|
||||
|
||||
# @note: This is also set in .env
|
||||
ENV POSTHOG_KEY=phc_VFn4CkEGHRdlVyOOw8mfkoj1DKVoG6y1007EClvzAnS
|
||||
ENV NEXT_PUBLIC_POSTHOG_KEY=$POSTHOG_KEY
|
||||
|
|
|
|||
|
|
@ -70,23 +70,69 @@ fi
|
|||
|
||||
echo -e "\e[34m[Info] Using config file at: '$CONFIG_PATH'.\e[0m"
|
||||
|
||||
# Update nextjs public env variables w/o requiring a rebuild.
|
||||
# Update NextJs public env variables w/o requiring a rebuild.
|
||||
# @see: https://phase.dev/blog/nextjs-public-runtime-variables/
|
||||
{
|
||||
# Infer NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED if it is not set
|
||||
if [ -z "$NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED" ] && [ ! -z "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
|
||||
export NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED="$SOURCEBOT_TELEMETRY_DISABLED"
|
||||
fi
|
||||
|
||||
# Infer NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED if it is not set
|
||||
if [ -z "$NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED" ] && [ ! -z "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
|
||||
export NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED="$SOURCEBOT_TELEMETRY_DISABLED"
|
||||
fi
|
||||
# Infer NEXT_PUBLIC_SOURCEBOT_VERSION if it is not set
|
||||
if [ -z "$NEXT_PUBLIC_SOURCEBOT_VERSION" ] && [ ! -z "$SOURCEBOT_VERSION" ]; then
|
||||
export NEXT_PUBLIC_SOURCEBOT_VERSION="$SOURCEBOT_VERSION"
|
||||
fi
|
||||
|
||||
# Infer NEXT_PUBLIC_SOURCEBOT_VERSION if it is not set
|
||||
if [ -z "$NEXT_PUBLIC_SOURCEBOT_VERSION" ] && [ ! -z "$SOURCEBOT_VERSION" ]; then
|
||||
export NEXT_PUBLIC_SOURCEBOT_VERSION="$SOURCEBOT_VERSION"
|
||||
fi
|
||||
# Iterate over all .js files in .next & public, making substitutions for the `BAKED_` sentinal values
|
||||
# with their actual desired runtime value.
|
||||
find /app/packages/web/public /app/packages/web/.next -type f -name "*.js" |
|
||||
while read file; do
|
||||
sed -i "s|BAKED_NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED|${NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED}|g" "$file"
|
||||
sed -i "s|BAKED_NEXT_PUBLIC_SOURCEBOT_VERSION|${NEXT_PUBLIC_SOURCEBOT_VERSION}|g" "$file"
|
||||
done
|
||||
}
|
||||
|
||||
find /app/packages/web/public /app/packages/web/.next -type f -name "*.js" |
|
||||
while read file; do
|
||||
sed -i "s|BAKED_NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED|${NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED}|g" "$file"
|
||||
sed -i "s|BAKED_NEXT_PUBLIC_SOURCEBOT_VERSION|${NEXT_PUBLIC_SOURCEBOT_VERSION}|g" "$file"
|
||||
done
|
||||
|
||||
# Update specifically NEXT_PUBLIC_DOMAIN_SUB_PATH w/o requiring a rebuild.
|
||||
# Ultimately, the DOMAIN_SUB_PATH sets the `basePath` param in the next.config.mjs.
|
||||
# Similar to above, we pass in a `BAKED_` sentinal value into next.config.mjs at build
|
||||
# time. Unlike above, the `basePath` configuration is set in files other than just javascript
|
||||
# code (e.g., manifest files, css files, etc.), so this section has subtle differences.
|
||||
#
|
||||
# @see: https://nextjs.org/docs/app/api-reference/next-config-js/basePath
|
||||
# @see: https://phase.dev/blog/nextjs-public-runtime-variables/
|
||||
{
|
||||
if [ ! -z "$DOMAIN_SUB_PATH" ]; then
|
||||
# If the sub-path is "/", this creates problems with certain replacements. For example:
|
||||
# /BAKED_NEXT_PUBLIC_DOMAIN_SUB_PATH/_next/image -> //_next/image (notice the double slash...)
|
||||
# To get around this, we default to an empty sub-path, which is the default when no sub-path is defined.
|
||||
if [ "$DOMAIN_SUB_PATH" = "/" ]; then
|
||||
DOMAIN_SUB_PATH=""
|
||||
|
||||
# Otherwise, we need to ensure that the sub-path starts with a slash, since this is a requirement
|
||||
# for the basePath property. For example, assume DOMAIN_SUB_PATH=/bot, then:
|
||||
# /BAKED_NEXT_PUBLIC_DOMAIN_SUB_PATH/_next/image -> /bot/_next/image
|
||||
elif [[ ! "$DOMAIN_SUB_PATH" =~ ^/ ]]; then
|
||||
DOMAIN_SUB_PATH="/$DOMAIN_SUB_PATH"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -z "$DOMAIN_SUB_PATH" ]; then
|
||||
echo -e "\e[34m[Info] DOMAIN_SUB_PATH was set to "$DOMAIN_SUB_PATH". Overriding default path.\e[0m"
|
||||
fi
|
||||
|
||||
# Always set NEXT_PUBLIC_DOMAIN_SUB_PATH to DOMAIN_SUB_PATH (even if it is empty!!)
|
||||
export NEXT_PUBLIC_DOMAIN_SUB_PATH="$DOMAIN_SUB_PATH"
|
||||
|
||||
# Iterate over _all_ files in the web directory, making substitutions for the `BAKED_` sentinal values
|
||||
# with their actual desired runtime value.
|
||||
find /app/packages/web -type f |
|
||||
while read file; do
|
||||
# @note: the leading "/" is required here as it is included at build time. See Dockerfile.
|
||||
sed -i "s|/BAKED_NEXT_PUBLIC_DOMAIN_SUB_PATH|${NEXT_PUBLIC_DOMAIN_SUB_PATH}|g" "$file"
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
# Run supervisord
|
||||
exec supervisord -c /etc/supervisor/conf.d/supervisord.conf
|
||||
|
|
@ -20,7 +20,12 @@ const nextConfig = {
|
|||
];
|
||||
},
|
||||
// This is required to support PostHog trailing slash API requests
|
||||
skipTrailingSlashRedirect: true,
|
||||
skipTrailingSlashRedirect: true,
|
||||
|
||||
// @note: this is evaluated at build time.
|
||||
...(process.env.NEXT_PUBLIC_DOMAIN_SUB_PATH ? {
|
||||
basePath: process.env.NEXT_PUBLIC_DOMAIN_SUB_PATH,
|
||||
} : {})
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
'use client';
|
||||
|
||||
import { NEXT_PUBLIC_DOMAIN_SUB_PATH } from "@/lib/environment.client";
|
||||
import { fileSourceResponseSchema, listRepositoriesResponseSchema, searchResponseSchema } from "@/lib/schemas";
|
||||
import { FileSourceRequest, FileSourceResponse, ListRepositoriesResponse, SearchRequest, SearchResponse } from "@/lib/types";
|
||||
|
||||
export const search = async (body: SearchRequest): Promise<SearchResponse> => {
|
||||
const result = await fetch(`/api/search`, {
|
||||
const path = resolveServerPath("/api/search");
|
||||
const result = await fetch(path, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
|
|
@ -14,7 +18,8 @@ export const search = async (body: SearchRequest): Promise<SearchResponse> => {
|
|||
}
|
||||
|
||||
export const fetchFileSource = async (body: FileSourceRequest): Promise<FileSourceResponse> => {
|
||||
const result = await fetch(`/api/source`, {
|
||||
const path = resolveServerPath("/api/source");
|
||||
const result = await fetch(path, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
|
|
@ -26,7 +31,8 @@ export const fetchFileSource = async (body: FileSourceRequest): Promise<FileSour
|
|||
}
|
||||
|
||||
export const getRepos = async (): Promise<ListRepositoriesResponse> => {
|
||||
const result = await fetch('/api/repos', {
|
||||
const path = resolveServerPath("/api/repos");
|
||||
const result = await fetch(path, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
|
|
@ -35,3 +41,12 @@ export const getRepos = async (): Promise<ListRepositoriesResponse> => {
|
|||
|
||||
return listRepositoriesResponseSchema.parse(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a subpath to a api route on the server (e.g., /api/search),
|
||||
* returns the full path to that route on the server, taking into account
|
||||
* the base path (if any).
|
||||
*/
|
||||
export const resolveServerPath = (path: string) => {
|
||||
return `${NEXT_PUBLIC_DOMAIN_SUB_PATH}${path}`;
|
||||
}
|
||||
|
|
@ -2,11 +2,15 @@
|
|||
import { NEXT_PUBLIC_POSTHOG_KEY, NEXT_PUBLIC_POSTHOG_UI_HOST, NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED } from '@/lib/environment.client'
|
||||
import posthog from 'posthog-js'
|
||||
import { PostHogProvider } from 'posthog-js/react'
|
||||
import { resolveServerPath } from './api/(client)/client'
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
if (!NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED) {
|
||||
// @see next.config.mjs for path rewrites to the "/ingest" route.
|
||||
const posthogHostPath = resolveServerPath('/ingest');
|
||||
|
||||
posthog.init(NEXT_PUBLIC_POSTHOG_KEY!, {
|
||||
api_host: "/ingest",
|
||||
api_host: posthogHostPath,
|
||||
ui_host: NEXT_PUBLIC_POSTHOG_UI_HOST,
|
||||
person_profiles: 'identified_only',
|
||||
capture_pageview: false, // Disable automatic pageview capture
|
||||
|
|
|
|||
|
|
@ -8,3 +8,4 @@ export const NEXT_PUBLIC_POSTHOG_UI_HOST = getEnv(process.env.NEXT_PUBLIC_POSTHO
|
|||
export const NEXT_PUBLIC_POSTHOG_ASSET_HOST = getEnv(process.env.NEXT_PUBLIC_POSTHOG_ASSET_HOST);
|
||||
export const NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED = getEnvBoolean(process.env.NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED, false);
|
||||
export const NEXT_PUBLIC_SOURCEBOT_VERSION = getEnv(process.env.NEXT_PUBLIC_SOURCEBOT_VERSION, "unknown");
|
||||
export const NEXT_PUBLIC_DOMAIN_SUB_PATH = getEnv(process.env.NEXT_PUBLIC_DOMAIN_SUB_PATH, "");
|
||||
|
|
|
|||
Loading…
Reference in a new issue