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:
77
docker/Dockerfile
Normal file
77
docker/Dockerfile
Normal 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
26
docker/build.sh
Normal 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
29
docker/dev/compose.yml
Normal 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
59
docker/prod/compose.yml
Normal 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
12
docker/start.sh
Normal 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
|
||||
|
Reference in New Issue
Block a user