aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2022-02-25 17:25:10 +0100
committerGitHub <noreply@github.com>2022-02-25 17:25:10 +0100
commit774d5b4c538d93889bf743b6cd7d01a85f8715e6 (patch)
treeece773efb8f625a05b0d8304ce610cf2e51368f0
parent2f1de56509948e4aecac058adeb07c3502bdf818 (diff)
feat: use Docker in production (#12)
* build: add experimental feature outputStandalone With this option, Next.js can create a standalone folder with the necessary files for a production deployment. It will be useful for Docker deployment. * chore: add Docker configuration * docs: update README with Docker instructions
-rw-r--r--.dockerignore7
-rw-r--r--.env.example4
-rw-r--r--Dockerfile54
-rw-r--r--README.md16
-rw-r--r--docker-compose.yml25
-rw-r--r--next.config.js1
6 files changed, 107 insertions, 0 deletions
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..c550055
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,7 @@
+Dockerfile
+.dockerignore
+node_modules
+npm-debug.log
+README.md
+.next
+.git
diff --git a/.env.example b/.env.example
index 6217f82..479f9b1 100644
--- a/.env.example
+++ b/.env.example
@@ -14,6 +14,10 @@ NEXT_PUBLIC_ACKEE_DOMAIN="www.ackeeDomain.com"
NEXT_PUBLIC_ACKEE_FILENAME="tracker.js"
NEXT_PUBLIC_ACKEE_SITE_ID="your-id-string"
+# Docker configuration
+APP_DOCKER_PORT_PROD=3000
+APP_DOCKER_PORT_DEV=3200
+
# Use this only in development mode. It prevents "unable to verify the first
# certificate" error when using a local domain with mkcert certificate for
# backend.
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..ce1176a
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,54 @@
+# Install dependencies only when needed
+FROM node:16-alpine AS deps
+# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
+RUN apk add --no-cache libc6-compat
+WORKDIR /app
+COPY package.json yarn.lock ./
+RUN yarn install --frozen-lockfile
+
+# If using npm with a `package-lock.json` comment out above and use below instead
+# COPY package.json package-lock.json ./
+# RUN npm ci
+
+# Rebuild the source code only when needed
+FROM node:16-alpine AS builder
+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 yarn build
+
+# Production image, copy all the files and run next
+FROM node:16-alpine 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
+
+# You only need to copy next.config.js if you are NOT using the default configuration
+# COPY --from=builder /app/next.config.js ./
+COPY --from=builder /app/public ./public
+COPY --from=builder /app/package.json ./package.json
+
+# 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
+
+ARG DOCKER_PORT=3000
+EXPOSE ${DOCKER_PORT}
+
+ENV PORT ${DOCKER_PORT}
+
+CMD ["node", "server.js"]
diff --git a/README.md b/README.md
index 04c2893..fda3b09 100644
--- a/README.md
+++ b/README.md
@@ -35,6 +35,22 @@ Even if the source code and the contents are under free licenses, I don't want t
Other contents come from WordPress as headless CMS.
+## Production
+
+In any case, you need a reverse-proxy if you want to bind the live app to a domain.
+
+### With Docker
+
+Make sure Docker and Docker Compose are installed then, you can run: `sudo docker-compose up -d --build <service-name>`.
+
+`<service-name>` is optional. You don't need it the first time. However, if you want to rebuild and update only one container, it can be useful.
+
+If you wish to use custom ports, you can edit your `.env` file and specify `APP_DOCKER_PORT_PROD` and `APP_DOCKER_PORT_DEV` variables. By default the ports are respectively `3000` and `3200`.
+
+### Without Docker
+
+Just run `yarn build && yarn start`.
+
## Development
### First step
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..c8d675b
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,25 @@
+version: '3.8'
+services:
+ apcom:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ args:
+ DOCKER_PORT: ${APP_DOCKER_PORT_PROD:-3000}
+ container_name: apcom
+ env_file:
+ - .env
+ ports:
+ - '${APP_DOCKER_PORT_PROD:-3000}:${APP_DOCKER_PORT_PROD:-3000}'
+ restart: always
+ apcom-dev:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ args:
+ DOCKER_PORT: ${APP_DOCKER_PORT_DEV:-3200}
+ container_name: apcom-dev
+ env_file:
+ - .env
+ ports:
+ - '${APP_DOCKER_PORT_DEV:-3200}:${APP_DOCKER_PORT_DEV:-3200}'
diff --git a/next.config.js b/next.config.js
index d85d5ec..077d0a0 100644
--- a/next.config.js
+++ b/next.config.js
@@ -70,6 +70,7 @@ const securityHeaders = [
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
+ outputStandalone: true,
scrollRestoration: true,
},
async headers() {