improve: prepare for coolify and general self-hosting improvements (#175)
* fix(self-hosting): improve docker compose, add healthchecks, rename env SELF_HOSTED * improve(db): improve initial migration when no data exists * fix(db): misstakes were made * improve(dashboard): better curl preview depending on project type * fix(db): fix migrations * fix(onboarding): ensure we publish event correctly * wip * fix: curl preview * add coolify template * fix(dashboard): page -> route * fix * fix env
This commit is contained in:
committed by
GitHub
parent
4a2dbc5c4d
commit
92d62c3e5c
@@ -20,6 +20,7 @@ ENV PATH="$PNPM_HOME:$PATH"
|
||||
RUN apt-get update && apt-get install -y \
|
||||
openssl \
|
||||
libssl3 \
|
||||
curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN corepack enable
|
||||
@@ -62,6 +63,7 @@ WORKDIR /app/apps/dashboard
|
||||
# Will be replaced on runtime
|
||||
ENV NEXT_PUBLIC_DASHBOARD_URL="__NEXT_PUBLIC_DASHBOARD_URL__"
|
||||
ENV NEXT_PUBLIC_API_URL="__NEXT_PUBLIC_API_URL__"
|
||||
ENV NEXT_PUBLIC_SELF_HOSTED="__NEXT_PUBLIC_SELF_HOSTED__"
|
||||
|
||||
RUN pnpm run build
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ set -e
|
||||
echo "> Replace env variable placeholders with runtime values..."
|
||||
|
||||
# Define environment variables to check (space-separated string)
|
||||
variables_to_replace="NEXT_PUBLIC_DASHBOARD_URL NEXT_PUBLIC_API_URL"
|
||||
variables_to_replace="NEXT_PUBLIC_DASHBOARD_URL NEXT_PUBLIC_API_URL NEXT_PUBLIC_SELF_HOSTED"
|
||||
|
||||
# Replace env variable placeholders with real values
|
||||
for key in $variables_to_replace; do
|
||||
|
||||
@@ -99,7 +99,7 @@ export default function LayoutMenu({
|
||||
</div>
|
||||
</ProjectLink>
|
||||
)}
|
||||
{process.env.SELF_HOSTED && (
|
||||
{process.env.NEXT_PUBLIC_SELF_HOSTED === 'true' && (
|
||||
<a
|
||||
className="rounded p-2 row items-center gap-2 hover:bg-def-200"
|
||||
href="https://openpanel.dev/supporter"
|
||||
@@ -231,7 +231,7 @@ export default function LayoutMenu({
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
{process.env.SELF_HOSTED && (
|
||||
{process.env.NEXT_PUBLIC_SELF_HOSTED === 'true' && (
|
||||
<div className="mt-auto w-full ">
|
||||
<div className={cn('text-sm w-full text-center')}>
|
||||
Self-hosted instance
|
||||
|
||||
@@ -27,7 +27,7 @@ export default async function Page({
|
||||
params: { organizationSlug: organizationId },
|
||||
searchParams,
|
||||
}: PageProps) {
|
||||
const isBillingEnabled = !process.env.SELF_HOSTED;
|
||||
const isBillingEnabled = process.env.NEXT_PUBLIC_SELF_HOSTED !== 'true';
|
||||
const tab = parseAsStringEnum(['org', 'billing', 'members', 'invites'])
|
||||
.withDefault('org')
|
||||
.parseServerSide(searchParams.tab);
|
||||
|
||||
@@ -104,22 +104,34 @@ function CurlPreview({ project }: { project: IServiceProjectWithClients }) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const payload: Record<string, any> = {
|
||||
type: 'track',
|
||||
payload: {
|
||||
name: 'screen_view',
|
||||
properties: {
|
||||
__title: `Testing OpenPanel - ${project.name}`,
|
||||
__path: `${project.domain}`,
|
||||
__referrer: `${process.env.NEXT_PUBLIC_DASHBOARD_URL}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
if (project.types.includes('app')) {
|
||||
payload.payload.properties.__path = '/';
|
||||
delete payload.payload.properties.__referrer;
|
||||
}
|
||||
|
||||
if (project.types.includes('backend')) {
|
||||
payload.payload.name = 'test_event';
|
||||
payload.payload.properties = {};
|
||||
}
|
||||
|
||||
const code = `curl -X POST ${process.env.NEXT_PUBLIC_API_URL}/track \\
|
||||
-H "Content-Type: application/json" \\
|
||||
-H "openpanel-client-id: ${client.id}" \\
|
||||
-H "openpanel-client-secret: ${secret}" \\
|
||||
-H "User-Agent: ${window.navigator.userAgent}" \\
|
||||
-d '{
|
||||
"type": "track",
|
||||
"payload": {
|
||||
"name": "screen_view",
|
||||
"properties": {
|
||||
"__title": "Testing OpenPanel - ${project.name}",
|
||||
"__path": "${project.domain}",
|
||||
"__referrer": "${process.env.NEXT_PUBLIC_DASHBOARD_URL}"
|
||||
}
|
||||
}
|
||||
}'`;
|
||||
-H "User-Agent: ${typeof window !== 'undefined' ? window.navigator.userAgent : ''}" \\
|
||||
-d '${JSON.stringify(payload)}'`;
|
||||
|
||||
return (
|
||||
<div className="card">
|
||||
|
||||
@@ -27,7 +27,7 @@ const Verify = async ({ params: { projectId } }: Props) => {
|
||||
const [project, events] = await Promise.all([
|
||||
await getProjectWithClients(projectId),
|
||||
getEvents(
|
||||
`SELECT * FROM ${TABLE_NAMES.events} WHERE project_id = ${escape(projectId)} LIMIT 100`,
|
||||
`SELECT * FROM ${TABLE_NAMES.events} WHERE project_id = ${escape(projectId)} ORDER BY created_at DESC LIMIT 100`,
|
||||
),
|
||||
]);
|
||||
|
||||
@@ -35,7 +35,7 @@ const Verify = async ({ params: { projectId } }: Props) => {
|
||||
return <div>Hmm, something fishy is going on. Please reload the page.</div>;
|
||||
}
|
||||
|
||||
return <OnboardingVerify project={project} events={events} />;
|
||||
return <OnboardingVerify project={project} events={events.reverse()} />;
|
||||
};
|
||||
|
||||
export default Verify;
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
export const runtime = 'edge';
|
||||
export const dynamic = 'force-dynamic'; // no caching
|
||||
|
||||
export async function GET(request: Request) {
|
||||
const headers = Object.fromEntries(request.headers.entries());
|
||||
return Response.json({ headers, region: process.env.VERCEL_REGION });
|
||||
}
|
||||
5
apps/dashboard/src/app/api/healthcheck/route.tsx
Normal file
5
apps/dashboard/src/app/api/healthcheck/route.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
export const dynamic = 'force-dynamic'; // no caching
|
||||
|
||||
export async function GET(request: Request) {
|
||||
return Response.json({ status: 'ok' });
|
||||
}
|
||||
Reference in New Issue
Block a user