Improve Self host setup (#30)

* Add self host setup

* Improve blunders

* Move to bull mq

* More changes

* Add example code for sending test emails
This commit is contained in:
KM Koushik
2024-06-24 08:21:37 +10:00
committed by GitHub
parent 8a2769621c
commit f77a8829be
67 changed files with 1771 additions and 688 deletions

77
docker/Dockerfile Normal file
View File

@@ -0,0 +1,77 @@
FROM node:20.11.1-alpine AS base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
ENV SKIP_ENV_VALIDATION="true"
ENV DOCKER_OUTPUT 1
ENV NEXT_TELEMETRY_DISABLED 1
ENV NEXT_PUBLIC_IS_CLOUD="false"
RUN corepack enable
FROM base AS builder
RUN apk add --no-cache libc6-compat
RUN apk update
# Set working directory
WORKDIR /app
# Replace <your-major-version> with the major version installed in your repository. For example:
# RUN yarn global add turbo@^2
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml turbo.json ./
COPY ./apps/web ./apps/web
COPY ./packages ./packages
RUN pnpm add turbo@^1.12.5 -g
# Generate a partial monorepo with a pruned lockfile for a target workspace.
# Assuming "web" is the name entered in the project's package.json: { name: "web" }
RUN pnpm turbo prune web --docker
# Add lockfile and package.json's of isolated subworkspace
FROM base AS installer
RUN apk add --no-cache libc6-compat
RUN apk update
WORKDIR /app
# First install the dependencies (as they change less often)
COPY .gitignore .gitignore
COPY --from=builder /app/out/json/ .
COPY --from=builder /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
# Build the project
COPY --from=builder /app/out/full/ .
RUN pnpm turbo run build --filter=web...
FROM base AS runner
WORKDIR /app
COPY --from=installer /app/apps/web/next.config.js .
COPY --from=installer /app/apps/web/package.json .
COPY --from=installer /app/pnpm-lock.yaml .
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=installer /app/apps/web/.next/standalone ./
COPY --from=installer /app/apps/web/.next/static ./apps/web/.next/static
COPY --from=installer /app/apps/web/public ./apps/web/public
# Copy prisma files
COPY --from=installer /app/apps/web/prisma/schema.prisma ./apps/web/prisma/schema.prisma
COPY --from=installer /app/apps/web/prisma/migrations ./apps/web/prisma/migrations
COPY --from=installer /app/apps/web/node_modules/prisma ./node_modules/prisma
COPY --from=installer /app/apps/web/node_modules/@prisma ./node_modules/@prisma
# Symlink the prisma binary
RUN mkdir node_modules/.bin
RUN ln -s /app/node_modules/prisma/build/index.js ./node_modules/.bin/prisma
# set this so it throws error where starting server
ENV SKIP_ENV_VALIDATION="false"
COPY ./docker/start.sh ./start.sh
CMD ["sh", "start.sh"]

26
docker/build.sh Normal file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/env bash
command -v docker >/dev/null 2>&1 || {
echo "Docker is not running. Please start Docker and try again."
exit 1
}
SCRIPT_DIR="$(readlink -f "$(dirname "$0")")"
MONOREPO_ROOT="$(readlink -f "$SCRIPT_DIR/../")"
APP_VERSION="$(git name-rev --tags --name-only $(git rev-parse HEAD) | head -n 1 | sed 's/\^0//')"
GIT_SHA="$(git rev-parse HEAD)"
echo "Building docker image for monorepo at $MONOREPO_ROOT"
echo "App version: $APP_VERSION"
echo "Git SHA: $GIT_SHA"
docker build -f "$SCRIPT_DIR/Dockerfile" \
--progress=plain \
-t "unsend/unsend:latest" \
-t "unsend/unsend:$GIT_SHA" \
-t "unsend/unsend:$APP_VERSION" \
-t "ghcr.io/unsend/unsend:latest" \
-t "ghcr.io/unsend/unsend:$GIT_SHA" \
-t "ghcr.io/unsend/unsend:$APP_VERSION" \
"$MONOREPO_ROOT"

29
docker/dev/compose.yml Normal file
View File

@@ -0,0 +1,29 @@
name: unsend-dev
services:
postgres:
image: postgres:16
container_name: unsend-db-dev
restart: always
environment:
- POSTGRES_USER=unsend
- POSTGRES_PASSWORD=password
- POSTGRES_DB=unsend
volumes:
- database:/var/lib/postgresql/data
ports:
- "54320:5432"
redis:
image: redis:7
container_name: unsend-redis-dev
restart: always
ports:
- "6379:6379"
volumes:
- redis:/data
command: ["redis-server", "--maxmemory-policy", "noeviction"]
volumes:
database:
redis:

59
docker/prod/compose.yml Normal file
View File

@@ -0,0 +1,59 @@
name: unsend-prod
services:
postgres:
image: postgres:16
container_name: unsend-db-prod
restart: always
environment:
- POSTGRES_USER=${POSTGRES_USER:?err}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?err}
- POSTGRES_DB=${POSTGRES_DB:?err}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
# ports:
# - "5432:5432"
volumes:
- database:/var/lib/postgresql/data
redis:
image: redis:7
container_name: unsend-redis-prod
restart: always
# ports:
# - "6379:6379"
volumes:
- cache:/data
command: ["redis-server", "--maxmemory-policy", "noeviction"]
unsend:
image: unsend/unsend:latest
container_name: unsend
restart: always
ports:
- ${PORT:-3000}:${PORT:-3000}
environment:
- PORT=${PORT:-3000}
- DATABASE_URL=${DATABASE_URL:?err}
- NEXTAUTH_URL=${NEXTAUTH_URL:?err}
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET:?err}
- AWS_ACCESS_KEY=${AWS_ACCESS_KEY:?err}
- AWS_SECRET_KEY=${AWS_SECRET_KEY:?err}
- AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION:?err}
- GITHUB_ID=${GITHUB_ID:?err}
- GITHUB_SECRET=${GITHUB_SECRET:?err}
- REDIS_URL=${REDIS_URL:?err}
- NEXT_PUBLIC_IS_CLOUD=${NEXT_PUBLIC_IS_CLOUD:-false}
- API_RATE_LIMIT=${API_RATE_LIMIT:-1}
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
volumes:
database:
cache:

12
docker/start.sh Normal file
View File

@@ -0,0 +1,12 @@
#!/bin/sh
set -x
echo "Deploying prisma migrations"
pnpx prisma migrate deploy --schema ./apps/web/prisma/schema.prisma
echo "Starting web server"
node apps/web/server.js