带有 Turborepo 的 Remix 福音栈

The Remix Gospel Stack

带有 Turborepo 管道、Prisma、PostgreSQL 或 SQLite(Litefs)、Docker 部署到 Fly.io、pnpm、shadcn/ui TailwindCSS 的 Remix TypeScript 单仓库。

pnpm create remix@latest --init-script --install --template https://github.com/PhilDL/remix-gospel-stack

:minidisc: 这个仓库有自己的观点

  • TypeScript 仅此而已。
  • 仅与 pnpm 包管理器兼容,用于处理单仓库工作区。
  • 使用 turborepo 管道 + 缓存来构建、lint、类型检查和测试单仓库。

(替代) 克隆仓库

git clone [email protected]:PhilDL/remix-gospel-stack.git
cd remix-gospel-stack
pnpm add -w @remix-run/dev
pnpm remix init

堆栈中有什么

这个堆栈是一个由 turborepo 和 pnpm 工作区 驱动的面向 Remix 的单仓库。包含一个准备好在 fly.io 上部署的 Remix 应用程序,通过构建 Docker 容器实现。

这个包 使用 pnpm 作为首选的包管理器 来管理工作区。如果您将工作区定义放在 package.json 文件中,它可能与 yarnnpm 一起使用,但不能保证。

Turborepo 和 pnpm 工作区驱动的单仓库架构

  • apps 文件夹包含应用程序

  • packages 文件夹包含示例

    • ui: 由 shadcn/ui 提供支持的 React UI 包示例。一些示例组件和 shadcn/ui Tailwind 配置作为 Tailwind 插件和预设导出。
    • database: 一个 Prisma 包装器,准备在其他包或应用程序中使用。与 tsup 捆绑在一起。可以是 PostgreSQL 或 SQLite // Litefs,取决于您在安装过程中选择什么。
    • business: 一个示例包,使用 Prisma database 作为依赖项,并使用类似于示例的存储库模式
    • internal-nobuild: 一个示例包,它是纯粹的 TypeScript,没有构建步骤。包的 main 入口点直接是 src/index.ts。Remix 通过其自己的构建步骤(使用 esbuild)来处理编译。这个包还包含使用 Vitest 的单元测试。Remix 使用 tsconfig.json 路径来引用该项目及其类型。我建议在您不打算发布包时使用此类内部包。
  • config-packages:

    • 具有不同预设配置的 Eslint 包。
    • TS 配置,也具有不同的预设。
    • Tailwind 配置。

还有什么?

警告 以下所有命令都应该从 单仓库根目录 启动

开发

  • 安装依赖项。

    pnpm install
    

    您还需要复制示例 .env.example

    cp .env.example .env
    cp .env.example .env.docker
    
  • 启动 postgresql docker 容器

    pnpm run docker:db
    

    注意: 当 Docker 在后台设置容器时,npm 脚本将完成。确保 Docker 已完成并且您的容器正在运行,然后继续。

  • 生成 prisma 模式

    pnpm run generate
    
  • 将 Prisma 迁移到数据库

    pnpm run db:migrate:deploy
    
  • 运行第一次构建(使用 ... 选项通过依赖项)

    pnpm run build --filter=@remix-gospel-stack/remix-app...
    

    简单运行 pnpm run build 将构建所有内容,包括 NextJS 应用程序。

  • 运行 Remix 开发服务器

    pnpm run dev --filter=@remix-gospel-stack/remix-app
    

在 PostgreSQL 和 SQLite(Litefs)之间切换

  • 要在 PostgreSQL 和 SQLite(Litefs)之间切换,可以使用从仓库根目录开始的 turbo 生成器。

    pnpm turbo gen scaffold-database
    

    然后按照提示进行操作。但要注意,prisma 迁移与特定数据库相关联,因此您必须删除 migrations 文件夹。

    注意: 切换到 SQLite(Litefs)后,您必须再次运行 pnpm i --fix-lockfile,因为 SQLite(Litefs)需要另一个包(litefs-js)。您可能还需要再次运行 pnpm run setup 来生成第一个迁移。

创建包

内部包

turbo gen workspace --name @remix-gospel-stack/foobarbaz --type package --copy

然后按照提示进行操作

测试、类型检查、lint、安装包...

检查 turbo.json 文件以查看可用的管道。

  • 运行 Cypress 测试和开发
    pnpm run test:e2e:dev --filter=@remix-gospel-stack/remix-app
    
  • lint 所有内容
    pnpm run lint
    
  • 对整个单仓库进行类型检查
    pnpm run typecheck
    
  • 测试整个单仓库
    pnpm run test
    or
    pnpm run test:dev
    
  • 如何在 Remix 应用程序中安装 npm 包?
    pnpm add dayjs --filter @remix-gospel-stack/remix-app
    
  • 调整 config-package 文件夹中的 tsconfigs、eslint 配置。然后任何包或应用程序都将从这些配置中扩展。

在 fly.io 上部署 - PostgreSQL

警告 以下所有命令都应该从 单仓库根目录 启动

在您第一次部署之前,您需要做几件事

  • 首先注册 fly CLI

    fly auth signup
    
  • 在 Fly 上创建两个应用程序,一个用于预发布环境,一个用于生产环境

    fly apps create remix-gospel-stack
    fly apps create remix-gospel-stack-staging
    

    注意: 成功创建应用程序后,请仔细检查 fly.toml 文件,确保 app 键是您创建的生产应用程序的名称。这个栈 在初始化时会自动附加一个唯一的后缀,这可能与您在 Fly 上创建的应用程序不匹配。如果您存在这种不匹配,您可能会在 Github Actions CI 日志中看到 404 错误

  • 初始化 Git。

    git init
    
  • 创建一个新的 GitHub 仓库,然后将其添加为项目的远程仓库。请勿推送您的应用程序!

    git remote add origin <ORIGIN_URL>
    
  • 向您的 GitHub 仓库添加一个 FLY_API_TOKEN。为此,请转到您在 Fly 上的用户设置,创建一个新的 令牌,然后将其添加到 您的仓库机密 中,名称为 FLY_API_TOKEN

  • 为您的预发布环境和生产环境创建数据库

数据库创建

fly postgres create --name remix-gospel-stack-db
fly postgres attach --app remix-gospel-stack remix-gospel-stack-db

fly postgres create --name remix-gospel-stack-staging-db
fly postgres attach --app remix-gospel-stack-staging remix-gospel-stack-staging-db

注意: 在将预发布环境数据库附加到应用程序时,您会收到相同的警告,原因与上面 fly set secret 步骤中相同。不用担心。继续操作!

Fly 会为您处理 DATABASE_URL 机密的设置。

在 fly.io 上部署 - SQLite Litefs

警告 以下所有命令都应该从 单仓库根目录 启动

在您第一次部署之前,您需要做几件事

  • 首先注册 fly CLI

    fly auth signup
    
  • 在 Fly 上创建两个应用程序,一个用于预发布环境,一个用于生产环境

    fly apps create remix-gospel-stack
    fly apps create remix-gospel-stack-staging
    

    注意: 成功创建应用程序后,请仔细检查 fly.toml 文件,确保 app 键是您创建的生产应用程序的名称。这个栈 在初始化时会自动附加一个唯一的后缀,这可能与您在 Fly 上创建的应用程序不匹配。如果您存在这种不匹配,您可能会在 Github Actions CI 日志中看到 404 错误

  • 初始化 Git。

    git init
    
  • 创建一个新的 GitHub 仓库,然后将其添加为项目的远程仓库。请勿推送您的应用程序!

    git remote add origin <ORIGIN_URL>
    
  • 向您的 GitHub 仓库添加一个 FLY_API_TOKEN。为此,请转到您在 Fly 上的用户设置,创建一个新的 令牌,然后将其添加到 您的仓库机密 中,名称为 FLY_API_TOKEN

为您的预发布环境和生产环境的 sqlite 数据库创建一个持久卷。运行以下命令(您可以根据自己的需求和选择的区域调整 GB 大小 (https://fly.io/docs/reference/regions/)。如果确实更改了区域,请确保在 fly.toml 中也更改 primary_region

fly volumes create data --region cdg --size 1 --app remix-gospel-stack
fly volumes create data --region cdg --size 1 --app remix-gospel-stack-staging

然后将卷附加到应用程序

fly consul attach --app remix-gospel-stack
fly consul attach --app remix-gospel-stack-staging

开始编码!

现在一切设置就绪,您可以提交并推送更改到您的仓库。对 main 分支的每次提交都会触发到您的生产环境的部署,而对 dev 分支的每次提交都会触发到您的预发布环境的部署。

如果您在部署到 Fly 时遇到任何问题,请确保您已遵循上述所有步骤。如果您已遵循所有步骤,请将尽可能多的部署详细信息(包括您的应用程序名称)发布到 Fly 支持社区。他们通常会快速回复,希望能够帮助解决您的部署问题和疑问。

多区域部署

在将您的网站和数据库运行在一个区域后,您可以按照 Fly 的扩展多区域 PostgreSQL 文档添加更多区域。

确保为您的应用程序设置一个 PRIMARY_REGION 环境变量。您可以在 fly.toml 中使用 [env] 配置将其设置为要用作应用程序和数据库主要区域的区域。

在其他区域测试您的应用程序

安装 ModHeader 浏览器扩展(或类似的扩展),并使用它加载您的应用程序,并设置 fly-prefer-region 标头为要测试的区域名称。

您可以检查响应中的 x-fly-region 标头,以了解您的请求是在哪个区域处理的。

GitHub Actions

我们使用 GitHub Actions 进行持续集成和部署。任何进入 main 分支的内容将在运行测试/构建等后部署到生产环境。dev 分支中的任何内容都将部署到预发布环境。

手动构建 Docker 镜像以部署到 Fly.io

  • 创建一个 docker 网络
    docker network create app_network
    
  • 构建 docker 镜像
    pnpm docker:build:remix-app
    
  • 运行 docker 镜像
    pnpm docker:run:remix-app
    
  • (可选) 如果您想手动部署到 fly.io
    DOCKER_DEFAULT_PLATFORM=linux/amd64 flyctl deploy --config ./apps/remix-app/fly.toml --dockerfile ./apps/remix-app/Dockerfile
    

了解 Turborepo 的强大功能

感谢

支持

如果您发现该模板有用,请考虑为它点个 Star ⭐。谢谢!

免责声明

我并不是 Monorepo、Docker 或 CI 方面的专家。这里提出的设置只是众多方法中的一种,可能还有很大的改进空间,但我正在边学边做,如果您发现任何可能的改进,请提交 PR。我会非常感谢您的贡献!