用 Docker + Nginx 部署一个纯静态 2048 小游戏:10 分钟上线的最小实践

举报
yd_236964775 发表于 2026/10/22 19:39:54 2026/10/22
【摘要】 纯静态 2048 小游戏上线的最小实践:用 Docker 打镜像、Nginx 做子路径托管,以及三个最容易踩的坑(相对路径、alias 斜杠、外部 curl 验证)。

写在前面

想做一个"点开就能玩"的小应用,第一反应是上云、买服务器、配 Nginx——其实对于纯静态的小游戏来说,这套流程里 90% 的成本都是浪费。今天这篇就把这件事压缩到最简:用一个静态 HTML 文件 + 一个 Dockerfile + Nginx 镜像,本地打包、丢到服务器、用 Nginx 托管在子路径下,全程不超过十分钟。

文章末尾会给出完整的文件内容和部署命令,读者可以照着做一遍。

一、为什么静态游戏值得单独托管

像 2048 这种小游戏,逻辑全在浏览器里,服务器只需要做一件事:把一个 index.html 正确地吐给用户。既然如此,架构上就没什么可设计的——没有数据库,没有后端进程,没有会话状态。

但"简单"不等于"随便"。实际部署时我踩过三个坑:

  • 子路径部署:如果你的应用挂在 /hc-activity/ 而不是根路径,资源引用必须写成相对路径,否则 JS、CSS 全部 404。
  • 缓存与版本:浏览器会缓存 index.html,改完代码刷新没变化,多半是缓存而不是部署失败。
  • 端口与占用:服务器上往往已经跑着别的服务,直接 docker run -p 80:80 很可能端口冲突,得先确认。

二、准备一个"能跑"的 2048

不用从零手写。2048 的实现到处都有,挑一个逻辑清晰、样式干净的版本,核心代码大致长这样:

const SIZE = 4;
let board, score;

function reset() {
  board = Array.from({ length: SIZE }, () => Array(SIZE).fill(0));
  score = 0;
  addTile(); addTile();
}

function addTile() {
  const empty = [];
  board.forEach((row, r) => row.forEach((v, c) => { if (!v) empty.push([r, c]); }));
  if (!empty.length) return;
  const [r, c] = empty[Math.floor(Math.random() * empty.length)];
  board[r][c] = Math.random() < 0.9 ? 2 : 4;
}

把移动、合并、判定结束这几件事补齐,套上 CSS 网格布局,一个可玩的小游戏就成型了。关键的一点是所有资源都内联在同一个 HTML 文件里,或者用相对路径引用同目录下的资源——这是后面子路径部署能成立的前提。

三、Dockerfile:只有三行也有意义

静态站点的 Dockerfile 确实很短:

FROM nginx:alpine
COPY index.html /usr/share/nginx/html/index.html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

虽然只有三行,但用容器仍然有几个实在的好处:

  • 本地和线上跑的是同一份 nginx,配置行为一致,不会出现"我这儿好好的,上线就 404";
  • 换版本只要改 FROM 那一行,运维成本接近零;
  • 服务器上不需要装 Nginx,卸载只需要 docker rm 加删镜像,干净。

构建和运行也很直接:

docker build -t game2048 .
docker run -d --name game2048 -p 8080:80 game2048
curl -sI http://127.0.0.1:8080/ | head -1   # 期望 HTTP/1.1 200 OK

四、放到服务器的子路径下

如果服务器上 80 端口已经被 Nginx 占用(大概率如此),就不要去抢端口,而是把静态文件交给现有的 Nginx。做法是:

# 1. 启动一个只做文件托管的容器,把目录挂出来
docker run -d --name game2048-files -v /srv/game2048:/usr/share/nginx/html:ro nginx:alpine

# 2. 在宿主机 Nginx 里加一段 location
location /hc-activity/ {
    alias /srv/game2048/;
    index index.html;
    try_files $uri $uri/ /hc-activity/index.html;
}

这里的 alias 末尾那个斜杠很容易踩坑:alias 指向的目录必须带结尾斜杠,location 路径也必须以斜杠结尾,否则会出现路径拼接错位。

改完配置先验证再 reload:

nginx -t && nginx -s reload

五、从外部验证,别只信本地

很多"部署成功"其实是假象——容器起来了,但安全组没放行 80,外部访问依然不通。所以最后一定要从外面打一次:

curl -sI http://<公网IP>/hc-activity/index.html | head -1

看到 200 OK 才算真的完成。这一步能同时暴露端口未放行、Nginx 配置未生效、文件没挂进去三类问题。

如果返回 404,排查顺序是:容器内有没有文件(docker exec game2048-files ls /usr/share/nginx/html)→ location 路径和 alias 斜杠 → 页面内部资源是否用了绝对路径(把 /js/app.js 改成 js/app.js 试试)。

六、小结

整个过程其实只有三个关键决策:资源用相对路径、子路径用 alias 而不是 root、用外部 curl 验证。这三条记住了,把任何纯静态站点搬到服务器上都是十分钟内的事。

下一步想让它更有意思,可以加一个服务端计分排行榜(用 KV 存储或者最简单的文件写入),或者把部署过程写成一条 CI 流水线,推代码即上线。工具越简单,越值得把精力放在玩法本身。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。