如何使用 SST 和 Docker 将 Nextjs 应用程序部署到 Hetzner VPS

我的原创博文:https://www.prudkohliad.com/articles/deploy-next-js-to-vps-using-sst-2024-08-11

sst 是一个框架,可以让您轻松在自己的基础设施上构建现代全栈应用程序。 sst v3 使用 pulumi 和 terraform – sst 文档

在本指南中,我们将使用 sst 和 docker 在 hetzner vps 上部署 next.js 应用程序。本指南是我上一篇文章的后续内容。如果您在这里发现一些没有意义的内容,您很有可能会在那里找到答案 – 如何使用 docker 和 github actions 将 next.js 应用程序部署到 hetzner 上的 vps。

将sst添加到项目中

要将 sst 添加到项目中,请运行以下命令:

pnpx sst@ion init

这将显示一个交互式提示。选择“是”,然后选择“aws”:

如何使用 SST 和 Docker 将 Nextjs 应用程序部署到 Hetzner VPS

sst 初始化输出 – 终端

确保安装了所有必需的软件包:

pnpm install

这将创建 sst.config.ts 文件,我们将在其中添加所有配置。

此外,还会创建一些其他文件/目录。让我们将它们添加到 .dockerignore,我们不希望它们最终成为 docker 镜像:

# sst.sstsst.config.tstsconfig.json

这就是 sst 配置文件当前的样子:

/// export default $config({  app(input) {    return {      name: "next-self-hosted",      removal: input?.stage === "production" ? "retain" : "remove",      home: "aws",    };  },  async run() {},});

我们不打算使用aws,所以让我们将home参数设置为“local”:

/// export default $config({  app(input) {    return {      name: "next-self-hosted",      removal: input?.stage === "production" ? "retain" : "remove",      home: "local",    };  },  async run() {},});

现在可以开始向 run() 函数添加东西​​了。

在 hetzner 上创建 api 令牌

为了使用 sst 在 hetzner 上创建 vps,我们需要一个 hetzner api 令牌。让我们生成一个新的。

在 hetzner 控制台中打开项目,导航到“安全”选项卡:

如何使用 SST 和 Docker 将 Nextjs 应用程序部署到 Hetzner VPS

项目安全设置 – hetzner cloud ui

生成 api 令牌:

如何使用 SST 和 Docker 将 Nextjs 应用程序部署到 Hetzner VPS

生成 api 令牌 – hetzner cloud ui

新的代币将添加到您的项目中:

如何使用 SST 和 Docker 将 Nextjs 应用程序部署到 Hetzner VPS

api 令牌 – hetzner cloud ui

令牌只会显示一次,请确保不要丢失。

添加 tls 和 hetzner 提供商:

pnpm sst add tlspnpm sst add hcloudpnpm install

生成 ssh 密钥

为了在创建 hetzner vps 后执行进一步的命令,我们需要确保在创建过程中添加了 ssh 密钥。为此,我们将在本地创建一个 ssh 令牌,然后将其公共部分添加到 hetzner。在run函数中添加以下代码:

// in the run() function:// generate an ssh keyconst sshkeylocal = new tls.privatekey("ssh key - local", {  algorithm: "ed25519",});// add the ssh key to hetznerconst sshkeyhetzner = new hcloud.sshkey("ssh key - hetzner", {  publickey: sshkeylocal.publickeyopenssh,});

部署应用程序:

pnpm sst deploysst ❍ ion 0.1.90  ready!➜  app:        next-self-hosted   stage:      antonprudkohliad~  deploy|  created     ssh key - local tls:index:privatekey|  created     ssh key - hetzner hcloud:index:sshkey✓  complete

您将看到一个新的 ssh 密钥已添加到 hetzner 中:

如何使用 SST 和 Docker 将 Nextjs 应用程序部署到 Hetzner VPS

ssh 密钥 – hetzner cloud ui

现在我们可以继续创建 vps 了。

创建服务器

以下命令将确保在您的项目中创建新的 vps:

// in the run() function:// create a server on hetznerconst server = new hcloud.server("server", {  image: "docker-ce",  servertype: "cx22",  location: "nbg1",  sshkeys: [sshkeyhetzner.id],});

这里我使用 docker-ce 镜像,因为它已经安装了 docker。您可以使用 hetzner cloud api 列出所有可用的图像、服务器类型和数据中心。

验证服务器是否正确创建:

pnpm sst deploysst ❍ ion 0.1.90  ready!➜  app:        next-self-hosted   stage:      antonprudkohliad~  deploy|  created     server hcloud:index:server (34.5s)✓  complete

您还应该能够在控制台中看到新创建的服务器:

如何使用 SST 和 Docker 将 Nextjs 应用程序部署到 Hetzner VPS

服务器 – hetzner cloud ui

连接到 vps 上的 docker 服务器

为了在 vps 上构建应用程序 docker 镜像并能够创建网络、卷和容器,我们需要在本地计算机和 vps 上的 docker server 之间建立一座桥梁。为此,我们需要 docker 提供商:

pnpm sst add dockerpnpm install

将 ssh 私钥存储在磁盘上,以便 ssh 客户端可以访问它。创建与 vps 上 docker 服务器的连接:

// at the top of the file:import { resolve as pathresolve } from "node:path";import { writefilesync as fswritefilesync } from "node:fs";// in the run() function:// store the private ssh key on disk to be able to pass it to the docker// providerconst sshkeylocalpath = sshkeylocal.privatekeyopenssh.apply((k) => {  const path = "id_ed25519_hetzner";  fswritefilesync(path, k, { mode: 0o600 });  return pathresolve(path);});// connect to the docker server on the hetzner serverconst dockerserverhetzner = new docker.provider("docker server - hetzner", {  host: $interpolate`ssh://root@${server.ipv4address}`,  sshopts: ["-i", sshkeylocalpath, "-o", "stricthostkeychecking=no"],});

确保还将 ssh 私钥 id_ed25519_hetzner 添加到 .gitignore 和 .dockerignore,这样它就不会进入您的 github 存储库和 docker 镜像。

触发部署以验证更改:

pnpm sst deploysst ❍ ion 0.1.90  ready!➜  app:        next-self-hosted   stage:      antonprudkohliad~  deploy|  created     docker server - hetzner pulumi:providers:docker✓  complete

构建 docker 镜像

现在我们可以在删除的 docker 服务器上构建 docker 镜像了:

// in the run() function:// build the docker imageconst dockerimagehetzner = new docker.image(  "docker image - app - hetzner",  {    imagename: "next-self-hosted/next-self-hosted:latest",    build: {      context: pathresolve("./"),      dockerfile: pathresolve("./dockerfile"),      target: "production",      platform: "linux/amd64",    },    skippush: true,  },  {    provider: dockerserverhetzner,    dependson: [server],  });

让我们触发部署看看一切是否正常:

pnpm sst deploysst ❍ ion 0.1.90  ready!➜  app:        next-self-hosted   stage:      antonprudkohliad~  deploy|  log         starting docker build|  log         image built successfully, local id "sha256:629a6cdfc298c74599a3056278e31c64197a87f6d11aab09573bc9171d2f3362"|  created     docker image - app - hetzner docker:index:image (36.0s)✓  complete

现在,让我们检查 docker 镜像是否已到达服务器:

ssh root@116.203.183.180 -i ./id_ed25519_hetzner -o stricthostkeychecking=no -c "docker image ls"repository                          tag       image id       created              sizenext-self-hosted/next-self-hosted   latest    629a6cdfc298   about a minute ago   712mb

太棒了!

docker 网络

我们将创建两个网络:公共网络和内部网络。公共网络用于 nginx 连接的服务,即必须暴露于外部的服务(例如 next.js 应用程序或 api 服务器)。内部网络用于不应该暴露给外部的服务,例如postgres数据库、redis缓存:

// in the run() function:// setup docker networksconst dockernetworkpublic = new docker.network(  "docker network - public",  { name: "app_network_public" },  { provider: dockerserverhetzner, dependson: [server] });const dockernetworkinternal = new docker.network(  "docker network - internal",  { name: "app_network_internal" },  { provider: dockerserverhetzner, dependson: [server] });

触发部署:

pnpm sst deploysst ❍ ion 0.1.90  ready!➜  app:        next-self-hosted   stage:      antonprudkohliad~  deploy|  created     docker network - public docker:index:network (2.3s)|  created     docker network - internal docker:index:network (3.1s)✓  complete

检查网络 app_network_internal 和 app_network_public 是否存在于远程:

ssh root@116.203.183.180 -i ./id_ed25519_hetzner -o stricthostkeychecking=no -c "docker network ls"network id     name                   driver    scope0590360bd4ae   app_network_internal   bridge    locale3bd8be72506   app_network_public     bridge    local827fa5ca5de2   bridge                 bridge    localdc8880514199   host                   host      localf1481867db18   none                   null      local

docker 卷

我们将创建一个卷来存储应用程序构建文件(.next 文件夹):

// in the run() function:// setup docker volumesconst dockervolumeappbuild = new docker.volume(  "docker volume - app build",  { name: "app_volume_build" },  { provider: dockerserverhetzner, dependson: [server] });

部署并验证 docker 卷 app_volume_build 是否存在于 vps 上:

pnpm sst deploysst ❍ ion 0.1.90  ready!➜  app:        next-self-hosted   stage:      antonprudkohliad~  deploy|  created     docker volume - app build docker:index:volume✓  completessh root@116.203.183.180 -i ./id_ed25519_hetzner -o stricthostkeychecking=no -c "docker volume ls"driver    volume namelocal     app_volume_build

构建容器

我们将运行一个一次性容器(也称为 init 容器)来构建 next.js 应用程序并将结果存储在 .next 文件夹中,该文件夹将通过我们上面创建的卷与主应用程序容器共享:

// in the run() function:// run a one-off container to build the appconst dockerappbuildcontainer = new docker.container(  "docker container - app build",  {    name: "app_container_build",    image: dockerimagehetzner.imagename,    volumes: [      {        volumename: dockervolumeappbuild.name,        containerpath: "/app/.next",      },    ],    command: ["pnpm", "build"],    mustrun: true,  },  {    provider: dockerserverhetzner,  });

部署并通过日志验证构建是否成功:

pnpm sst deploysst ❍ ion 0.1.90  ready!➜  app:        next-self-hosted   stage:      antonprudkohliad~  deploy|  created     docker container - app build docker:index:container (1.1s)✓  completessh root@116.203.183.180 -i ./id_ed25519_hetzner -o stricthostkeychecking=no -c "docker logs -f app_container_build"> next-self-hosted@ build /app> next build  ▲ next.js 14.2.5   creating an optimized production build ... ✓ compiled successfully   linting and checking validity of types ...   collecting page data ...   generating static pages (0/4) ...   generating static pages (1/4)   generating static pages (2/4)   generating static pages (3/4) ✓ generating static pages (4/4)   finalizing page optimization ...   collecting build traces ...route (app)                              size     first load js┌ ○ /                                    142 b          87.2 kb└ ○ /_not-found                          871 b          87.9 kb+ first load js shared by all            87 kb  ├ chunks/52d5e6ad-40eff88d15e66edb.js  53.6 kb  ├ chunks/539-e1fa9689ed3badf0.js       31.5 kb  └ other shared chunks (total)          1.84 kb○  (static)  prerendered as static content

应用程序容器

现在我们将添加一个“runner”容器,它将使用构建容器的构建输出,并在下次启动时运行:

// in the run() function:const dockerappcontainer = new docker.container(  "docker container - app",  {    name: "app",    image: dockerimagehetzner.imagename,    volumes: [      {        volumename: dockervolumeappbuild.name,        containerpath: "/app/.next",      },    ],    networksadvanced: [      { name: dockernetworkpublic.id },      { name: dockernetworkinternal.id },    ],    command: ["pnpm", "start"],    restart: "always",  },  { provider: dockerserverhetzner, dependson: [dockerappbuildcontainer] });

部署并验证应用是否启动成功:

pnpm sst deploysst ❍ ion 0.1.90  ready!➜  app:        next-self-hosted   stage:      antonprudkohliad~  deploy|  created     docker container - app docker:index:container (1.1s)✓  completessh root@116.203.183.180 -i ./id_ed25519_hetzner -o stricthostkeychecking=no -c "docker logs -f app"> next-self-hosted@ start /app> next start  ▲ next.js 14.2.5  - local:        http://localhost:3000 ✓ starting... ✓ ready in 497ms

应用程序容器可能会失败,因为构建容器尚未完成构建,但它很快就会恢复并正常运行。

添加 cloudflare 证书

为了将文件上传到vps,我们需要安装命令提供程序和polumi包:

pnpm sst add @pulumi/commandpnpm add -d @pulumi/pulumipnpm install

确保 vps 上存在 /root/app 和 /root/app/certs 目录并上传 cloudflare origin server 证书:

// at the top of the fileimport { asset as pulumiasset } from "@pulumi/pulumi";// in the run() function:// make sure that app directory existsnew command.remote.command("command - ensure app directory", {  create: "mkdir -p /root/app",  connection: {    host: server.ipv4address,    user: "root",    privatekey: sshkeylocal.privatekeyopenssh,  },});// make sure that app/certs directory existsnew command.remote.command("command - ensure app/certs directory", {  create: "mkdir -p /root/app/certs",  connection: {    host: server.ipv4address,    user: "root",    privatekey: sshkeylocal.privatekeyopenssh,  },});// copy certificates to the vpsnew command.remote.copytoremote(  "copy - certificates - key",  {    source: new pulumiasset.fileasset(      pathresolve("./certs/cloudflare.key.pem")    ),    remotepath: "/root/app/certs/cloudflare.key.pem",    connection: {      host: server.ipv4address,      user: "root",      privatekey: sshkeylocal.privatekeyopenssh,    },  });new command.remote.copytoremote(  "copy - certificates - cert",  {    source: new pulumiasset.fileasset(      pathresolve("./certs/cloudflare.cert.pem")    ),    remotepath: "/root/app/certs/cloudflare.cert.pem",    connection: {      host: server.ipv4address,      user: "root",      privatekey: sshkeylocal.privatekeyopenssh,    },  });new command.remote.copytoremote(  "copy - certificates - authenticated origin pull",  {    source: new pulumiasset.fileasset(      pathresolve("./certs/authenticated_origin_pull_ca.pem")    ),    remotepath: "/root/app/certs/authenticated_origin_pull_ca.pem",    connection: {      host: server.ipv4address,      user: "root",      privatekey: sshkeylocal.privatekeyopenssh,    },  });

启动 nginx

复制 nginx 配置文件到 vps 并启动 nginx 容器:

// in the run() function:// copy nginx config to the vpsconst commandcopynginxconfig = new command.remote.copytoremote(  "copy - nginx config",  {    source: new pulumiasset.fileasset(      pathresolve("./nginx/production.conf")    ),    remotepath: "/root/app/nginx.conf",    connection: {      host: server.ipv4address,      user: "root",      privatekey: sshkeylocal.privatekeyopenssh,    },  });// run the nginx containerconst dockernginxcontainer = new docker.container(  "docker container - nginx",  {    name: "app_container_nginx",    image: "nginx:1.27.0-bookworm",    volumes: [      {        hostpath: "/root/app/nginx.conf",        containerpath: "/etc/nginx/nginx.conf",      },      {        hostpath: "/root/app/certs",        containerpath: "/certs",      },    ],    command: ["nginx", "-g", "daemon off;"],    networksadvanced: [{ name: dockernetworkpublic.id }],    restart: "always",    ports: [      {        external: 443,        internal: 443,      },    ],    healthcheck: {      tests: ["cmd", "service", "nginx", "status"],      interval: "30s",      timeout: "5s",      retries: 5,      startperiod: "10s",    },  },  { provider: dockerserverhetzner, dependson: [dockerappcontainer] });return { ip: server.ipv4address };

部署并验证 nginx 容器是否正在运行:

pnpm sst deploysst ❍ ion 0.1.90  ready!➜  app:        next-self-hosted   stage:      antonprudkohliad~  deploy|  deleted     docker container - app build docker:index:container|  created     command - ensure app/certs directory command:remote:command|  created     command - ensure app directory command:remote:command|  created     docker container - app build docker:index:container|  created     copy - certificates - cert command:remote:copytoremote (1.2s)|  created     copy - nginx config command:remote:copytoremote (1.2s)|  created     copy - certificates - key command:remote:copytoremote (1.2s)|  created     copy - certificates - authenticated origin pull command:remote:copytoremote (1.2s)|  deleted     docker container - app docker:index:container|  created     docker container - app docker:index:container (1.2s)|  created     docker container - nginx docker:index:container (7.1s)✓  complete   ip: 116.203.183.180ssh root@116.203.183.180 -i ./id_ed25519_hetzner -o stricthostkeychecking=no -c "docker ps -a"container id   image                                      command                  created         status                     ports                          names9c2cb18db304   nginx:1.27.0-bookworm                      "/docker-entrypoint.…"   3 minutes ago   up 3 minutes (healthy)     80/tcp, 0.0.0.0:443->443/tcp   app_container_nginx32e6a4cee8bc   next-self-hosted/next-self-hosted:latest   "docker-entrypoint.s…"   4 minutes ago   up 3 minutes               3000/tcp                       appf0c50aa32493   next-self-hosted/next-self-hosted:latest   "docker-entrypoint.s…"   4 minutes ago   exited (0) 3 minutes ago                                  app_container_build

可以看到,nginx 和应用程序运行顺利。

最后检查

是时候确保 dns 记录指向正确的 ip 地址了(是的,也可以通过 cloudflare 提供商将其添加到 sst 配置中):

dns settings – cloudflare ui

dns 设置 – cloudflare ui

然后,我们可以打开应用程序并验证它是否有效:

如何使用 SST 和 Docker 将 Nextjs 应用程序部署到 Hetzner VPS

浏览器中的应用程序

恭喜!我们现在已经完成了 sst 潜水,可以享受新部署的应用程序了?

清理

sst 使得清理变得非常容易 – 只需运行 pnpm sst remove ,整个设置就会消失:

pnpm sst removeSST ❍ ion 0.1.90  ready!➜  App:        next-self-hosted   Stage:      antonprudkohliad~  Remove|  Deleted     Docker Container - Nginx docker:index:Container (1.9s)|  Deleted     Docker Container - App docker:index:Container|  Deleted     Docker Container - App Build docker:index:Container|  Deleted     Docker Image - App - Hetzner docker:index:Image|  Deleted     Docker Volume - App Build docker:index:Volume (2.1s)|  Deleted     Docker Network - Public docker:index:Network (3.1s)|  Deleted     Docker Network - Internal docker:index:Network (3.2s)|  Deleted     Copy - Nginx Config command:remote:CopyToRemote|  Deleted     Docker Server - Hetzner pulumi:providers:docker|  Deleted     Copy - Certificates - Authenticated Origin Pull command:remote:CopyToRemote|  Deleted     Command - Ensure app/certs directory command:remote:Command|  Deleted     Copy - Certificates - Key command:remote:CopyToRemote|  Deleted     Command - Ensure app directory command:remote:Command|  Deleted     Copy - Certificates - Cert command:remote:CopyToRemote|  Deleted     Server hcloud:index:Server (16.8s)|  Deleted     SSH Key - Hetzner hcloud:index:SshKey|  Deleted     SSH Key - Local tls:index:PrivateKey✓  Removed

以上就是如何使用 SST 和 Docker 将 Nextjs 应用程序部署到 Hetzner VPS的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1490313.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
使用 Nextjs 构建中间件
上一篇 2025年12月19日 13:05:41
掌握 JavaScript:了解调用、应用和绑定
下一篇 2025年12月19日 13:05:53

相关推荐

  • 开源免费PHP工具 PHP开发效率提升利器

    推荐开源免费PHP开发工具以提升效率:VS Code、Sublime Text轻量高效,PhpStorm专业强大;调试用Xdebug、Kint、Ray;依赖管理选Composer;代码质量工具包括PHPStan、Psalm、PHP_CodeSniffer;数据库管理可用%ignore_a_1%MyA…

    2026年5月10日
    000
  • 怎么在PHP代码中实现图片上传功能_PHP图片上传功能实现与安全处理教程

    首先创建含enctype的HTML表单,再用PHP接收文件,检查目录、移动临时文件,验证类型与大小,生成唯一文件名,并调整php.ini限制以确保上传成功。 如果您尝试在PHP项目中添加图片上传功能,但服务器无法正确接收或保存文件,则可能是由于表单配置、文件处理逻辑或安全限制的问题。以下是实现该功能…

    2026年5月10日
    300
  • Python命令怎样使用profile分析脚本性能 Python命令性能分析的基础教程

    使用Python的cProfile模块分析脚本性能最直接的方式是通过命令行执行python -m cProfile your_script.py,它会输出每个函数的调用次数、总耗时、累积耗时等关键指标,帮助定位性能瓶颈;为进一步分析,可将结果保存为文件python -m cProfile -o ou…

    2026年5月10日
    000
  • c++如何实现UDP通信_c++基于UDP的网络通信示例

    UDP通信基于套接字实现,适用于实时性要求高的场景。1. 流程包括创建套接字、绑定地址(接收方)、发送(sendto)与接收(recvfrom)数据、关闭套接字;2. 服务端监听指定端口,接收客户端消息并回传;3. 客户端发送消息至服务端并接收响应;4. 跨平台需处理Winsock初始化与库链接,编…

    2026年5月10日
    100
  • 谷歌浏览器如何截图 谷歌浏览器页面截图技巧

    谷歌浏览器如何截图 谷歌浏览器页面截图技巧谷歌浏览器如何截图 谷歌浏览器页面截图技巧谷歌浏览器如何截图 谷歌浏览器页面截图技巧谷歌浏览器如何截图 谷歌浏览器页面截图技巧

    使用谷歌浏览器的开发者工具截图步骤:1. 按ctrl+shift+i(windows/linux)或cmd+option+i(mac)打开开发者工具。2. 点击右上角三个点,选择”更多工具”,再选择”截图”。3. 选择截取整个页面。推荐的谷歌浏览器扩展…

    2026年5月10日 用户投稿
    100
  • JavaScript计算器开发:解决数值显示与初始化问题

    本教程深入探讨了使用JavaScript构建计算器时常见的数值显示异常问题,特别是由于类属性未初始化导致的`Cannot read properties of undefined`错误。我们将详细分析问题根源,并通过在构造函数中调用初始化方法来解决该问题,同时优化显示逻辑,确保计算器功能稳定且界面显…

    2026年5月10日
    000
  • NextAuth getToken 在服务端返回 null 的问题排查与解决

    问题描述 在使用 Next.js 和 NextAuth 构建应用程序时,有时需要在服务端获取用户的身份验证信息。getToken 函数是 NextAuth 提供的一个便捷方法,用于从请求中提取 JWT (JSON Web Token)。然而,在某些情况下,尤其是在使用 getServerSidePr…

    2026年5月10日
    000
  • pycharm解析器怎么添加 解析器添加详细流程

    在pycharm中添加解析器的步骤包括:1) 打开pycharm并进入设置,2) 选择project interpreter,3) 点击齿轮图标并选择add,4) 选择解析器类型并配置路径,5) 点击ok完成添加。添加解析器后,选择合适的类型和版本,配置环境变量,并利用解析器的功能提高开发效率。 在…

    2026年5月10日
    100
  • HTML文档如何工作?如何编辑HTML格式文件?

    HTML文档如何工作?如何编辑HTML格式文件?HTML文档如何工作?如何编辑HTML格式文件?HTML文档如何工作?如何编辑HTML格式文件?HTML文档如何工作?如何编辑HTML格式文件?

    浏览器解析和渲染html的过程包括:1. 解析html构建dom树;2. 结合css构建渲染树;3. 布局计算元素位置;4. 绘制像素到屏幕。编辑html可使用记事本、vs code、sublime text等文本或代码编辑器,其中vs code因语法高亮、自动补全和插件生态成为主流选择。标准htm…

    2026年5月10日 用户投稿
    100
  • 一台服务器上如何同时运行多个UWSGI服务避免冲突?

    多UWSGI服务部署方案:利用Docker实现服务器资源隔离 本文探讨如何在单台服务器上安全运行多个UWSGI服务,避免服务冲突。 问题在于,即使端口不同,两个UWSGI服务(例如:san和san_test)也可能发生冲突,后启动的服务覆盖之前的服务。 理想情况下,san_test应该持续运行,而s…

    2026年5月10日
    000
  • GolangWeb项目异常捕获与日志记录

    答案:通过中间件使用defer和recover捕获panic,结合zap等结构化日志库记录请求链路信息,为每个请求生成trace ID,实现异常捕获与可追踪日志,提升系统稳定性与可观测性。 在Go语言Web项目中,异常捕获与日志记录是保障系统稳定性和可维护性的关键环节。Go本身没有像其他语言那样的t…

    2026年5月10日
    100
  • Python官网用户调查的参与方式_Python官网反馈提交详细教程

    答案是通过访问Python官网新闻页面、邮件邀请链接或GitHub仓库提交反馈。具体为:访问官网查找用户调查公告,或点击邮件中的专属链接参与,在GitHub的cpython仓库提交技术建议,并注意如实填写问卷与保护隐私。 如果您希望参与Python官网的用户调查并提交反馈,可以通过官方指定的渠道完成…

    2026年5月10日
    300
  • 我有时使用 awk 而不是 Python 的四个原因

    Python 是一门强大的编程语言,但在某些特定场景下,Awk 的优势更为显著,尤其体现在可移植性、生命周期、代码简洁性和与其他工具的互操作性方面。 Python 脚本通常具有良好的可移植性,但并非总能在所有环境中完美运行,例如流行的 Docker 基础镜像 (如 Debian 和 Alpine)。…

    2026年5月10日
    000
  • JavaScript Electron桌面应用

    答案:使用JavaScript开发%ignore_a_1%桌面应用需结合Web技术与Node.js,通过主进程管理窗口、渲染进程展示界面,并利用IPC通信,调用系统功能如文件对话框,最后用electron-builder打包发布,注意安全与进程职责分离。 用JavaScript开发Electron桌…

    2026年5月10日
    100
  • Go语言连接外部MySQL数据库:DSN配置与常见错误解析

    本文详细阐述了go语言使用`go-sql-driver/mysql`驱动连接外部mysql数据库的正确方法。重点介绍了数据源名称(dsn)的规范格式,特别是主机地址部分的配置,以避免常见的“getaddrinfow: the specified class was not found.”等网络解析错…

    2026年5月10日
    000
  • php超过字数怎么解密_用PHP分段处理超字数加密数据并解密教程【技巧】

    分段解密超长加密数据需先确定算法限制,再通过OpenSSL扩展支持,编写函数逐段解密并拼接结果。1、明确加密算法与密钥对应的分段大小;2、启用php.ini中openssl扩展并重启服务;3、自定义函数读取私钥、base64解码密文、循环截取块解密;4、确保去除密文换行符并按原加密块大小切分;5、解…

    2026年5月10日
    000
  • Tensorflow 音乐预测

    在本文中,我展示了如何使用张量流来预测音乐风格。在我的示例中,我比较了电子音乐和古典音乐。 你可以在我的github上找到代码:https://github.com/victordalet/sound_to_partition i – 数据集 第一步,您需要创建一个数据集文件夹,并在里面…

    2026年5月10日
    000
  • PHP代码注入检测日志分析_PHP代码注入日志检测方法详解

    答案:日志分析是发现PHP代码注入的关键手段,主要通过Web服务器访问日志、PHP错误日志、PHP-FPM日志及应用自定义日志等多源数据,结合grep、ELK、WAF等工具识别含eval()、system()、Base64编码、目录遍历等特征的异常请求,并建立基线、设置检测规则与自动化告警,配合事件…

    2026年5月10日
    000
  • Linux文件系统iostat命令使用技巧

    Linux文件系统iostat命令使用技巧Linux文件系统iostat命令使用技巧Linux文件系统iostat命令使用技巧Linux文件系统iostat命令使用技巧

    iostat是Linux系统中用于监控I/O设备负载的关键工具,能分析磁盘性能并识别瓶颈。默认输出包括CPU使用率和设备I/O统计,分为系统启动以来的平均值和当前采样周期数据。核心指标有:%util反映设备利用率,持续接近100%可能表示I/O瓶颈;await为平均I/O等待时间,过高说明响应变慢;…

    2026年5月10日 用户投稿
    000
  • 如何测试html5编码_测试HTML5页面编码兼容性方法【编码测试】

    HTML5页面编码兼容性测试需五步:一查meta charset是否正确且前置;二验HTTP响应头Content-Type charset是否为utf-8;三用file或chardet工具探测实际编码;四跨浏览器测试URL参数中中文、Emoji解析;五通过W3C验证服务检查编码声明与字节一致性。 如…

    2026年5月10日
    100

发表回复

登录后才能评论
关注微信