From 73b2e6104d652db258e54ead5d4d0eb1b01c3163 Mon Sep 17 00:00:00 2001 From: Colin Date: Mon, 1 Aug 2022 13:39:29 -0400 Subject: [PATCH 1/5] Significant Refactor. - added numerous environment variable changes such as implied defaults that can be overriden. - skipped out on using git modules and just pull repo into build/launch step. Adherance to license requires no repackaging and this solves this. - cleaned up now unnecessary .env file. - recycled environment section using yaml features. - writing a few strings to config path to persist data between container starts that focus on cryptography and secrets. - writing installed commit to the config path in case the end user needs to change the upstream git commit ID to a newer version for detection and automagic upgrades. - added docker-compose.override.yml pattern to .gitignore to allow users to customize their local dev environment if they use docker-compose.yml - wrote a dockerfile/container image which allows for uploading the base container to a private or public docker container registry without breaking the license rules. - left .env ignore in case users wish to continue to use the old method. - updated README.md to include updated simplified instructions. - added start.sh script and wait-for-it.sh into the shell $PATH to allow for a potential future of allowing the main executable (node JS app) to run under a limited privilege user while still allowing the init scripts to be executed securely. - added some input sanitation for certain critical variables. - by default disabled/commented out the studio service as its not to typically be run to enforce better default deployment practices. I would like to figure out what specific query to execute via the CLI instead of running a whole container to establish the first user in the end. - wrote relatively unopinionated docker-compose.yml file to avoid causing problems for people trying to deploy this behind a reverse proxy for potential features such as TLS/HTTPS termination. - upgraded compose version to latest '3.9' to be sure to enable most modern feature set. Fixes #87 by providing a working baseline with sober defaults. Fixes #88 by ensuring consistency across all containers Environment vars. Fixes #93 by allowing users to mount the application files within their IDE workspace, however, this will never solve for any times you will need to run yarn build steps. Fixes #99 by no longer using git submodules and just pulling a single commit depth copy of the ORIGIN repository on app bootstrap/first boot. Fixes #113 by no longer requiring build locally if the community maintainer of the Cal docker repository on GitHub will push this image to the hub. Fixes #121 by removing dependency on BuildKit this is done by simply deploying the app if its detected to be the first execution of this container be it due to no container persistence or a commit version upgrade from ORIGIN. Fixes #128 by removing dep on BuildKit Fixes #123 not replicatable and confirmed to be working in repository shipped state. Fixes #136 by building app on first launch from user define-able envvars which can be defined in numerous ways. --- .env.example | 55 ------- .github/workflows/update-submodules.yml | 26 --- .gitignore | 3 +- .gitmodules | 4 - Dockerfile | 59 ++----- README.md | 139 ++++++++-------- calcom | 1 - docker-compose.yaml | 62 -------- docker-compose.yml | 98 ++++++++++++ scripts/start.sh | 200 +++++++++++++++++++++++- 10 files changed, 382 insertions(+), 265 deletions(-) delete mode 100644 .env.example delete mode 100644 .github/workflows/update-submodules.yml delete mode 100644 .gitmodules delete mode 160000 calcom delete mode 100644 docker-compose.yaml create mode 100644 docker-compose.yml diff --git a/.env.example b/.env.example deleted file mode 100644 index 26ce814e1..000000000 --- a/.env.example +++ /dev/null @@ -1,55 +0,0 @@ -# Set this value to 'agree' to accept our license: -# LICENSE: https://github.com/calendso/calendso/blob/main/LICENSE -# -# Summary of terms: -# - The codebase has to stay open source, whether it was modified or not -# - You can not repackage or sell the codebase -# - Acquire a commercial license to remove these terms by emailing: license@cal.com -NEXT_PUBLIC_LICENSE_CONSENT= -LICENSE= - -# BASE_URL and NEXT_PUBLIC_APP_URL are both deprecated. Both are replaced with one variable, NEXT_PUBLIC_WEBAPP_URL -# BASE_URL=http://localhost:3000 -# NEXT_PUBLIC_APP_URL=http://localhost:3000 - -NEXT_PUBLIC_WEBAPP_URL=http://localhost:3000 - -# It is highly recommended that the NEXTAUTH_SECRET must be overridden and very unique -# Use `openssl rand -base64 32` to generate a key -NEXTAUTH_SECRET=secret - -# Encryption key that will be used to encrypt CalDAV credentials, choose a random string, for example with `dd if=/dev/urandom bs=1K count=1 | md5sum` -CALENDSO_ENCRYPTION_KEY=secret - -# Deprecation note: JWT_SECRET is no longer used -# JWT_SECRET=secret - -POSTGRES_USER=unicorn_user -POSTGRES_PASSWORD=magical_password -POSTGRES_DB=calendso -DATABASE_HOST=database:5432 -DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DATABASE_HOST}/${POSTGRES_DB} -GOOGLE_API_CREDENTIALS={} - -# Set this to '1' if you don't want Cal to collect anonymous usage -CALCOM_TELEMETRY_DISABLED= - -# 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 -# Configures the global From: header whilst sending emails. -EMAIL_FROM=notifications@example.com - -# Configure SMTP settings (@see https://nodemailer.com/smtp/). -EMAIL_SERVER_HOST=smtp.example.com -EMAIL_SERVER_PORT=587 -EMAIL_SERVER_USER=email_user -EMAIL_SERVER_PASSWORD=email_password - -NODE_ENV=production diff --git a/.github/workflows/update-submodules.yml b/.github/workflows/update-submodules.yml deleted file mode 100644 index 6a8a92a61..000000000 --- a/.github/workflows/update-submodules.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Update Calendso -on: - schedule: - - cron: "0 4 * * *" - workflow_dispatch: ~ - -jobs: - sync: - name: 'Submodules Sync' - runs-on: ubuntu-latest - defaults: - run: - shell: bash - steps: - - name: checkout - uses: actions/checkout@v2 - - - name: Git submodule update - run: | - git submodule update --remote --init - - - name: Commit - run: | - git config user.email "actions@github.com" - git config user.name "actions-user" - git commit -am "Auto updated submodule references" && git push || echo "No changes to commit" diff --git a/.gitignore b/.gitignore index d0c241807..586a4c49c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # .env file -.env \ No newline at end of file +.env +docker-compose.override.yml diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index d2e4d9aa6..000000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "calcom"] - path = calcom - url = https://github.com/calcom/cal.com.git - branch = main diff --git a/Dockerfile b/Dockerfile index 30a51ae84..47c1eec36 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,48 +1,11 @@ -FROM node:16 as builder - -WORKDIR /calcom -ARG NEXT_PUBLIC_WEBAPP_URL=http://localhost:3000 -ARG NEXT_PUBLIC_APP_URL -ARG NEXT_PUBLIC_LICENSE_CONSENT -ARG CALCOM_TELEMETRY_DISABLED -ARG DATABASE_URL -ARG NEXTAUTH_SECRET=secret -ARG CALENDSO_ENCRYPTION_KEY=secret -ARG MAX_OLD_SPACE_SIZE=4096 - -ENV NEXT_PUBLIC_WEBAPP_URL=$NEXT_PUBLIC_WEBAPP_URL \ - NEXT_PUBLIC_APP_URL=$NEXT_PUBLIC_APP_URL \ - NEXT_PUBLIC_LICENSE_CONSENT=$NEXT_PUBLIC_LICENSE_CONSENT \ - CALCOM_TELEMETRY_DISABLED=$CALCOM_TELEMETRY_DISABLED \ - DATABASE_URL=$DATABASE_URL \ - NEXTAUTH_SECRET=${NEXTAUTH_SECRET} \ - CALENDSO_ENCRYPTION_KEY=${CALENDSO_ENCRYPTION_KEY} \ - NODE_OPTIONS=--max-old-space-size=${MAX_OLD_SPACE_SIZE} - -COPY calcom/package.json calcom/yarn.lock calcom/turbo.json ./ -COPY calcom/apps/web ./apps/web -COPY calcom/packages ./packages - -RUN yarn install --frozen-lockfile - -RUN yarn build - -FROM node:16 as runner - -WORKDIR /calcom -ENV NODE_ENV production - -RUN apt-get update && \ - apt-get -y install netcat && \ - rm -rf /var/lib/apt/lists/* && \ - npm install --global prisma - -COPY calcom/package.json calcom/yarn.lock calcom/turbo.json ./ -COPY --from=builder /calcom/node_modules ./node_modules -COPY --from=builder /calcom/packages ./packages -COPY --from=builder /calcom/apps/web ./apps/web -COPY --from=builder /calcom/packages/prisma/schema.prisma ./prisma/schema.prisma -COPY scripts scripts - -EXPOSE 3000 -CMD ["/calcom/scripts/start.sh"] +FROM node:16 + +COPY scripts /opt/scripts +RUN apt-get update && \ + apt-get -y install netcat && \ + rm -rf /var/lib/apt/lists/* && \ + npm install --location=global prisma && \ + ln -s /opt/scripts/start.sh /opt/scripts/wait-for-it.sh /usr/bin/ + +EXPOSE 3000 +CMD ["start.sh"] diff --git a/README.md b/README.md index 351b935eb..01303ccda 100644 --- a/README.md +++ b/README.md @@ -26,89 +26,116 @@ For Production, for the time being, please checkout the repository and build/pus ## Requirements -Make sure you have `docker` & `docker compose` installed on the server / system. Both are installed by most docker utilities, including Docker Desktop and Rancher Desktop. +Make sure you have `docker` & `docker-compose` installed on the server / system. Both are installed by most docker utilities, including Docker Desktop and Rancher Desktop. -Note: `docker compose` without the hyphen is now the primary method of using docker-compose, per the Docker documentation. +Note: `docker-compose` without the hyphen is now the primary method of using docker-compose, per the Docker documentation. ## Getting Started -1. Clone calcom-docker +1. wget docker-compose.yml to wherever you plan on running this. ```bash - git clone https://github.com/calcom/docker.git calcom-docker + wget https://raw.githubusercontent.com/calcom/docker/main/docker-compose.yml ``` -2. Change into the directory +2. Modify the environment section at the top of the `docker-compose.yml` file. + + + ```yaml + x-environment: &environment + environment: + # Set this value to 'agree' to accept our license: + # LICENSE: https://github.com/calendso/calendso/blob/main/LICENSE + # + # Summary of terms: + # - The codebase has to stay open source, whether it was modified or not + # - You can not repackage or sell the codebase + # - Acquire a commercial license to remove these terms by emailing: license@cal.com + ## You must agree to these terms manually we can't agree to them for you. + # NEXT_PUBLIC_LICENSE_CONSENT: + # LICENSE: + + ## Deployment configuration section you may need to change this if you're using a reverse proxy such as nginx, haproxy or træfik. + NEXT_PUBLIC_WEBAPP_URL: http://localhost:3000 + + # E-mail settings + # Configures the global From: header whilst sending emails. + EMAIL_FROM: notifications@example.com + + # Configure SMTP settings (@see https://nodemailer.com/smtp/). + EMAIL_SERVER_HOST: smtp.example.com + EMAIL_SERVER_PORT: 587 + EMAIL_SERVER_USER: email_user + EMAIL_SERVER_PASSWORD: email_password + + ## Only change these if you know what you're doing. Changes are unlikely to be needed. + ## However, you could change the password if you like before you start the first time. Also feel free to read about and implement Docker Secrets. + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres + DATABASE_HOST: postgres:5432 + DATABASE_URL: ${DATABASE_URL:='postgresql://postgres:postgres@postgres:5432/postgres'} + # GOOGLE_API_CREDENTIALS: {} + + # Set this to '1' if you don't want Cal to collect anonymous usage. This is not necessary, however, its kind to give back metrics to the app developers if you trust them. + CALCOM_TELEMETRY_DISABLED: 0 + + # 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: + + ## Probably only change this if you know what you're doing. + NODE_ENV: production + ``` + +3. Start Cal.com via docker-compose - ```bash - cd calcom-docker - ``` - -3. Update the calcom submodule. + (Most basic users, and for First Run) To run the complete stack, which includes a local Postgres database, Cal.com web app, and Prisma Studio: ```bash - git submodule update --remote --init + docker-compose up -d ``` - - Note: DO NOT use recursive submodule update, otherwise you will receive a git authentication error. - -4. Rename `.env.example` to `.env` and then update `.env` - -5. Build the Cal.com docker image: - - Note: Due to application configuration requirements, an available database is currently required during the build process. - - a) If hosting elsewhere, configure the `DATABASE_URL` in the .env file, and skip the next step - - b) If a local or temporary database is required, start a local database via docker compose. - + ...and if you wish to follow the logs you may run... ```bash - docker compose up -d database + docker-compose logs -f ``` + and press `ctrl+c` to end following the console logging output. -6. Build Cal.com via docker compose (DOCKER_BUILDKIT=0 must be provided to allow a network bridge to be used at build time. This requirement will be removed in the future) - - ```bash - DOCKER_BUILDKIT=0 docker compose build calcom - ``` +8. (First Run) Open a browser to [http://localhost:5555](http://localhost:5555) to look at or modify the database content. -7. Start Cal.com via docker compose + a. Click on the `User` model to add a new user record. - (Most basic users, and for First Run) To run the complete stack, which includes a local Postgres database, Cal.com web app, and Prisma Studio: + b. 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. - ```bash - docker compose up -d - ``` +9. Open a browser to [http://localhost:3000](http://localhost:3000) (or your appropriately configured NEXT_PUBLIC_WEBAPP_URL) and login with your just created, first user. +### Bonus tips To run Cal.com web app and Prisma Studio against a remote database, ensure that DATABASE_URL is configured for an available database and run: ```bash - docker compose up -d calcom studio + docker-compose up -d calcom studio ``` To run only the Cal.com web app, ensure that DATABASE_URL is configured for an available database and run: ```bash - docker compose up -d calcom + docker-compose up -d calcom ``` **Note: to run in attached mode for debugging, remove `-d` from your desired run command.** -8. (First Run) Open a browser to [http://localhost:5555](http://localhost:5555) to look at or modify the database content. - - a. Click on the `User` model to add a new user record. - - b. 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. - -9. Open a browser to [http://localhost:3000](http://localhost:3000) (or your appropriately configured NEXT_PUBLIC_WEBAPP_URL) and login with your just created, first user. ## Configuration ### Build-time variables -These variables must be provided at the time of the docker build, and can be provided by updating the .env file. Currently, if you require changes to these variables, you must follow the instructions to build and publish your own image. +These variables must be provided at the time of the docker build, and can be provided by updating the .env file. Currently, if you require changes to these variables, you must follow the instructions to build and publish your own image. -Updating these variables is not required for evaluation, but is required for running in production. Instructions for generating variables can be found in the [cal.com instructions](https://github.com/calcom/cal.com) +Updating these variables is not required for evaluation, but is required for running in production. Instructions for generating variables can be found in the [cal.com instructions](https://github.com/calcom/cal.com) | Variable | Description | Required | Default | | --- | --- | --- | --- | @@ -116,8 +143,8 @@ Updating these variables is not required for evaluation, but is required for run | NEXT_PUBLIC_LICENSE_CONSENT | license consent - true/false | | | | CALCOM_TELEMETRY_DISABLED | Allow cal.com to collect anonymous usage data (set to `1` to disable) | | | | DATABASE_URL | database url with credentials | required | `postgresql://unicorn_user:magical_password@database:5432/calendso` | -| NEXTAUTH_SECRET | Cookie encryption key | required | `secret` | -| CALENDSO_ENCRYPTION_KEY | Authentication encryption key | required | `secret` | +| NEXTAUTH_SECRET | Cookie encryption key | required | `randomly defined on first boot` | +| CALENDSO_ENCRYPTION_KEY | Authentication encryption key | required | `randomly defined on first boot` | ### Important Run-time variables @@ -126,22 +153,10 @@ These variables must also be provided at runtime | Variable | Description | Required | Default | | --- | --- | --- | --- | | CALCOM_LICENSE_KEY | Enterprise License Key | | | -| NEXTAUTH_SECRET | must match build variable | required | `secret` | -| CALENDSO_ENCRYPTION_KEY | must match build variable | required | `secret` | +| NEXTAUTH_SECRET | must match build variable | required | `randomly defined on first boot` | +| CALENDSO_ENCRYPTION_KEY | must match build variable | required | `randomly defined on first boot` | | DATABASE_URL | database url with credentials | required | `postgresql://unicorn_user:magical_password@database:5432/calendso` | -## Git Submodules - -This repository uses a git submodule. - -To update the calcom submodule, use the following command: - -```bash -git submodule update --remote --init -``` - -For more advanced usage, please refer to the git documentation: [https://git-scm.com/book/en/v2/Git-Tools-Submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules) - ## Troubleshooting * SSL edge termination: If running behind a load balancer which handles SSL certificates, you will need to add the environmental variable `NODE_TLS_REJECT_UNAUTHORIZED=0` to prevent requests from being rejected. Only do this if you know what you are doing and trust the services/load-balancers directing traffic to your service. diff --git a/calcom b/calcom deleted file mode 160000 index 6b0ac96b3..000000000 --- a/calcom +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6b0ac96b38b0dbd78809a73e19010192f31cc769 diff --git a/docker-compose.yaml b/docker-compose.yaml deleted file mode 100644 index ce3bf2a9a..000000000 --- a/docker-compose.yaml +++ /dev/null @@ -1,62 +0,0 @@ -# Use postgres/example user/password credentials -version: '3.1' - -volumes: - database-data: - -networks: - stack: - name: stack - external: false - -services: - database: - image: postgres - restart: always - volumes: - - database-data:/var/lib/postgresql/data/ - env_file: .env - networks: - - stack - - calcom: - build: - context: . - dockerfile: Dockerfile - args: - - NEXT_PUBLIC_WEBAPP_URL=${NEXT_PUBLIC_WEBAPP_URL} - - NEXT_PUBLIC_LICENSE_CONSENT=${NEXT_PUBLIC_LICENSE_CONSENT} - - CALCOM_TELEMETRY_DISABLED=${CALCOM_TELEMETRY_DISABLED} - - NEXTAUTH_SECRET=${NEXTAUTH_SECRET} - - CALENDSO_ENCRYPTION_KEY=${CALENDSO_ENCRYPTION_KEY} - - DATABASE_URL=${DATABASE_URL} - network: stack - restart: always - networks: - - stack - ports: - - 3000:3000 - env_file: .env - environment: - - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DATABASE_HOST}/${POSTGRES_DB} - depends_on: - - database - -# Optional use of Prisma Studio. In production, comment out or remove the section below to prevent unwanted access to your database. - studio: - image: calendso/calendso:latest - restart: always - networks: - - stack - ports: - - 5555:5555 - env_file: .env - environment: - - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DATABASE_HOST}/${POSTGRES_DB} - depends_on: - - database - command: - - npx - - prisma - - studio -# END SECTION: Optional use of Prisma Studio. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..002076a8a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,98 @@ +# Use postgres/example user/password credentials +version: '3.9' + +x-environment: &environment + environment: + # Set this value to 'agree' to accept our license: + # LICENSE: https://github.com/calendso/calendso/blob/main/LICENSE + # + # Summary of terms: + # - The codebase has to stay open source, whether it was modified or not + # - You can not repackage or sell the codebase + # - Acquire a commercial license to remove these terms by emailing: license@cal.com + ## You must agree to these terms manually we can't agree to them for you. + # NEXT_PUBLIC_LICENSE_CONSENT: + # LICENSE: + + ## Deployment configuration section you may need to change this if you're using a reverse proxy such as nginx, haproxy or træfik. + NEXT_PUBLIC_WEBAPP_URL: http://localhost:3000 + + # E-mail settings + # Configures the global From: header whilst sending emails. + EMAIL_FROM: notifications@example.com + + # Configure SMTP settings (@see https://nodemailer.com/smtp/). + EMAIL_SERVER_HOST: smtp.example.com + EMAIL_SERVER_PORT: 587 + EMAIL_SERVER_USER: email_user + EMAIL_SERVER_PASSWORD: email_password + + ## Only change these if you know what you're doing. Changes are unlikely to be needed. + ## However, you could change the password if you like before you start the first time. Also feel free to read about and implement Docker Secrets. + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres + POSTGRES_PORT: 5432 + + # GOOGLE_API_CREDENTIALS: {} + + # Set this to '1' if you don't want Cal to collect anonymous usage. This is not necessary, however, its kind to give back metrics to the app developers if you trust them. + CALCOM_TELEMETRY_DISABLED: 0 + + # 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: + + ## Probably only change this if you know what you're doing. + NODE_ENV: production + + +volumes: + postgres-data: + +networks: + default: + external: false + +services: + postgres: + image: postgres + restart: always + volumes: + - postgres-data:/var/lib/postgresql/data/ + <<: *environment + networks: + - default + + calcom: + image: calendso/calcom + build: . + restart: always + networks: + - default + ports: + - 3000:3000 + <<: *environment + depends_on: + - postgres + +# # Optional use of Prisma Studio. +# # You may delete the leading comments(hashtags) from the segment below from studio: onward to the command: section. +# # IMPORTANT NOTICE: In production, comment out or remove the section below to prevent unwanted access to your database. + +# studio: +# image: calendso/calendso:latest +# restart: always +# networks: +# - default +# ports: +# - 5555:5555 +# <<: *environment +# depends_on: +# - postgres +# command: ["npx", "prisma", "studio"] +# # END SECTION: Optional use of Prisma Studio. diff --git a/scripts/start.sh b/scripts/start.sh index a70f1f23d..7b6feac9b 100755 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -1,7 +1,195 @@ -#!/bin/sh -set -x +#!/usr/bin/env bash +# set -x ## uncomment for debug -scripts/wait-for-it.sh ${DATABASE_HOST} -- echo "database is up" -npx prisma migrate deploy --schema /calcom/packages/prisma/schema.prisma -npx ts-node --transpile-only /calcom/packages/prisma/seed-app-store.ts -yarn start +## Environment Config +export NEXT_PUBLIC_WEBAPP_URL=${NEXT_PUBLIC_WEBAPP_URL:-"http://localhost:3000"} +export NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL:-"http://localhost:3000"} +export NEXT_PUBLIC_LICENSE_CONSENT=${NEXT_PUBLIC_LICENSE_CONSENT:-"false"} +export CALCOM_TELEMETRY_DISABLED=${CALCOM_TELEMETRY_DISABLED:-"0"} +export POSTGRES_USER=${POSTGRES_USER:-"postgres"} +export POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-"postgres"} +export POSTGRES_DB=${POSTGRES_DB:-"postgres"} +export POSTGRES_PORT=${POSTGRES_PORT:-"5432"} +## Use this in a case where you have an external DB. +export POSTGRES_ADDRESS=${POSTGRES_ADDRESS:-"postgres"} +export DATABASE_HOST="$POSTGRES_ADDRESS:$POSTGRES_PORT" +export DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DATABASE_HOST}/${POSTGRES_DB} +export NEXTAUTH_SECRET=${NEXTAUTH_SECRET:-$(cat /config/NEXTAUTH_SECRET)} +export CALENDSO_ENCRYPTION_KEY=${CALENDSO_ENCRYPTION_KEY:-$(cat /config/NEXTAUTH_SECRET)} +export NODE_OPTIONS=--max-old-space-size=${MAX_OLD_SPACE_SIZE:-"4096"} +export RELEASE_COMMIT_ID="${RELEASE_COMMIT_ID:-6b0ac96b38b0dbd78809a73e19010192f31cc769}" +export REPOSITORY_URL="${REPOSITORY_URL:-'https://github.com/calcom/cal.com.git'}" +export APP_PATH=${APP_PATH:-"/calendso"} + +function basic_start() { + cd $APP_PATH + echo "Waiting for a healthy Postgres server connection prior to booting." + wait-for-it.sh $DATABASE_HOST -- echo "database is up" + npx prisma migrate deploy --schema $APP_PATH/packages/prisma/schema.prisma + npx ts-node --transpile-only $APP_PATH/packages/prisma/seed-app-store.ts + echo "Final systems checks cleared and are go for launch." + yarn start +} + +function bootstrap_copyandcleanup() { + cp -Rfv /tmp/calendso/node_modules $APP_PATH/node_modules + cp -Rfv /tmp/calendso/packages $APP_PATH/packages + cp -Rfv /tmp/calendso/apps/web $APP_PATH/apps/web + cp -Rfv /tmp/calendso/packages/prisma/schema.prisma $APP_PATH/prisma/schema.prisma + cp -Rfv /tmp/calendso/.git $APP_PATH/ + cp -v package.json $APP_PATH/ + cp -v yarn.lock $APP_PATH/ + cp -v turbo.json $APP_PATH/ + cd $APP_PATH + rm -Rf /tmp/calendso +} + +function bootstrap_start() { + mkdir -p /tmp/calendso + cd /tmp/calendso + ## Essentially running "git clone https://github.com/calcom/cal.com.git" with a depth of 1 and to the specific release commit SHA. + git init . + git remote add origin https://github.com/calcom/cal.com.git + git fetch --depth 1 origin $RELEASE_COMMIT_ID + git checkout FETCH_HEAD + yarn install --frozen-lockfile + yarn build + bootstrap_copyandcleanup + echo "$RELEASE_COMMIT_ID" > /config/RELEASE_COMMIT_ID && echo "/config/RELEASE_COMMIT_ID is now set to $(cat /config/RELEASE_COMMIT_ID)" + basic_start +} + +## Test for file +function test_for_file() { + if [[ -f "$1" ]]; then + echo "$1 exists" + else + touch $1 + fi +} + +function test_for_dir() { + if [[ -d $1 ]]; then + echo "directory $1 exists." + else + echo "directory $1 doesn't exist prior to container startup, creating $1" + mkdir -pv $1 + echo "$1 is not not mounted and will be reset every boot." + echo "Please mount $1 in your Docker deployment to avoid this message in the future" + echo "and to persist your environments state beyond the life of this container." + fi +} + +## Will I persist? +function test_for_volume() { + if grep -qs "$1" /proc/mounts; then + echo "$1 is a docker volume." + $2 + else + test_for_dir $1 + $2 + fi +} + +## Preboot Check NEXTAUTH_SECRET +function autoconfigure_nextauth_secret() { + echo "Rudimentary NEXTAUTH_SECRET test: $NEXTAUTH_SECRET --------- $(cat /config/NEXTAUTH_SECRET)" + echo "Check if encryption key is set and if not generating a random one and placing it in a /config/NEXTAUTH_SECRET file." + test_for_volume /config + test_for_file /config/NEXTAUTH_SECRET + if [ $(echo $(cat /config/NEXTAUTH_SECRET)|wc -c) != 65 ]; + then + echo "NEXTAUTH_SECRET seems unset, attempting to set a new secret now." + RAND32STR=$(tr -dc '[:alnum:]' < /dev/urandom | dd bs=4 count=16 2>/dev/null) + echo "${NEXTAUTH_SECRET:=$RAND32STR}" > /config/NEXTAUTH_SECRET + echo "Set the /config/NEXTAUTH_SECRET to the following:" + cat /config/NEXTAUTH_SECRET + echo "Secret set and recorded to filesystem, now checking to see if its recorded correctly to the environment." + autoconfigure_nextauth_secret + else + echo "/config/NEXTAUTH_SECRET seems to be correctly installed." + export NEXTAUTH_SECRET=$(cat /config/NEXTAUTH_SECRET) + if [[ $NEXTAUTH_SECRET == $(cat /config/NEXTAUTH_SECRET) ]]; then + echo "NEXTAUTH_SECRET is set correctly in the environment and on disk." + echo "Rudimentary NEXTAUTH_SECRET postconfigure proof: $NEXTAUTH_SECRET --------- $(cat /config/NEXTAUTH_SECRET)" + else + echo "There is something wrong here someone has configured the environment variable NEXTAUTH_SECRET strangely please fix this and start over." + exit + fi + fi +} + +## Preboot Check CALENDSO_ENCRYPTION_KEY +function autoconfigure_calendso_encryption_key() { + echo "Rudimentary CALENDSO_ENCRYPTION_KEY test: $CALENDSO_ENCRYPTION_KEY --------- $(cat /config/CALENDSO_ENCRYPTION_KEY)" + echo "Check if encryption key is set and if not generating a random one and placing it in a /config/NEXTAUTH_SECRET file." + test_for_volume /config + test_for_file /config/CALENDSO_ENCRYPTION_KEY + if [ $(echo $(cat /config/CALENDSO_ENCRYPTION_KEY)|wc -c) != 65 ]; + then + echo "CALENDSO_ENCRYPTION_KEY seems unset, attempting to set a new secret now." + RAND32STR=$(tr -dc '[:alnum:]' < /dev/urandom | dd bs=4 count=16 2>/dev/null) + echo "${CALENDSO_ENCRYPTION_KEY:=$RAND32STR}" > /config/CALENDSO_ENCRYPTION_KEY + echo "Set the /config/CALENDSO_ENCRYPTION_KEY to the following:" + cat /config/CALENDSO_ENCRYPTION_KEY + echo "Secret set and recorded to filesystem, now checking to see if its recorded correctly to the environment." + autoconfigure_calendso_encryption_key + else + export CALENDSO_ENCRYPTION_KEY=$(cat /config/CALENDSO_ENCRYPTION_KEY) + echo "/config/CALENDSO_ENCRYPTION_KEY seems to be correctly installed." + if [[ $CALENDSO_ENCRYPTION_KEY == $(cat /config/CALENDSO_ENCRYPTION_KEY) ]]; then + echo "CALENDSO_ENCRYPTION_KEY is set correctly in the environment and on disk." + echo "Rudimentary CALENDSO_ENCRYPTION_KEY postconfigure proof: $CALENDSO_ENCRYPTION_KEY --------- $(cat /config/CALENDSO_ENCRYPTION_KEY)" + else + echo "There is something wrong here someone has configured the environment variable CALENDSO_ENCRYPTION_KEY strangely please fix this and start over." + exit + fi + fi +} + +## Preboot Check RELEASE_COMMIT_ID +function bootmode_check() { + echo "Rudimentary RELEASE_COMMIT_ID test: $RELEASE_COMMIT_ID --------- $(cat /config/RELEASE_COMMIT_ID)" + echo "Check if commit ID is present and is identical to deployed RELEASE_COMMIT_ID." + test_for_volume /config + test_for_file /config/RELEASE_COMMIT_ID + if [ $(echo $(cat /config/RELEASE_COMMIT_ID)|wc -c) == 41 ]; then + # export RELEASE_COMMIT_ID=$(cat /config/RELEASE_COMMIT_ID) + # echo "$APP_PATH/RELEASE_COMMIT_ID seems to be correctly installed." + if [[ $RELEASE_COMMIT_ID == $(cat /config/RELEASE_COMMIT_ID) ]]; then + # echo "RELEASE_COMMIT_ID is set correctly in the environment and on disk." + # echo "Rudimentary RELEASE_COMMIT_ID postconfigure proof: $RELEASE_COMMIT_ID --------- $(cat /config/RELEASE_COMMIT_ID)" + export BOOTMODE="basic_start" + else + echo "RELEASE_COMMIT_ID is different from previously installed RELEASE_COMMIT_ID assuming an upgrade is required and setting bootstrap_start." + export BOOTMODE="bootstrap_start" + fi + else + echo "RELEASE_COMMIT_ID seems incorrect or unset triggering further checks." + if [[ -z $(cat /config/RELEASE_COMMIT_ID) ]]; then + echo "Cal is not yet installed setting boot flag for first time installation." + export BOOTMODE="bootstrap_start" + fi + fi +} + +## Preflight Checks +autoconfigure_nextauth_secret +autoconfigure_calendso_encryption_key +bootmode_check + +## Start app. +case $BOOTMODE in + basic_start ) + echo "Systems go for basic start." + basic_start + ;; + bootstrap_start ) + echo "Systems go for bootstrap start." + bootstrap_start + ;; + * ) + echo "Invalid BOOTMODE selected. Valid options are basic_start and bootstrap_start." + echo "BOOTMODE selected was instead: $BOOTMODE" + ;; +esac From 7e4190eb773c57d62978964631b4151292db6c60 Mon Sep 17 00:00:00 2001 From: Colin Date: Mon, 1 Aug 2022 14:43:48 -0400 Subject: [PATCH 2/5] fixup --- README.md | 2 +- docker-compose.yml | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 01303ccda..1170f7957 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ Note: `docker-compose` without the hyphen is now the primary method of using doc 9. Open a browser to [http://localhost:3000](http://localhost:3000) (or your appropriately configured NEXT_PUBLIC_WEBAPP_URL) and login with your just created, first user. ### Bonus tips - To run Cal.com web app and Prisma Studio against a remote database, ensure that DATABASE_URL is configured for an available database and run: + To run Cal.com web app and Prisma Studio against a remote database, ensure that DATABASE_URL is configured for an available database, uncomment the studio segment of the included `docker-compose.yml` and run: ```bash docker-compose up -d calcom studio diff --git a/docker-compose.yml b/docker-compose.yml index 002076a8a..81952ad72 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -53,6 +53,8 @@ x-environment: &environment volumes: postgres-data: + calcom-app: + calcom-config: networks: default: @@ -72,6 +74,9 @@ services: image: calendso/calcom build: . restart: always + volumes: + - calcom-app:/calendso/ + - calcom-config:/config/ networks: - default ports: From 5aeeac7279c922a9b05e248537e1b4850507a6ae Mon Sep 17 00:00:00 2001 From: Leopere <1068374+Leopere@users.noreply.github.com> Date: Tue, 2 Aug 2022 10:24:46 -0400 Subject: [PATCH 3/5] fixup please squash this commit before merge --- scripts/start.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/start.sh b/scripts/start.sh index 7b6feac9b..9b526ba9f 100755 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -15,7 +15,7 @@ export POSTGRES_ADDRESS=${POSTGRES_ADDRESS:-"postgres"} export DATABASE_HOST="$POSTGRES_ADDRESS:$POSTGRES_PORT" export DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DATABASE_HOST}/${POSTGRES_DB} export NEXTAUTH_SECRET=${NEXTAUTH_SECRET:-$(cat /config/NEXTAUTH_SECRET)} -export CALENDSO_ENCRYPTION_KEY=${CALENDSO_ENCRYPTION_KEY:-$(cat /config/NEXTAUTH_SECRET)} +export CALENDSO_ENCRYPTION_KEY=${CALENDSO_ENCRYPTION_KEY:-$(cat /config/CALENDSO_ENCRYPTION_KEY)} export NODE_OPTIONS=--max-old-space-size=${MAX_OLD_SPACE_SIZE:-"4096"} export RELEASE_COMMIT_ID="${RELEASE_COMMIT_ID:-6b0ac96b38b0dbd78809a73e19010192f31cc769}" export REPOSITORY_URL="${REPOSITORY_URL:-'https://github.com/calcom/cal.com.git'}" From 40e93a3da865d6a98ddf381045e34f710e7c5850 Mon Sep 17 00:00:00 2001 From: Leopere <1068374+Leopere@users.noreply.github.com> Date: Tue, 2 Aug 2022 11:22:28 -0400 Subject: [PATCH 4/5] Added ifndef function for declaring container vars. To clean up visually environment variable definitions and defaults `ifndef` function has been added. It checks var for null, and if null, defines the default string based on defined defaults. Also, it prints variable strings to the console[stdout] for debugging. I also added more comments to start.sh's environment definitions for posterity. --- scripts/start.sh | 51 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/scripts/start.sh b/scripts/start.sh index 9b526ba9f..3bf73df81 100755 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -2,24 +2,41 @@ # set -x ## uncomment for debug ## Environment Config -export NEXT_PUBLIC_WEBAPP_URL=${NEXT_PUBLIC_WEBAPP_URL:-"http://localhost:3000"} -export NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL:-"http://localhost:3000"} -export NEXT_PUBLIC_LICENSE_CONSENT=${NEXT_PUBLIC_LICENSE_CONSENT:-"false"} -export CALCOM_TELEMETRY_DISABLED=${CALCOM_TELEMETRY_DISABLED:-"0"} -export POSTGRES_USER=${POSTGRES_USER:-"postgres"} -export POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-"postgres"} -export POSTGRES_DB=${POSTGRES_DB:-"postgres"} -export POSTGRES_PORT=${POSTGRES_PORT:-"5432"} +function ifndef () { + ## Test for null variable and set default, echo result to stdout. + export ${1}="${!1:=$2}" + echo "$1 is ${!1}" +} + +ifndef NEXT_PUBLIC_WEBAPP_URL "http://localhost:3000" +ifndef NEXT_PUBLIC_APP_URL "http://localhost:3000" +## Must be manually overridden to "true" by end user. +ifndef NEXT_PUBLIC_LICENSE_CONSENT "false" + +## If you want to keep your secrets set this to 1 +ifndef CALCOM_TELEMETRY_DISABLED "0" + +## Database Config, usually good to be set as default. +ifndef POSTGRES_USER "postgres" +ifndef POSTGRES_PASSWORD "postgres" +ifndef POSTGRES_DB "postgres" +ifndef POSTGRES_PORT "5432" + ## Use this in a case where you have an external DB. -export POSTGRES_ADDRESS=${POSTGRES_ADDRESS:-"postgres"} -export DATABASE_HOST="$POSTGRES_ADDRESS:$POSTGRES_PORT" -export DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DATABASE_HOST}/${POSTGRES_DB} -export NEXTAUTH_SECRET=${NEXTAUTH_SECRET:-$(cat /config/NEXTAUTH_SECRET)} -export CALENDSO_ENCRYPTION_KEY=${CALENDSO_ENCRYPTION_KEY:-$(cat /config/CALENDSO_ENCRYPTION_KEY)} -export NODE_OPTIONS=--max-old-space-size=${MAX_OLD_SPACE_SIZE:-"4096"} -export RELEASE_COMMIT_ID="${RELEASE_COMMIT_ID:-6b0ac96b38b0dbd78809a73e19010192f31cc769}" -export REPOSITORY_URL="${REPOSITORY_URL:-'https://github.com/calcom/cal.com.git'}" -export APP_PATH=${APP_PATH:-"/calendso"} +ifndef POSTGRES_ADDRESS "postgres" +## More database environment strings required for launch. +ifndef DATABASE_HOST "$POSTGRES_ADDRESS:$POSTGRES_PORT" +ifndef DATABASE_URL "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DATABASE_HOST}/${POSTGRES_DB}" +## Cryptography and secrets. +ifndef NEXTAUTH_SECRET $([ -f /config/NEXTAUTH_SECRET ] && cat /config/NEXTAUTH_SECRET) +ifndef CALENDSO_ENCRYPTION_KEY $([ -f /config/CALENDSO_ENCRYPTION_KEY ] && cat /config/CALENDSO_ENCRYPTION_KEY) + +## Other settings that are mostly for container internal operations but are available for customization if desired. +ifndef MAX_OLD_SPACE_SIZE 4096 +ifndef NODE_OPTIONS "--max-old-space-size=$MAX_OLD_SPACE_SIZE" +ifndef RELEASE_COMMIT_ID "6b0ac96b38b0dbd78809a73e19010192f31cc769" +ifndef REPOSITORY_URL "https://github.com/calcom/cal.com.git" +ifndef APP_PATH "/calendso" function basic_start() { cd $APP_PATH From 0f4740e54fd57743f7da8d46b7200a69c339f323 Mon Sep 17 00:00:00 2001 From: Leopere <1068374+Leopere@users.noreply.github.com> Date: Wed, 10 Aug 2022 00:57:33 -0400 Subject: [PATCH 5/5] Update README.md Co-authored-by: Avinal Kumar --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1170f7957..175c09d78 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ For Production, for the time being, please checkout the repository and build/pus Make sure you have `docker` & `docker-compose` installed on the server / system. Both are installed by most docker utilities, including Docker Desktop and Rancher Desktop. -Note: `docker-compose` without the hyphen is now the primary method of using docker-compose, per the Docker documentation. +Note: `docker compose` without the hyphen is now the primary method of using docker-compose, per the Docker documentation. ## Getting Started