部署
我们终于准备好将我们的打包应用部署到世界上了。恭喜你坚持到了这一步!
这一步在教程中是可选的,但值得了解以理解整个流程。如果你对部署不感兴趣,可以直接跳到 下一步。
Dioxus Deploy
如前言所述,Dioxus是一个独立项目,旨在通过付费部署平台实现自我资金支持。希望未来有足够多的开发者使用Dioxus Deploy部署应用,从而为Dioxus本身的发展提供资金支持!
目前,Dioxus尚未提供自有部署平台。如果您希望参与测试版并协助我们设计理想的“端到端应用开发体验”,请加入候补名单!
部署您的桌面和移动应用
通常,部署桌面应用只需直接分发应用包即可。只需将应用包上传至 GitHub 或 S3 等托管平台。通过下载链接,用户即可轻松下载并安装您的应用。
📣 在将全栈应用部署至生产环境时,请确保正确设置后端 API URL,相关内容将在后续章节中详细说明。 如果您希望通过应用商店分发应用,则需要执行一些额外步骤。
- iOS:直接发布到 Apple App Store
- macOS:直接发布到 Apple App Store
- Android:直接发布到 Google Play Store
Tauri 提供了一些有用的指南,用于部署 Tauri 应用程序,尽管这些应用程序不是 Dioxus 应用程序,但它们需要遵循许多相同的步骤来部署到应用商店。
让原生应用程序的分发更加轻松是 Dioxus Deploy 的首要任务!
部署要求
Dioxus 网页应用程序由客户端包和服务器可执行文件组成。通常,任何提供简单容器的部署服务商均可满足 Dioxus 全栈网页应用程序的部署需求。
部分提供商如 Cloudflare Workers 和 Fermyon Spin 提供基于 WASM 的容器用于应用程序。WASM 运行时通常运营成本更低,且相较于传统虚拟机容器,其水平扩展能力更强。在 WASM 运行时上部署时,您需要手动创建服务器程序的 WASM 构建版本。
运行 Web 服务器只需执行 ./server 命令即可。请确保正确设置 IP 和 PORT 环境变量:
选择部署服务提供商
市面上有许多部署服务提供商!我们不会过多探讨任何特定提供商的优缺点。通常,提供商在以下几个类别中表现出色:价格、性能、用户界面/用户体验(UI/UX)、高级功能以及企业级需求。
根据您的应用需求,您可能需要满足严格的合规要求,例如SOC2或HIPAA认证。请务必根据自身使用场景进行独立调研。
- AWS:由亚马逊提供的功能齐全的云服务提供商。
- GCP:由谷歌提供的功能齐全的云服务提供商。
- Azure:由微软提供的功能齐全的云服务提供商。
- Fly.io:基于微虚拟机的简单可缩放至零的云服务,集成WireGuard。
- Vercel:基于AWS云函数的开发者导向云服务,深受JavaScript框架欢迎。
- Render:专注于开发者体验和简洁性的“现代Heroku”。
- Digital Ocean:以虚拟机、数据库和存储为核心的云服务。
对于HotDog,我们将部署在Fly.io上。我们选择Fly.io有诸多原因。最重要的是,Fly基于亚马逊的Firecracker项目,该项目完全采用Rust语言编写!
Fly的入门也非常简单——只需使用您的GitHub账户或Google账户登录即可。
构建 Dockerfile
部分部署提供商为各种运行时环境提供了预构建的解决方案。例如,某些提供商专门针对 NodeJS 和 Python 运行时环境提供了严格要求的预构建方案。
对于 Rust 应用程序,通常不存在预构建的“包”可供直接使用。在这种情况下,我们需要编写一个简单的 Dockerfile,用于编译并启动我们的应用程序。
我们的 Dockerfile 将包含三个阶段。第一个阶段下载并缓存依赖项,以确保增量构建:
FROM rust:1 AS chef
RUN cargo install cargo-chef
WORKDIR /app
FROM chef AS planner
COPY . .
RUN cargo chef prepare --recipe-path recipe.json
在第二阶段,我们使用 cargo chef 加载缓存的依赖项并执行构建:
FROM chef AS builder
COPY --from=planner /app/recipe.json recipe.json
RUN cargo chef cook --release --recipe-path recipe.json
COPY . .
# Install `dx`
RUN curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
RUN cargo binstall dioxus-cli --root /.cargo -y --force
ENV PATH="/.cargo/bin:$PATH"
# Create the final bundle folder. Bundle always executes in release mode with optimizations enabled
RUN dx bundle --platform web
最后,我们将生成的web文件夹复制到用于运行我们应用程序的slim运行时环境中。
FROM chef AS runtime
COPY --from=builder /app/target/dx/hot_dog/release/web/ /usr/local/app
# set our port and make sure to listen for all connections
ENV PORT=8080
ENV IP=0.0.0.0
# expose the port 8080
EXPOSE 8080
WORKDIR /usr/local/app
ENTRYPOINT [ "/usr/local/app/server" ]
另外,创建一个 .dockerignore 文件也是个好主意:
**/target
**/dist
LICENSES
LICENSE
temp
README.md
部署到 Fly
要开始使用 Fly,我们需要完成注册流程并填写相关信息。这个过程不会花费太长时间。
我们将添加上述的 Dockerfile 以及 dockerignore 文件。我们需要安装 flyctl,它同时也会安装 Fly CLI。
现在我们执行 fly launch 命令,这将自动初始化我们的 fly.toml 文件。
fly launch 将为我们启动一台构建机器并构建我们的应用程序。一两分钟后,我们的应用程序就应完全构建并部署完毕。
如果我们需要重新部署代码,可以运行 fly deploy。
我们还可以通过在 fly.toml 文件中添加一个 [mounts] 部分,为我们的应用程序添加一个``Volume```,以持久化我们的 SQLite 数据库:
[mounts]
source = "hotdogdb"
destination = "/usr/local/app/hotdogdb"
构建完成后,Fly 将为我们的应用分配一个 URL,我们稍后可以对其进行自定义。如果一切顺利,我们的应用应该已经上线了!
持续部署
Fly 还支持持续部署。每当我们向 GitHub 仓库推送代码时,可以自动执行 fly deploy 命令。这可以作为 staging 环境和自动发布的基础。
我们的应用只需在 .github/workflows/ 目录下创建一个 fly-deploy.yml 文件即可。
name: Fly Deploy
on:
push:
branches:
- main
jobs:
deploy:
name: Deploy app
runs-on: ubuntu-latest
concurrency: deploy-group
steps:
- uses: actions/checkout@v4
- uses: superfly/flyctl-actions/setup-flyctl@master
- run: flyctl deploy --remote-only
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
全栈桌面和移动应用
现在我们的后端已经上线,我们可以将API与我们的原生应用进行集成。默认情况下,Dioxus并不知道API的具体位置,因此您需要手动指定URL,方法是调用server_fn::client::set_server_url。
fn main() {
#[cfg(not(feature = "server"))]
server_fn::client::set_server_url("https://hot-dog.fly.dev");
dioxus::launch(App);
}
请注意,随着我们的应用程序发生变化,服务器函数的“真实”端点也可能发生变化。#[server] 宏会生成一个 API 端点,格式为 /api/fetch_dogs-jkhj12,其中末尾的数据是一个唯一的哈希值。随着我们更新服务器函数,该哈希值也会随之改变。
为了使服务器函数保持稳定的端点,我们可以手动为其命名,使用 endpoint = "xyz" 属性。
#[server(endpoint = "list_dogs")]
pub async fn list_dogs() -> Result<Vec<(usize, String)>, ServerFnError> {
todo!()
}
#[server(endpoint = "remove_dog")]
pub async fn remove_dog(id: usize) -> Result<(), ServerFnError> {
todo!()
}
#[server(endpoint = "save_dog")]
pub async fn save_dog(image: String) -> Result<(), ServerFnError> {
todo!()
}
让我们使用 fly deploy 重新部署我们的 Web 应用。这次部署应该会更快完成,因为 cargo chef 已经缓存了我们的构建结果。
现在,使用 dx serve --platform desktop,我们应该能够在 Web 和桌面端与同一个后端进行交互。
太棒了!我们的初创公司进展顺利。
下一步
我们的应用程序尚未完成,但这篇指南已经变得相当长了!
还有很多额外的工作要做:
- 添加用户、登录和身份验证。
- 使用Cloudflare工具保护我们的网站免受DDOS攻击。
- 添加更多功能
- 营销和与朋友分享!