Initialize ChuBlog backend with SSH Git publishing

This commit is contained in:
TheBadRoger committed 2026-10-15 20:08:15 +08:00
commit a631d75cee
31 files changed
+4850

No files matched your search

+16
View File
@@ -0,0 +1,16 @@
*
!Dockerfile
!bin/
!bin/chublog-api
!bin/chusql-server
!bin/csql-bootstrap
!bin/libchusql_core_storage.so
!sshd_config
!gitconfig
!authorized-keys.sh
!ssh-entrypoint.sh
!init-volumes.sh
!db-entrypoint.sh
!chusql.toml
!hooks/
!hooks/pre-receive
+25
View File
@@ -0,0 +1,25 @@
{$SITE_ADDRESS:localhost} {
request_body {
max_size 8KB
}
header {
X-Content-Type-Options nosniff
Referrer-Policy no-referrer
-Server
}
handle /api/* {
reverse_proxy api:3001 {
transport http {
read_timeout 15s
write_timeout 15s
}
}
}
handle {
respond "ChuBlog backend is running. Frontend is planned separately." 200
}
log {
output stdout
format json
}
}
+38
View File
@@ -0,0 +1,38 @@
FROM debian:trixie-slim AS base
ARG DEBIAN_MIRROR=deb.debian.org
RUN sed -i "s|deb.debian.org|${DEBIAN_MIRROR}|g" /etc/apt/sources.list.d/debian.sources
RUN apt-get update && apt-get install -y --no-install-recommends git ca-certificates libgmp10 curl util-linux && rm -rf /var/lib/apt/lists/*
COPY bin/chublog-api /usr/local/bin/chublog-api
COPY gitconfig /etc/chublog/gitconfig
RUN groupadd -g 10002 ingress && useradd -u 10001 -g ingress -M -s /usr/sbin/nologin blog
FROM base AS api
USER 10001:10002
ENV API_BIND=0.0.0.0:3001 DATA_DIR=/data CHUBLOG_SSH_CONFIG=/auth/publishers.json INGRESS_REPO=/srv/ingress/content.git RUST_LOG=info
ENTRYPOINT ["chublog-api"]
FROM base AS ssh
RUN apt-get update && apt-get install -y --no-install-recommends openssh-server && rm -rf /var/lib/apt/lists/* && useradd -u 10002 -g ingress -M -d /srv/ingress -s /bin/sh git && passwd -d git
COPY sshd_config /etc/ssh/sshd_config
COPY hooks /hooks
COPY ssh-entrypoint.sh /usr/local/bin/ssh-entrypoint
COPY authorized-keys.sh /usr/local/bin/chublog-authorized-keys
RUN chmod 755 /hooks/pre-receive /usr/local/bin/ssh-entrypoint /usr/local/bin/chublog-authorized-keys
ENTRYPOINT ["/usr/local/bin/ssh-entrypoint"]
FROM base AS init
COPY init-volumes.sh /usr/local/bin/init-volumes
RUN chmod 755 /usr/local/bin/init-volumes
ENTRYPOINT ["/usr/local/bin/init-volumes"]
FROM debian:trixie-slim AS database
ARG DEBIAN_MIRROR=deb.debian.org
RUN sed -i "s|deb.debian.org|${DEBIAN_MIRROR}|g" /etc/apt/sources.list.d/debian.sources
RUN apt-get update && apt-get install -y --no-install-recommends libgmp10 ca-certificates && rm -rf /var/lib/apt/lists/* && useradd -u 10003 -M -s /usr/sbin/nologin chusql
COPY bin/chusql-server bin/csql-bootstrap bin/libchusql_core_storage.so /usr/local/bin/
COPY chusql.toml /etc/chusql/settings.toml
COPY db-entrypoint.sh /usr/local/bin/db-entrypoint
RUN chmod 755 /usr/local/bin/db-entrypoint
ENV LD_LIBRARY_PATH=/usr/local/bin
USER 10003:10003
ENTRYPOINT ["/usr/local/bin/db-entrypoint"]
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
set -eu
exec /usr/local/bin/chublog-api authorized-keys
+9
View File
@@ -0,0 +1,9 @@
[storage]
data_dir = "/var/lib/chusql"
log_files = "/var/log/chusql"
[server]
listen_host = "0.0.0.0"
port = 7777
max_message = 1048576
max_rows = 1000
sudo_auth_user = ""
+137
View File
@@ -0,0 +1,137 @@
name: chublog
x-logging: &logging
driver: json-file
options:
max-size: "10m"
max-file: "3"
services:
init:
build: { context: ., target: init, args: { DEBIAN_MIRROR: "${DEBIAN_MIRROR:-deb.debian.org}" } }
volumes:
- content:/data
- authorization:/auth
- ingress:/srv/ingress
- database:/db-data
- db-logs:/db-logs
restart: "no"
network_mode: none
logging: *logging
api:
build: { context: ., target: api, args: { DEBIAN_MIRROR: "${DEBIAN_MIRROR:-deb.debian.org}" } }
depends_on:
init: { condition: service_completed_successfully }
environment:
PUBLIC_ORIGIN: ${PUBLIC_ORIGIN:?Set PUBLIC_ORIGIN}
ADMIN_USERNAME: ${ADMIN_USERNAME:-admin}
ADMIN_PASSWORD_HASH: ${ADMIN_PASSWORD_HASH:?Set ADMIN_PASSWORD_HASH}
ALLOW_REGISTRATION: ${ALLOW_REGISTRATION:-false}
CHUSQL_ADDRESS: db:7777
CHUSQL_USER: chublog_index
CHUSQL_PASSWORD: ${CHUSQL_PASSWORD:?Set CHUSQL_PASSWORD}
CHUSQL_DATABASE: chublog
volumes:
- content:/data
- authorization:/auth
- ingress:/srv/ingress:ro
read_only: true
tmpfs: ["/tmp:size=16m,noexec,nosuid"]
cap_drop: [ALL]
security_opt: [no-new-privileges:true]
pids_limit: 128
mem_limit: 512m
cpus: 1.0
networks: [backend]
restart: unless-stopped
healthcheck:
test: [CMD, curl, -fsS, http://127.0.0.1:3001/api/health]
interval: 10s
timeout: 3s
retries: 3
logging: *logging
ssh:
build: { context: ., target: ssh, args: { DEBIAN_MIRROR: "${DEBIAN_MIRROR:-deb.debian.org}" } }
depends_on:
init: { condition: service_completed_successfully }
api: { condition: service_healthy }
environment:
CHUBLOG_SSH_CONFIG: /auth/publishers.json
ports: ["${SSH_BIND:-0.0.0.0}:${SSH_PORT:-2222}:2222"]
volumes:
- ingress:/srv/ingress
- authorization:/auth:ro
- ssh-host-keys:/host-keys
read_only: true
tmpfs: ["/run:size=8m,noexec,nosuid", "/tmp:size=16m,noexec,nosuid"]
cap_drop: [ALL]
cap_add: [SETUID, SETGID, SYS_CHROOT]
security_opt: [no-new-privileges:true]
pids_limit: 64
mem_limit: 256m
cpus: 1.0
networks: [ssh]
restart: unless-stopped
logging: *logging
db:
build: { context: ., target: database, args: { DEBIAN_MIRROR: "${DEBIAN_MIRROR:-deb.debian.org}" } }
depends_on:
init: { condition: service_completed_successfully }
environment:
CHUSQL_ROOT_PASSWORD: ${CHUSQL_ROOT_PASSWORD:?Set CHUSQL_ROOT_PASSWORD}
volumes:
- database:/var/lib/chusql
- db-logs:/var/log/chusql
read_only: true
tmpfs: ["/tmp:size=16m,noexec,nosuid"]
cap_drop: [ALL]
security_opt: [no-new-privileges:true]
pids_limit: 64
mem_limit: 512m
cpus: 1.0
networks: [backend]
restart: unless-stopped
logging: *logging
db-init:
build: { context: ., target: api, args: { DEBIAN_MIRROR: "${DEBIAN_MIRROR:-deb.debian.org}" } }
profiles: [setup]
entrypoint: [chublog-api, provision-db]
environment:
CHUSQL_ADDRESS: db:7777
CHUSQL_ROOT_PASSWORD: ${CHUSQL_ROOT_PASSWORD:?Set CHUSQL_ROOT_PASSWORD}
CHUSQL_PASSWORD: ${CHUSQL_PASSWORD:?Set CHUSQL_PASSWORD}
depends_on: [db]
networks: [backend]
cap_drop: [ALL]
security_opt: [no-new-privileges:true]
read_only: true
restart: "no"
logging: *logging
caddy:
image: caddy:2
environment:
SITE_ADDRESS: ${SITE_ADDRESS:-localhost}
ports: ["${HTTP_BIND:-0.0.0.0}:${HTTP_PORT:-80}:80", "${HTTP_BIND:-0.0.0.0}:${HTTPS_PORT:-443}:443"]
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy-data:/data
- caddy-config:/config
cap_drop: [ALL]
cap_add: [NET_BIND_SERVICE]
security_opt: [no-new-privileges:true]
networks: [backend, edge]
depends_on:
api: { condition: service_healthy }
restart: unless-stopped
logging: *logging
networks:
backend: { internal: true }
ssh: {}
edge: {}
volumes:
content: {}
ingress: {}
authorization: {}
ssh-host-keys: {}
database: {}
db-logs: {}
caddy-data: {}
caddy-config: {}
+7
View File
@@ -0,0 +1,7 @@
#!/bin/sh
set -eu
if [ ! -d /var/lib/chusql/system ]; then
printf '%s\n' "$CHUSQL_ROOT_PASSWORD" | csql-bootstrap --config /etc/chusql/settings.toml --user root --password-stdin
fi
unset CHUSQL_ROOT_PASSWORD
exec chusql-server --config /etc/chusql/settings.toml --listen-host 0.0.0.0 --port 7777
+2
View File
@@ -0,0 +1,2 @@
[safe]
directory = /srv/ingress/content.git
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
set -eu
exec /usr/local/bin/chublog-api pre-receive
+14
View File
@@ -0,0 +1,14 @@
#!/bin/sh
set -eu
mkdir -p /data /auth /srv/ingress /db-data /db-logs
chown 10001:10002 /data /auth
chmod 700 /data
chmod 755 /auth
chown 10002:10002 /srv/ingress
chmod 750 /srv/ingress
chown 10003:10003 /db-data /db-logs
if [ ! -d /srv/ingress/content.git ]; then
setpriv --reuid=10002 --regid=10002 --clear-groups git init --bare --initial-branch=main --shared=group /srv/ingress/content.git
setpriv --reuid=10002 --regid=10002 --clear-groups git -C /srv/ingress/content.git config receive.denyNonFastForwards true
setpriv --reuid=10002 --regid=10002 --clear-groups git -C /srv/ingress/content.git config receive.denyDeletes true
fi
+7
View File
@@ -0,0 +1,7 @@
#!/bin/sh
set -eu
mkdir -p /run/sshd
if [ ! -f /host-keys/ssh_host_ed25519_key ]; then
ssh-keygen -q -t ed25519 -N '' -f /host-keys/ssh_host_ed25519_key
fi
exec /usr/sbin/sshd -D -e
+33
View File
@@ -0,0 +1,33 @@
Port 2222
ListenAddress 0.0.0.0
HostKey /host-keys/ssh_host_ed25519_key
PidFile /run/sshd.pid
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitEmptyPasswords no
PubkeyAuthentication yes
AuthenticationMethods publickey
PubkeyAcceptedAlgorithms ssh-ed25519
AllowUsers git
AuthorizedKeysFile none
AuthorizedKeysCommand /usr/local/bin/chublog-authorized-keys
AuthorizedKeysCommandUser root
AllowAgentForwarding no
AllowTcpForwarding no
AllowStreamLocalForwarding no
GatewayPorts no
PermitTunnel no
X11Forwarding no
PermitTTY no
PermitUserEnvironment no
PermitUserRC no
DisableForwarding yes
MaxAuthTries 3
MaxSessions 1
MaxStartups 3:50:10
LoginGraceTime 20
ClientAliveInterval 15
ClientAliveCountMax 3
LogLevel VERBOSE
UsePAM no