Skip to content

Gitea webhooks never created — OAuth scopes missing write:repository #4412

@lamualfa

Description

@lamualfa

To Reproduce

  1. Set up a self-hosted Gitea instance
  2. Add Gitea as a Git Provider in Dokploy via OAuth application
  3. Create a Compose project linked to a Gitea repository, enable "Auto Deploy"
  4. Push a commit to the Gitea repo
  5. No deployment is triggered — checking Gitea's database shows the webhook and hook_task tables are completely empty

Current vs. Expected behavior

Current: Dokploy never creates webhooks in Gitea. Pushing to a Gitea-linked repo does not trigger any deployment. The Gitea database tables webhook and hook_task remain empty.

Expected: Dokploy should automatically create a webhook in the Gitea repository when a Gitea-linked compose/application is saved with auto-deploy enabled. Push events should trigger deployments.

Root cause: The Gitea OAuth scopes across the codebase only request read permissions. Creating webhooks via POST /api/v1/repos/{owner}/{repo}/hooks requires the write:repository scope. The API call fails with:

token does not have at least one required scope, required=[write:repository], token scope=read:organization,read:repository,read:user

Since Dokploy silently fails to create the webhook, the user never gets any error feedback — deployments just never trigger.

Provide environment information

Operating System:
  OS: Ubuntu
  Arch: x86_64
Dokploy version: v0.29.4
Gitea version: 1.24.4
VPS Provider: Self-hosted
Applications: Docker Compose (Gitea-linked)

Which area(s) are affected?

  • Application
  • Docker Compose

Are you deploying the applications where Dokploy is installed or on a remote server?

Same server where Dokploy is installed

Additional context

Additional setup issues for self-hosted Gitea + Dokploy on the same Docker host

Even after manually creating the webhook (as a workaround), two more issues surfaced:

  1. Internal DNS resolution: Gitea's container could not resolve Dokploy's external domain. Had to use the Docker internal IP as the webhook target URL and add the internal subnet to Gitea's webhook.ALLOWED_HOST_LIST config (SSRF protection blocks private IPs by default). It would be helpful if Dokploy supported an internal callback URL for webhooks (similar to the existing giteaInternalUrl field used for clone operations).

  2. Compose webhook endpoint: The correct webhook path for compose deployments is /api/deploy/compose/{refreshToken}, not /api/deploy/{refreshToken}. If/when Dokploy auto-creates Gitea webhooks, it must use the correct endpoint based on whether the resource is an application or a compose.

Suggested fix

The scope needs to include write:repository in three files:

1. apps/dokploy/pages/api/providers/gitea/authorize.ts — line 37:

- authorizationUrl.searchParams.append("scope", "read:user repo");
+ authorizationUrl.searchParams.append("scope", "read:user repo write:repository");

2. apps/dokploy/utils/gitea-utils.ts — line 29:

- const scopes = "read:repository read:user read:organization";
+ const scopes = "read:repository write:repository read:user read:organization";

3. packages/server/src/db/schema/gitea.ts — line 24:

- scopes: text("scopes").default("repo,repo:status,read:user,read:org"),
+ scopes: text("scopes").default("repo,repo:status,read:user,read:org,write:repository"),

After fixing the scopes, Dokploy also needs webhook creation logic (similar to what the GitHub integration does). When a Gitea-linked application or compose is saved/updated with auto-deploy enabled, Dokploy should call the Gitea API:

POST {giteaUrl}/api/v1/repos/{owner}/{repo}/hooks

With body:

{
  "active": true,
  "config": {
    "content_type": "json",
    "url": "{dokployUrl}/api/deploy/{refreshToken}"
  },
  "events": ["push"],
  "type": "gitea"
}

Using the correct endpoint path:

  • For applications: /api/deploy/{refreshToken}
  • For compose: /api/deploy/compose/{refreshToken}

And if giteaInternalUrl is configured, prefer that for the webhook target URL to avoid DNS resolution issues when Gitea and Dokploy run on the same Docker host.

Will you send a PR to fix it?

No

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions