admin管理员组文章数量:1122826
I have a docker setup with a nextjs application in a container and another container with a postgres database, using prisma as ORM. The containers start fine and I can access my nextjs application on localhost:3000, but no content from the layout.tsx or root page.tsx is showing? I've put some logs in those files as well but see no output.
I believe this is some problem with connecting to the database because i can reproduce this in my development setup with just setting the incorrect postgres .env variables. In development I've used Neon as remote database, but I want to move on to production I want a local postgres database in a container, which is where the problem starts. Switching back to the Neon connection variables the site load normally as expected.
I can access the database with the pgadmin service and can connect to the database service and I see all tables there, however they are empty because the site wont load in the body content.
I can ping the containers between each other with a success, so they have to communicate somehow. Using docker dekstop interface and using the terminal in the nextjs-app logobrewer:
/app $ ping postgres_db
PING postgres_db (172.31.0.2): 56 data bytes
64 bytes from 172.31.0.2: seq=0 ttl=42 time=0.038 ms
64 bytes from 172.31.0.2: seq=1 ttl=42 time=0.053 ms
.env
DATABASE_URL=postgres://postgres:password@postgres_db:5432/logobrewer?schema=public
PGHOST=postgres_db
PGDATABASE=logobrewer
PGUSER=postgres
PGPASSWORD=password
Docker-compose.yml (Edited after Ravis comment)
version: '3.8'
services:
postgres_db:
image: postgres:15
container_name: postgres_db
restart: always
environment:
POSTGRES_DB: $PGDATABASE
POSTGRES_USER: $PGUSER
POSTGRES_PASSWORD: $PGPASSWORD
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
networks:
- app_network
app:
container_name: logobrewer
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
- "5555:5555"
environment:
NODE_ENV: production
DATABASE_URL: postgres://postgres:password@postgres_db:5432/logobrewer?schema=public
volumes:
- F:\React\LogoAi\logo-ai\logs:/logs
command: >
sh -c "
until pg_isready -h postgres_db -p 5432 -U postgres; do
echo 'Waiting for Postgres...';
sleep 2;
done;
npx prisma migrate deploy && node server.js"
depends_on:
postgres_db:
condition: service_healthy
networks:
- app_network
pgadmin:
image: dpage/pgadmin4
container_name: pgadmin4_container
restart: always
ports:
- "8888:80"
environment:
PGADMIN_DEFAULT_EMAIL: [email protected]
PGADMIN_DEFAULT_PASSWORD: 1234
volumes:
- pgadmin_data:/var/lib/pgadmin
depends_on:
- postgres_db
networks:
- app_network
volumes:
postgres_data:
pgadmin_data:
networks:
app_network:
driver: bridge
schema.prisma:
// This is your Prisma schema file,
// learn more about it in the docs:
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate:
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "debian-openssl-1.1.x", "debian-openssl-3.0.x", "linux-musl", "linux-musl-openssl-3.0.x", "linux-musl-arm64-openssl-1.1.x"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Product {
id String @id @default(cuid())
name String
description String?
stripeProductId String
type String
orders Order[] // Establishes a one-to-many relationship with Order
}
Dockerfile:
FROM node:18.18-alpine AS deps
WORKDIR /app
RUN apk add --no-cache \
libc6-compat \
cairo-dev \
pango-dev \
cairo-tools \
giflib-dev \
pixman-dev \
libjpeg-turbo-dev \
build-base \
python3 \
make \
g++ \
bash \
pkgconfig \
wget \
&& ln -sf /usr/bin/python3 /usr/bin/python
COPY package.json package-lock.json* ./
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
fi
# Force canvas installation if it has issues
RUN npm install canvas --build-from-source --legacy-peer-deps
# Rebuild the source code only when needed
FROM deps AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npx prisma generate
RUN npm run build
# Production image, copy all the files and run Next.js
FROM builder AS runner
WORKDIR /app
# Install Cairo runtime libraries (needed for canvas)
RUN apk add --no-cache \
cairo \
pango \
fontconfig \
libc6-compat # Sometimes required for compatibility in Alpine
# Set environment variables
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
ENV HOME=/home/nextjs
# Create and configure non-root user
RUN addgroup -S nodejs && adduser -S -G nodejs -u 1001 -D -h /home/nextjs nextjs \
&& mkdir -p /home/nextjs \
&& chown -R nextjs:nodejs /home/nextjs
# Create and set permissions for the /logs directory
RUN mkdir -p /logs && chown nextjs:nodejs /logs
# Copy necessary files from builder stage
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next ./app/.next
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
COPY --from=builder --chown=nextjs:nodejs /app/prisma ./prisma
# Set ownership for the app directory
RUN chown -R nextjs:nodejs /app
#Use this to specify which folders instead of above which takes all the files
#RUN chown -R nextjs:nodejs /app/.next /app/public /app/prisma
# Use non-root user
USER nextjs
# Expose port and start the server
EXPOSE 3000
CMD ["node", "server.js"]
So, in the development (starting application locally npm run dev) using the Neon connection variables, which worked fine. But now switching to a local database running alongside in a container in the same docker network the problem starts.
I believe I've tried multiple solutions like rewriting the docker-compose, dockerfile, docker networking configurations.
EDIT: After some more thinking, could the issue be that during building the docker image my dockerfile I get a warning like this:
Invalid `prisma.generation.findFirst()` invocation:
Can't reach database server at `postgres_db:5432`
Please make sure your database server is running at `postgres_db:5432`. PrismaClientInitializationError:
Invalid `prisma.generation.findFirst()` invocation:
Can't reach database server at `postgres_db:5432`
Please make sure your database server is running at `postgres_db:5432`.
at qn.handleRequestError (F:\React\LogoAi\logo-ai\node_modules\@prisma\client\runtime\library.js:121:7615)
Can this cause a problem later on when spinning up the image to the container?
Also, I tried to use Postman to reach a api endpoint in my code which makes a database lookup like this:
export async function GET() {
try {
const getUserSession = await prisma.session.findFirst();
if (getUserSession) {
return NextResponse.json(getUserSession);
}
}
And I actually get data back form the database. So the application needs to have connection i believe? This is so strange.
For some reason the application still don't load the layout.tsx children, but the navbar and the footer is loaded. This is the layout page where I have some debugging going on but they never show any output:
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import SessionProvider from "./components/SessionProvider";
import CookieConsentBanner from "./components/CookieConsentBanner";
import Register from "./components/Register";
import { Toaster } from "react-hot-toast";
import Footer from "./components/Footer";
import logger from "@/utils/logger";
import Nav from "./components/Nav";
import { log } from "console";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "LogoBrewer",
description: "Generated by create next app",
};
export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
try {
console.log("RootLayout");
logger.info("RootLayout");
return (
<html lang="en" className="bg-base-100 min-h-screen ">
<SessionProvider>
<body className={`${inter.className} min-h-screen flex flex-col`}>
{/* only appears if user hasnt registered */}
<Register />
<Nav />
<div className="flex justify-center">
<Toaster
position="bottom-center"
toastOptions={{
duration: 5000,
style: {
padding: "1em",
},
}}
/>
{children}
<CookieConsentBanner />
</div>
<Footer />
</body>
</SessionProvider>
</html>
);
} catch (error) {
logger.error(error);
}
}
I have a docker setup with a nextjs application in a container and another container with a postgres database, using prisma as ORM. The containers start fine and I can access my nextjs application on localhost:3000, but no content from the layout.tsx or root page.tsx is showing? I've put some logs in those files as well but see no output.
I believe this is some problem with connecting to the database because i can reproduce this in my development setup with just setting the incorrect postgres .env variables. In development I've used Neon as remote database, but I want to move on to production I want a local postgres database in a container, which is where the problem starts. Switching back to the Neon connection variables the site load normally as expected.
I can access the database with the pgadmin service and can connect to the database service and I see all tables there, however they are empty because the site wont load in the body content.
I can ping the containers between each other with a success, so they have to communicate somehow. Using docker dekstop interface and using the terminal in the nextjs-app logobrewer:
/app $ ping postgres_db
PING postgres_db (172.31.0.2): 56 data bytes
64 bytes from 172.31.0.2: seq=0 ttl=42 time=0.038 ms
64 bytes from 172.31.0.2: seq=1 ttl=42 time=0.053 ms
.env
DATABASE_URL=postgres://postgres:password@postgres_db:5432/logobrewer?schema=public
PGHOST=postgres_db
PGDATABASE=logobrewer
PGUSER=postgres
PGPASSWORD=password
Docker-compose.yml (Edited after Ravis comment)
version: '3.8'
services:
postgres_db:
image: postgres:15
container_name: postgres_db
restart: always
environment:
POSTGRES_DB: $PGDATABASE
POSTGRES_USER: $PGUSER
POSTGRES_PASSWORD: $PGPASSWORD
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
networks:
- app_network
app:
container_name: logobrewer
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
- "5555:5555"
environment:
NODE_ENV: production
DATABASE_URL: postgres://postgres:password@postgres_db:5432/logobrewer?schema=public
volumes:
- F:\React\LogoAi\logo-ai\logs:/logs
command: >
sh -c "
until pg_isready -h postgres_db -p 5432 -U postgres; do
echo 'Waiting for Postgres...';
sleep 2;
done;
npx prisma migrate deploy && node server.js"
depends_on:
postgres_db:
condition: service_healthy
networks:
- app_network
pgadmin:
image: dpage/pgadmin4
container_name: pgadmin4_container
restart: always
ports:
- "8888:80"
environment:
PGADMIN_DEFAULT_EMAIL: [email protected]
PGADMIN_DEFAULT_PASSWORD: 1234
volumes:
- pgadmin_data:/var/lib/pgadmin
depends_on:
- postgres_db
networks:
- app_network
volumes:
postgres_data:
pgadmin_data:
networks:
app_network:
driver: bridge
schema.prisma:
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "debian-openssl-1.1.x", "debian-openssl-3.0.x", "linux-musl", "linux-musl-openssl-3.0.x", "linux-musl-arm64-openssl-1.1.x"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Product {
id String @id @default(cuid())
name String
description String?
stripeProductId String
type String
orders Order[] // Establishes a one-to-many relationship with Order
}
Dockerfile:
FROM node:18.18-alpine AS deps
WORKDIR /app
RUN apk add --no-cache \
libc6-compat \
cairo-dev \
pango-dev \
cairo-tools \
giflib-dev \
pixman-dev \
libjpeg-turbo-dev \
build-base \
python3 \
make \
g++ \
bash \
pkgconfig \
wget \
&& ln -sf /usr/bin/python3 /usr/bin/python
COPY package.json package-lock.json* ./
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
fi
# Force canvas installation if it has issues
RUN npm install canvas --build-from-source --legacy-peer-deps
# Rebuild the source code only when needed
FROM deps AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npx prisma generate
RUN npm run build
# Production image, copy all the files and run Next.js
FROM builder AS runner
WORKDIR /app
# Install Cairo runtime libraries (needed for canvas)
RUN apk add --no-cache \
cairo \
pango \
fontconfig \
libc6-compat # Sometimes required for compatibility in Alpine
# Set environment variables
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
ENV HOME=/home/nextjs
# Create and configure non-root user
RUN addgroup -S nodejs && adduser -S -G nodejs -u 1001 -D -h /home/nextjs nextjs \
&& mkdir -p /home/nextjs \
&& chown -R nextjs:nodejs /home/nextjs
# Create and set permissions for the /logs directory
RUN mkdir -p /logs && chown nextjs:nodejs /logs
# Copy necessary files from builder stage
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next ./app/.next
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
COPY --from=builder --chown=nextjs:nodejs /app/prisma ./prisma
# Set ownership for the app directory
RUN chown -R nextjs:nodejs /app
#Use this to specify which folders instead of above which takes all the files
#RUN chown -R nextjs:nodejs /app/.next /app/public /app/prisma
# Use non-root user
USER nextjs
# Expose port and start the server
EXPOSE 3000
CMD ["node", "server.js"]
So, in the development (starting application locally npm run dev) using the Neon connection variables, which worked fine. But now switching to a local database running alongside in a container in the same docker network the problem starts.
I believe I've tried multiple solutions like rewriting the docker-compose, dockerfile, docker networking configurations.
EDIT: After some more thinking, could the issue be that during building the docker image my dockerfile I get a warning like this:
Invalid `prisma.generation.findFirst()` invocation:
Can't reach database server at `postgres_db:5432`
Please make sure your database server is running at `postgres_db:5432`. PrismaClientInitializationError:
Invalid `prisma.generation.findFirst()` invocation:
Can't reach database server at `postgres_db:5432`
Please make sure your database server is running at `postgres_db:5432`.
at qn.handleRequestError (F:\React\LogoAi\logo-ai\node_modules\@prisma\client\runtime\library.js:121:7615)
Can this cause a problem later on when spinning up the image to the container?
Also, I tried to use Postman to reach a api endpoint in my code which makes a database lookup like this:
export async function GET() {
try {
const getUserSession = await prisma.session.findFirst();
if (getUserSession) {
return NextResponse.json(getUserSession);
}
}
And I actually get data back form the database. So the application needs to have connection i believe? This is so strange.
For some reason the application still don't load the layout.tsx children, but the navbar and the footer is loaded. This is the layout page where I have some debugging going on but they never show any output:
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import SessionProvider from "./components/SessionProvider";
import CookieConsentBanner from "./components/CookieConsentBanner";
import Register from "./components/Register";
import { Toaster } from "react-hot-toast";
import Footer from "./components/Footer";
import logger from "@/utils/logger";
import Nav from "./components/Nav";
import { log } from "console";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "LogoBrewer",
description: "Generated by create next app",
};
export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
try {
console.log("RootLayout");
logger.info("RootLayout");
return (
<html lang="en" className="bg-base-100 min-h-screen ">
<SessionProvider>
<body className={`${inter.className} min-h-screen flex flex-col`}>
{/* only appears if user hasnt registered */}
<Register />
<Nav />
<div className="flex justify-center">
<Toaster
position="bottom-center"
toastOptions={{
duration: 5000,
style: {
padding: "1em",
},
}}
/>
{children}
<CookieConsentBanner />
</div>
<Footer />
</body>
</SessionProvider>
</html>
);
} catch (error) {
logger.error(error);
}
}
Share
Improve this question
edited yesterday
jnilssonn
asked yesterday
jnilssonnjnilssonn
11 bronze badge
1 Answer
Reset to default 0Prisma relies on the DATABASE_URL
to connect, and if the database isn't ready yet, migrations and subsequent queries fail.
- Add Wait-for-DB Logic:
Ensure the database is ready before the Next.js app starts. Update the
command
indocker-compose.yml
:command: > sh -c " until pg_isready -h postgres_db -p 5432 -U postgres; do echo 'Waiting for Postgres...'; sleep 2; done; npx prisma migrate deploy && node server.js"
Adjust depends_on: While depends_on ensures startup order, it doesn't wait for readiness. Use a proper health check, which you already have for postgres_db.
Rebuild Containers: Ensure all changes are applied:
docker-compose down -v
docker-compose up --build
本文标签: postgresqlNextjsPrismapostgresDocker wont show layouttsx children pagesStack Overflow
版权声明:本文标题:postgresql - Nextjs + Prismapostgres + Docker wont show layout.tsx children pages - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736284010a1927155.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论