diff --git a/.env.compose b/.env.compose new file mode 100644 index 000000000..0f9f93b75 --- /dev/null +++ b/.env.compose @@ -0,0 +1,6 @@ +# Docker Compose sample .env file for Production + +NODE_ENV=production + +# set true if running inside Docker container +IS_DOCKER=true diff --git a/.env.demo.compose b/.env.demo.compose new file mode 100644 index 000000000..0f9f93b75 --- /dev/null +++ b/.env.demo.compose @@ -0,0 +1,6 @@ +# Docker Compose sample .env file for Production + +NODE_ENV=production + +# set true if running inside Docker container +IS_DOCKER=true diff --git a/.env.docker b/.env.docker new file mode 100644 index 000000000..0f9f93b75 --- /dev/null +++ b/.env.docker @@ -0,0 +1,6 @@ +# Docker Compose sample .env file for Production + +NODE_ENV=production + +# set true if running inside Docker container +IS_DOCKER=true diff --git a/README.md b/README.md index 5fdf6a7fc..4dcd098b9 100644 --- a/README.md +++ b/README.md @@ -92,16 +92,54 @@ Please refer to our official [Platform Documentation](https://docs.ever.team) (W -### Quick Start with our public live APIs +### Run with Docker Compose + +- Clone repo. +- Make sure you have the latest Docker Compose [installed locally](https://docs.docker.com/compose/install). Important: you need a minimum [v2.20](https://docs.docker.com/compose/release-notes/#2200). +- Run `docker-compose -f docker-compose.demo.yml up`, if you want to run the platform in basic configuration (e.g. for Demo / explore functionality / quick run) using our prebuilt Docker images. Check `.env.demo.compose` file for different settings (optionally). _(Note: Docker Compose will use latest images pre-build automatically from head of `master` branch using GitHub CI/CD.)_ +- Run `docker-compose up`, if you want to run the platform in production configuration using our prebuilt Docker images. Check `.env.compose` file for different settings (optionally). _(Note: Docker Compose will use latest images pre-build automatically from head of `master` branch using GitHub CI/CD.)_ +- Run `docker-compose -f docker-compose.build.yml up`, if you want to build everything (code and Docker images) locally. Check `.env.compose` file for different settings (optionally). _(Note: this can be long process because it builds whole platform locally. Other options above are much faster!)_ +- :coffee: time... It might take some time for the first Docker Compose run, even if you used prebuilt Docker images. +- Open in your browser, register a new account, and start using Ever Teams! +- Enjoy! + +_Notes:_ +- _You can execute `docker-compose` command with `-d` option to run it in the "detached" mode (allows containers to run in the background, separate from the terminal)._ +- _By default, Ever Teams web frontend will be connected to our production [Ever Gauzy API](https://github.com/ever-co/ever-gauzy) API endpoint . You can change it in environment variables `GAUZY_API_SERVER_URL` and `NEXT_PUBLIC_GAUZY_API_SERVER_URL`, see more in the section about how to run with a Self-hosted Backend._ + +### Run with Docker + +#### Build & Run + +Run with Public Images: +- You can pull our public docker image with `docker pull everco/ever-teams-webapp .` command. +- You can run docker image with the following command: `docker run -p 127.0.0.1:3030:3030/tcp everco/ever-teams-webapp`. +- Open in your browser, register a new account, and start using Ever Teams! + +_Note: To build such images on each release (push to our master branch), we are using relevant [Github Action](https://github.com/ever-co/ever-teams/blob/develop/.github/workflows/docker-build-publish-prod.yml)._ + +Build and Run Locally: +- If you want to build an image locally from our source code (after clone repo locally), please run the following command (from the root of mono-repo): `docker build . -t ever-teams-webapp -f Dockerfile`. +- To run the locally built image, please run the following command: `docker run -p 127.0.0.1:3030:3030/tcp ever-teams-webapp`. +- Open in your browser, register a new account, and start using Ever Teams! + +_Note: By default, Ever Teams web frontend will be connected to our production [Ever Gauzy API](https://github.com/ever-co/ever-gauzy) API endpoint . You can change it in environment variables `GAUZY_API_SERVER_URL` and `NEXT_PUBLIC_GAUZY_API_SERVER_URL`, see more in the section about how to run with a Self-hosted Backend._ + +#### Images + +We have Ever Teams Docker images published into: +- https://hub.docker.com/u/everco?page=1&search=ever-teams +- https://github.com/orgs/ever-co/packages?tab=packages&q=ever-teams + +### Quick Start to manually build & run locally 1. Clone this repo 2. Run `yarn install` 3. Run `yarn build:web && yarn start:web` OR `yarn start:web:dev` 4. Open in in your Browser -Notes: - -- by default, Ever Teams web frontend will be connected to our production [Ever Gauzy API](https://github.com/ever-co/ever-gauzy) API endpoint . You can change it in environment variables `GAUZY_API_SERVER_URL` and `NEXT_PUBLIC_GAUZY_API_SERVER_URL`, see below how to run with a Self-hosted Backend. +_Notes:_ +- _by default, Ever Teams web frontend will be connected to our production [Ever Gauzy API](https://github.com/ever-co/ever-gauzy) API endpoint . You can change it in environment variables `GAUZY_API_SERVER_URL` and `NEXT_PUBLIC_GAUZY_API_SERVER_URL`, see below how to run with a Self-hosted Backend._ ### Run with a Self-hosted Backend @@ -128,10 +166,6 @@ DevContainers for VSCode are supported (WIP). [Click here to get started.](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/ever-co/ever-teams) -### Run in Docker & Docker Compose - -WIP - ## 🚗 Self Hosting ### DigitalOcean diff --git a/docker-compose.build.yml b/docker-compose.build.yml new file mode 100644 index 000000000..2fc03b31b --- /dev/null +++ b/docker-compose.build.yml @@ -0,0 +1,28 @@ +services: + webapp: + container_name: webapp + image: ever-teams-webapp:latest + build: + context: . + dockerfile: Dockerfile + args: + GAUZY_API_SERVER_URL: ${GAUZY_API_SERVER_URL:-https://api.ever.team} + NEXT_PUBLIC_GAUZY_API_SERVER_URL: ${NEXT_PUBLIC_GAUZY_API_SERVER_URL:-https://api.ever.team} + NODE_ENV: ${NODE_ENV:-development} + DEMO: 'true' + environment: + GAUZY_API_SERVER_URL: ${GAUZY_API_SERVER_URL:-https://api.ever.team} + NEXT_PUBLIC_GAUZY_API_SERVER_URL: ${NEXT_PUBLIC_GAUZY_API_SERVER_URL:-https://api.ever.team} + NODE_ENV: ${NODE_ENV:-development} + DEMO: 'true' + env_file: + - .env.compose + restart: on-failure + ports: + - '3030:${UI_PORT:-3030}' + networks: + - overlay + +networks: + overlay: + driver: bridge diff --git a/docker-compose.demo.yml b/docker-compose.demo.yml new file mode 100644 index 000000000..3832a11b5 --- /dev/null +++ b/docker-compose.demo.yml @@ -0,0 +1,20 @@ +services: + webapp: + container_name: webapp + image: ghcr.io/ever-co/ever-teams-webapp:latest + environment: + GAUZY_API_SERVER_URL: ${GAUZY_API_SERVER_URL:-https://api.ever.team} + NEXT_PUBLIC_GAUZY_API_SERVER_URL: ${NEXT_PUBLIC_GAUZY_API_SERVER_URL:-https://api.ever.team} + NODE_ENV: ${NODE_ENV:-development} + DEMO: 'true' + env_file: + - .env.demo.compose + restart: on-failure + ports: + - '3030:${UI_PORT:-3030}' + networks: + - overlay + +networks: + overlay: + driver: bridge diff --git a/docker-compose.infra.yml b/docker-compose.infra.yml new file mode 100644 index 000000000..0aae0b4ad --- /dev/null +++ b/docker-compose.infra.yml @@ -0,0 +1,233 @@ +services: + db: + image: postgres:15-alpine + container_name: db + restart: always + environment: + POSTGRES_DB: ${DB_NAME:-gauzy} + POSTGRES_USER: ${DB_USER:-postgres} + POSTGRES_PASSWORD: ${DB_PASS:-gauzy_password} + healthcheck: + test: + [ + 'CMD-SHELL', + 'psql postgres://$${POSTGRES_USER}:$${POSTGRES_PASSWORD}@localhost:5432/$${POSTGRES_DB} || exit 1' + ] + volumes: + - postgres_data:/var/lib/postgresql/data/ + - ./.deploy/db/init-user-db.sh:/docker-entrypoint-initdb.d/init-user-db.sh + ports: + - '5432:5432' + networks: + - overlay + + zipkin: + image: ghcr.io/openzipkin/zipkin-slim:latest + container_name: zipkin + # Environment settings are defined here https://github.com/openzipkin/zipkin/blob/master/zipkin-server/README.md#environment-variables + environment: + - STORAGE_TYPE=mem + # Uncomment to enable self-tracing + # - SELF_TRACING_ENABLED=true + # Uncomment to increase heap size + # - JAVA_OPTS=-Xms128m -Xmx128m -XX:+ExitOnOutOfMemoryError + ports: + # Port used for the Zipkin UI and HTTP Api + - 9411:9411 + networks: + - overlay + + cube: + image: cubejs/cube:latest + container_name: cube + ports: + - '4000:4000' # Cube Playground + - '5430:5430' # Port for Cube SQL + environment: + CUBEJS_DEV_MODE: 'true' + CUBEJS_DB_TYPE: postgres + CUBEJS_DB_HOST: db + CUBEJS_DB_PORT: 5432 + CUBEJS_DB_NAME: ${DB_NAME:-gauzy} + CUBEJS_DB_USER: ${DB_USER:-postgres} + CUBEJS_DB_PASS: ${DB_PASS:-gauzy_password} + # Credentials to connect to Cube SQL APIs + CUBEJS_PG_SQL_PORT: 5430 + CUBEJS_SQL_USER: ${CUBE_USER:-cube_user} + CUBEJS_SQL_PASSWORD: ${CUBE_PASS:-cube_pass} + volumes: + - 'cube_data:/cube/conf' + links: + - db + networks: + - overlay + + jitsu: + container_name: jitsu + image: jitsucom/jitsu:latest + extra_hosts: + - 'host.docker.internal:host-gateway' + environment: + - REDIS_URL=redis://redis:6379 + # Retroactive users recognition can affect RAM significant. + # Read more about the solution https://jitsu.com/docs/other-features/retroactive-user-recognition + - USER_RECOGNITION_ENABLED=true + - USER_RECOGNITION_REDIS_URL=redis://jitsu_redis_users_recognition:6380 + - TERM=xterm-256color + depends_on: + redis: + condition: service_healthy + jitsu_redis_users_recognition: + condition: service_healthy + volumes: + - ./.deploy/jitsu/configurator/data/logs:/home/configurator/data/logs + - ./.deploy/jitsu/server/data/logs:/home/eventnative/data/logs + - ./.deploy/jitsu/server/data/logs/events:/home/eventnative/data/logs/events + - /var/run/docker.sock:/var/run/docker.sock + - jitsu_workspace:/home/eventnative/data/airbyte + restart: always + ports: + - '8000:8000' + networks: + - overlay + + elasticsearch: + image: 'elasticsearch:7.17.7' + container_name: elasticsearch + volumes: + - elasticsearch_data:/usr/share/elasticsearch/data + environment: + ES_JAVA_OPTS: -Xms512m -Xmx1024m + discovery.type: single-node + http.port: 9200 + http.cors.enabled: 'true' + http.cors.allow-origin: http://localhost:3000,http://127.0.0.1:3000,http://localhost:1358,http://127.0.0.1:1358 + http.cors.allow-headers: X-Requested-With,X-Auth-Token,Content-Type,Content-Length,Authorization + http.cors.allow-credentials: 'true' + bootstrap.memory_lock: 'true' + xpack.security.enabled: 'false' + ports: + - '9200' + - '9300' + ulimits: + memlock: + soft: -1 + hard: -1 + healthcheck: + test: ['CMD', 'curl', '-f', 'http://localhost:9200/_cat/health'] + interval: 5s + timeout: 5s + retries: 10 + start_period: 20s + networks: + - overlay + + # Elasticsearch Management UI + dejavu: + image: appbaseio/dejavu:3.6.0 + container_name: dejavu + ports: + - '1358:1358' + links: + - elasticsearch + networks: + - overlay + + # TODO: For now used in Jitsu, but we will need to create another one dedicated for Jitsu later + redis: + image: 'redis:7.0.2-alpine' + container_name: redis + restart: unless-stopped + healthcheck: + test: ['CMD-SHELL', 'redis-cli -h localhost -p 6379 PING'] + interval: 1s + timeout: 30s + ports: + - '6379' + volumes: + - ./.deploy/redis/data:/data + networks: + - overlay + + jitsu_redis_users_recognition: + image: 'redis:7.0.2-alpine' + container_name: jitsu_redis_users_recognition + command: redis-server /usr/local/etc/redis/redis.conf + restart: unless-stopped + healthcheck: + test: ['CMD-SHELL', 'redis-cli -h localhost -p 6380 PING'] + interval: 1s + timeout: 30s + ports: + - '6380' + volumes: + - ./.deploy/redis/jitsu_users_recognition/data:/data + - ./.deploy/redis/jitsu_users_recognition/redis.conf:/usr/local/etc/redis/redis.conf + networks: + - overlay + + minio: + restart: unless-stopped + image: quay.io/minio/minio:latest + container_name: minio + volumes: + - minio_data:/data + environment: + MINIO_ROOT_USER: ever-gauzy-access-key + MINIO_ROOT_PASSWORD: ever-gauzy-secret-key + command: server /data --address :9000 --console-address ":9001" + ports: + - 9000:9000 + - 9001:9001 + networks: + - overlay + + minio_create_buckets: + image: minio/mc + environment: + MINIO_ROOT_USER: ever-gauzy-access-key + MINIO_ROOT_PASSWORD: ever-gauzy-secret-key + entrypoint: + - '/bin/sh' + - '-c' + command: + - "until (/usr/bin/mc alias set minio http://minio:9000 $$MINIO_ROOT_USER $$MINIO_ROOT_PASSWORD) do + echo 'Waiting to start minio...' && sleep 1; + done; + /usr/bin/mc mb minio/ever-gauzy --region=eu-north-1; + exit 0;" + depends_on: + - minio + networks: + - overlay + + pgweb: + image: sosedoff/pgweb + container_name: pgweb + restart: always + depends_on: + - db + links: + - db:${DB_HOST:-db} + environment: + POSTGRES_DB: ${DB_NAME:-gauzy} + POSTGRES_USER: ${DB_USER:-postgres} + POSTGRES_PASSWORD: ${DB_PASS:-gauzy_password} + PGWEB_DATABASE_URL: postgres://${DB_USER:-postgres}:${DB_PASS:-gauzy_password}@${DB_HOST:-db}:${DB_PORT:-5432}/${DB_NAME:-gauzy}?sslmode=disable + ports: + - '8081:8081' + networks: + - overlay + +volumes: + postgres_data: {} + redis_data: {} + elasticsearch_data: {} + minio_data: {} + cube_data: {} + certificates: {} + jitsu_workspace: {} + +networks: + overlay: + driver: bridge diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..3ce242d32 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,117 @@ +include: + - ./docker-compose.infra.yml + +services: + api: + container_name: api + image: ghcr.io/ever-co/gauzy-api:latest + environment: + API_HOST: ${API_HOST:-api} + API_PORT: ${API_PORT:-3000} + NODE_ENV: ${NODE_ENV:-development} + DB_HOST: db + API_BASE_URL: ${API_BASE_URL:-http://localhost:3000} + CLIENT_BASE_URL: ${CLIENT_BASE_URL:-http://localhost:4200} + CLOUD_PROVIDER: ${CLOUD_PROVIDER:-} + SENTRY_DSN: ${SENTRY_DSN:-} + SENTRY_HTTP_TRACING_ENABLED: ${SENTRY_HTTP_TRACING_ENABLED:-} + SENTRY_POSTGRES_TRACKING_ENABLED: ${SENTRY_POSTGRES_TRACKING_ENABLED:-} + SENTRY_PROFILING_ENABLED: ${SENTRY_PROFILING_ENABLED:-} + JITSU_SERVER_URL: ${JITSU_SERVER_URL:-} + OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: ${OTEL_EXPORTER_OTLP_TRACES_ENDPOINT:-} + OTEL_EXPORTER_OTLP_HEADERS: ${OTEL_EXPORTER_OTLP_HEADERS:-} + OTEL_ENABLED: ${OTEL_ENABLED:-} + OTEL_PROVIDER: ${OTEL_PROVIDER:-} + JITSU_SERVER_WRITE_KEY: ${JITSU_SERVER_WRITE_KEY:-} + GAUZY_GITHUB_CLIENT_ID: ${GAUZY_GITHUB_CLIENT_ID:-} + GAUZY_GITHUB_CLIENT_SECRET: ${GAUZY_GITHUB_CLIENT_SECRET:-} + GAUZY_GITHUB_WEBHOOK_URL: ${GAUZY_GITHUB_WEBHOOK_URL:-} + GAUZY_GITHUB_WEBHOOK_SECRET: ${GAUZY_GITHUB_WEBHOOK_SECRET:-} + GAUZY_GITHUB_APP_PRIVATE_KEY: ${GAUZY_GITHUB_APP_PRIVATE_KEY:-} + GAUZY_GITHUB_APP_ID: ${GAUZY_GITHUB_APP_ID:-} + GAUZY_GITHUB_APP_NAME: ${GAUZY_GITHUB_APP_NAME:-} + GAUZY_GITHUB_POST_INSTALL_URL: ${GAUZY_GITHUB_POST_INSTALL_URL:-} + GAUZY_GITHUB_OAUTH_CLIENT_ID: ${GAUZY_GITHUB_OAUTH_CLIENT_ID:-} + GAUZY_GITHUB_OAUTH_CLIENT_SECRET: ${GAUZY_GITHUB_OAUTH_CLIENT_SECRET:-} + GAUZY_GITHUB_OAUTH_CALLBACK_URL: ${GAUZY_GITHUB_OAUTH_CALLBACK_URL:-} + MAGIC_CODE_EXPIRATION_TIME: ${MAGIC_CODE_EXPIRATION_TIME:-} + APP_NAME: ${APP_NAME:-} + APP_LOGO: ${APP_LOGO:-} + APP_SIGNATURE: ${APP_SIGNATURE:-} + APP_LINK: ${APP_LINK:-} + APP_EMAIL_CONFIRMATION_URL: ${APP_EMAIL_CONFIRMATION_URL:-} + APP_MAGIC_SIGN_URL: ${APP_MAGIC_SIGN_URL:-} + COMPANY_LINK: ${COMPANY_LINK:-} + COMPANY_NAME: ${COMPANY_NAME:-} + + env_file: + - .env.compose + entrypoint: './entrypoint.compose.sh' + command: ['node', 'main.js'] + restart: on-failure + depends_on: + db: + condition: service_healthy + zipkin: + condition: service_started + redis: + condition: service_started + minio: + condition: service_started + minio_create_buckets: + condition: service_started + elasticsearch: + condition: service_healthy + cube: + condition: service_started + links: + - db:${DB_HOST:-db} + - cube:${CUBE_HOST:-cube} + - redis:${REDIS_HOST:-redis} + - minio:${MINIO_HOST:-minio} + - elasticsearch:${ES_HOST:-elasticsearch} + # volumes: + # - webapp_node_modules:/srv/gauzy/node_modules + # - api_node_modules:/srv/gauzy/apps/api/node_modules + ports: + - '3000:${API_PORT:-3000}' + networks: + - overlay + + webapp: + container_name: webapp + image: ghcr.io/ever-co/ever-teams-webapp:latest + environment: + GAUZY_API_SERVER_URL: ${GAUZY_API_SERVER_URL:-https://api.ever.team} + NEXT_PUBLIC_GAUZY_API_SERVER_URL: ${NEXT_PUBLIC_GAUZY_API_SERVER_URL:-https://api.ever.team} + NODE_ENV: ${NODE_ENV:-development} + DEMO: 'true' + env_file: + - .env.compose + restart: on-failure + links: + - db:${DB_HOST:-db} + - api:${API_HOST:-api} + - cube:${CUBE_HOST:-cube} + - redis:${REDIS_HOST:-redis} + - minio:${MINIO_HOST:-minio} + - elasticsearch:${ES_HOST:-elasticsearch} + depends_on: + db: + condition: service_healthy + redis: + condition: service_started + minio: + condition: service_started + minio_create_buckets: + condition: service_started + elasticsearch: + condition: service_healthy + api: + condition: service_started + # volumes: + # - webapp_node_modules:/srv/gauzy/node_modules + ports: + - '3030:${UI_PORT:-3030}' + networks: + - overlay