Skip to content

Commit cfe2252

Browse files
committed
updates for appservices
1 parent 9cdc440 commit cfe2252

17 files changed

+771
-102
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "synapse"]
2+
path = synapse
3+
url = https://github.com/element-hq/synapse.git

Dockerfile

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# syntax=docker/dockerfile:1
2+
# Custom Dockerfile for Synapse — replaces ghcr.io/astral-sh/uv with pip
3+
# for riscv64 compatibility. Based on upstream synapse/docker/Dockerfile.
4+
#
5+
# Changes from upstream:
6+
# - Stage 0: Replace uv image with python-slim, use pip-installed poetry
7+
# - Stage 1: Replace uv image with python, use pip instead of uv
8+
# - Stage 2: Add riscv64 to runtime dependency architectures
9+
10+
ARG DEBIAN_VERSION=trixie
11+
ARG PYTHON_VERSION=3.13
12+
ARG POETRY_VERSION=2.1.1
13+
14+
###
15+
### Stage 0: generate requirements.txt
16+
###
17+
### This stage is platform-agnostic, so we can use the build platform in case of cross-compilation.
18+
###
19+
FROM --platform=$BUILDPLATFORM docker.io/library/python:${PYTHON_VERSION}-slim-${DEBIAN_VERSION} AS requirements
20+
21+
WORKDIR /synapse
22+
23+
# Copy just what we need to run `poetry export`...
24+
COPY pyproject.toml poetry.lock /synapse/
25+
26+
# If specified, we won't verify the hashes of dependencies.
27+
# This is only needed if the hashes of dependencies cannot be checked for some
28+
# reason, such as when a git repository is used directly as a dependency.
29+
ARG TEST_ONLY_SKIP_DEP_HASH_VERIFICATION
30+
31+
# If specified, we won't use the Poetry lockfile.
32+
# Instead, we'll just install what a regular `pip install` would from PyPI.
33+
ARG TEST_ONLY_IGNORE_POETRY_LOCKFILE
34+
35+
# Export the dependencies, but only if we're actually going to use the Poetry lockfile.
36+
# Otherwise, just create an empty requirements file so that the Dockerfile can
37+
# proceed.
38+
ARG POETRY_VERSION
39+
RUN --mount=type=cache,target=/root/.cache/pip \
40+
if [ -z "$TEST_ONLY_IGNORE_POETRY_LOCKFILE" ]; then \
41+
pip install poetry==${POETRY_VERSION} poetry-plugin-export==1.9.0 && \
42+
poetry export --extras all -o /synapse/requirements.txt ${TEST_ONLY_SKIP_DEP_HASH_VERIFICATION:+--without-hashes}; \
43+
else \
44+
touch /synapse/requirements.txt; \
45+
fi
46+
47+
###
48+
### Stage 1: builder
49+
###
50+
FROM docker.io/library/python:${PYTHON_VERSION}-${DEBIAN_VERSION} AS builder
51+
52+
# Install rust and ensure its in the PATH
53+
ENV RUSTUP_HOME=/rust
54+
ENV CARGO_HOME=/cargo
55+
ENV PATH=/cargo/bin:/rust/bin:$PATH
56+
RUN mkdir /rust /cargo
57+
58+
RUN curl -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path --default-toolchain stable --profile minimal
59+
60+
# arm64 builds consume a lot of memory if `CARGO_NET_GIT_FETCH_WITH_CLI` is not
61+
# set to true, so we expose it as a build-arg.
62+
ARG CARGO_NET_GIT_FETCH_WITH_CLI=false
63+
ENV CARGO_NET_GIT_FETCH_WITH_CLI=$CARGO_NET_GIT_FETCH_WITH_CLI
64+
65+
# To speed up rebuilds, install all of the dependencies before we copy over
66+
# the whole synapse project, so that this layer in the Docker cache can be
67+
# used while you develop on the source
68+
#
69+
# This is aiming at installing the `[tool.poetry.depdendencies]` from pyproject.toml.
70+
COPY --from=requirements /synapse/requirements.txt /synapse/
71+
RUN --mount=type=cache,target=/root/.cache/pip \
72+
pip install --prefix="/install" --no-deps -r /synapse/requirements.txt
73+
74+
# Copy over the rest of the synapse source code.
75+
COPY synapse /synapse/synapse/
76+
COPY rust /synapse/rust/
77+
# ... and what we need to `pip install`.
78+
COPY pyproject.toml README.rst build_rust.py Cargo.toml Cargo.lock /synapse/
79+
80+
# Repeat of earlier build argument declaration, as this is a new build stage.
81+
ARG TEST_ONLY_IGNORE_POETRY_LOCKFILE
82+
83+
# Install the synapse package itself.
84+
# If we have populated requirements.txt, we don't install any dependencies
85+
# as we should already have those from the previous `pip install` step.
86+
RUN \
87+
--mount=type=cache,target=/root/.cache/pip \
88+
--mount=type=cache,target=/synapse/target,sharing=locked \
89+
--mount=type=cache,target=${CARGO_HOME}/registry,sharing=locked \
90+
if [ -z "$TEST_ONLY_IGNORE_POETRY_LOCKFILE" ]; then \
91+
pip install --prefix="/install" --no-deps /synapse[all]; \
92+
else \
93+
pip install --prefix="/install" /synapse[all]; \
94+
fi
95+
96+
###
97+
### Stage 2: runtime dependencies download for ARM64, AMD64, and RISCV64
98+
###
99+
FROM --platform=$BUILDPLATFORM docker.io/library/debian:${DEBIAN_VERSION} AS runtime-deps
100+
101+
# Tell apt to keep downloaded package files, as we're using cache mounts.
102+
RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
103+
104+
# Add all target architectures
105+
RUN dpkg --add-architecture arm64
106+
RUN dpkg --add-architecture amd64
107+
RUN dpkg --add-architecture riscv64
108+
109+
# Fetch the runtime dependencies debs for all architectures
110+
# We do that by building a recursive list of packages we need to download with `apt-cache depends`
111+
# and then downloading them with `apt-get download`.
112+
RUN \
113+
--mount=type=cache,target=/var/cache/apt,sharing=locked \
114+
--mount=type=cache,target=/var/lib/apt,sharing=locked \
115+
apt-get update -qq && \
116+
apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances --no-pre-depends \
117+
curl \
118+
gosu \
119+
libjpeg62-turbo \
120+
libpq5 \
121+
libwebp7 \
122+
xmlsec1 \
123+
libjemalloc2 \
124+
| grep '^\w' > /tmp/pkg-list && \
125+
for arch in arm64 amd64 riscv64; do \
126+
mkdir -p /tmp/debs-${arch} && \
127+
chown _apt:root /tmp/debs-${arch} && \
128+
cd /tmp/debs-${arch} && \
129+
apt-get -o APT::Architecture="${arch}" download $(cat /tmp/pkg-list); \
130+
done
131+
132+
# Extract the debs for each architecture
133+
RUN \
134+
for arch in arm64 amd64 riscv64; do \
135+
mkdir -p /install-${arch}/var/lib/dpkg/status.d/ && \
136+
for deb in /tmp/debs-${arch}/*.deb; do \
137+
package_name=$(dpkg-deb -I ${deb} | awk '/^ Package: .*$/ {print $2}'); \
138+
echo "Extracting: ${package_name}"; \
139+
dpkg --ctrl-tarfile $deb | tar -Ox ./control > /install-${arch}/var/lib/dpkg/status.d/${package_name}; \
140+
dpkg --extract $deb /install-${arch}; \
141+
done; \
142+
done
143+
144+
145+
###
146+
### Stage 3: runtime
147+
###
148+
149+
FROM docker.io/library/python:${PYTHON_VERSION}-slim-${DEBIAN_VERSION}
150+
151+
ARG TARGETARCH
152+
153+
LABEL org.opencontainers.image.url='https://github.com/element-hq/synapse'
154+
LABEL org.opencontainers.image.documentation='https://element-hq.github.io/synapse/latest/'
155+
LABEL org.opencontainers.image.source='https://github.com/element-hq/synapse.git'
156+
LABEL org.opencontainers.image.licenses='AGPL-3.0-or-later OR LicenseRef-Element-Commercial'
157+
158+
COPY --from=runtime-deps /install-${TARGETARCH}/etc /etc
159+
COPY --from=runtime-deps /install-${TARGETARCH}/usr /usr
160+
COPY --from=runtime-deps /install-${TARGETARCH}/var /var
161+
162+
# Copy the installed python packages from the builder stage.
163+
#
164+
# uv will generate a `.lock` file when installing packages, which we don't want
165+
# to copy to the final image.
166+
COPY --from=builder --exclude=.lock /install /usr/local
167+
COPY ./docker/start.py /start.py
168+
COPY ./docker/conf /conf
169+
170+
EXPOSE 8008/tcp 8009/tcp 8448/tcp
171+
172+
ENTRYPOINT ["/start.py"]
173+
174+
HEALTHCHECK --start-period=5s --interval=15s --timeout=5s \
175+
CMD curl -fSs http://localhost:8008/health || exit 1

Dockerfile-sqlite

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
FROM alpine:latest
2+
RUN apk add --no-cache sqlite
3+
ENTRYPOINT ["sqlite3"]

Makefile

Lines changed: 7 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,23 @@
1-
PACKAGE_ID := $(shell awk -F"'" '/id:/ {print $$2}' startos/manifest.ts)
2-
INGREDIENTS := $(shell start-cli s9pk list-ingredients 2>/dev/null)
31
SYNAPSE_ADMIN_VERSION = v0.11.1-etke50
42
SYNAPSE_ADMIN_CHECKSUM = c2a6888db6e4ac2766f17be2bc703d284a7e5f6e8af1c1a7fda0af9ae44e06aa
53

6-
.PHONY: all aarch64 x86_64 riscv64 arm arm64 x86 riscv arch/* clean install check-deps check-init package ingredients
7-
.DELETE_ON_ERROR:
8-
.SECONDARY:
4+
include s9pk.mk
95

10-
define SUMMARY
11-
@manifest=$$(start-cli s9pk inspect $(1) manifest); \
12-
size=$$(du -h $(1) | awk '{print $$1}'); \
13-
title=$$(printf '%s' "$$manifest" | jq -r .title); \
14-
version=$$(printf '%s' "$$manifest" | jq -r .version); \
15-
arches=$$(printf '%s' "$$manifest" | jq -r '[.images[].arch // []] | flatten | unique | join(", ")'); \
16-
sdkv=$$(printf '%s' "$$manifest" | jq -r .sdkVersion); \
17-
gitHash=$$(printf '%s' "$$manifest" | jq -r .gitHash | sed -E 's/(.*-modified)$$/\x1b[0;31m\1\x1b[0m/'); \
18-
printf "\n"; \
19-
printf "\033[1;32m✅ Build Complete!\033[0m\n"; \
20-
printf "\n"; \
21-
printf "\033[1;37m📦 $$title\033[0m \033[36mv$$version\033[0m\n"; \
22-
printf "───────────────────────────────\n"; \
23-
printf " \033[1;36mFilename:\033[0m %s\n" "$(1)"; \
24-
printf " \033[1;36mSize:\033[0m %s\n" "$$size"; \
25-
printf " \033[1;36mArch:\033[0m %s\n" "$$arches"; \
26-
printf " \033[1;36mSDK:\033[0m %s\n" "$$sdkv"; \
27-
printf " \033[1;36mGit:\033[0m %s\n" "$$gitHash"; \
28-
echo ""
29-
endef
30-
31-
all: $(PACKAGE_ID).s9pk
32-
$(call SUMMARY,$<)
33-
34-
arch/%: $(PACKAGE_ID)_%.s9pk
35-
$(call SUMMARY,$<)
36-
37-
x86 x86_64: arch/x86_64
38-
arm arm64 aarch64: arch/aarch64
39-
riscv riscv64: arch/riscv64
40-
41-
$(PACKAGE_ID).s9pk: $(INGREDIENTS) .git/HEAD .git/index assets/synapse-admin
42-
@$(MAKE) --no-print-directory ingredients
43-
@echo " Packing '$@'..."
44-
start-cli s9pk pack -o $@
45-
46-
$(PACKAGE_ID)_%.s9pk: $(INGREDIENTS) .git/HEAD .git/index assets/synapse-admin
47-
@$(MAKE) --no-print-directory ingredients
48-
@echo " Packing '$@'..."
49-
start-cli s9pk pack --arch=$* -o $@
50-
51-
ingredients: $(INGREDIENTS)
52-
@echo " Re-evaluating ingredients..."
53-
54-
install: | check-deps check-init
55-
@HOST=$$(awk -F'/' '/^host:/ {print $$3}' ~/.startos/config.yaml); \
56-
if [ -z "$$HOST" ]; then \
57-
echo "Error: You must define \"host: http://server-name.local\" in ~/.startos/config.yaml"; \
58-
exit 1; \
59-
fi; \
60-
S9PK=$$(ls -t *.s9pk 2>/dev/null | head -1); \
61-
if [ -z "$$S9PK" ]; then \
62-
echo "Error: No .s9pk file found. Run 'make' first."; \
63-
exit 1; \
64-
fi; \
65-
printf "\n🚀 Installing %s to %s ...\n" "$$S9PK" "$$HOST"; \
66-
start-cli package install -s "$$S9PK"
67-
68-
check-deps:
69-
@command -v start-cli >/dev/null || \
70-
(echo "Error: start-cli not found. Please see https://docs.start9.com/latest/developer-guide/sdk/installing-the-sdk" && exit 1)
71-
@command -v npm >/dev/null || \
72-
(echo "Error: npm not found. Please install Node.js and npm." && exit 1)
73-
74-
check-init:
75-
@if [ ! -f ~/.startos/developer.key.pem ]; then \
76-
echo "Initializing StartOS developer environment..."; \
77-
start-cli init-key; \
78-
fi
79-
80-
javascript/index.js: $(shell find startos -type f) tsconfig.json node_modules
81-
npm run build
82-
83-
node_modules: package-lock.json
84-
npm ci
85-
86-
package-lock.json: package.json
87-
npm i
6+
# Add synapse-admin as additional prerequisite for s9pk targets
7+
$(BASE_NAME).s9pk: assets/synapse-admin
8+
$(BASE_NAME)_%.s9pk: assets/synapse-admin
889

10+
# Override clean to also remove synapse-admin artifacts
8911
clean:
9012
@echo "Cleaning up build artifacts..."
9113
@rm -rf $(PACKAGE_ID).s9pk $(PACKAGE_ID)_x86_64.s9pk $(PACKAGE_ID)_aarch64.s9pk $(PACKAGE_ID)_riscv64.s9pk javascript assets/synapse-admin tmp node_modules
9214

93-
94-
# Custom recipes for synapse
95-
15+
# Custom recipes for synapse-admin
9616
assets/synapse-admin: tmp/synapse-admin.tar.gz
9717
rm -rf assets/synapse-admin
9818
tar -xzvf tmp/synapse-admin.tar.gz -C assets
9919

10020
tmp/synapse-admin.tar.gz:
10121
mkdir -p tmp
10222
(cd tmp && curl --progress-bar -OL https://github.com/etkecc/synapse-admin/releases/download/$(SYNAPSE_ADMIN_VERSION)/synapse-admin.tar.gz)
103-
echo "$(SYNAPSE_ADMIN_CHECKSUM) tmp/synapse-admin.tar.gz" | shasum -a 256 -c
23+
echo "$(SYNAPSE_ADMIN_CHECKSUM) tmp/synapse-admin.tar.gz" | shasum -a 256 -c

package-lock.json

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
"check": "tsc --noEmit"
77
},
88
"dependencies": {
9-
"@start9labs/start-sdk": "^0.4.0-beta.46"
9+
"@start9labs/start-sdk": "^0.4.0-beta.48"
1010
},
1111
"devDependencies": {
12-
"@types/node": "^20.19.27",
12+
"@types/node": "^22.19.0",
1313
"@vercel/ncc": "^0.38.4",
1414
"prettier": "^3.7.4",
1515
"typescript": "^5.9.3"

0 commit comments

Comments
 (0)