|
1
|
#!/bin/bash |
|
2
|
# fossilrepo entrypoint — starts sshd as root, drops to app user for gunicorn. |
|
3
|
# |
|
4
|
# sshd needs root for port binding and key access. |
|
5
|
# gunicorn runs as the unprivileged 'app' user. |
|
6
|
|
|
7
|
set -euo pipefail |
|
8
|
|
|
9
|
# Ensure SSH host keys exist (persistent across restarts via volume) |
|
10
|
if [ ! -f /etc/ssh/ssh_host_ed25519_key ]; then |
|
11
|
ssh-keygen -A |
|
12
|
fi |
|
13
|
|
|
14
|
# Ensure data dirs exist with correct permissions |
|
15
|
mkdir -p /data/ssh /data/repos /data/trash |
|
16
|
touch /data/ssh/authorized_keys |
|
17
|
chmod 600 /data/ssh/authorized_keys |
|
18
|
chown -R fossil:fossil /data/ssh |
|
19
|
chown -R app:app /data/repos /data/trash |
|
20
|
# fossil user needs read access to repos for SSH sync |
|
21
|
chmod -R g+r /data/repos |
|
22
|
|
|
23
|
# Start sshd in the background (runs as root) |
|
24
|
/usr/sbin/sshd -p 2222 -e & |
|
25
|
SSHD_PID=$! |
|
26
|
echo "sshd started (PID $SSHD_PID) on port 2222" |
|
27
|
|
|
28
|
# Trap signals to clean up sshd |
|
29
|
cleanup() { |
|
30
|
echo "Shutting down sshd..." |
|
31
|
kill "$SSHD_PID" 2>/dev/null || true |
|
32
|
wait "$SSHD_PID" 2>/dev/null || true |
|
33
|
} |
|
34
|
trap cleanup EXIT TERM INT |
|
35
|
|
|
36
|
# Drop to non-root 'app' user for gunicorn |
|
37
|
exec gosu app gunicorn config.wsgi:application \ |
|
38
|
--bind 0.0.0.0:8000 \ |
|
39
|
--workers 3 \ |
|
40
|
--timeout 120 |
|
41
|
|