Dockerized Nestjs 访问公共文件夹中的静态文件

问题描述 投票:0回答:2

已更新

src
文件夹旁边,我创建了另一个名为
public
的文件夹,并在该文件夹中放置了一个图像文件。我像这样修改了
main.ts
文件:

1) app.useStaticAssets(join(__dirname, '..', 'public'));

2) app.useStaticAssets(join(__dirname, '/../public')); 

3) app.useStaticAssets(join(__dirname, '..', 'public'), {
    index: false,
    prefix: '/public/',
});

镜像文件名为

pic.png
,我的项目可以通过以下 Docker 地址访问:

192.168.1.102

测试简单的

url
api

http://192.168.1.102/api/test

回复:

{"response":"200"}

对于这个项目,前缀定义如下:

app.setGlobalPrefix('api');

现在,当我尝试显示具有以下地址的图像文件时,它给出了 404 错误,并且我无法解决它:

1) http://192.168.1.102/pic.png
2) http://192.168.1.102/public/pic.png

错误:

1) {"message":"Cannot GET /pic.png","error":"Not Found","statusCode":404}
2) {"message":"Cannot GET /public/pic.png","error":"Not Found","statusCode":404}

整个 main.ts 文件如下所示:

import {NestFactory} from '@nestjs/core';
import {AppModule} from './modules/app/app.module';
import {ValidationPipe} from '@nestjs/common';
import {ConfigService} from '@nestjs/config';

import {FreezePipe} from "./common/pipes/freeze-pipe";
import {HttpExceptionFilter} from "./common/filters/http-exception.filter";
import { join } from 'path';
import { NestExpressApplication } from '@nestjs/platform-express';

async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);

const allowedOrigins: string[] = [
'http://192.168.1.102'
];


app.useStaticAssets(join(__dirname, '..', 'public'));

/*app.useStaticAssets(join(__dirname, '/../public')); 

app.useStaticAssets(join(__dirname, '..', 'public'), {
    index: false,
    prefix: '/public/',
});*/

app.setGlobalPrefix('api');

const configService = app.get(ConfigService);

app.enableCors({
    origin: (origin, callback) => {
        if (allowedOrigins.indexOf(origin) !== -1 || !origin) {
            callback(null, true);
        } else {
            callback(new Error('Not allowed by CORS'));
        }
    },
    optionsSuccessStatus: 200,
    credentials: true,
});
await app.listen(3000);
}

bootstrap().then(r => console.log('... SERVER STARTED NOW ...'));

docker-compose.yaml
内容:

networks:
  host:
    name: myapp
    external: true
  lan_access:
    driver: bridge

services:
  myapp:
    build:
      context: .
      dockerfile: src/modules/app/Dockerfile
      target: development
    command: npm run start:dev myapp
    env_file:
      - .env
    volumes:
      - .:/usr/src/app
      - /usr/src/app/node_modules
    networks:
      - default
    depends_on:
      - database
      - redis
    ports:
      - '80:3000'

  redis:
    image: redis
    restart: always
    command: /bin/sh -c "redis-server --requirepass $$REDIS_PASSWORD"
    env_file:
      - .env
    ports:
      - 6379:6379
    environment:
      - ALLOW_EMPTY_PASSWORD=yes
    volumes:
      - ./redis/data:/data

  database:
    image: mysql:latest
    restart: always
    command: --default-authentication-plugin=mysql_native_password
    env_file:
      - .env
    environment:
      MYSQL_HOST: 'database'
      MYSQL_DATABASE: 'myapp'
      MYSQL_PASSWORD: 'root'
      MYSQL_ROOT_PASSWORD: 'root'
    ports:
      - '3306:3306'
    expose:
      - '3306'
    volumes:
      - myapp-db:/var/lib/mysql

  phpmyadmin:
    image: phpmyadmin:latest
    restart: always
    ports:
      - 8080:80
    environment:
      - PMA_ARBITRARY=1
volumes:
  myapp-db:

Dockerfile

# Development stage
FROM node:alpine As development

WORKDIR /usr/src/app

COPY package*.json ./
# COPY prisma ../../prisma/

RUN npm install -g pnpm
RUN pnpm install --save

COPY ../.. .
COPY ../../../sysctl.conf /etc/sysctl.d/

RUN pnpm run build

# Production stage
FROM node:alpine as production

ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}

WORKDIR /usr/src/app

COPY package*.json ./
# COPY prisma ../../prisma/

RUN pnpm install -g pnpm
RUN pnpm install --only=production

COPY ../.. .
COPY ../../../sysctl.conf /etc/sysctl.d/

COPY --from=development /usr/src/app/dist ./dist
COPY --chown=node:node --from=builder /usr/src/app/prisma /prisma


CMD ["node", "dist/src/myapp/main"]
javascript docker nestjs nestjs-config
2个回答
0
投票

在您的配置中,您将公共资产的前缀设置为

public
。但是,您正在尝试以
/uploads
的身份访问它们。

因此,如果您不想更改

main.ts
文件,您应该访问
http://192.168.1.102/public/pic.png
并且它应该可以工作。

如果您想在 URL 中包含

uploads
,您可以将配置修改为:

app.useStaticAssets(path.join(__dirname, '..', 'public'), {
  index: false,
  prefix: '/uploads',
});

现在,

http://192.168.1.102/uploads/pic.png
应该可以工作了。

旁注:

您需要将

app
转换为正确的类型才能在打字稿中正确输入。

const app = await NestFactory.create<NestExpressApplication>(AppModule);

0
投票

对我来说,删除

'..'
字符串是有效的,似乎我基本上是在
app/public
而不是
app/dist/public

设置路径

所以这就是我所做的:

app.useStaticAssets(join(__dirname, 'public'), {
    index: false,
    prefix: '/public/',
}); 
© www.soinside.com 2019 - 2024. All rights reserved.