mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2026-06-23 04:10:17 +00:00
fix(backend): expose backend port for non-localhost
E2E Tests / backend-sqlite (push) Has been cancelled
Docker / build-and-push (backend) (push) Has been cancelled
Docker / build-and-push (frontend) (push) Has been cancelled
Deploy HD2 docs to Netlify / Deploys to netlify (push) Has been cancelled
REUSE Compliance Check / reuse (push) Has been cancelled
E2E Tests / backend-mariadb (push) Has been cancelled
E2E Tests / backend-postgres (push) Has been cancelled
Lint and check format / Lint files and check formatting (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
Static Analysis / Njsscan code scanning (push) Has been cancelled
Static Analysis / CodeQL analysis (javascript) (push) Has been cancelled
Run tests & build / Test and build with NodeJS 24 (push) Has been cancelled
E2E Tests / backend-sqlite (push) Has been cancelled
Docker / build-and-push (backend) (push) Has been cancelled
Docker / build-and-push (frontend) (push) Has been cancelled
Deploy HD2 docs to Netlify / Deploys to netlify (push) Has been cancelled
REUSE Compliance Check / reuse (push) Has been cancelled
E2E Tests / backend-mariadb (push) Has been cancelled
E2E Tests / backend-postgres (push) Has been cancelled
Lint and check format / Lint files and check formatting (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
Static Analysis / Njsscan code scanning (push) Has been cancelled
Static Analysis / CodeQL analysis (javascript) (push) Has been cancelled
Run tests & build / Test and build with NodeJS 24 (push) Has been cancelled
The current implementation restricts the backend port binding to 127.0.0.1, since this is the default of fastify. This is a reasonable default from a security standpoint. However, in certain contexts like docker network, this won't work. The new configuration option HD_BACKEND_BIND_IP allows to set a custom IP address to which fastify binds, or setting 0.0.0.0 to bind to all interfaces. At the same time this fix extends the Dockerfile to announce port 3000 to be available to the docker daemon. Signed-off-by: Erik Michelson <github@erik.michelson.eu>
This commit is contained in:
@@ -74,4 +74,5 @@ COPY --chown=node commons/package.json /usr/src/app/commons/package.json
|
||||
COPY --chown=node --from=builder /usr/src/app/commons/dist commons/dist
|
||||
|
||||
WORKDIR /usr/src/app/backend
|
||||
EXPOSE 3000/tcp
|
||||
CMD ["node", "dist/main.js"]
|
||||
|
||||
@@ -17,6 +17,9 @@ describe('appConfig', () => {
|
||||
const floatPort = 3.14;
|
||||
const outOfRangePort = 1000000;
|
||||
const invalidPort = 'not-a-port';
|
||||
const bindIp = '0.0.0.0';
|
||||
const bindIpV6 = '::1';
|
||||
const invalidBindIp = 'not-an-ip';
|
||||
const loglevel = Loglevel.TRACE;
|
||||
const showLogTimestamp = false;
|
||||
const invalidLoglevel = 'not-a-loglevel';
|
||||
@@ -29,6 +32,7 @@ describe('appConfig', () => {
|
||||
HD_BASE_URL: baseUrl,
|
||||
HD_RENDERER_BASE_URL: rendererBaseUrl,
|
||||
HD_BACKEND_PORT: port.toString(),
|
||||
HD_BACKEND_BIND_IP: bindIp,
|
||||
HD_LOG_LEVEL: loglevel,
|
||||
HD_LOG_SHOW_TIMESTAMP: showLogTimestamp.toString(),
|
||||
/* oxlint-enable @typescript-eslint/naming-convention */
|
||||
@@ -41,11 +45,49 @@ describe('appConfig', () => {
|
||||
expect(config.baseUrl).toEqual(baseUrl);
|
||||
expect(config.rendererBaseUrl).toEqual(rendererBaseUrl);
|
||||
expect(config.backendPort).toEqual(port);
|
||||
expect(config.backendBindIp).toEqual(bindIp);
|
||||
expect(config.log.level).toEqual(loglevel);
|
||||
expect(config.log.showTimestamp).toEqual(showLogTimestamp);
|
||||
restore();
|
||||
});
|
||||
|
||||
it('when given an IPv6 address as HD_BACKEND_BIND_IP', () => {
|
||||
const restore = mockedEnv(
|
||||
{
|
||||
/* oxlint-disable @typescript-eslint/naming-convention */
|
||||
HD_BASE_URL: baseUrl,
|
||||
HD_BACKEND_BIND_IP: bindIpV6,
|
||||
HD_LOG_LEVEL: loglevel,
|
||||
HD_LOG_SHOW_TIMESTAMP: showLogTimestamp.toString(),
|
||||
/* oxlint-enable @typescript-eslint/naming-convention */
|
||||
},
|
||||
{
|
||||
clear: true,
|
||||
},
|
||||
);
|
||||
const config = appConfig();
|
||||
expect(config.backendBindIp).toEqual(bindIpV6);
|
||||
restore();
|
||||
});
|
||||
|
||||
it('when no HD_BACKEND_BIND_IP is set', () => {
|
||||
const restore = mockedEnv(
|
||||
{
|
||||
/* oxlint-disable @typescript-eslint/naming-convention */
|
||||
HD_BASE_URL: baseUrl,
|
||||
HD_LOG_LEVEL: loglevel,
|
||||
HD_LOG_SHOW_TIMESTAMP: showLogTimestamp.toString(),
|
||||
/* oxlint-enable @typescript-eslint/naming-convention */
|
||||
},
|
||||
{
|
||||
clear: true,
|
||||
},
|
||||
);
|
||||
const config = appConfig();
|
||||
expect(config.backendBindIp).toEqual('127.0.0.1');
|
||||
restore();
|
||||
});
|
||||
|
||||
it('when no HD_RENDER_BASE_URL is set', () => {
|
||||
const restore = mockedEnv(
|
||||
{
|
||||
@@ -289,6 +331,26 @@ describe('appConfig', () => {
|
||||
restore();
|
||||
});
|
||||
|
||||
it('when given a non-IP address as HD_BACKEND_BIND_IP', async () => {
|
||||
const restore = mockedEnv(
|
||||
{
|
||||
/* oxlint-disable @typescript-eslint/naming-convention */
|
||||
HD_BASE_URL: baseUrl,
|
||||
HD_BACKEND_BIND_IP: invalidBindIp,
|
||||
HD_LOG_LEVEL: loglevel,
|
||||
HD_LOG_SHOW_TIMESTAMP: showLogTimestamp.toString(),
|
||||
/* oxlint-enable @typescript-eslint/naming-convention */
|
||||
},
|
||||
{
|
||||
clear: true,
|
||||
},
|
||||
);
|
||||
appConfig();
|
||||
expect(spyConsoleError.mock.calls[0][0]).toContain('HD_BACKEND_BIND_IP');
|
||||
expect(spyProcessExit).toHaveBeenCalledWith(1);
|
||||
restore();
|
||||
});
|
||||
|
||||
it('when given a non-loglevel HD_LOG_LEVEL', async () => {
|
||||
const restore = mockedEnv(
|
||||
{
|
||||
|
||||
@@ -61,6 +61,7 @@ const schema = z
|
||||
.default('')
|
||||
.describe('HD_RENDERER_BASE_URL'),
|
||||
backendPort: z.number().positive().int().max(65535).default(3000).describe('HD_BACKEND_PORT'),
|
||||
backendBindIp: z.string().ip().default('127.0.0.1').describe('HD_BACKEND_BIND_IP'),
|
||||
log: z.object({
|
||||
level: z
|
||||
.enum(Object.values(Loglevel) as [Loglevel, ...Loglevel[]])
|
||||
@@ -84,6 +85,7 @@ export default registerAs('appConfig', () => {
|
||||
baseUrl: process.env.HD_BASE_URL,
|
||||
rendererBaseUrl: process.env.HD_RENDERER_BASE_URL,
|
||||
backendPort: parseOptionalNumber(process.env.HD_BACKEND_PORT),
|
||||
backendBindIp: process.env.HD_BACKEND_BIND_IP,
|
||||
log: {
|
||||
level: process.env.HD_LOG_LEVEL,
|
||||
showTimestamp: parseOptionalBoolean(process.env.HD_LOG_SHOW_TIMESTAMP),
|
||||
|
||||
@@ -14,6 +14,7 @@ export function createDefaultMockAppConfig(): AppConfig {
|
||||
baseUrl: 'md.example.com',
|
||||
rendererBaseUrl: 'md-renderer.example.com',
|
||||
backendPort: 3000,
|
||||
backendBindIp: '127.0.0.1',
|
||||
log: {
|
||||
level: Loglevel.INFO,
|
||||
showTimestamp: true,
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ async function bootstrap(): Promise<void> {
|
||||
await setupApp(app, appConfig, authConfig, mediaConfig, securityConfig, logger);
|
||||
|
||||
// Start the server
|
||||
await app.listen(appConfig.backendPort);
|
||||
await app.listen(appConfig.backendPort, appConfig.backendBindIp);
|
||||
}
|
||||
|
||||
void bootstrap();
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
| `HD_BASE_URL` | - | `https://md.example.com` | The URL the HedgeDoc instance is accessed with, like it is entered in the browser |
|
||||
| `HD_BACKEND_PORT` | 3000 | | The port the backend process listens on. |
|
||||
| `HD_FRONTEND_PORT` | 3001 | | The port the frontend process listens on. |
|
||||
| `HD_BACKEND_BIND_IP` | 127.0.0.1 | `0.0.0.0` | The IP address to which the backend server should bind. |
|
||||
| `HD_RENDERER_BASE_URL` | Content of HD_BASE_URL | | The URL the renderer runs on. If omitted this will be the same as `HD_BASE_URL`. For more detail see [this faq entry][faq-entry] |
|
||||
| `HD_INTERNAL_API_URL` | Content of HD_BASE_URL | `http://localhost:3000` | This URL is used by the frontend to access the backend directly if it can't reach the backend using the `HD_BASE_URL` |
|
||||
| `HD_LOG_LEVEL` | warn | | The loglevel that should be used. Options are `error`, `warn`, `info`, `debug` or `trace`. |
|
||||
|
||||
Reference in New Issue
Block a user