diff --git a/.env b/.env new file mode 100644 index 0000000..401de56 --- /dev/null +++ b/.env @@ -0,0 +1,34 @@ +POSTGRES_USER=unicorn_user +POSTGRES_PASSWORD=magical_password +POSTGRES_DB=calendso +DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}" +GOOGLE_API_CREDENTIALS='secret' +BASE_URL='http://localhost:3000' +NEXTAUTH_URL='http://localhost:3000' + +# Remove this var if you don't want Calendso to collect anonymous usage +NEXT_PUBLIC_TELEMETRY_KEY=js.2pvs2bbpqq1zxna97wcml.oi2jzirnbj1ev4tc57c5r + +# Used for the Office 365 / Outlook.com Calendar integration +MS_GRAPH_CLIENT_ID= +MS_GRAPH_CLIENT_SECRET= + +# Used for the Zoom integration +ZOOM_CLIENT_ID= +ZOOM_CLIENT_SECRET= + +# E-mail settings + +# Calendso uses nodemailer (@see https://nodemailer.com/about/) to provide email sending. As such we are trying to +# allow access to the nodemailer transports from the .env file. E-mail templates are accessible within lib/emails/ + +# Configures the global From: header whilst sending emails. +EMAIL_FROM='notifications@yourselfhostedcalendso.com' + +# Configure SMTP settings (@see https://nodemailer.com/smtp/). +# Note: The below configuration for Office 365 has been verified to work. +EMAIL_SERVER_HOST='smtp.office365.com' +EMAIL_SERVER_PORT=587 +EMAIL_SERVER_USER='' +# Keep in mind that if you have 2FA enabled, you will need to provision an App Password. +EMAIL_SERVER_PASSWORD='' diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..90cc27b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +FROM node:14-alpine as deps +WORKDIR /app +COPY calendso/package.json . +COPY calendso/prisma prisma +RUN yarn install --frozen + +FROM node:14-alpine as builder +WORKDIR /app +COPY calendso . +COPY --from=deps /app/node_modules ./node_modules +RUN yarn build +RUN yarn install --production --ignore-scripts --prefer-offline + +FROM node:14-alpine as runner +WORKDIR /app +ENV NODE_ENV production + +COPY --from=builder /app/public ./public +COPY --from=builder /app/.next ./.next +COPY --from=builder /app/node_modules ./node_modules +COPY --from=builder /app/package.json ./package.json +COPY --from=builder /app/prisma ./prisma +COPY scripts scripts +EXPOSE 3000 +CMD ["/app/scripts/start.sh"] \ No newline at end of file diff --git a/README.md b/README.md index 3e887e7..4afcb4f 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,24 @@ Make sure you have `docker` & `docker-compose` installed on the server / system. 1. Clone calendso-docker -```bash -git clone git@github.com:calendso/calendso-docker.git --recursive -``` + ```bash + git clone git@github.com:calendso/calendso-docker.git --recursive + ``` -... +2. Update `.env` if needed + +3. Build and start calendso + + ``` + docker-compose up --build + ``` + +4. Start prisma studio + ``` + docker-compose exec calendso -- npx prisma studio + ``` +5. Open a browser to [http://localhost:5555](http://localhost:5555) to look at or modify the database content. + +6. Click on the `User` model to add a new user record. +7. Fill out the fields (remembering to encrypt your password with [BCrypt](https://bcrypt-generator.com/)) and click `Save 1 Record` to create your first user. +8. Open a browser to [http://localhost:3000](http://localhost:3000) and login with your just created, first user. \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..d0d08a7 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,20 @@ +# Use postgres/example user/password credentials +version: '3.1' +services: + db: + image: postgres + restart: always + volumes: + - database-data:/var/lib/postgresql/data/ + env_file: .env + ports: + - 5432:5432 + calendso: + build: . + restart: always + ports: + - 3000:3000 + - 5555:5555 + env_file: .env +volumes: + database-data: \ No newline at end of file diff --git a/scripts/start.sh b/scripts/start.sh new file mode 100755 index 0000000..dc8b64e --- /dev/null +++ b/scripts/start.sh @@ -0,0 +1,6 @@ +#!/bin/sh +set -x + +/app/scripts/wait-for-it.sh db:5432 -- echo "db is up" +npx prisma db push +yarn start \ No newline at end of file diff --git a/scripts/wait-for-it.sh b/scripts/wait-for-it.sh new file mode 100755 index 0000000..0816f6f --- /dev/null +++ b/scripts/wait-for-it.sh @@ -0,0 +1,184 @@ +#!/bin/sh + +# The MIT License (MIT) +# +# Copyright (c) 2017 Eficode Oy +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +set -- "$@" -- "$TIMEOUT" "$QUIET" "$PROTOCOL" "$HOST" "$PORT" "$result" +TIMEOUT=15 +QUIET=0 +# The protocol to make the request with, either "tcp" or "http" +PROTOCOL="tcp" + +echoerr() { + if [ "$QUIET" -ne 1 ]; then printf "%s\n" "$*" 1>&2; fi +} + +usage() { + exitcode="$1" + cat << USAGE >&2 +Usage: + $0 host:port|url [-t timeout] [-- command args] + -q | --quiet Do not output any status messages + -t TIMEOUT | --timeout=timeout Timeout in seconds, zero for no timeout + -- COMMAND ARGS Execute command with args after the test finishes +USAGE + exit "$exitcode" +} + +wait_for() { + case "$PROTOCOL" in + tcp) + if ! command -v nc >/dev/null; then + echoerr 'nc command is missing!' + exit 1 + fi + ;; + wget) + if ! command -v wget >/dev/null; then + echoerr 'nc command is missing!' + exit 1 + fi + ;; + esac + + while :; do + case "$PROTOCOL" in + tcp) + nc -w 1 -z "$HOST" "$PORT" > /dev/null 2>&1 + ;; + http) + wget --timeout=1 -q "$HOST" -O /dev/null > /dev/null 2>&1 + ;; + *) + echoerr "Unknown protocol '$PROTOCOL'" + exit 1 + ;; + esac + + result=$? + + if [ $result -eq 0 ] ; then + if [ $# -gt 7 ] ; then + for result in $(seq $(($# - 7))); do + result=$1 + shift + set -- "$@" "$result" + done + + TIMEOUT=$2 QUIET=$3 PROTOCOL=$4 HOST=$5 PORT=$6 result=$7 + shift 7 + exec "$@" + fi + exit 0 + fi + + if [ "$TIMEOUT" -le 0 ]; then + break + fi + TIMEOUT=$((TIMEOUT - 1)) + + sleep 1 + done + echo "Operation timed out" >&2 + exit 1 +} + +while :; do + case "$1" in + http://*|https://*) + HOST="$1" + PROTOCOL="http" + shift 1 + ;; + *:* ) + HOST=$(printf "%s\n" "$1"| cut -d : -f 1) + PORT=$(printf "%s\n" "$1"| cut -d : -f 2) + shift 1 + ;; + -q | --quiet) + QUIET=1 + shift 1 + ;; + -q-*) + QUIET=0 + echoerr "Unknown option: $1" + usage 1 + ;; + -q*) + QUIET=1 + result=$1 + shift 1 + set -- -"${result#-q}" "$@" + ;; + -t | --timeout) + TIMEOUT="$2" + shift 2 + ;; + -t*) + TIMEOUT="${1#-t}" + shift 1 + ;; + --timeout=*) + TIMEOUT="${1#*=}" + shift 1 + ;; + --) + shift + break + ;; + --help) + usage 0 + ;; + -*) + QUIET=0 + echoerr "Unknown option: $1" + usage 1 + ;; + *) + QUIET=0 + echoerr "Unknown argument: $1" + usage 1 + ;; + esac +done + +if ! [ "$TIMEOUT" -ge 0 ] 2>/dev/null; then + echoerr "Error: invalid timeout '$TIMEOUT'" + usage 3 +fi + +case "$PROTOCOL" in + tcp) + if [ "$HOST" = "" ] || [ "$PORT" = "" ]; then + echoerr "Error: you need to provide a host and port to test." + usage 2 + fi + ;; + http) + if [ "$HOST" = "" ]; then + echoerr "Error: you need to provide a host to test." + usage 2 + fi + ;; +esac + +wait_for "$@" \ No newline at end of file