commit 7b6a2fee140e0b77353296a04422fd0ec6b4c06f Author: 3wc <3wc@doesthisthing.work> Date: Tue Aug 10 16:43:48 2021 +0200 Initial import 📅 diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..25fd269 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,56 @@ +--- +kind: pipeline +name: deploy to swarm-test.autonomic.zone +steps: + - name: deployment + image: decentral1se/stack-ssh-deploy:latest + settings: + host: swarm-test.autonomic.zone + stack: calendso + purge: true + deploy_key: + from_secret: drone_ssh_swarm_test + environment: + DOMAIN: calendso.swarm-test.autonomic.zone + LETS_ENCRYPT_ENV: production + + - name: notify coopcloud-dev on failure + image: plugins/matrix + settings: + homeserver: https://matrix.autonomic.zone + roomid: "IFazIpLtxiScqbHqoa:autonomic.zone" + userid: "@autono-bot:autonomic.zone" + accesstoken: + from_secret: autono_bot_access_token + depends_on: + - deployment + when: + status: + - failure +trigger: + branch: + - main + +--- +kind: pipeline +name: recipe release +steps: + - name: release a new version + image: decentral1se/drone-abra:latest + settings: + command: recipe calendso release + deploy_key: + from_secret: abra_bot_deploy_key + + - name: trigger downstream builds + image: plugins/downstream + settings: + server: https://drone.autonomic.zone + token: + from_secret: decentral1se_token + fork: true + repositories: + - coop-cloud/auto-apps-json + depends_on: + - release a new version + version diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000..ef3f5da --- /dev/null +++ b/.env.sample @@ -0,0 +1,47 @@ +TYPE=calendso + +DOMAIN=calendso.example.com + +## Domain aliases +#EXTRA_DOMAINS=', `www.calendso.example.com`' +LETS_ENCRYPT_ENV=production + +SECRET_DB_PASSWORD_VERSION=v1 + +## Uncomment this to enable collection of anonymous usage data +#NEXT_PUBLIC_TELEMETRY_KEY=js.2pvs2bbpqq1zxna97wcml.oi2jzirnbj1ev4tc57c5r + +# This is here so later lines can extend it; you likely don't wanna edit +COMPOSE_FILE="compose.yml" + +##################################################################### +# Email # +##################################################################### + +#EMAIL_SERVER_HOST='smtp.example.com' +#EMAIL_SERVER_PORT=587 +#EMAIL_SERVER_USER='email_user' +## Configures the global From: header whilst sending emails. +#EMAIL_FROM='notifications@example.com' +## Authenticated SMTP +#COMPOSE_FILE="$COMPOSE_FILE:compose.smtpauth.yml" +#SECRET_EMAIL_SERVER_PASSWORD_VERSION=v1 + +##################################################################### +# Integrations # +##################################################################### + +## Used for the Zoom integration +#ZOOM_CLIENT_ID= +#COMPOSE_FILE="$COMPOSE_FILE:compose.zoom.yml" +#SECRET_ZOOM_CLIENT_SECRET_VERSION=v1 + +## Google calendar, see https://docs.calendso.com/docs/integrations/google +#COMPOSE_FILE="$COMPOSE_FILE:compose.google.yml" +#SECRET_GOOGLE_API_SECRET_VERSION=v1 + +## Used for the Office 365 / Outlook.com Calendar integration +## note(3wc): un-tested! +#MS_GRAPH_CLIENT_ID= +#COMPOSE_FILE="$COMPOSE_FILE:compose.microsoft.yml" +#SECRET_MS_GRAPH_CLIENT_SECRET_VERSION=v1 diff --git a/README.md b/README.md new file mode 100644 index 0000000..914650d --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# calendso + +TODO + + + +- **Category**: +- **Status**: +- **Image**: +- **Healthcheck**: +- **Backups**: +- **Email**: +- **Tests**: +- **SSO**: + + + +## Basic usage + +1. Set up Docker Swarm and [`abra`] +2. Deploy [`coop-cloud/traefik`] +3. `abra app new ${REPO_NAME} --secrets` (optionally with `--pass` if you'd like + to save secrets in `pass`) +4. `abra app YOURAPPDOMAIN config` - be sure to change `$DOMAIN` to something that resolves to + your Docker swarm box +5. `abra app YOURAPPDOMAIN deploy` +6. Open the configured domain in your browser to finish set-up + +[`abra`]: https://git.coopcloud.tech/coop-cloud/abra +[`coop-cloud/traefik`]: https://git.coopcloud.tech/coop-cloud/traefik +op-cloud/traefik diff --git a/abra.sh b/abra.sh new file mode 100644 index 0000000..e1813e3 --- /dev/null +++ b/abra.sh @@ -0,0 +1 @@ +export ENTRYPOINT_CONF_VERSION=v6 diff --git a/compose.google.yml b/compose.google.yml new file mode 100644 index 0000000..779732a --- /dev/null +++ b/compose.google.yml @@ -0,0 +1,15 @@ +--- +# Google calendar, see https://docs.calendso.com/docs/integrations/google +version: "3.8" + +services: + app: + environment: + - GOOGLE_API_CREDENTIALS_FILE=/run/secrets/google_api_credentials + secrets: + - google_api_credentials + +secrets: + google_api_credentials: + external: true + name: ${STACK_NAME}_google_api_credentials_${SECRET_GOOGLE_API_CREDENTIALS_VERSION} diff --git a/compose.smtpauth.yml b/compose.smtpauth.yml new file mode 100644 index 0000000..981897d --- /dev/null +++ b/compose.smtpauth.yml @@ -0,0 +1,14 @@ +--- +version: "3.8" + +services: + app: + environment: + - EMAIL_SERVER_PASSWORD_FILE=/run/secrets/email_server_password + secrets: + - email_server_password + +secrets: + email_server_password: + external: true + name: ${STACK_NAME}_email_server_password_${SECRET_EMAIL_SERVER_PASSWORD_VERSION} diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..3f65de3 --- /dev/null +++ b/compose.yml @@ -0,0 +1,89 @@ +--- +version: "3.8" + +services: + app: + image: 3wordchant/calendso:latest + networks: + - proxy + - backend + secrets: + - db_password + environment: + - POSTGRES_USER=calendso + - POSTGRES_PASSWORD_FILE=/run/secrets/db_password + - POSTGRES_DB=calendso + - POSTGRES_HOST=db + - "BASE_URL=${DOMAIN}" + - "NEXTAUTH_URL=${DOMAIN}" + - NEXT_PUBLIC_TELEMETRY_KEY + - MS_GRAPH_CLIENT_ID + - ZOOM_CLIENT_ID + - EMAIL_FROM + - EMAIL_SERVER_HOST + - EMAIL_SERVER_PORT + - EMAIL_SERVER_USER + configs: + - source: entrypoint_conf + target: /docker-entrypoint.sh + mode: 0555 + entrypoint: ['/docker-entrypoint.sh'] + deploy: + update_config: + failure_action: rollback + order: start-first + labels: + - "traefik.enable=true" + - "traefik.http.services.${STACK_NAME}_admin.loadbalancer.server.port=5555" + - "traefik.http.routers.${STACK_NAME}_admin.rule=Host(`admin.${DOMAIN}`)" + - "traefik.http.routers.${STACK_NAME}_admin.entrypoints=web-secure" + - "traefik.http.routers.${STACK_NAME}_admin.tls.certresolver=${LETS_ENCRYPT_ENV}" + - "traefik.http.routers.${STACK_NAME}_admin.service=${STACK_NAME}_admin" + - "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=3000" + - "traefik.http.routers.${STACK_NAME}.rule=Host(`${DOMAIN}`${EXTRA_DOMAINS})" + - "traefik.http.routers.${STACK_NAME}.entrypoints=web-secure" + - "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV}" + - "traefik.http.routers.${STACK_NAME}.service=${STACK_NAME}" + ## Redirect from EXTRA_DOMAINS to DOMAIN + #- "traefik.http.routers.${STACK_NAME}.middlewares=${STACK_NAME}-redirect" + #- "traefik.http.middlewares.${STACK_NAME}-redirect.headers.SSLForceHost=true" + #- "traefik.http.middlewares.${STACK_NAME}-redirect.headers.SSLHost=${DOMAIN}" + # healthcheck: + # test: ["CMD", "curl", "-f", "http://localhost"] + # interval: 30s + # timeout: 10s + # retries: 10 + # start_period: 1m + + db: + image: "postgres:13-alpine" + networks: + - backend + secrets: + - db_password + networks: + - backend + environment: + - POSTGRES_DB=calendso + - POSTGRES_USER=calendso + - POSTGRES_PASSWORD_FILE=/run/secrets/db_password + volumes: + - "postgres:/var/lib/postgresql/data" + +networks: + proxy: + external: true + backend: + +volumes: + postgres: + +secrets: + db_password: + external: true + name: ${STACK_NAME}_db_password_${SECRET_DB_PASSWORD_VERSION} + +configs: + entrypoint_conf: + name: ${STACK_NAME}_entrypoint_conf_${ENTRYPOINT_CONF_VERSION} + file: entrypoint.sh diff --git a/compose.zoom.yml b/compose.zoom.yml new file mode 100644 index 0000000..c6bf5a2 --- /dev/null +++ b/compose.zoom.yml @@ -0,0 +1,14 @@ +--- +version: "3.8" + +services: + app: + environment: + - ZOOM_CLIENT_SECRET_FILE=/var/run/secrets/zoom_client_secret + secrets: + - zoom_client_secret + +secrets: + zoom_client_secret: + external: true + name: ${STACK_NAME}_zoom_client_secret_${SECRET_ZOOM_CLIENT_SECRET_VERSION} diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..110cb5c --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env sh + +# usage: file_env VAR [DEFAULT] +# ie: file_env 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +# https://git.chihiro.org.cn/GitHub/nextcloud-docker/commit/530edd68aa6bc3bc493dd7c96f673239edeef130 +file_env() { + var="$1" + fileVar="${var}_FILE" + def="${2:-}" + varValue=$(env | grep -E "^${var}=" | sed -E -e "s/^${var}=//") + fileVarValue=$(env | grep -E "^${fileVar}=" | sed -E -e "s/^${fileVar}=//") + if [ -n "${varValue}" ] && [ -n "${fileVarValue}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + if [ -n "${varValue}" ]; then + export "$var"="${varValue}" + elif [ -n "${fileVarValue}" ]; then + export "$var"="$(cat "${fileVarValue}")" + elif [ -n "${def}" ]; then + export "$var"="$def" + fi + unset "$fileVar" +} + +load_vars() { + file_env "POSTGRES_PASSWORD" + file_env "GOOGLE_API_CREDENTIALS" + file_env "ZOOM_CLIENT_SECRET" + file_env "EMAIL_SERVER_PASSWORD" + + export "DATABASE_URL=postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST:5432/$POSTGRES_DB" +} + +main() { + set -eu + + load_vars +} + +main + +# 3wc: upstream CMD +# https://github.com/calendso/docker/blob/main/Dockerfile +/app/scripts/start.sh