Skip to content

Commit

Permalink
feat: add docker support
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-guoba committed Mar 10, 2024
1 parent a17d731 commit 7fd9bd9
Show file tree
Hide file tree
Showing 10 changed files with 846 additions and 20 deletions.
76 changes: 76 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
FROM node:21-alpine AS base

# Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/main?tab=readme-ov-file#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app

# 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 --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
fi


# Rebuild the source code only when needed
FROM base AS builder

# set building environment duiring building
ARG NOTION_TOKEN
ENV NOTION_TOKEN $NOTION_TOKEN
ARG NOTION_DATABASE_ID
ENV NOTION_DATABASE_ID $NOTION_DATABASE_ID

WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry during the build.
# ENV NEXT_TELEMETRY_DISABLED 1

RUN \
if [ -f yarn.lock ]; then yarn run build; \
elif [ -f package-lock.json ]; then npm run build; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
else echo "Lockfile not found." && exit 1; \
fi

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
# ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public

# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
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
# set hostname to localhost
ENV HOSTNAME "0.0.0.0"

# server.js is created by next build from the standalone output
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
CMD ["node", "server.js"]
5 changes: 0 additions & 5 deletions app/notion/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,6 @@ export const retrieveBlockChildren = async (blockID: string): Promise<any> => {

const blockId = blockID.replaceAll("-", ""); // ???

// TODO: only 100, unfinished and serial
// const { results } = await notion.blocks.children.list({
// block_id: blockId,
// page_size: 100,
// });
const result = await proxyListBlockChildren(blockId);
if (!result) {
return [];
Expand Down
32 changes: 23 additions & 9 deletions app/notion/proxy/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import prisma from "./prisma";
const notion = new Client({
auth: env.NOTION_TOKEN,
});

const dftMaxRetry = 2;
const enableCache: boolean = !!env.DATABASE_URL;

function expired(updated_at: Date): boolean {
Expand All @@ -19,7 +19,7 @@ function expired(updated_at: Date): boolean {
return false;
}

export async function proxyRetrieveDatabase(database_id: string) {
export async function proxyRetrieveDatabase(database_id: string, maxTries: number = dftMaxRetry) {
try {
// cache first
if (enableCache) {
Expand Down Expand Up @@ -56,12 +56,16 @@ export async function proxyRetrieveDatabase(database_id: string) {

return response;
} catch (error) {
console.log(error);
console.log(error, maxTries);

if (maxTries > 0) {
return proxyRetrieveDatabase(database_id, maxTries - 1);
}
return null;
}
}

export async function proxyQueryDatabases(database_id: string) {
export async function proxyQueryDatabases(database_id: string, maxTries: number = dftMaxRetry) {
try {
if (enableCache) {
const db = await prisma.dBRows.findUnique({
Expand Down Expand Up @@ -112,12 +116,15 @@ export async function proxyQueryDatabases(database_id: string) {

return response;
} catch (error) {
console.log(error);
console.log(error, maxTries);
if (maxTries > 0) {
return proxyQueryDatabases(database_id, maxTries - 1);
}
return null;
}
}

export async function proxyRetrievePage(page_id: string) {
export async function proxyRetrievePage(page_id: string, maxTries: number = dftMaxRetry) {
try {
if (enableCache) {
const db = await prisma.pageProperties.findUnique({
Expand Down Expand Up @@ -155,12 +162,15 @@ export async function proxyRetrievePage(page_id: string) {
}
return response;
} catch (error) {
console.log(error);
console.log(error, maxTries);
if (maxTries > 0) {
return proxyRetrievePage(page_id, maxTries - 1);
}
return null;
}
}

export async function proxyListBlockChildren(block_id: string) {
export async function proxyListBlockChildren(block_id: string, maxTries: number = dftMaxRetry) {
try {
if (enableCache) {
const db = await prisma.blockChildren.findUnique({
Expand Down Expand Up @@ -209,7 +219,11 @@ export async function proxyListBlockChildren(block_id: string) {
}
return response;
} catch (error) {
console.log(error);
console.log(error, maxTries);

if (maxTries > 0) {
return proxyListBlockChildren(block_id, maxTries - 1);
}
return null;
}
}
34 changes: 34 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
version: "3.9"
services:
iframely:
image: dogbin/iframely:latest
container_name: iframely
ports:
- "8061:8061"
services:
image: next-blogger:1.0
build:
context: .
dockerfile: Dockerfile
args:
- NOTION_TOKEN=
- NOTION_DATABASE_ID=
container_name: next-blogger
ports:
- "3000:3000"
environment:
- NOTION_TOKEN=
- NOTION_DATABASE_ID=
- IFRAMELY_URI=
- IFRAMELY_KEY=
- DATABASE_URL=mysql://user:pwd@mysql-test:3306/notion_blog
- NOTION_CACHE_EXPIRER=3600
depends_on:
- iframely
entrypoint:
[
"/app/scripts/startup/wait-for.sh",
"iframely:8061",
"--",
"node server.js"
]
3 changes: 3 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ const nextConfig = {
config.resolve.alias.canvas = false;
return config;
},

// This will build the project as a standalone app inside the Docker image.
output: "standalone",
};

module.exports = nextConfig;

0 comments on commit 7fd9bd9

Please sign in to comment.