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' });
|
||||
}
|
||||
@@ -3,6 +3,14 @@ title: Changelog for self-hosting
|
||||
description: This is a list of changes that have been made to the self-hosting setup.
|
||||
---
|
||||
|
||||
## 1.2.0
|
||||
|
||||
We have renamed `SELF_HOSTED` to `NEXT_PUBLIC_SELF_HOSTED`. It's important to rename this env before your upgrade to this version.
|
||||
|
||||
## 1.1.1
|
||||
|
||||
Packed with new features since our first stable release.
|
||||
|
||||
## 1.0.0 (stable)
|
||||
|
||||
OpenPanel self-hosting is now in a stable state and should not be any breaking changes in the future.
|
||||
|
||||
@@ -15,6 +15,7 @@ RUN corepack enable && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
openssl \
|
||||
curl \
|
||||
libssl3 && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
@@ -36,7 +36,11 @@ export async function bootCron() {
|
||||
},
|
||||
];
|
||||
|
||||
if (process.env.SELF_HOSTED && process.env.NODE_ENV === 'production') {
|
||||
if (
|
||||
(process.env.NEXT_PUBLIC_SELF_HOSTED === 'true' ||
|
||||
process.env.SELF_HOSTED) &&
|
||||
process.env.NODE_ENV === 'production'
|
||||
) {
|
||||
jobs.push({
|
||||
name: 'ping',
|
||||
type: 'ping',
|
||||
|
||||
@@ -57,6 +57,10 @@ async function start() {
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/healthcheck', (req, res) => {
|
||||
res.json({ status: 'ok' });
|
||||
});
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log(`For the UI, open http://localhost:${PORT}/`);
|
||||
});
|
||||
|
||||
@@ -46,9 +46,10 @@ export async function deleteProjects(job: Job<CronQueuePayload>) {
|
||||
];
|
||||
|
||||
for (const table of tables) {
|
||||
const query = process.env.SELF_HOSTED
|
||||
? `ALTER TABLE ${table} DELETE WHERE ${where};`
|
||||
: `ALTER TABLE ${table}_replicated ON CLUSTER '{cluster}' DELETE WHERE ${where};`;
|
||||
const query =
|
||||
process.env.NEXT_PUBLIC_SELF_HOSTED === 'true'
|
||||
? `ALTER TABLE ${table} DELETE WHERE ${where};`
|
||||
: `ALTER TABLE ${table}_replicated ON CLUSTER '{cluster}' DELETE WHERE ${where};`;
|
||||
|
||||
await ch.command({
|
||||
query,
|
||||
|
||||
Reference in New Issue
Block a user