From e426c89cb2bd4c09f3cef6b16c462640646d2a64 Mon Sep 17 00:00:00 2001 From: Mauricio Siu Date: Sat, 7 Feb 2026 13:00:47 -0600 Subject: [PATCH 1/2] feat(gitea): add optional internal URL for Gitea integration - Introduced a new field `giteaInternalUrl` in the Gitea provider settings to allow users to specify an internal URL for OAuth token exchange when Gitea runs on the same instance as Dokploy. - Updated the Gitea provider forms to include the new field with appropriate descriptions. - Modified the token exchange logic to utilize the internal URL if provided, enhancing connectivity options for users. - Updated database schema to accommodate the new field. --- .../settings/git/gitea/add-gitea-provider.tsx | 31 + .../git/gitea/edit-gitea-provider.tsx | 30 + .../dokploy/drizzle/0141_plain_earthquake.sql | 1 + apps/dokploy/drizzle/meta/0141_snapshot.json | 7248 +++++++++++++++++ apps/dokploy/drizzle/meta/_journal.json | 7 + .../pages/api/providers/gitea/callback.ts | 4 +- .../pages/api/providers/gitea/helper.ts | 1 + packages/server/src/db/schema/gitea.ts | 3 + packages/server/src/db/schema/schema.dbml | 1 + packages/server/src/utils/providers/gitea.ts | 4 +- 10 files changed, 7328 insertions(+), 2 deletions(-) create mode 100644 apps/dokploy/drizzle/0141_plain_earthquake.sql create mode 100644 apps/dokploy/drizzle/meta/0141_snapshot.json diff --git a/apps/dokploy/components/dashboard/settings/git/gitea/add-gitea-provider.tsx b/apps/dokploy/components/dashboard/settings/git/gitea/add-gitea-provider.tsx index 4cb6bd50e..f474c376d 100644 --- a/apps/dokploy/components/dashboard/settings/git/gitea/add-gitea-provider.tsx +++ b/apps/dokploy/components/dashboard/settings/git/gitea/add-gitea-provider.tsx @@ -21,6 +21,7 @@ import { FormControl, FormField, FormItem, + FormDescription, FormLabel, FormMessage, } from "@/components/ui/form"; @@ -39,6 +40,10 @@ const Schema = z.object({ giteaUrl: z.string().min(1, { message: "Gitea URL is required", }), + giteaInternalUrl: z + .union([z.string().url(), z.literal("")]) + .optional() + .transform((v) => (v === "" ? undefined : v)), clientId: z.string().min(1, { message: "Client ID is required", }), @@ -70,6 +75,7 @@ export const AddGiteaProvider = () => { redirectUri: webhookUrl, name: "", giteaUrl: "https://gitea.com", + giteaInternalUrl: "", }, resolver: zodResolver(Schema), }); @@ -83,6 +89,7 @@ export const AddGiteaProvider = () => { redirectUri: webhookUrl, name: "", giteaUrl: "https://gitea.com", + giteaInternalUrl: "", }); }, [form, webhookUrl, isOpen]); @@ -95,6 +102,7 @@ export const AddGiteaProvider = () => { name: data.name, redirectUri: data.redirectUri, giteaUrl: data.giteaUrl, + giteaInternalUrl: data.giteaInternalUrl || undefined, organizationName: data.organizationName, })) as unknown as GiteaProviderResponse; @@ -223,6 +231,29 @@ export const AddGiteaProvider = () => { )} /> + ( + + Internal URL (Optional) + + + + + Use when Gitea runs on the same instance as Dokploy. + Used for OAuth token exchange to reach Gitea via + internal network (e.g. Docker service name). + + + + )} + /> + (v === "" ? undefined : v)), clientId: z.string().min(1, "Client ID is required"), clientSecret: z.string().min(1, "Client Secret is required"), }); @@ -94,6 +99,7 @@ export const EditGiteaProvider = ({ giteaId }: Props) => { defaultValues: { name: "", giteaUrl: "https://gitea.com", + giteaInternalUrl: "", clientId: "", clientSecret: "", }, @@ -104,6 +110,7 @@ export const EditGiteaProvider = ({ giteaId }: Props) => { form.reset({ name: gitea.gitProvider?.name || "", giteaUrl: gitea.giteaUrl || "https://gitea.com", + giteaInternalUrl: gitea.giteaInternalUrl || "", clientId: gitea.clientId || "", clientSecret: gitea.clientSecret || "", }); @@ -116,6 +123,7 @@ export const EditGiteaProvider = ({ giteaId }: Props) => { gitProviderId: gitea?.gitProvider?.gitProviderId || "", name: values.name, giteaUrl: values.giteaUrl, + giteaInternalUrl: values.giteaInternalUrl ?? null, clientId: values.clientId, clientSecret: values.clientSecret, }) @@ -224,6 +232,28 @@ export const EditGiteaProvider = ({ giteaId }: Props) => { )} /> + ( + + Internal URL (Optional) + + + + + Use when Gitea runs on the same instance as Dokploy. Used + for OAuth token exchange to reach Gitea via internal + network (e.g. Docker service name). + + + + )} + /> { // Helper to fetch access token from Gitea const fetchAccessToken = async (gitea: Gitea, code: string) => { - const response = await fetch(`${gitea.giteaUrl}/login/oauth/access_token`, { + // Use internal URL for token exchange when Gitea is on same instance as Dokploy + const baseUrl = gitea.giteaInternalUrl || gitea.giteaUrl; + const response = await fetch(`${baseUrl}/login/oauth/access_token`, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", diff --git a/apps/dokploy/pages/api/providers/gitea/helper.ts b/apps/dokploy/pages/api/providers/gitea/helper.ts index 90f09d571..207eb9075 100644 --- a/apps/dokploy/pages/api/providers/gitea/helper.ts +++ b/apps/dokploy/pages/api/providers/gitea/helper.ts @@ -9,6 +9,7 @@ export interface Gitea { refreshToken: string | null; expiresAt: number | null; giteaUrl: string; + giteaInternalUrl: string | null; clientId: string | null; clientSecret: string | null; organizationName?: string; diff --git a/packages/server/src/db/schema/gitea.ts b/packages/server/src/db/schema/gitea.ts index e7b4b9ea3..0f31adeb3 100644 --- a/packages/server/src/db/schema/gitea.ts +++ b/packages/server/src/db/schema/gitea.ts @@ -11,6 +11,7 @@ export const gitea = pgTable("gitea", { .primaryKey() .$defaultFn(() => nanoid()), giteaUrl: text("giteaUrl").default("https://gitea.com").notNull(), + giteaInternalUrl: text("giteaInternalUrl"), redirectUri: text("redirect_uri"), clientId: text("client_id"), clientSecret: text("client_secret"), @@ -40,6 +41,7 @@ export const apiCreateGitea = createSchema.extend({ redirectUri: z.string().optional(), name: z.string().min(1), giteaUrl: z.string().min(1), + giteaInternalUrl: z.string().optional().nullable(), giteaUsername: z.string().optional(), accessToken: z.string().optional(), refreshToken: z.string().optional(), @@ -76,6 +78,7 @@ export const apiUpdateGitea = createSchema.extend({ name: z.string().min(1), giteaId: z.string().min(1), giteaUrl: z.string().min(1), + giteaInternalUrl: z.string().optional().nullable(), giteaUsername: z.string().optional(), accessToken: z.string().optional(), refreshToken: z.string().optional(), diff --git a/packages/server/src/db/schema/schema.dbml b/packages/server/src/db/schema/schema.dbml index 8134885fe..271dca395 100644 --- a/packages/server/src/db/schema/schema.dbml +++ b/packages/server/src/db/schema/schema.dbml @@ -471,6 +471,7 @@ table git_provider { table gitea { giteaId text [pk, not null] giteaUrl text [not null, default: 'https://gitea.com'] + giteaInternalUrl text redirect_uri text client_id text client_secret text diff --git a/packages/server/src/utils/providers/gitea.ts b/packages/server/src/utils/providers/gitea.ts index ec8946ab3..1555e7713 100644 --- a/packages/server/src/utils/providers/gitea.ts +++ b/packages/server/src/utils/providers/gitea.ts @@ -49,7 +49,9 @@ export const refreshGiteaToken = async (giteaProviderId: string) => { } // Token is expired or about to expire, refresh it - const tokenEndpoint = `${giteaProvider.giteaUrl}/login/oauth/access_token`; + // Use internal URL when Gitea is on same instance as Dokploy + const baseUrl = giteaProvider.giteaInternalUrl || giteaProvider.giteaUrl; + const tokenEndpoint = `${baseUrl}/login/oauth/access_token`; const params = new URLSearchParams({ grant_type: "refresh_token", refresh_token: giteaProvider.refreshToken, From 1a810790cd1597a2d2fddd7725dd35ed19702b5f Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Sat, 7 Feb 2026 19:01:22 +0000 Subject: [PATCH 2/2] [autofix.ci] apply automated fixes --- .../dashboard/settings/git/gitea/edit-gitea-provider.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/dokploy/components/dashboard/settings/git/gitea/edit-gitea-provider.tsx b/apps/dokploy/components/dashboard/settings/git/gitea/edit-gitea-provider.tsx index 049a21eff..fe578acce 100644 --- a/apps/dokploy/components/dashboard/settings/git/gitea/edit-gitea-provider.tsx +++ b/apps/dokploy/components/dashboard/settings/git/gitea/edit-gitea-provider.tsx @@ -247,8 +247,8 @@ export const EditGiteaProvider = ({ giteaId }: Props) => { Use when Gitea runs on the same instance as Dokploy. Used - for OAuth token exchange to reach Gitea via internal - network (e.g. Docker service name). + for OAuth token exchange to reach Gitea via internal network + (e.g. Docker service name).