Deploy Nextjs on Docker with haproxy on ubuntu

Deploy Nextjs on Docker with haproxy on ubuntu

Posted on by Petter Kjelkenes - last updated 19. March, 2021

I will go trough installing a nextjs app on your own ubuntu machine using docker, docker-compose and haproxy.

With this method you can have multiple nextjs apps on a single machine, haproxy will take care of mapping each domain against correct nextjs app.

As a prereq install docker, docker-compose and haproxy on your ubuntu machine.


In your next app directory place the following files:

docker-compose.yml

version: "3"

services:
  appname:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: app-name
    restart: always
    ports:
      - "3000:3000"

Dockerfile

# Install dependencies only when needed
FROM node: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 package-lock.json ./
RUN npm install

# Rebuild the source code only when needed
FROM node:alpine AS builder
WORKDIR /app
COPY . .
COPY --from=deps /app/node_modules ./node_modules
RUN npm run build

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

ENV NODE_ENV production

# 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/.next ./.next
COPY --from=builder /app/node_modules ./node_modules

RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
RUN chown -R nextjs:nodejs /app/.next
USER nextjs

EXPOSE 3000

# 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.
# RUN npx next telemetry disable

CMD ["node_modules/.bin/next", "start"]

Now you can start your next-app on port 3000 like this:

sudo docker-compose up -d --build

The haproxy setup

Lets edit /etc/haproxy/haproxy.cfg

global
	log /dev/log	local0
	log /dev/log	local1 notice
	chroot /var/lib/haproxy
	stats socket /run/haproxy/admin.sock mode 660 level admin
	stats timeout 30s
	user haproxy
	group haproxy
	daemon

defaults
	log	global
	mode	http
	option	httplog
	option	dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
	errorfile 400 /etc/haproxy/errors/400.http
	errorfile 403 /etc/haproxy/errors/403.http
	errorfile 408 /etc/haproxy/errors/408.http
	errorfile 500 /etc/haproxy/errors/500.http
	errorfile 502 /etc/haproxy/errors/502.http
	errorfile 503 /etc/haproxy/errors/503.http
	errorfile 504 /etc/haproxy/errors/504.http


frontend http-in
   bind *:80

   acl my-app-acl hdr(host) -i my-app.com
   use_backend my-app if my-app-acl

   default_backend my-app



backend my-app
   server my-app 127.0.0.1:3000

We setup one app here called my-app against the domain my-app.com. The backend config for my-app runs on port 3000.

If you want more apps, run the next app on port 3001 an so fourth.

Comments