diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..1dccbe1 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +.next/ +.git/ +node_modules/ +README.md + diff --git a/next.config.js b/next.config.js new file mode 100644 index 0000000..5c2c44f --- /dev/null +++ b/next.config.js @@ -0,0 +1,3 @@ +module.exports = { + output: "standalone", +}; diff --git a/posts/example-post.mdx b/posts/golang/example-post.mdx similarity index 100% rename from posts/example-post.mdx rename to posts/golang/example-post.mdx diff --git a/posts/hello-world.mdx b/posts/golang/hello-world.mdx similarity index 100% rename from posts/hello-world.mdx rename to posts/golang/hello-world.mdx diff --git a/prod.docker-compose.yml b/prod.docker-compose.yml new file mode 100644 index 0000000..187d919 --- /dev/null +++ b/prod.docker-compose.yml @@ -0,0 +1,10 @@ +version: "3" + +services: + rawpotion-man: + build: + context: . + dockerfile: scripts/docker/prod.Dockerfile + restart: unless-stopped + ports: + - 3000:3000 diff --git a/public/.gitkeep b/public/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/scripts/docker/prod.Dockerfile b/scripts/docker/prod.Dockerfile new file mode 100644 index 0000000..5bdccce --- /dev/null +++ b/scripts/docker/prod.Dockerfile @@ -0,0 +1,63 @@ +# Step 1. Rebuild the source code only when needed +FROM node:18-alpine AS builder + +WORKDIR /app + +# Install dependencies based on the preferred package manager +COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./ +# Omit --production flag for TypeScript devDependencies +RUN \ + if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ + elif [ -f package-lock.json ]; then npm ci; \ + elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i; \ + else echo "Lockfile not found." && exit 1; \ + fi + + +COPY src ./src +COPY public ./public +COPY posts ./posts +COPY next.config.js . +COPY tsconfig.json . + +# Environment variables must be present at build time +# https://github.com/vercel/next.js/discussions/14030 +ARG ENV_VARIABLE +ENV ENV_VARIABLE=${ENV_VARIABLE} +ARG NEXT_PUBLIC_ENV_VARIABLE +ENV NEXT_PUBLIC_ENV_VARIABLE=${NEXT_PUBLIC_ENV_VARIABLE} + +# Uncomment the following line to disable telemetry at build time +# ENV NEXT_TELEMETRY_DISABLED 1 + +RUN yarn build + +# Step 2. Production image, copy all the files and run next +FROM node:18-alpine AS runner + +WORKDIR /app + +# Don't run production as root +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs +USER nextjs + +COPY --from=builder /app/public ./public + +# 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 +COPY --from=builder --chown=nextjs:nodejs /app/posts ./posts + +# Environment variables must be redefined at run time +ARG ENV_VARIABLE +ENV ENV_VARIABLE=${ENV_VARIABLE} +ARG NEXT_PUBLIC_ENV_VARIABLE +ENV NEXT_PUBLIC_ENV_VARIABLE=${NEXT_PUBLIC_ENV_VARIABLE} + +# Uncomment the following line to disable telemetry at run time +# ENV NEXT_TELEMETRY_DISABLED 1 + +CMD node server.js + diff --git a/components/CustomLink.tsx b/src/components/CustomLink.tsx similarity index 100% rename from components/CustomLink.tsx rename to src/components/CustomLink.tsx diff --git a/components/Layout.tsx b/src/components/Layout.tsx similarity index 100% rename from components/Layout.tsx rename to src/components/Layout.tsx diff --git a/components/TestComponent.tsx b/src/components/TestComponent.tsx similarity index 100% rename from components/TestComponent.tsx rename to src/components/TestComponent.tsx diff --git a/pages/golang/posts/[slug].tsx b/src/pages/golang/posts/[slug].tsx similarity index 92% rename from pages/golang/posts/[slug].tsx rename to src/pages/golang/posts/[slug].tsx index 6c53a8d..358e430 100644 --- a/pages/golang/posts/[slug].tsx +++ b/src/pages/golang/posts/[slug].tsx @@ -8,7 +8,7 @@ import Link from "next/link"; import path from "path"; import CustomLink from "../../../components/CustomLink"; import Layout from "../../../components/Layout"; -import { postFilePaths, POSTS_PATH } from "../../../utils/mdxUtils"; +import { golangPostFilePaths, GOLANG_POSTS_PATH } from "../../../utils/mdxUtils"; // Custom components/renderers to pass to MDX. // Since the MDX files aren't loaded by webpack, they have no knowledge of how @@ -60,7 +60,7 @@ export default function PostPage({ source, frontMatter }) { } export const getStaticProps = async ({ params }) => { - const postFilePath = path.join(POSTS_PATH, `${params.slug}.mdx`); + const postFilePath = path.join(GOLANG_POSTS_PATH, `${params.slug}.mdx`); const source = fs.readFileSync(postFilePath); const { content, data } = matter(source); @@ -83,7 +83,7 @@ export const getStaticProps = async ({ params }) => { }; export const getStaticPaths = async () => { - const paths = postFilePaths + const paths = golangPostFilePaths // Remove file extensions for page paths .map((path) => path.replace(/\.mdx?$/, "")) // Map the path into the static paths object required by Next.js diff --git a/pages/index.tsx b/src/pages/index.tsx similarity index 81% rename from pages/index.tsx rename to src/pages/index.tsx index 69793aa..d49a474 100644 --- a/pages/index.tsx +++ b/src/pages/index.tsx @@ -3,7 +3,7 @@ import matter from "gray-matter"; import Link from "next/link"; import path from "path"; import Layout from "../components/Layout"; -import { postFilePaths, POSTS_PATH } from "../utils/mdxUtils"; +import { golangPostFilePaths, GOLANG_POSTS_PATH } from "../utils/mdxUtils"; export default function Index({ posts }) { return ( @@ -30,8 +30,8 @@ export default function Index({ posts }) { } export function getStaticProps() { - const posts = postFilePaths.map((filePath) => { - const source = fs.readFileSync(path.join(POSTS_PATH, filePath)); + const posts = golangPostFilePaths.map((filePath) => { + const source = fs.readFileSync(path.join(GOLANG_POSTS_PATH, filePath)); const { content, data } = matter(source); return { diff --git a/utils/mdxUtils.ts b/src/utils/mdxUtils.ts similarity index 64% rename from utils/mdxUtils.ts rename to src/utils/mdxUtils.ts index de8db69..06b7ce3 100644 --- a/utils/mdxUtils.ts +++ b/src/utils/mdxUtils.ts @@ -2,10 +2,10 @@ import fs from "fs"; import path from "path"; // POSTS_PATH is useful when you want to get the path to a specific file -export const POSTS_PATH = path.join(process.cwd(), "posts"); +export const GOLANG_POSTS_PATH = path.join(process.cwd(), "posts/golang"); // postFilePaths is the list of all mdx files inside the POSTS_PATH directory -export const postFilePaths = fs - .readdirSync(POSTS_PATH) +export const golangPostFilePaths = fs + .readdirSync(GOLANG_POSTS_PATH) // Only include md(x) files .filter((path) => /\.mdx?$/.test(path));