Files
MineGeo/docs/dokploy-deployment.md
pavel444-byte 2cb34fff86
Some checks failed
Deploy MineGeo to Dokploy / deploy (push) Failing after 5m50s
Pin Dokploy deployment URL in workflow
2026-10-17 13:21:24 +05:00

7.1 KiB

Dokploy deployment

The Gitea Actions workflow in .gitea/workflows/deploy-dokploy.yml deploys commits from master to Dokploy. The act_runner service runs in Docker on the MacBook, and this workflow selects its Linux Docker job environment with the ubuntu-latest label. The job checks out the private repository, creates a ZIP from the committed files only, and uploads it to Dokploy over HTTPS. Dokploy builds the Docker image from the repository's root Dockerfile on the VPS and performs the deployment. No image registry is used, and the workflow does not use SSH or the VPS root password.

One-time Dokploy setup

Create a Dokploy Application for MineGeo with the Drop (drag-and-drop) source provider. If the current Gitea-linked application cannot switch its provider, create a separate application and move the domain after its first successful deployment. Configure its build type as Dockerfile, with the Dockerfile and build context both at the repository root.

In the Dokploy application, open Environment and add both values under Build Time Arguments (not only under the regular runtime environment variables):

NEXT_PUBLIC_SUPABASE_URL=<your Supabase project URL>
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=<your Supabase publishable key>

These values are used by Next.js while compiling browser code. Setting them only as runtime environment variables does not populate Dockerfile ARG values, which causes the build error that says they were empty. Both values are public client configuration; do not put SUPABASE_SECRET_KEY in Build Time Arguments.

Also set the following in Dokploy's regular runtime environment:

  • NEXT_PUBLIC_SUPABASE_URL
  • NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY
  • SUPABASE_SECRET_KEY (server-only; never a build argument)
  • MINEGEO_URL=https://minegeo.site (the public HTTPS site origin)
  • MINEGEO_ALLOW_ANY_ORIGIN=false

Add any optional production variables from .env.example in Dokploy's environment settings. Do not upload .env.local or add it to the repository.

Building on a 2 GiB VPS

The Dockerfile uses npm run build:docker. It generates route types and runs the full TypeScript check in a separate process before compiling with Webpack. Next.js skips its duplicate TypeScript check only after the separate check succeeds. The Docker build enables Webpack's build worker and memory optimizations, and keeps page collection at one worker. Each build Node process has a 640 MiB JavaScript heap ceiling; this is not a limit on the total memory used by all processes or native libraries.

Dependencies are installed once, then pruned after compilation. The dependency installation for the final image no longer runs independently alongside the application build. Normal npm run build retains its usual type checking and bundler behavior. See Next.js's memory usage guide for the build options.

In Dokploy, keep builds concurrency at 1 on this VPS. Dokploy, PostgreSQL, Redis, Traefik, the running application, and the new build share the host's RAM. Avoid starting a panorama render during a deployment. Application runtime resource limits do not necessarily limit the Docker image build.

If the host freezes, capture these read-only diagnostics from the VPS shell before retrying. They print resource figures and Dokploy container state without environment values, API keys, private addresses, or repository names:

free -m
df -h /
vmstat 1 5
journalctl -k --since '30 minutes ago' --no-pager -o cat |
  awk '/oom-kill|Out of memory|Killed process/ {n++} END {print "Kernel OOM messages:", n+0}'
docker ps -aq --filter label=com.docker.swarm.service.name=dokploy |
  xargs -r docker inspect --format 'OOMKilled={{.State.OOMKilled}} ExitCode={{.State.ExitCode}} Started={{.State.StartedAt}} Finished={{.State.FinishedAt}}'

A startup log containing Cancelled 1 deployments is Dokploy's startup cleanup, not proof of a deployment timeout. Correlate container start/finish times and kernel OOM messages with the failed build. OOMKilled=false for Dokploy does not rule out a different process being killed or host-wide memory pressure. Journal permissions or missing history can also prevent the OOM count from being useful.

If swap is absent and memory pressure is confirmed, adding swap can prevent abrupt memory exhaustion, but it consumes disk space and can make builds slower. Approve server configuration changes separately; the repository changes do not create swap, restart services, or change server resource limits. If builds still exceed available memory, move image compilation to the MacBook runner and use a private image-transfer or private-registry workflow.

Gitea Actions secrets

Add the following repository Actions secrets in Gitea. The workflow pins Dokploy to https://dokploy.minegeo.site with a readonly shell assignment. Environment variables, .env files, and any existing DOKPLOY_URL secret cannot override that address. Changing the deployment domain requires editing the workflow.

  • DOKPLOY_API_KEY (create this in Dokploy)
  • DOKPLOY_APPLICATION_ID (copy this from the target Application)

In the runner's Gitea configuration, ensure ubuntu-latest is registered with the Docker schema, for example:

ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest

The workflow uses runs-on: ubuntu-latest, so it runs inside that Linux job container rather than directly on macOS or inside the act_runner service container. If your runner uses another Docker label, change runs-on to that label. The selected image needs git, curl, and Node.js so the job can archive the commit, upload it, and inspect deployment status. Gitea documents how runner labels select host versus Docker execution in the runner documentation.

Every push to master triggers a deployment. The job suppresses API response bodies and infrastructure addresses in its logs, waits for Dokploy's deployment status, and fails if the upload or deployment fails. Build logs remain available in the Dokploy dashboard.

git archive sends tracked files from that commit only. It does not include .git metadata, local environment files, untracked files, or local caches. The public Windows installer remains in the site image because MineGeo serves it from /desktop/; the large JVM heap dump was removed because it is neither application code nor a runtime asset. The Docker build also excludes the Minecraft Java workspace, Gradle caches, build output, and heap dumps.

The ZIP still contains the required Windows installer (about 96 MiB), so the Dokploy endpoint and any reverse proxy in front of it must accept the archive's full size. If the upload is rejected with a size-related HTTP error, use the Dokploy deployment logs to distinguish an upload limit from a build failure.

Dokploy documents the upload endpoint and deployment-status API in its Application API and Deployment API. This workflow uses TLS certificate verification and does not publish the image or source to a public service.