apply_patch.sh applies one or more GitHub PRs or branch URLs into a running Coolify container without rebuilding the image.
It is meant for fast self-hosted testing when you want to layer a patch set on top of an existing Coolify install and validate the result quickly.
remove_patch.sh removes the entries listed in remove_patch.txt by rebuilding the patched workspace with those entries excluded, then syncing the resulting delta into the container.
The removal script defaults to upstream/v4.x as its reset base, so it removes only the patches you list and does not move the workspace to next. Override with BASE_REF=... if you need a different reset branch.
Every entry in remove_patch.txt must also exist in patches.txt. The removal script treats patches.txt as the active patch stack and subtracts only the listed entries from it.
The apply script now builds one aggregate git workspace instead of copying each PR directly into the container one at a time.
That means it will:
- Clone the upstream Coolify repo into a temporary workspace.
- Check out a local work branch from
BASE_REF. - Read every GitHub PR or branch URL from
patches.txt. - Fetch each source ref.
- Generate that ref's diff against
BASE_REF. - Apply each diff into the same workspace with
git apply --3way. - Stop if patches conflict instead of silently overwriting later files.
- Compute the final merged file set.
- Copy changed files into the container and remove deleted files.
- Clear Laravel caches, optionally run migrations, and optionally restart the container.
This is safer than the older flow because overlapping PRs are now handled as a combined patch set instead of "last file copied wins".
Each non-empty, non-comment line in patches.txt must be one of these:
https://github.com/<owner>/<repo>/pull/<number>https://github.com/<owner>/<repo>/tree/<branch>
remove_patch.txt uses the same formats, but it is interpreted as the subset of patches.txt to remove.
The included patches.txt currently points at:
https://github.com/Iisyourdad/coolify/pull/4
https://github.com/Iisyourdad/coolify/pull/5Compared with the earlier script, this version:
- applies all entries into one shared workspace instead of copying each PR independently
- fails on conflicts instead of silently overwriting previous file copies
- handles deletions and renames when syncing into the container
- supports
DRY_RUN=trueso you can validate the combined patch set without touching Docker - clears Laravel caches by default after file sync
- can auto-run migrations when files under
database/migrations/changed - preserves the temp workspace automatically when the script fails
You need:
bashgittardockerunless you useDRY_RUN=true
You also need Docker access on the machine running the script.
If you are not using DRY_RUN=true, the target container must already exist.
From this directory:
chmod +x apply_patch.sh
./apply_patch.shTo remove selected patches:
chmod +x remove_patch.sh
./remove_patch.shBy default it reads patches.txt from the same directory as the script, patches the coolify container, clears caches, runs migrations only when migration files changed, and then restarts the container.
Preview the combined patch set without touching the container:
DRY_RUN=true ./apply_patch.shPatch a different container:
CONTAINER=my-coolify ./apply_patch.shUse a different patch list:
PATCHES_FILE=/path/to/patches.txt ./apply_patch.shUse a different removal list:
REMOVE_PATCHES_FILE=/path/to/remove_patch.txt ./remove_patch.shUse a different base ref:
BASE_REF=upstream/main ./apply_patch.shSkip the restart:
RESTART_CONTAINER=false ./apply_patch.shDisable cache clear:
CLEAR_CACHE=false ./apply_patch.shAlways run migrations:
RUN_MIGRATIONS=true ./apply_patch.shNever run migrations:
RUN_MIGRATIONS=false ./apply_patch.shRun an extra command inside the container after syncing files:
POST_APPLY_COMMAND='php artisan queue:restart' ./apply_patch.shKeep the temp workspace even on success:
KEEP_WORKDIR=true ./apply_patch.shUPSTREAM_URL: upstream repo to clone and compare againstBASE_REF: base ref used for diffs, defaultupstream/nextPATCHES_FILE: patch source list, default is the localpatches.txtREMOVE_PATCHES_FILE: removal list used byremove_patch.sh, default is the localremove_patch.txtCONTAINER: target Docker container name, defaultcoolifyDEST_DIR: destination path inside the container, default/var/www/htmlRESTART_CONTAINER:trueorfalseCLEAR_CACHE:trueorfalseRUN_MIGRATIONS:true,false, orautoPOST_APPLY_COMMAND: optional shell command to run inside the container after file syncDRY_RUN:trueorfalseKEEP_WORKDIR:trueorfalse
RUN_MIGRATIONS=auto means migrations only run when the final merged patch set changes files under database/migrations/.
- This script still overlays files directly into a running container. If the container is recreated or Coolify is updated, these changes can be lost.
- The script is safer than the original version, but it still assumes the listed PRs or branches are intended to be combined on top of the same
BASE_REF. - If a patch fails to apply cleanly, the script stops and keeps the temp workspace so you can inspect the conflict.
- If your patch set needs extra build or runtime steps beyond cache clear, migrations, or restart, use
POST_APPLY_COMMANDor handle those manually.