Skip to content

Commit cc595bf

Browse files
committed
Run production from built JavaScript
Add a tsdown build for the server entrypoint and switch production and worker scripts to run the compiled JavaScript with Node.js. The build keeps the module graph unbundled, emits ESM .js files, and copies runtime assets needed by the compiled server. Build the Docker image in two stages so the runtime image includes the compiled dist tree while still installing only production dependencies. Update manual installation docs and the changelog to describe the new build step. Fix #357 Assisted-by: Codex:gpt-5.5
1 parent 06bc348 commit cc595bf

11 files changed

Lines changed: 601 additions & 13 deletions

File tree

.dockerignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.env
22
.git/
33
.github/
4+
dist/
45
node_modules/

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
.env
22
assets/
3+
dist/
34
fedify-hollo-*.tgz
45
*.jsonl
56
node_modules/

CHANGES.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ To be released.
3838
- Preview card scraping, media processing, and authentication helpers now
3939
load on demand instead of eagerly during route registration.
4040

41+
- Added a production build step powered by `tsdown`, and changed
42+
`pnpm prod` and `pnpm worker` to run the compiled JavaScript output with
43+
Node.js instead of running TypeScript through `tsx`. Docker images now
44+
build these JavaScript files in a builder stage and include them in the
45+
runtime image. [[#357]]
46+
4147
- Moved remote replies scraping from synchronous post ingestion to a
4248
rate-limited background worker. Remote posts now enqueue reply collection
4349
scraping jobs instead of fetching nested replies inline, which prevents
@@ -145,6 +151,7 @@ To be released.
145151

146152
[#348]: https://github.com/fedify-dev/hollo/issues/348
147153
[#350]: https://github.com/fedify-dev/hollo/issues/350
154+
[#357]: https://github.com/fedify-dev/hollo/issues/357
148155
[#409]: https://github.com/fedify-dev/hollo/issues/409
149156
[#420]: https://github.com/fedify-dev/hollo/issues/420
150157
[#424]: https://github.com/fedify-dev/hollo/issues/424

Dockerfile

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
FROM docker.io/node:24-alpine AS builder
2+
3+
ARG VERSION
4+
5+
RUN apk add --no-cache ffmpeg jq libstdc++ pnpm
6+
7+
COPY pnpm-lock.yaml package.json /app/
8+
WORKDIR /app/
9+
RUN pnpm install --frozen-lockfile
10+
11+
COPY . /app/
12+
RUN \
13+
if [ "$VERSION" != "" ]; then \
14+
jq --arg version "$VERSION" '.version = $version' package.json > .pkg.json \
15+
&& mv .pkg.json package.json; \
16+
fi \
17+
&& pnpm run build
18+
119
FROM docker.io/node:24-alpine
220

321
LABEL org.opencontainers.image.title="Hollo"
@@ -14,6 +32,7 @@ WORKDIR /app/
1432
RUN pnpm install --frozen-lockfile --prod
1533

1634
COPY . /app/
35+
COPY --from=builder /app/dist /app/dist
1736

1837
ARG VERSION
1938
LABEL org.opencontainers.image.version="${VERSION}"

docs/src/content/docs/install/manual.mdx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,10 @@ Hollo.
9191
Starting the server
9292
-------------------
9393

94-
To start the server, run the following command:
94+
Build the JavaScript files and start the server:
9595

9696
~~~~ sh frame="none"
97+
pnpm run build
9798
pnpm run prod
9899
~~~~
99100

@@ -117,7 +118,13 @@ dependencies:
117118
pnpm install
118119
~~~~
119120

120-
3. Restart the server:
121+
3. Rebuild the JavaScript files:
122+
123+
~~~~ sh frame="none"
124+
pnpm run build
125+
~~~~
126+
127+
4. Restart the server:
121128

122129
~~~~ sh frame="none"
123130
pnpm run prod

docs/src/content/docs/ja/install/manual.mdx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,10 @@ Holloをインストールしたら、設定を行う必要があります。
8888
サーバー起動
8989
------------
9090

91-
サーバーを起動する準備が整ったら、以下のコマンドを実行します
91+
JavaScriptファイルをビルドしてから、サーバーを起動します
9292

9393
~~~~ sh frame="none"
94+
pnpm run build
9495
pnpm run prod
9596
~~~~
9697

@@ -114,7 +115,13 @@ GitHubリポジトリから最新のコードを取得し、依存関係を再
114115
pnpm install
115116
~~~~
116117

117-
3. サーバーを再起動します:
118+
3. JavaScriptファイルを再ビルドします:
119+
120+
~~~~ sh frame="none"
121+
pnpm run build
122+
~~~~
123+
124+
4. サーバーを再起動します:
118125

119126
~~~~ sh frame="none"
120127
pnpm run prod

docs/src/content/docs/ko/install/manual.mdx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,10 @@ Hollo가 설치되었다면, 설정을 해야 합니다.
8989
서버 시작하기
9090
-------------
9191

92-
서버를 시작하려면 다음 명령을 실행하세요:
92+
JavaScript 파일을 빌드한 뒤 서버를 시작합니다:
9393

9494
~~~~ sh frame="none"
95+
pnpm run build
9596
pnpm run prod
9697
~~~~
9798

@@ -115,7 +116,13 @@ GitHub 저장소에서 최신 코드를 받고 의존성을 다시 설치하면
115116
pnpm install
116117
~~~~
117118

118-
3. 서버를 다시 시작합니다:
119+
3. JavaScript 파일을 다시 빌드합니다:
120+
121+
~~~~ sh frame="none"
122+
pnpm run build
123+
~~~~
124+
125+
4. 서버를 다시 시작합니다:
119126

120127
~~~~ sh frame="none"
121128
pnpm run prod

docs/src/content/docs/zh-cn/install/manual.mdx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,10 @@ import { Steps } from "@astrojs/starlight/components";
8383
启动服务端
8484
----------
8585

86-
要启动服务端,请运行以下命令
86+
先构建 JavaScript 文件,然后启动服务端
8787

8888
~~~~ sh frame="none"
89+
pnpm run build
8990
pnpm run prod
9091
~~~~
9192

@@ -108,7 +109,13 @@ pnpm run prod
108109
pnpm install
109110
~~~~
110111

111-
3. 重启服务端:
112+
3. 重新构建 JavaScript 文件:
113+
114+
~~~~ sh frame="none"
115+
pnpm run build
116+
~~~~
117+
118+
4. 重启服务端:
112119

113120
~~~~ sh frame="none"
114121
pnpm run prod

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55
"private": true,
66
"type": "module",
77
"scripts": {
8-
"prod": "pnpm run migrate && tsx --env-file-if-exists=.env --dns-result-order=ipv6first bin/server.ts",
8+
"prod": "pnpm run migrate && node --env-file-if-exists=.env --dns-result-order=ipv6first dist/bin/server.js",
99
"dev": "pnpm run migrate && tsx watch --env-file-if-exists=.env --dns-result-order=ipv6first bin/server.ts",
10-
"worker": "NODE_TYPE=worker tsx --env-file-if-exists=.env --dns-result-order=ipv6first bin/server.ts",
10+
"worker": "NODE_TYPE=worker node --env-file-if-exists=.env --dns-result-order=ipv6first dist/bin/server.js",
1111
"list:routes": "tsx --env-file-if-exists=.env bin/routes.ts",
1212
"measure:memory": "node --expose-gc --import tsx --env-file-if-exists=.env scripts/measure-memory.ts",
13+
"build": "tsdown",
1314
"test": "pnpm run migrate:test && vitest",
1415
"test:ci": "vitest",
1516
"typecheck": "tsgo --noEmit",
@@ -94,6 +95,7 @@
9495
"oxfmt": "^0.46.0",
9596
"oxlint": "^1.61.0",
9697
"timekeeper": "^2.3.1",
98+
"tsdown": "^0.21.10",
9799
"typescript": "^6.0.3",
98100
"vitest": "^3.1.4"
99101
},

0 commit comments

Comments
 (0)