From fb38a613115f36a8f17d44fb29beae34a2f44036 Mon Sep 17 00:00:00 2001 From: DrMxrcy <58747968+DrMxrcy@users.noreply.github.com> Date: Tue, 16 May 2023 10:02:08 -0400 Subject: [PATCH] Add Logto (#534) * Add Logto * Update docker-compose.yml --- apps/logto/config.json | 31 ++++++++++++++++++ apps/logto/docker-compose.yml | 50 +++++++++++++++++++++++++++++ apps/logto/metadata/description.md | 30 +++++++++++++++++ apps/logto/metadata/logo.jpg | Bin 0 -> 23713 bytes 4 files changed, 111 insertions(+) create mode 100644 apps/logto/config.json create mode 100644 apps/logto/docker-compose.yml create mode 100644 apps/logto/metadata/description.md create mode 100644 apps/logto/metadata/logo.jpg diff --git a/apps/logto/config.json b/apps/logto/config.json new file mode 100644 index 00000000..40d26fde --- /dev/null +++ b/apps/logto/config.json @@ -0,0 +1,31 @@ +{ + "$schema": "../schema.json", + "name": "Logto", + "port": 8203, + "available": true, + "exposable": true, + "id": "logto", + "tipi_version": 1, + "version": "1.3.0", + "force_expose": true, + "categories": ["security"], + "description": "Logto is a cost-effective open-source alternative to Auth0.", + "short_desc": "Logto is a cost-effective open-source alternative to Auth0. ", + "author": "Logto Team", + "source": "https://github.com/logto-io/logto", + "form_fields": [ + { + "type": "random", + "label": "Database Password", + "min": 32, + "env_variable": "LOGTO_DB_PASSWORD" + }, + { + "type": "text", + "label": "Logto Admin Console URL URL", + "hint": "Example: admin.example.com", + "required": true, + "env_variable": "LOGTO_ADMIN_URL" + } + ] +} diff --git a/apps/logto/docker-compose.yml b/apps/logto/docker-compose.yml new file mode 100644 index 00000000..0defe4d6 --- /dev/null +++ b/apps/logto/docker-compose.yml @@ -0,0 +1,50 @@ +version: "3.9" +services: + logto: + depends_on: + logto-db: + condition: service_healthy + image: svhd/logto:1.3.0 + container_name: logto + entrypoint: ["sh", "-c", "npm run cli db seed -- --swe && npm start"] + ports: + - ${APP_PORT}:3001 + - 8204:3002 + environment: + - NODE_ENV=production + - TRUST_PROXY_HEADER=1 + - DB_URL=postgres://tipi:${LOGTO_DB_PASSWORD}@logto-db:5432/logto + - ENDPOINT=https://${APP_DOMAIN} + - ADMIN_ENDPOINT=https://${LOGTO_ADMIN_URL} + networks: + - tipi_main_network + labels: + traefik.enable: ${APP_EXPOSED} + traefik.http.routers.logto.rule: Host(`${APP_DOMAIN}`) + traefik.http.routers.logto.entrypoints: websecure + traefik.http.routers.logto.service: logto + traefik.http.routers.logto.tls.certresolver: myresolver + traefik.http.services.logto.loadbalancer.server.port: 3001 + traefik.http.routers.logto-admin.rule: Host(`${LOGTO_ADMIN_URL}`) + traefik.http.routers.logto-admin.entrypoints: websecure + traefik.http.routers.logto-admin.service: logto + traefik.http.routers.logto-admin.tls.certresolver: myresolver + traefik.http.services.logto-admin.loadbalancer.server.port: 3002 + + logto-db: + container_name: logto-db + image: postgres:14 + restart: unless-stopped + environment: + - POSTGRES_USER=tipi + - POSTGRES_PASSWORD=${LOGTO_DB_PASSWORD} + - POSTGRES_DB=logto + volumes: + - ${APP_DATA_DIR}/data/postgres:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready"] + interval: 10s + timeout: 5s + retries: 5 + networks: + - tipi_main_network \ No newline at end of file diff --git a/apps/logto/metadata/description.md b/apps/logto/metadata/description.md new file mode 100644 index 00000000..a18bcc35 --- /dev/null +++ b/apps/logto/metadata/description.md @@ -0,0 +1,30 @@ +[![](https://github.com/logto-io/logto/raw/master/logo.png)](https://logto.io) + +Logto is a cost-effective open-source alternative to Auth0. It offers a seamless developer experience and is well-suited for individuals and growing companies. + +🧑💻 **A frontend-to-backend identity solution** + +- OIDC-based authentication and RBAC authorization. +- Passwordless sign in and much more diverse options, including Email, Phone number, Username, Google, Facebook and other social sign in methods. +- Beautiful UI components with customizable CSS to fit your business needs. + +📦 **Out-of-box infrastructure** + +- A ready-to-use management API can serve as your authentication provider, eliminating the need for extra implementation. +- SDKs that can integrate your apps with Logto quickly, multi-platform and language compatible, tailored to your development environment. +- Flexible connectors, scalable with community contributions, customizable with SAML, OAuth, and OIDC protocols. + +💻 **Enterprise-ready solutions** + +- RBAC to control your resource through scalable role authorization for diverse use cases. +- User management and audit Logs to understand identity related user info and keep your security on track. +- We are currently working on SSO, Organizations and MFA! Stay tuned! + +Boringly, we call it "[customer identity access management](https://en.wikipedia.org/wiki/Customer_identity_access_management)" (CIAM) or "customer identity solution." + +[Subscribe to us](https://logto.io/subscribe/?utm_source=github&utm_medium=repo_logto) right away to receive up-to-date information about the Logto Cloud (SaaS) as well as in-time feature updates. + +## Get started + +- Visit our 🎨 [website](https://logto.io/?utm_source=github&utm_medium=repo_logto) for a brief introduction if you are new to Logto. +- A step-by-step guide is available on 📖 [docs.logto.io](https://docs.logto.io/?utm_source=github&utm_medium=repo_logto). \ No newline at end of file diff --git a/apps/logto/metadata/logo.jpg b/apps/logto/metadata/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5670bd938613ae3f9a304ec68e9c48e6fe06e8aa GIT binary patch literal 23713 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 literal 0 HcmV?d00001