사용자가 공유한 콘텐츠
-
안녕하세요, Next.js로 띄운 Container에 HTTPS를 적용하면서 문제가 발생해 도움을 요청드립니다.
배경
Next.js 애플리케이션을 Docker 컨테이너로 실행하고 있습니다. 처음에는 Next.js의 standalone 설정과 빌드된 server.js
를 사용했을 때는 문제가 없었습니다. 그러나 HTTPS 설정이 포함된 custom.server.js
를 사용하기 시작하면서 이슈가 나타났습니다.
현재 Dockerfile
```dockerfile
FROM node:20-alpine AS base
# Step 1. Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
# Add non-root user
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
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; \
else echo "Warning: Lockfile not found. It is recommended to commit lockfiles to version control." && yarn install; \
fi
# Copy source files
COPY src ./src
COPY public ./public
COPY next.config.js .
COPY tsconfig.json .
COPY holiday-kr.d.ts .
COPY server.custom.js .
COPY certificates ./certificates
# Set correct permissions
RUN chown -R nextjs:nodejs /app
# Build Next.js based on the preferred package manager
RUN \
if [ -f yarn.lock ]; then yarn build; \
elif [ -f package-lock.json ]; then npm run build; \
elif [ -f pnpm-lock.yaml ]; then pnpm build; \
else npm run build; \
fi
# Step 2. Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
# Don't run production as root
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nextjs
# Set the correct permission for the /app directory
RUN mkdir -p /app && chown -R nextjs:nodejs /app
# Copy built artifacts and set permissions
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
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/.next/standalone/server.js ./server.js
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/next ./node_modules/next
COPY --from=builder --chown=nextjs:nodejs /app/server.custom.js .
COPY --from=builder --chown=nextjs:nodejs /app/certificates ./certificates
# Ensure all files are owned by nextjs user
RUN chown -R nextjs:nodejs /app
# Switch to non-root user
USER nextjs
CMD ["node", "server.custom.js"]
```
## 현재 custom.server.js
const { createServer: https } = require('https');
const { createServer: http } = require('http');
const { parse } = require('url');
const next = require('next');
const fs = require('fs');
const path = require('path');
const { config } = require(path.join(
process.cwd(),
'.next',
'required-server-files.json',
));
const dev = process.env.NODE_ENV !== 'production';
const hostname = 'localhost';
const app = next({ dev: dev, hostname, conf: config });
const handle = app.getRequestHandler();
process.env.NODE_ENV = 'production';
const ports = {
http: 3000,
https: 3001,
};
const httpsOptions = {
cert: fs.readFileSync('certificates/localhost.pem'),
key: fs.readFileSync('certificates/localhost-key.pem'),
};
app.prepare().then(() => {
http((req, res) => {
const parsedUrl = parse(req.url, true);
handle(req, res, parsedUrl);
}).listen(ports.http, (err) => {
if (err) {
throw err;
}
console.log(`> Ready on http://${hostname}:${ports.http}`);
});
https(httpsOptions, (req, res) => {
const parsedUrl = parse(req.url, true);
handle(req, res, parsedUrl);
}).listen(ports.https, (err) => {
if (err) {
throw err;
}
console.log(`> Ready on http://${hostname}:${ports.https}`);
});
});
문제점
1. 컨테이너를 실행할 때(docker compose -f docker/docker-compose.prod.yml up -d
의존성을 다시 설치하려고 합니다. ( 로그는 다음 스택오버플로우 게시물에서 확인하실 수 있습니다.https://stackoverflow.com/questions/78891241/dependency-installation-and-permission-issues-with-https-setting-custom-server)
2. 의존성을 설치할 때 "permission denied" 오류가 발생합니다.
( 로그는 다음 스택오버플로우 게시물에서 확인하실 수 있습니다.https://stackoverflow.com/questions/78891241/dependency-installation-and-permission-issues-with-https-setting-custom-server)
3. 커스텀 HTTPS 서버 사용이 원인인지, 아니면 Docker 환경에서 추가 설정이 필요한지 확실하지 않습니다.
시도해본 것들
- Dockerfile에서 올바른 권한을 설정하려고 했지만 문제가 지속됩니다.
- 필요한 모든 파일을 컨테이너에 복사하고 nextjs
사용자가 소유하도록 했습니다.
질문
1. 컨테이너 시작 시 의존성 재설치를 방지할 수 있을까요?
2. "permission denied" 오류를 해결하는 가장 좋은 방법은 무엇인가요?
3. 최종 이미지에 프로덕션 의존성만 설치되도록 하려면 어떻게 해야 할까요?
4. Docker 환경에서 Next.js와 커스텀 HTTPS 서버를 사용할 때 고려해야 할 사항이 있나요?
5. 보안을 compromise하지 않으면서 필요한 경우 의존성 설치에 필요한 권한을 부여하는 방법이 있을까요?
경험이 있으신 분들의 조언이나 제안을 환영합니다. 감사합니다!
다음 내용이 궁금하다면?
이미 회원이신가요?
2024년 8월 20일 오전 8:23