Support serving Document Server under an app sub-path.
office.sejong.dev/pipeline/head This commit looks good
ysj7705/sejong-office/pipeline/head This commit looks good

- toInternalOnlyOfficeUrl swaps the whole public prefix (e.g.
  https://office.example.com/ds) for the internal base, so saved-file
  downloads don't hit http://documentserver/ds/... and 404.
- README: note the proxy setup (strip prefix, X-Forwarded-Host with path).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ysj7705andClaude Opus 5.5 committed 2026-10-13 21:46:42 +09:00
1 parent 2cb0c75092
commit 381ea8f221
2 files changed
+16

No files matched your search

+2
View File
@@ -101,6 +101,8 @@ volumes:
documentserver_data:
```
Document Server를 앱과 같은 도메인의 하위 경로(위 예시의 `/ds`)로 두면 편집기 iframe이 같은 출처가 되어 `X-Frame-Options: SAMEORIGIN`에 막히지 않습니다. 리버스 프록시는 접두어를 떼고 Document Server로 넘기면서 `X-Forwarded-Host`에 경로까지 넣어야 합니다(예: Caddy `handle_path /ds/*` + `header_up X-Forwarded-Host {host}/ds`).
## CI/CD (Jenkins)
[`Jenkinsfile`](Jenkinsfile) 이 `main` PR/브랜치에서 `npm ci` + `npm run build`를 돌리고, **`main` 브랜치 빌드**(PR 제외)에서만 이미지를 push한 뒤 서버에 SSH로 배포합니다.
@@ -57,6 +57,20 @@ export function toInternalOnlyOfficeUrl(raw: string): string {
const target = new URL(raw);
const publicBase = new URL(config.onlyOfficeUrl);
const internalBase = new URL(config.onlyOfficeInternalUrl);
// Public URL may be a sub-path of the app (e.g. https://office.example.com/ds):
// swap the whole prefix, not just the host, so /ds doesn't leak inward.
const publicPath = publicBase.pathname.replace(/\/$/, '');
if (
publicPath &&
target.host === publicBase.host &&
target.pathname.startsWith(`${publicPath}/`)
) {
return (
config.onlyOfficeInternalUrl +
target.pathname.slice(publicPath.length) +
target.search
);
}
if (
target.host === publicBase.host ||
target.host === internalBase.host