UPDATED
Next to the src
folder, I created another folder called public
and placed an image file inside this folder. I modified the main.ts
file like this:
1) app.useStaticAssets(join(__dirname, '..', 'public'));
2) app.useStaticAssets(join(__dirname, '/../public'));
3) app.useStaticAssets(join(__dirname, '..', 'public'), {
index: false,
prefix: '/public/',
});
The image file is named pic.png
and my project is accessible at the following Docker address:
192.168.1.102
testing a simpleurl
and api
:
http://192.168.1.102/api/test
response:
{"response":"200"}
For this project, a prefix is defined as follows:
app.setGlobalPrefix('api');
Now when I try to display the image file with the following address, it gives a 404 error and I couldn’t solve it:
1) http://192.168.1.102/pic.png
2) http://192.168.1.102/public/pic.png
Error:
1) {"message":"Cannot GET /pic.png","error":"Not Found","statusCode":404}
2) {"message":"Cannot GET /public/pic.png","error":"Not Found","statusCode":404}
The entire main.ts file looks like this:
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
content:
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:
and 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"]
2
Answers
In your configuration, you set the prefix for your public assets as
public
. However, you are trying to access them as/uploads
.So, if you do not want to change your
main.ts
file, you should accesshttp://192.168.1.102/public/pic.png
and it should work.If you want to have
uploads
in your URL, you can modify the configuration to:And now,
http://192.168.1.102/uploads/pic.png
should work.Side note:
You need to cast
app
to the correct type to get correct typing in typescript.For me removing the
'..'
string works, seems like i was basically setting a path atapp/public
instead ofapp/dist/public
so this is what i did: