From 97e7d7190dfe219caf441dffcd7830c304c3c939 Mon Sep 17 00:00:00 2001 From: Elias Schneider Date: Mon, 9 Oct 2023 11:14:51 +0200 Subject: [PATCH] fix: memory leak while downloading large files --- Dockerfile | 6 ++++-- README.md | 2 ++ backend/src/app.controller.ts | 19 +++++++++++++++++++ backend/src/app.module.ts | 4 ++++ frontend/src/pages/api/[...all].tsx | 2 ++ frontend/src/pages/api/health.tsx | 14 -------------- nginx/nginx.conf | 22 ++++++++++++++++++++++ 7 files changed, 53 insertions(+), 16 deletions(-) create mode 100644 backend/src/app.controller.ts delete mode 100644 frontend/src/pages/api/health.tsx create mode 100644 nginx/nginx.conf diff --git a/Dockerfile b/Dockerfile index 60f3f14..27dc1b1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,7 +32,9 @@ ENV NODE_ENV=docker # Alpine specific dependencies RUN apk update --no-cache RUN apk upgrade --no-cache -RUN apk add --no-cache curl +RUN apk add --no-cache curl nginx + +COPY ./nginx/nginx.conf /etc/nginx/nginx.conf WORKDIR /opt/app/frontend COPY --from=frontend-builder /opt/app/public ./public @@ -55,4 +57,4 @@ HEALTHCHECK --interval=10s --timeout=3s CMD curl -f http://localhost:3000/api/he # Application startup # HOSTNAME=0.0.0.0 fixes https://github.com/vercel/next.js/issues/51684. It can be removed as soon as the issue is fixed -CMD cp -rn /tmp/img /opt/app/frontend/public && HOSTNAME=0.0.0.0 node frontend/server.js & cd backend && npm run prod \ No newline at end of file +CMD cp -rn /tmp/img /opt/app/frontend/public && nginx && PORT=3333 HOSTNAME=0.0.0.0 node frontend/server.js & cd backend && npm run prod \ No newline at end of file diff --git a/README.md b/README.md index 672a80a..65fb3a8 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,8 @@ npm run build pm2 start --name="pingvin-share-frontend" npm -- run start ``` +**Uploading Large Files**: By default, Pingvin Share uses a built-in reverse proxy to reduce the installation steps. However, this reverse proxy is not optimized for uploading large files. If you wish to upload larger files, you can either use the Docker installation or set up your own reverse proxy. An example configuration for Nginx can be found in `/nginx/nginx.conf`. + The website is now listening on `http://localhost:3000`, have fun with Pingvin Share 🐧! ### Integrations diff --git a/backend/src/app.controller.ts b/backend/src/app.controller.ts new file mode 100644 index 0000000..f7b3bc9 --- /dev/null +++ b/backend/src/app.controller.ts @@ -0,0 +1,19 @@ +import { Controller, Get, Res } from "@nestjs/common"; +import { Response } from "express"; +import { PrismaService } from "./prisma/prisma.service"; + +@Controller("/") +export class AppController { + constructor(private prismaService: PrismaService) {} + + @Get("health") + async health(@Res({ passthrough: true }) res: Response) { + try { + await this.prismaService.config.findMany(); + return "OK"; + } catch { + res.statusCode = 500; + return "ERROR"; + } + } +} diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index 7f47e08..985d795 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -14,6 +14,7 @@ import { ShareModule } from "./share/share.module"; import { UserModule } from "./user/user.module"; import { ClamScanModule } from "./clamscan/clamscan.module"; import { ReverseShareModule } from "./reverseShare/reverseShare.module"; +import { AppController } from "./app.controller"; @Module({ imports: [ @@ -33,6 +34,9 @@ import { ReverseShareModule } from "./reverseShare/reverseShare.module"; ClamScanModule, ReverseShareModule, ], + controllers:[ + AppController, + ], providers: [ { provide: APP_GUARD, diff --git a/frontend/src/pages/api/[...all].tsx b/frontend/src/pages/api/[...all].tsx index 8e7e850..ff27d57 100644 --- a/frontend/src/pages/api/[...all].tsx +++ b/frontend/src/pages/api/[...all].tsx @@ -11,6 +11,8 @@ export const config = { const { apiURL } = getConfig().serverRuntimeConfig; +// A proxy to the API server only used in development. +// In production this route gets overridden by nginx. export default (req: NextApiRequest, res: NextApiResponse) => { httpProxyMiddleware(req, res, { headers: { diff --git a/frontend/src/pages/api/health.tsx b/frontend/src/pages/api/health.tsx deleted file mode 100644 index e015da1..0000000 --- a/frontend/src/pages/api/health.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import axios from "axios"; -import { NextApiRequest, NextApiResponse } from "next"; -import getConfig from "next/config"; - -const { apiURL } = getConfig().serverRuntimeConfig; - -export default async (req: NextApiRequest, res: NextApiResponse) => { - const apiStatus = await axios - .get(`${apiURL}/api/configs`) - .then(() => "OK") - .catch(() => "ERROR"); - - res.status(apiStatus == "OK" ? 200 : 500).send(apiStatus); -}; diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000..7134235 --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,22 @@ +events {} + +http { + server { + listen 3000; + client_max_body_size 100M; + + location /api { + proxy_pass http://localhost:8080; + proxy_set_header X-Forwarded-Host $host:$server_port; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location / { + proxy_pass http://localhost:3333; + proxy_set_header X-Forwarded-Host $host:$server_port; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + } +}