forked from tangled.org/core
Monorepo for Tangled — https://tangled.org

Docker support

This container embeds everything in one container:
- knotserver
- repoguard
- keyfetch
- sshd server

To supervise knot and sshd servers I decided to use well known s6-overlay. After first launch it execline script will create host keys. knotserver runs under git, sshd under root.

Changed files
+108
docker
rootfs
etc
s6-overlay
s6-rc.d
create-sshd-host-keys
knotserver
dependencies.d
run
sshd
user
contents.d
scripts
ssh
sshd_config.d
+52
docker/Dockerfile
···
+
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"]
+16
docker/docker-compose.yml
···
+
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"
+1
docker/rootfs/etc/s6-overlay/s6-rc.d/create-sshd-host-keys/type
···
+
oneshot
+1
docker/rootfs/etc/s6-overlay/s6-rc.d/create-sshd-host-keys/up
···
+
/etc/s6-overlay/scripts/create-sshd-host-keys
docker/rootfs/etc/s6-overlay/s6-rc.d/knotserver/dependencies.d/base

This is a binary file and will not be displayed.

+3
docker/rootfs/etc/s6-overlay/s6-rc.d/knotserver/run
···
+
#!/command/with-contenv ash
+
+
exec s6-setuidgid git /usr/local/bin/knotserver
+1
docker/rootfs/etc/s6-overlay/s6-rc.d/knotserver/type
···
+
longrun
docker/rootfs/etc/s6-overlay/s6-rc.d/sshd/dependencies.d/base

This is a binary file and will not be displayed.

docker/rootfs/etc/s6-overlay/s6-rc.d/sshd/dependencies.d/create-sshd-host-keys

This is a binary file and will not be displayed.

+3
docker/rootfs/etc/s6-overlay/s6-rc.d/sshd/run
···
+
#!/usr/bin/execlineb -P
+
+
/usr/sbin/sshd -e -D
+1
docker/rootfs/etc/s6-overlay/s6-rc.d/sshd/type
···
+
longrun
docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/knotserver

This is a binary file and will not be displayed.

docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/sshd

This is a binary file and will not be displayed.

+21
docker/rootfs/etc/s6-overlay/scripts/create-sshd-host-keys
···
+
#!/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 ""
+
}
+9
docker/rootfs/etc/ssh/sshd_config.d/tangled_sshd.conf
···
+
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