Fix git deploy permissions: entrypoint chown and no remote set-url

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-06 22:45:55 +03:00
parent d10f25eb06
commit 6a6704bc4b
3 changed files with 77 additions and 25 deletions
+6 -4
View File
@@ -6,6 +6,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
libpq-dev \ libpq-dev \
gcc \ gcc \
git \ git \
gosu \
docker.io \ docker.io \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
@@ -14,10 +15,10 @@ RUN pip install --no-cache-dir -r requirements.txt
COPY . . COPY . .
RUN mkdir -p /app/uploads && adduser --disabled-password --gecos "" appuser \ RUN mkdir -p /app/uploads \
&& chown -R appuser:appuser /app && adduser --disabled-password --gecos "" appuser \
&& chown -R appuser:appuser /app \
USER appuser && chmod +x /app/entrypoint.sh
ENV FLASK_APP=wsgi:app ENV FLASK_APP=wsgi:app
ENV GIT_CONFIG_COUNT=1 ENV GIT_CONFIG_COUNT=1
@@ -26,4 +27,5 @@ ENV GIT_CONFIG_VALUE_0=/repo
EXPOSE 8000 EXPOSE 8000
ENTRYPOINT ["/app/entrypoint.sh"]
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "2", "--timeout", "120", "wsgi:app"] CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "2", "--timeout", "120", "wsgi:app"]
+59 -20
View File
@@ -38,38 +38,77 @@ def run_git(args, timeout=120):
return True, result.stdout.strip() return True, result.stdout.strip()
def run_ls_remote(extra_args=None, timeout=60):
remote = get_git_remote()
if not remote:
return False, "GIT_REMOTE_URL не задан", []
cmd = ["git", "ls-remote", remote]
if extra_args:
cmd.extend(extra_args)
result = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
if result.returncode != 0:
return False, (result.stderr or result.stdout or "ls-remote error").strip(), []
return True, "", result.stdout.splitlines()
def fetch_remote(): def fetch_remote():
remote = get_git_remote() remote = get_git_remote()
if remote: if not remote:
ok, msg = run_git(["remote", "set-url", "origin", remote])
if not ok:
return False, msg
return run_git(["fetch", "--all", "--tags", "--prune"], timeout=180) return run_git(["fetch", "--all", "--tags", "--prune"], timeout=180)
# Fetch from URL directly — do not write remote.origin.url to .git/config
return run_git(
[
"fetch",
"--tags",
"--prune",
remote,
"+refs/heads/*:refs/remotes/origin/*",
"+refs/tags/*:refs/tags/*",
],
timeout=180,
)
def list_tags(): def list_tags():
ok, msg = fetch_remote() ok, err, lines = run_ls_remote(["--tags"])
if not ok: if not ok:
return [], msg return [], err
ok, out = run_git(["tag", "--sort=-version:refname"])
if not ok: tags = []
return [], out for line in lines:
return [line for line in out.splitlines() if line.strip()], None parts = line.split()
if len(parts) < 2:
continue
ref = parts[1]
if not ref.startswith("refs/tags/"):
continue
tag = ref.removeprefix("refs/tags/")
if tag.endswith("^{}"):
continue
tags.append(tag)
tags = sorted(set(tags), reverse=True)
return tags, None
def list_branches(): def list_branches():
ok, msg = fetch_remote() ok, err, lines = run_ls_remote(["--heads"])
if not ok: if not ok:
return [], msg return [], err
ok, out = run_git(["branch", "-a", "--format=%(refname:short)"])
if not ok:
return [], out
branches = [] branches = []
for line in out.splitlines(): for line in lines:
name = line.strip().replace("origin/", "") parts = line.split()
if name and name not in branches and "HEAD" not in name: if len(parts) < 2:
branches.append(name) continue
return branches, None ref = parts[1]
if ref.startswith("refs/heads/"):
branches.append(ref.removeprefix("refs/heads/"))
return sorted(set(branches)), None
def get_current_version(): def get_current_version():
+11
View File
@@ -0,0 +1,11 @@
#!/bin/sh
set -e
# Mounted /repo belongs to host user; appuser needs write access for git deploy.
if [ "$ALLOW_GIT_DEPLOY" = "true" ] || [ "$ALLOW_GIT_DEPLOY" = "1" ] || [ "$ALLOW_GIT_DEPLOY" = "yes" ]; then
if [ -d /repo ]; then
chown -R appuser:appuser /repo
fi
fi
exec gosu appuser "$@"