diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..f7c7604 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,52 @@ +FROM docker.io/golang:1.24-alpine3.21 AS build + +ENV CGO_ENABLED=1 + +RUN apk add --no-cache gcc musl-dev + +WORKDIR /usr/src/app + +COPY go.mod go.sum ./ +RUN go mod download + +COPY . . +RUN go build -v \ + -o /usr/local/bin/knotserver \ + -ldflags='-s -w -extldflags "-static"' \ + ./cmd/knotserver && \ + go build -v \ + -o /usr/local/bin/keyfetch \ + ./cmd/keyfetch && \ + go build -v \ + -o /usr/local/bin/repoguard \ + ./cmd/repoguard + +FROM docker.io/alpine:3.21 + +LABEL org.opencontainers.image.title=Tangled +LABEL org.opencontainers.image.description="Tangled is a decentralized and open code collaboration platform, built on atproto." +LABEL org.opencontainers.image.vendor=Tangled.sh +LABEL org.opencontainers.image.licenses=MIT +LABEL org.opencontainers.image.url=https://tangled.sh +LABEL org.opencontainers.image.source=https://tangled.sh/@tangled.sh/core + +RUN apk add --no-cache shadow s6-overlay execline openssh git && \ + adduser --disabled-password git && \ + # We need to set password anyway since otherwise ssh won't work + head -c 32 /dev/random | base64 | tr -dc 'a-zA-Z0-9' | passwd git --stdin && \ + mkdir /app && mkdir /home/git/repositories + +COPY --from=build /usr/local/bin/knotserver /usr/local/bin +COPY --from=build /usr/local/bin/keyfetch /usr/local/libexec/tangled-keyfetch +COPY --from=build /usr/local/bin/repoguard /home/git/repoguard +COPY docker/rootfs/ . + +RUN chown root:root /usr/local/libexec/tangled-keyfetch && \ + chmod 755 /usr/local/libexec/tangled-keyfetch && \ + chown git:git /home/git/repoguard && \ + chown git:git /app && chown git:git /home/git/repositories + +EXPOSE 22 +EXPOSE 5555 + +ENTRYPOINT ["/init"] diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..83670ab --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,16 @@ +services: + knot: + build: + context: .. + dockerfile: docker/Dockerfile + environment: + KNOT_SERVER_HOSTNAME: "knot.example.org" + KNOT_SERVER_SECRET: "secret" + KNOT_SERVER_DB_PATH: "/app/knotserver.db" + volumes: + - "./keys:/etc/ssh/keys" + - "./repositories:/home/git/repositories" + - "./server:/app" + ports: + - "5555:5555" + - "2222:22" diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/create-sshd-host-keys/type b/docker/rootfs/etc/s6-overlay/s6-rc.d/create-sshd-host-keys/type new file mode 100644 index 0000000..bdd22a1 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/create-sshd-host-keys/type @@ -0,0 +1 @@ +oneshot diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/create-sshd-host-keys/up b/docker/rootfs/etc/s6-overlay/s6-rc.d/create-sshd-host-keys/up new file mode 100644 index 0000000..d25eb18 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/create-sshd-host-keys/up @@ -0,0 +1 @@ +/etc/s6-overlay/scripts/create-sshd-host-keys diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/knotserver/dependencies.d/base b/docker/rootfs/etc/s6-overlay/s6-rc.d/knotserver/dependencies.d/base new file mode 100644 index 0000000..e69de29 diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/knotserver/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/knotserver/run new file mode 100755 index 0000000..d1e492e --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/knotserver/run @@ -0,0 +1,3 @@ +#!/command/with-contenv ash + +exec s6-setuidgid git /usr/local/bin/knotserver diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/knotserver/type b/docker/rootfs/etc/s6-overlay/s6-rc.d/knotserver/type new file mode 100644 index 0000000..5883cff --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/knotserver/type @@ -0,0 +1 @@ +longrun diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/sshd/dependencies.d/base b/docker/rootfs/etc/s6-overlay/s6-rc.d/sshd/dependencies.d/base new file mode 100644 index 0000000..e69de29 diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/sshd/dependencies.d/create-sshd-host-keys b/docker/rootfs/etc/s6-overlay/s6-rc.d/sshd/dependencies.d/create-sshd-host-keys new file mode 100644 index 0000000..e69de29 diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/sshd/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/sshd/run new file mode 100755 index 0000000..a7efea4 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/sshd/run @@ -0,0 +1,3 @@ +#!/usr/bin/execlineb -P + +/usr/sbin/sshd -e -D diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/sshd/type b/docker/rootfs/etc/s6-overlay/s6-rc.d/sshd/type new file mode 100644 index 0000000..5883cff --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/sshd/type @@ -0,0 +1 @@ +longrun diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/knotserver b/docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/knotserver new file mode 100644 index 0000000..e69de29 diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/sshd b/docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/sshd new file mode 100644 index 0000000..e69de29 diff --git a/docker/rootfs/etc/s6-overlay/scripts/create-sshd-host-keys b/docker/rootfs/etc/s6-overlay/scripts/create-sshd-host-keys new file mode 100755 index 0000000..e435536 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/scripts/create-sshd-host-keys @@ -0,0 +1,21 @@ +#!/usr/bin/execlineb -P + +foreground { + if -n { test -d /etc/ssh/keys } + mkdir /etc/ssh/keys +} + +foreground { + if -n { test -f /etc/ssh/keys/ssh_host_rsa_key } + ssh-keygen -t rsa -f /etc/ssh/keys/ssh_host_rsa_key -q -N "" +} + +foreground { + if -n { test -f /etc/ssh/keys/ssh_host_ecdsa_key } + ssh-keygen -t rsa -f /etc/ssh/keys/ssh_host_ecdsa_key -q -N "" +} + +foreground { + if -n { test -f /etc/ssh/keys/ssh_host_ed25519_key } + ssh-keygen -t rsa -f /etc/ssh/keys/ssh_host_ed25519_key -q -N "" +} diff --git a/docker/rootfs/etc/ssh/sshd_config.d/tangled_sshd.conf b/docker/rootfs/etc/ssh/sshd_config.d/tangled_sshd.conf new file mode 100644 index 0000000..d41844a --- /dev/null +++ b/docker/rootfs/etc/ssh/sshd_config.d/tangled_sshd.conf @@ -0,0 +1,9 @@ +HostKey /etc/ssh/keys/ssh_host_rsa_key +HostKey /etc/ssh/keys/ssh_host_ecdsa_key +HostKey /etc/ssh/keys/ssh_host_ed25519_key + +PasswordAuthentication no + +Match User git + AuthorizedKeysCommand /usr/local/libexec/tangled-keyfetch -git-dir /home/git/repositories + AuthorizedKeysCommandUser nobody