{"id":14155359,"url":"https://github.com/ttttonyhe/ouorz-mono","last_synced_at":"2025-04-13T23:55:13.818Z","repository":{"id":37964589,"uuid":"323296748","full_name":"ttttonyhe/ouorz-mono","owner":"ttttonyhe","description":"A Monorepo for My ( :earth_asia: Personal Website / :microscope: Academic Profile ) and { Other Related Projects }","archived":false,"fork":false,"pushed_at":"2024-10-28T12:07:29.000Z","size":21459,"stargazers_count":994,"open_issues_count":7,"forks_count":25,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-29T14:14:43.277Z","etag":null,"topics":["blog","command-palette","cypress","frontend","monorepo","nextjs","nodejs","openai-api","personal-website","php","portfolio-website","react","reactjs","redux","redux-saga","storybook","tailwindcss","turborepo","typescript","wordpress"],"latest_commit_sha":null,"homepage":"https://lipeng.ac","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ttttonyhe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-21T10:02:35.000Z","updated_at":"2024-10-28T03:46:29.000Z","dependencies_parsed_at":"2024-01-26T21:45:22.721Z","dependency_job_id":"2c45c96f-23de-47e9-b519-04d2bbaf6529","html_url":"https://github.com/ttttonyhe/ouorz-mono","commit_stats":{"total_commits":855,"total_committers":6,"mean_commits":142.5,"dds":0.1625730994152047,"last_synced_commit":"473470204cab70c3e57c24a6ad5263b97c49eb4b"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ttttonyhe%2Fouorz-mono","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ttttonyhe%2Fouorz-mono/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ttttonyhe%2Fouorz-mono/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ttttonyhe%2Fouorz-mono/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ttttonyhe","download_url":"https://codeload.github.com/ttttonyhe/ouorz-mono/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248799913,"owners_count":21163403,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blog","command-palette","cypress","frontend","monorepo","nextjs","nodejs","openai-api","personal-website","php","portfolio-website","react","reactjs","redux","redux-saga","storybook","tailwindcss","turborepo","typescript","wordpress"],"created_at":"2024-08-17T08:02:58.011Z","updated_at":"2025-04-13T23:55:13.787Z","avatar_url":"https://github.com/ttttonyhe.png","language":"TypeScript","funding_links":[],"categories":["blog"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003eOUORZ-MONO\u003c/h1\u003e\n  \u003cp\u003eSource code \u0026 Docker image that power \u003ca href=\"https://lipeng.ac\" target=\"_blank\"\u003elipeng.ac\u003c/a\u003e and other related projects\u003c/p\u003e\n\n  \u003ca href=\"https://github.com/ttttonyhe/ouorz-mono\"\u003e\n    \u003cimg src=\"https://github.com/ttttonyhe/ouorz-mono/actions/workflows/main-app-testing.yml/badge.svg\" alt=\"build status\"\u003e\n  \u003c/a\u003e\n\n  \u003ca href=\"https://github.com/ttttonyhe/ouorz-mono\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/license/ttttonyhe/ouorz-mono.svg\" alt=\"license\"\u003e\n  \u003c/a\u003e\n\u003c/div\u003e\n\n\u003cbr/\u003e\n\n![screenshot-ouorz-com](https://user-images.githubusercontent.com/21199796/181861480-011d2fb7-6d7d-4d77-bbff-abb3c78c222d.png)\n\n\u003cbr/\u003e\n\u003chr/\u003e\n\n## Main App\n\n### Past Iterations\n\n- Antony-Nuxt (Nuxt.js / Vue.js v2) [https://github.com/ttttonyhe/antony-nuxt →](https://github.com/ttttonyhe/antony-nuxt)\n- Antony (Vue.js v2) [https://github.com/ttttonyhe/antony →](https://github.com/ttttonyhe/antony)\n- Tony (Vue.js v2 / PHP) [https://github.com/ttttonyhe/tony →](https://github.com/ttttonyhe/tony)\n\n\u003cbr/\u003e\n\n### Feature Highlights\n\n- SSR/SSG/On-demand ISR\n- Command palette\n- Redux + Redux Saga state management\n- [Nexment](https://github.com/ttttonyhe/nexment) comment system\n- Dynamic table of contents sidebar\n- Personal dashboard\n- Dark mode\n\n\u003cbr/\u003e\n\n### Summary of Tech Stacks\n\nSuper opinionated, completely overkill.\n\n- TypeScript\n- Framework\n  - React (Next.js)\n  - Foundation/Adaptor implementation *coming soon*\n  - Storybook\n  - Turborepo\n- Data Fetching\n  - swr\n    - Infinite Loading\n    - Revalidation\n    - Suspense\n  - fetch (API Routes)\n- State Management\n  - Redux Toolkit\n  - Redux Saga\n- Styling:\n  - styled-components\n  - Tailwind CSS\n- Content Management:\n  - WordPress (Qiniu - Static file storage)\n  - WP REST API (GraphQL implementation coming soon)\n  - Tencent Cloud CVM (CentOS/Nginx/MySQL/PHP)\n  - [Nexment](https://github.com/ttttonyhe/nexment) (LeanCloud)\n  - Newsletter (Listmonk)\n- Error Logging \u0026 Web Vitals Metric\n  - Sentry\n- Linters\n  - ESLint\n  - Prettier\n  - CommitLint\n- CI/CD\n  - Github Actions\n  - Vercel\n\n\u003cbr/\u003e\n\n### Project Setup\n\n```bash\ngit clone git@github.com:ttttonyhe/ouorz-mono.git\npnpm install\ncd apps/main\n```\n\nCreate a `.env` file with your configuration, see below for a list of environment variables used in this project:\n\n- LeanCloud:\n  - NEXT_PUBLIC_LC_KEY\n  - NEXT_PUBLIC_LC_ID\n- Sentry:\n  - NEXT_PUBLIC_SENTRY_DSN\n  - SENTRY_AUTH_TOKEN\n  - SENTRY_PROJECT\n  - SENTRY_ORG\n- On-demand ISR:\n  - REVALIDATION_REQUEST_TOKEN\n\n```\npnpm run dev:main\n```\n\n\u003cbr/\u003e\n\u003chr/\u003e\n\n## WordPress App\n\u003e **Warning**\n\u003e \n\u003e Running WordPress in a Docker container is extremely slow on lower-spec machines\n\u003e \n\u003e \\\u003e=1 GB of RAM without MySQL 8, or \u003e=2 GB of RAM with MySQL 8 is recommended\n\nThis project is wrapped up in a Docker container built based on the official WordPress Docker image: [wordpress:php8.0-apache](https://hub.docker.com/layers/library/wordpress/php8.0-apache/images/sha256-121ce32b1837fa372989ae498eee6c7ff49e022715e035e00d65c8d07592a5d9).\n\n\u003cbr/\u003e\n\n### Static Image\n\nEach build outputs a static Docker image (similar to a typical containerized application) which means updating WordPress itself or adding new themes/plugins requires redeployment.\n\n\u003cbr/\u003e\n\n### Persistent Storage\n\nAll uploads are stored in an external store (Qiniu, similar to AWS S3), therefore `wp-content/uploads` can be treated as temporary data.\n\n\u003cbr/\u003e\n\n### Custom Themes\n\n`main` app uses WordPress REST API to fetch data, `wordpress` app functions as a headless CMS. The theme `peg` is used to customize the behaviour of the REST API endpoints, therefore `peg/functions.php` should be the main focus when it comes to the development of `wordpress` app.\n\n\u003cbr/\u003e\n\n### Environment Variables\n\n- MySQL Database:\n  - WORDPRESS_DB_HOST\n  - WORDPRESS_DB_NAME\n  - WORDPRESS_DB_PASSWORD\n  - WORDPRESS_DB_USER\n  - WORDPRESS_TABLE_PREFIX\n- Settings:\n  - WORDPRESS_DEBUG\n\nOptionally, `WORDPRESS_CONFIG_EXTRA` can be set to include other configurations:\n\n- MySQL SSL Connection:\n  - `define(\"MYSQL_CLIENT_FLAGS\", MYSQLI_CLIENT_SSL);`\n- Turn Off PHP Warnings \u0026 Notices:\n  - `ini_set(\"error_reporting\", E_ALL \u0026 ~E_NOTICE);`\n  - `ini_set(\"display_errors\",\"Off\")`\n- Redis Object Cache:\n  - `define(\"WP_REDIS_HOST\", \"redis_database_host\");`\n  - `define(\"WP_REDIS_PASSWORD\", \"redis_database_pwd\");\"`\n  - `define(\"WP_REDIS_PORT\", \"redis_database_port\")`\n\n\u003cbr/\u003e\n\n### Local Development\n\n```bash\ndocker build --tag ouorz-wordpress .\ndocker run -p 8080:80 \\\n-e WORDPRESS_DB_HOST=[dev_database_host] \\\n-e WORDPRESS_DB_USER=[dev_database_user] \\\n-e WORDPRESS_DB_PASSWORD=[dev_database_pwd] \\\n-e WORDPRESS_DB_NAME=[dev_database_name] \\\n-e WORDPRESS_DEBUG=true \\\n-e WORDPRESS_CONFIG_EXTRA=\"define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);\" \\\n-e WORDPRESS_TABLE_PREFIX=[dev_database_prefix] \\\nouorz-wordpress\n```\n\n\u003cbr/\u003e\n\u003chr/\u003e\n\n## Analytics App\n\nThis project is based on [Umami](https://umami.is)\n\n### Geolocation Data Access\nFollow the instructions [here →](https://dev.maxmind.com/geoip/geolite2-free-geolocation-data) to sign up for Maxmind GeoLite2, and retrieve a license key\n\n\u003cbr/\u003e\n\n### Project Setup\n\n```bash\ngit clone git@github.com:ttttonyhe/ouorz-mono.git\npnpm install\ncd apps/analytics\n```\n\nCreate a `.env` file with your configuration, see below for a list of environment variables used in this project:\n\n- DATABASE_URL\n- HASH_SALT\n- MAXMIND_LICENSE_KEY\n\n```\npnpm --filter @ouorz/analytics run build-postgresql-client\npnpm run dev:analytics\n```\n\n\u003cbr/\u003e\n\u003chr/\u003e\n\n## Twilight Toolkit\n\nA super opinionated front-end toolkit library\n\n![twilight-toolkit-storybook](https://user-images.githubusercontent.com/21199796/182478030-52acb1f1-c60d-415b-9924-195e9b9d2ca5.png)\n\n\n### UI\n\nStorybook: [https://ui.twilight-toolkit.ouorz.com →](https://ui.twilight-toolkit.ouorz.com)\n\nCurrently only available in React, Foundation/Adaptor implementation is coming soon.\n\n\u003cbr/\u003e\n\n### Utilities\n\nWork in progress\n\n\u003cbr/\u003e\n\u003chr/\u003e\n\n## Monorepo\n\n### Tooling\n\nBuild system: [Turborepo](https://turborepo.org) with Remote Caching\n\nMonorepo Manager: [PNpm](https://pnpm.io/workspaces)\n\n\u003cbr/\u003e\n\n### Practices\n\n#### Running Scripts\n+ Use project aliases to run commands in different packages more easily:\n  ```bash\n  pnpm --filter @ouorz/main run upgrade\n  ```\n+ Use pre-defined Turborepo scripts whenever content awareness (i.e. caching) is needed:\n  ```bash\n  pnpm run build:main\n  ```\n\n#### Managing Dependencies\n+ Root `package.json` should only contain development dependencies\n\n\u003e WIP\n\n\u003cbr/\u003e\n\n### Statistics\n\n![Repobeats analytics image](https://repobeats.axiom.co/api/embed/f2cb67ca660ac944b8df17763a07e74eddbd187d.svg)\n\n\u003cbr/\u003e\n\u003chr/\u003e\n\n## Development\n\n### Gitflow\n\nNot really following this though...\n\n![git_branching_workflow](https://user-images.githubusercontent.com/21199796/135544887-50b1e78b-aa72-4e98-8f08-baac092cf393.jpg)\n\n\u003cbr/\u003e\n\n### E2E Testing\n\nTest runner: [Cypress](https://www.cypress.io)\n\nStart server:\n\n```bash\npnpm run build:main\npnpm run start:main\n\n# or\ncd apps/main\npnpm run dev:test\n```\n\nRun tests:\n\n```bash\npnpm run test:main\n```\n\n`apps/main` uses Cypress Dashboard, disable it by changing the configuration file accordingly.\n\n\u003cbr/\u003e\n\u003chr/\u003e\n\n## Deployment\n\n### apps/wordpress\n\nBuild then deploy the Docker image via `apps/wordpress/Dockerfile`.\n\n\u003e Note: by default, the image listens on port 80, rather than the more common 8080\n\n\u003cbr/\u003e\n\n### apps/main\n\nThis project utilizes a combination of Server-side Rendering (SSR) and (On-demand) Incremental Static Generation (ISG):\n\n```bash\npnpm run build:main\npnpm run start:main\n```\n\n\u003cbr/\u003e\n\n### apps/analytics\n\n```bash\npnpm run build:analytics\npnpm run start:analytics\n```\n\n\u003cbr/\u003e\n\n### packages/twilight-ui\n\nTo deploy the storybook, export it as a static web app:\n\n```bash\npnpm run build:twilight:ui:storybook\n```\n\n\u003cbr/\u003e\n\n### Deploy with Fly.io\n\nConfiguration file `fly.toml` can be found under `apps/wordpress`. Persistent storage should mount to `/var/www/html/wp-content`.\n\n```bash\nfly launch\n\nfly secrets set \\\nWORDPRESS_DB_HOST=[dev_database_host] \\\nWORDPRESS_DB_USER=[dev_database_user] \\\nWORDPRESS_DB_PASSWORD=[dev_database_pwd] \\\nWORDPRESS_DB_NAME=[dev_database_name] \\\nWORDPRESS_DEBUG=false \\\nWORDPRESS_TABLE_PREFIX=[dev_database_prefix] \\\n\nfly deploy\n```\n\nOptionally, volumes with the same name can be created in multiple Fly.io regions which allows Fly to run one or more instances of the app in multiple regions:\n\n```bash\nfly volumes create ouorz_wordpress_wp_content --region yyz --size 1 --no-encryption\nfly volumes create ouorz_wordpress_wp_content --region fra --size 1 --no-encryption\nfly volumes create ouorz_wordpress_wp_content --region hkg --size 1 --no-encryption\n```\n\n```bash\nfly scale count 3\n```\n\nOptionally, Fly.io offers full-managed Redis databases which can be created using the following commands:\n\n```bash\nfly redis create\n```\n\nTraffic is automatically routed through a private IPv6 address restricted to your Fly organization.\n\n\u003cbr/\u003e\n\n### Deploy with Vercel / Netlify\n\nMake sure to set root directory path to `apps/\u003cproject-name\u003e`, then update build command to the following:\n\n```bash\ncd ../.. \u0026\u0026 pnpm run build:\u003cproject-name\u003e\n```\n\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/ttttonyhe/ouorz-mono)\n\n[![Deploy with Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/ttttonyhe/ouorz-mono)\n\n\u003cbr/\u003e\n\nEnabling diff-based deployment is highly recommended:\n\n```bash\ngit diff --quiet HEAD^ HEAD ./\n```\n\n\u003cbr/\u003e\n\n## License\n[GPL-3.0](https://github.com/ttttonyhe/ouorz-mono/blob/main/LICENSE)\n\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fttttonyhe%2Fouorz-mono.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fttttonyhe%2Fouorz-mono?ref=badge_large)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fttttonyhe%2Fouorz-mono","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fttttonyhe%2Fouorz-mono","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fttttonyhe%2Fouorz-mono/lists"}