I am building an application in nest.js ,then I want to dockerize it by using docker, this is my docker file:
FROM node:14 AS builder
# Create app directory
WORKDIR /app
# A wildcard is used to ensure both package.json AND package-lock.json are copied
COPY package*.json ./
COPY prisma ./prisma/
# Install app dependencies
RUN npm install
COPY . .
RUN npm run build
FROM node:14
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD [ "npm", "run", "start:prod" ]
Then when I run :
docker build -t medicine-api .
I got this erorr from prisma
Module '"#prisma/client"' has no exported member 'User'.
3 import { User } from '#prisma/client';
and this is my prisma.schema file
/ This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
generator prismaClassGenerator {
provider = "prisma-class-generator"
dryRun = false
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int #id #default(autoincrement())
phoneNumber String #unique
lastName String
firstName String
role Role
bio String?
certificate String?
pic String?
verified Boolean #default(false)
medicine Medicine[]
pharmacyMedicine PharmacyMedicine[]
medicineCategory MedicineCategory[]
pharmacyPackage PharmacyPackage[]
pharmacistOrder Order[] #relation("pharmacistOrder")
userOrder Order[] #relation("userOrder")
}
I try to fix this by searching through difference resource and website, then they recommend me to put npx prisma generate in my dockefil. But still I get another erorr here:
Error: Generator at prisma-class-generator could not start:
/bin/sh: 1: prisma-class-generator: not found
If you have any solutions , I am really happy to try. Thanks in advance.
You have to generate the prisma client by running the command
yarn prisma generate
this should come before the step of coping the prisma folder
so I would suggest to change the dockerFile to be
FROM node:14 AS builder
# Create app directory
WORKDIR /app
# A wildcard is used to ensure both package.json AND package-lock.json are copied
COPY package*.json ./
# Install app dependencies
RUN npm install
COPY . .
RUN yarn prisma generate
COPY prisma ./prisma/
RUN npm run build
FROM node:14
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD [ "npm", "run", "start:prod" ]
the prisma generate step will make sure you will have the prisma client in your node_modules so that it can be used to migrate the prisma models
Related
I use Next js 12.1 and I define some env in .env.local everything is fine in local but when I deploy in the server I realize environment variables that I define in server are undefined. when I log the env, it is undefined in the browser and is work in the server terminal.
here is my next.config.js
/** #type {import('next').NextConfig} */
const nextConfig = {
experimental: {
outputStandalone: true,
},
compiler: { styledComponents: true },
env: {
NEXT_PUBLIC_SITE_URL: process.env.NEXT_PUBLIC_SITE_URL,
},
};
module.exports = nextConfig;
Dockerfile
FROM node:16-alpine AS deps
ENV http_proxy=http://fodev.org:8118
ENV https_proxy=http://fodev.org:8118
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install --force
# If using yarn with a `yarn.lock` comment out above and use below instead
# COPY package.json yarn.lock ./
# RUN yarn install --frozen-lockfile
FROM node:16-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED 1
RUN npm run build
# If using yarn comment out above and use below instead
# RUN yarn build
FROM node:16-alpine AS runner
WORKDIR /app
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/next.config.js ./
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
CMD ["node", "server.js"]
and this is one of my components name Footer
import React from "react";
import Link from "next/link";
const Footer = () => {
console.log(process.env.NEXT_PUBLIC_COMPANY_NAME );
return (
<footer
className="md:px-10 lg:p-14 text-gray-600 relative flex flex-wrap justify-center mx-auto "
style={{ background: "var(--gray)" }}
dir="rtl"
>
<div>{process.env.NEXT_PUBLIC_COMPANY_NAME || "CmpName"}{" "}</div>
</footer>
);
};
export default Footer;
browser console
Browser console
and server logs
Server Logs
Update your question with example how you use this env.
From docs:
The value will be inlined into JavaScript sent to the browser because of the NEXT_PUBLIC_ prefix. This inlining occurs at build time, so your various NEXT_PUBLIC_ envs need to be set when the project is built.
Read this page https://nextjs.org/docs/basic-features/environment-variables
there is difference when you use process.env.NEXT_PUBLIC_ANALYTICS_ID or const env = process.env and then env.NEXT_PUBLIC_ANALYTICS_ID
I use prisma and node.js.
When I called some functions (example prisma.users.findAll()) in docker container I have error User 'postgres' was denied access on the database 'my_db.public', but if I run in local I don't have any problem.
However, my containers are successfully, but when I call any function with database I had an error.
My docker file
FROM node:15.13.0
RUN mkdir -p /project/node_modules && chown -R node:node /project
WORKDIR /project
COPY package*.json ./
COPY --chown=node:node prisma ./prisma
COPY config ./config
RUN npm install
RUN npx prisma generate
RUN npx prisma db push --preview-feature
COPY --chown=node:node ./temp ./temp
COPY --chown=node:node . .
CMD [ "node", "index.js" ]
Also, my db
my_db | postgres | UTF8 | C.UTF-8 | C.UTF-8 |
prisma settings
DATABASE_URL=postgresql://postgres:password#172.17.0.1:5432/my_db?connect_timeout=300&connection_limit=150
If you can get the same error message by running either of these two prisma commands in your project,
npx prisma db pull
npx prisma generate
it means that the error comes from a bad DATABASE_URL value.
For example: the user should be chris instead of postgres.
// wrong user
DATABASE_URL="postgresql://postgres:passw#localhost:5432/dbname?schema=public"
// correct user
DATABASE_URL="postgresql://chris:passw#localhost:5432/dbname?schema=public"
Make sure you have the correct values.
here is my Dockerfile:
FROM node AS builder
WORKDIR /app
COPY package*.json ./
COPY prisma ./prisma/
COPY tsconfig.build.json ./
COPY tsconfig.json ./
RUN npm install
COPY . .
RUN npm run build
FROM node
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD [ "npm", "run", "start:dev" ]
and here is my docker-compose.yml:
version: "3.7"
services:
web:
image: Dockerfile
build:
context: ./
dockerfile: Dockerfile.development
volumes:
- ./:/app:z
environment:
NODE_ENV : development
TZ: "${TZ:-America/Los_Angeles}"
ports:
- "3000:3000"
After I run the docker-compose up -d, I can have the error from the console :
Error Could not find TypeScript configuration file "tsconfig.build.json". Please, ensure that you are running this command in the appropriate directory (inside Nest workspace).
I have tried to copy and paste tsconfig.build.json to the docker, but it still does not work.
please help.
In your last step, you never copy over the tsconfig.build.json file or the tsconfig.json. Though, I don't see why you're using start:dev when you've already built the server in the docker image. You should just be calling node dist/main
I don't use Docker, but I've got the same error:
Error Could not find TypeScript configuration file "tsconfig.build.json". Please, ensure that you are running this command in the appropriate directory (inside Nest workspace).
I solved this by deleting the dist folder and npm run start:dev again.
I would like to put my Nodejs app into a docker. When deploying it via npm run build and start I can send requests to it.
But when creating a docker image I getting problems:
First I have an EXPOSE 8080 in my Dockerfile. Then I am running docker run -p=3000:8080 --env-file .env my-docker-file. After that I am getting the info that the server is running on http://localhost:3000.
I know localhost:3000 ist just in the docker file. But at least the docker is running.
When I use the command http localhost:3000 (or the browser) I am getting http: error: ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response')) while doing a GET request to URL: http://localhost:3000/.
Does someone have an idea what's going wrong??? I have no clue.
tanks to all hints that directs me into the right direction.
My Dockerfile:
## this is the stage one , also know as the build step
FROM node:12.17.0-alpine as builder
WORKDIR /app
COPY package*.json ./
COPY prisma ./prisma/
COPY tsconfig.json .
COPY src ./src/
COPY tests ./tests/
RUN npm install
RUN npx prisma generate
COPY . .
RUN npm run build
## this is stage two , where the app actually runs
FROM node:12.17.0-alpine
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/dist ./dist
EXPOSE 8080
CMD npm start
If you use a Dockerfile, first you better to build your image.
FROM node:12.17.0-alpine as builder
WORKDIR /app
COPY . .
RUN npm install
RUN npx prisma generate
RUN npm run build
## this is stage two , where the app actually runs
FROM node:12.17.0-alpine
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/dist ./dist
EXPOSE 8080
CMD ["npm","start"]
From the location where your Dockerfile located:
docker build -t your-image-name .
docker run -p 3000:8080 --env-file .env your-image-name
Did you check the IP address?
When i first deploy my Node project to Docker, i couldn't access it too, because my Node project was listening for localhost requests. But if you don't specify your network as host, your Docker container will have some other IP address in your subnet.
I've changed my Node projects listening IP address to 0.0.0.0 and after that i could connect to my Node project running in a Docker container.
I have a node project that has a web server and a service on the root.
--myNodeProj
--app.js //the web server
--service.js //an update service
In my package.json I have the following:
"scripts": {
"start": "node app.js",
"service": "node service.js"
},
For my DockerFile I have:
FROM node:8
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm#5+)
COPY package*.json ./
RUN npm install
# If you are building your code for production
# RUN npm install --only=production
# Bundle app source
COPY . .
EXPOSE 8080
CMD [ "npm", "start" ]
The CMD will run the app.js (webserver). How do I build another container with the service? Do I create another Dockerfile? Would the docker build command look different?
You can override the command -
docker run <image> node service.js
https://docs.docker.com/engine/reference/run/#general-form
I ended up using docker-compose.
You need to create a docker-compose.yml file with the following code:
version: '3'
services:
web:
# will build ./docker/web/Dockerfile
build:
context: .
dockerfile: ./docker/web/Dockerfile
ports:
- "3000:3000"
env_file:
- web.env
service:
# will build ./docker/service/Dockerfile
build:
context: .
dockerfile: ./docker/service/Dockerfile
env_file:
- service.env
This files reference 2 Dockerfiles that build the containers:
For service
FROM node:8
# Create app directory
WORKDIR /usr/src/service
# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm#5+)
COPY package*.json ./
RUN npm install
# If you are building your code for production
# RUN npm install --only=production
# Bundle app source
COPY . .
CMD [ "node", "service.js" ]
For web:
FROM node:8
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm#5+)
COPY package*.json ./
RUN npm install
# If you are building your code for production
# RUN npm install --only=production
# Bundle app source
COPY . .
#EXPOSE 8080
CMD [ "npm", "start" ]
Notice that I can only do one NPM start. I call the service directly using node.
When I want to build containers, I issue the command:
docker-compose build