feat: add docker support and docker-compose quickstart

Add support for production container builds using the provided `Dockerfile` and `build.sh` script. This can later be used with actions to automatically publish to the provided docker registry.

Additionally, support an accelerated developer quickstart using `docker-compose`. Developers can now run the `dx` npm command to quickly spin up a database and mail server.
This commit is contained in:
Mythie
2023-04-08 23:09:57 +10:00
committed by Lucas Smith
parent 30c1c76dd7
commit 5dd3713475
10 changed files with 272 additions and 4 deletions

38
.dockerignore Normal file
View File

@ -0,0 +1,38 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
**/node_modules
**/.pnp
**.pnp.js
# testing
**/coverage
# next.js
**/.next/
**/out/
# production
**/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# local env files
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
.env
.env.example

View File

@ -1,6 +1,9 @@
# Database
# Option 1: You can use the provided remote test database, courtesy of the documenso team: postgres://documenso_test_user:GnmLG14u12sd9zHsd4vVWwP40WneFJMo@dpg-cf2hljh4reb5o45oqpq0-a.oregon-postgres.render.com/documenso_test_e2i3
# Option 2: Set up a local Postgres SQL instance (RECOMMENDED)
# Option 3: Use the provided dx setup (RECOMMENDED)
# => postgres://documenso:password@127.0.0.1:5432/documenso
#
# ⚠ WARNING: The test database can be resetted or taken offline at any point.
# ⚠ WARNING: Please be aware that nothing written to the test databae is private.
DATABASE_URL=''
@ -20,6 +23,12 @@ SENDGRID_API_KEY=''
# SMTP
# Set SMTP credentials to use SMTP instead of the Sendgrid API.
# If you're using the dx setup you can use the following values:
#
# SMTP_MAIL_HOST='127.0.0.1'
# SMTP_MAIL_PORT='2500'
# SMTP_MAIL_USER='documenso'
# SMTP_MAIL_PASSWORD='documenso'
SMTP_MAIL_HOST=''
SMTP_MAIL_PORT=''
SMTP_MAIL_USER=''
@ -30,4 +39,4 @@ MAIL_FROM='documenso@localhost.com'
#FEATURE FLAGS
# Allow users to register via the /signup page. Otherwise they will be redirect to the home page.
ALLOW_SIGNUP=true
ALLOW_SIGNUP=true

View File

@ -99,6 +99,29 @@ To run Documenso locally you need
- Node Package Manger NPM - included in Node.js
- [PostgreSQL (local or remote)](https://www.postgresql.org/download/)
## Developer Quickstart
> **Note**: This is a quickstart for developers. It assumes that you have both [docker](https://docs.docker.com/get-docker/) and [docker-compose](https://docs.docker.com/compose/) installed on your machine.
Want to get up and running quickly? Follow these steps:
- [Clone the repository](https://help.github.com/articles/cloning-a-repository/) it to your local device.
```sh
git clone https://github.com/documenso/documenso
```
- Set up your .env file using the recommendations in the .env.example file.
- Run `npm run dx` in the root directory
- This will spin up a postgres database and inbucket mail server in docker containers.
- Run `npm run dev` in the root directory
That's it! You should now be able to access the app at http://localhost:3000
Incoming mail will be available at http://localhost:9000
Your database will also be available on port `5432`. You can connect to it using your favorite database client.
## Developer Setup
Follow these steps to setup documenso on you local machnine:
@ -153,6 +176,15 @@ For the digital signature of you documents you need a signign certificate in .p1
4. You will be prompted to enter a password for the p12 file. Choose a strong password and remember it, as you will need it to use the certificate (**can be empty for dev certificates**)
5. Place the certificate <code>/apps/web/ressource/certificate.p12</code>
# Docker
> We are still working on the publishing of docker images, in the meantime you can follow the steps below to create a production ready docker image.
Want to create a production ready docker image? Follow these steps:
- Run `./docker/build.sh` in the root directory.
- Publish the image to your docker registry of choice.
# Deploying - Coming Soon™
- Docker support

50
docker/Dockerfile Normal file
View File

@ -0,0 +1,50 @@
FROM node:18-alpine AS base
# Install dependencies only when needed
FROM base AS production_deps
WORKDIR /app
# 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
# Copy our current monorepo
COPY . .
RUN npm ci --production
# Install dependencies only when needed
FROM base AS builder
WORKDIR /app
# 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
# Copy our current monorepo
COPY . .
RUN npm ci
RUN npm run build --workspaces
# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=production_deps --chown=nextjs:nodejs /app/node_modules ./node_modules
COPY --from=production_deps --chown=nextjs:nodejs /app/package-lock.json ./package-lock.json
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/package.json ./package.json
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next ./.next
EXPOSE 3000
ENV PORT 3000
CMD ["npm", "run", "start"]

28
docker/build.sh Executable file
View File

@ -0,0 +1,28 @@
#!/usr/bin/env bash
command -v docker >/dev/null 2>&1 || {
echo "Docker is not running. Please start Docker and try again."
exit 1
}
command -v jq >/dev/null 2>&1 || {
echo "jq is not installed. Please install jq and try again."
exit 1
}
SCRIPT_DIR="$(readlink -f "$(dirname "$0")")"
MONOREPO_ROOT="$(readlink -f "$SCRIPT_DIR/../")"
APP_VERSION="$(jq -r '.version' "$MONOREPO_ROOT/apps/web/package.json")"
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 "documentso:latest" \
-t "documenso:$GIT_SHA" \
-t "documenso:$APP_VERSION" \
"$MONOREPO_ROOT"

12
docker/compose-entrypoint.sh Executable file
View File

@ -0,0 +1,12 @@
#!/usr/bin/env bash
SCRIPT_DIR="$(readlink -f "$(dirname "$0")")"
MONOREPO_ROOT="$(readlink -f "$SCRIPT_DIR/../")"
cd "$MONOREPO_ROOT"
npm ci
npm run db-migrate:dev
npm run dev

View File

@ -0,0 +1,16 @@
services:
database:
image: postgres:15
environment:
- POSTGRES_USER=documenso
- POSTGRES_PASSWORD=password
- POSTGRES_DB=documenso
ports:
- 5432:5432
inbucket:
image: inbucket/inbucket
ports:
- 9000:9000
- 2500:2500
- 1100:1100

40
docker/compose.yml Normal file
View File

@ -0,0 +1,40 @@
services:
database:
image: postgres:15
environment:
- POSTGRES_USER=documenso
- POSTGRES_PASSWORD=password
- POSTGRES_DB=documenso
ports:
- 5432:5432
inbucket:
image: inbucket/inbucket
ports:
- 9000:9000
- 2500:2500
- 1100:1100
documenso:
image: node:18
working_dir: /app
command: ./docker/compose-entrypoint.sh
depends_on:
- database
- inbucket
environment:
- DATABASE_URL=postgres://documenso:password@database:5432/documenso
- NEXT_PUBLIC_WEBAPP_URL=http://localhost:3000
- NEXTAUTH_SECRET=my-super-secure-secret
- NEXTAUTH_URL=http://localhost:3000
- SENDGRID_API_KEY=
- SMTP_MAIL_HOST=inbucket
- SMTP_MAIL_PORT=2500
- SMTP_MAIL_USER=username
- SMTP_MAIL_PASSWORD=password
- MAIL_FROM=admin@example.com
- ALLOW_SIGNUP=true
ports:
- 3000:3000
volumes:
- ../:/app

View File

@ -2,12 +2,13 @@
"name": "documenso-monorepo",
"version": "0.0.0",
"scripts": {
"dev": "cd apps && cd web && next dev",
"dev": "npm run dev -w apps/web",
"build": "npm i && cd apps && cd web && npm i && next build",
"start": "cd apps && cd web && next start",
"db-migrate:dev": "prisma migrate dev",
"db-seed": "prisma db seed",
"db-studio": "prisma studio"
"db-studio": "prisma studio",
"dx": "./scripts/dx.sh"
},
"workspaces": [
"apps/*",
@ -49,4 +50,4 @@
"prettier": "^2.8.7",
"prettier-plugin-tailwindcss": "^0.2.5"
}
}
}

42
scripts/dx.sh Executable file
View File

@ -0,0 +1,42 @@
#!/usr/bin/env bash
SCRIPT_DIR="$(readlink -f "$(dirname "$0")")"
MONOREPO_ROOT="$(readlink -f "$SCRIPT_DIR/../")"
# Check if docker is installed
if ! command -v docker >/dev/null 2>&1; then
echo "Docker is not installed. Please install Docker and try again."
exit 1
fi
# Check if docker-compose is installed
if ! command -v docker-compose >/dev/null 2>&1; then
echo "Docker Compose is not installed. Please install Docker Compose and try again."
exit 1
fi
# Check if we have a .env file
if [ ! -f "$MONOREPO_ROOT/.env" ]; then
echo "No .env file found. Please create one and try again."
echo "See .env.example for an example."
exit 1
fi
# Change to the monorepo root directory
pushd "$MONOREPO_ROOT" >/dev/null
# On failure popd back to the original directory
trap "popd >/dev/null" EXIT
docker-compose -f "$MONOREPO_ROOT/docker/compose-without-app.yml" up -d
# Install dependencies
npm ci
# Migrate the database
npm run db-migrate:dev
echo "All done! You can now start the app with: npm run dev"
# Return to the original directory
popd >/dev/null