-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix production build broken by missing env DATABASE_URL at build time #41
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,12 @@ | ||
Dockerfile | ||
.dockerignore | ||
node_modules | ||
npm-debug.log | ||
.pnpm-store | ||
out | ||
dist | ||
*.md | ||
.git | ||
.next | ||
!.next/static | ||
!.next/standalone |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,9 +5,11 @@ COPY . . | |
|
||
RUN turbo prune @latitude-data/web --docker | ||
|
||
# COMMON stage (installer) | ||
# BUILDER stage | ||
# ------------------------------------------------------ | ||
FROM base AS installer | ||
FROM base AS builder | ||
WORKDIR /app | ||
|
||
COPY --from=base /app/out/json/ . | ||
COPY --from=base /app/out/pnpm-lock.yaml ./pnpm-lock.yaml | ||
COPY --from=base /app/out/pnpm-workspace.yaml ./pnpm-workspace.yaml | ||
|
@@ -17,38 +19,48 @@ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install \ | |
--frozen-lockfile \ | ||
--filter "@latitude-data/web..." | ||
|
||
# PRODUCTION stage | ||
# ------------------------------------------------------ | ||
FROM installer AS builder | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. builder and installer can be merged I think. |
||
|
||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \ | ||
BUILDING_CONTAINER=true \ | ||
pnpm turbo build --filter='@latitude-data/web...' | ||
|
||
FROM base AS runner | ||
FROM base as prod-deps | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is worth it to have a stage only to install production deps. That then are copied in |
||
WORKDIR /app | ||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install \ | ||
--prod \ | ||
--frozen-lockfile \ | ||
--filter "@latitude-data/web..." | ||
|
||
# PRODUCTION | ||
FROM base AS production | ||
WORKDIR /app-prod | ||
|
||
# Don't run production as root | ||
# Public files doesn't have the unpriviledged user | ||
COPY --from=base /app/apps/web/public ./apps/web/public | ||
|
||
# Unpriviledged user | ||
RUN addgroup --system --gid 1001 nodejs | ||
RUN adduser --system --uid 1001 nextjs | ||
USER nextjs | ||
|
||
COPY --from=installer /app/apps/web/next.config.mjs . | ||
COPY --from=installer /app/apps/web/package.json . | ||
COPY --from=installer /app/node_modules ./node_modules | ||
COPY --from=installer /app/apps/web/package.json ./apps/web/package.json | ||
andresgutgon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
COPY --from=builder /app/apps/web/next.config.mjs . | ||
COPY --from=builder /app/apps/web/package.json . | ||
COPY --from=prod-deps /app/node_modules ./node_modules | ||
|
||
# Automatically leverage output traces to reduce image size | ||
# https://nextjs.org/docs/advanced-features/output-file-tracing | ||
COPY --from=prod-builder --chown=nextjs:nodejs /app/apps/web/.next/standalone ./apps | ||
COPY --from=prod-builder --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static | ||
COPY --from=prod-builder --chown=nextjs:nodejs /app/apps/web/public ./apps/web/public | ||
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next/standalone ./apps | ||
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static | ||
|
||
ARG PORT=3000 | ||
ENV PORT $PORT | ||
|
||
# Configure host name. Important for setting the domain. | ||
ARG HOSTNAME="0.0.0.0" | ||
ENV HOSTNAME $HOSTNAME | ||
|
||
ENV NODE_ENV=production | ||
ENV NEXT_TELEMETRY_DISABLED=1 | ||
|
||
EXPOSE 3000 | ||
|
||
CMD HOSTNAME="0.0.0.0" node apps/web/server.js -p $PORT | ||
CMD node apps/web/server.js -p $PORT |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,12 +5,14 @@ services: | |
context: . | ||
dockerfile: docker/Dockerfile.base | ||
restart: 'none' | ||
|
||
elastic: | ||
image: elasticsearch:8.14.1 | ||
environment: | ||
- 'discovery.type=single-node' | ||
- 'ELASTIC_USERNAME=latitude' | ||
- 'ELASTIC_PASSWORD=secret' | ||
|
||
db: | ||
image: postgres | ||
environment: | ||
|
@@ -21,7 +23,26 @@ services: | |
volumes: | ||
- ./docker/init-db.sh:/docker-entrypoint-initdb.d/init-db.sh | ||
- ./docker/pgdata:/var/lib/postgresql/data | ||
|
||
redis: | ||
image: redis | ||
ports: | ||
- '6379:6379' | ||
|
||
web: | ||
build: | ||
context: . | ||
target: production | ||
dockerfile: apps/web/docker/Dockerfile | ||
# This enables to have this service for testing production build | ||
# It will not run when doing docker compose up | ||
profiles: [building] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Docker compose allow to have profiles. So no profile runs when |
||
volumes: | ||
- ./packages/env:/app/packages/env | ||
- ./packages/core:/app/packages/core | ||
- ./packages/jobs:/app/packages/jobs | ||
- ./packages/web-ui:/app/packages/web-ui | ||
- ./apps/web:/app/apps/web | ||
depends_on: | ||
- base | ||
- db |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ | |
}, | ||
"dependencies": { | ||
"@latitude-data/env": "workspace:^", | ||
"@t3-oss/env-core": "^0.10.1", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have the perfect excuse for this sorry. Explained in the next comment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. plz... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand why you don't want a tool built for this propose There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I actually like it for NextJS for the client-side safety measures that you mention ☝🏼 . I hate that we use it in api because it brings 0 value there, and adding a dependency is just overhead. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also this package is type save. When you do |
||
"bcrypt": "^5.1.1", | ||
"drizzle-orm": "0.31.4", | ||
"lodash-es": "^4.17.21", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,13 @@ | ||
import { createEnv } from '@t3-oss/env-core' | ||
import z from 'zod' | ||
|
||
import '@latitude-data/env' | ||
|
||
const envvars = z.object({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doing this breaks production build because it tries to find There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why? I don't get it why is this code evaluated at build time? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because it's imported by nextjs bundler. And because is imported zod There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. next bundler runs the code of its dependencies at compile time? :drunk: |
||
NODE_ENV: z.string(), | ||
DATABASE_URL: z.string(), | ||
export default createEnv({ | ||
skipValidation: process.env.BUILDING_CONTAINER == 'true', | ||
server: { | ||
NODE_ENV: z.string(), | ||
DATABASE_URL: z.string().url(), | ||
}, | ||
runtimeEnv: process.env, | ||
}) | ||
|
||
export default envvars.parse(process.env) | ||
|
||
declare global { | ||
namespace NodeJS { | ||
interface ProcessEnv extends z.infer<typeof envvars> {} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We were inserting a lot of shit in the image.