Docker 实验上手:用 Nginx 容器发布 HTML5 小游戏
为什么先用容器做这次实验
很多同学第一次上云,会直接在 ECS 里安装 Nginx,改完配置却说不清这台机器和昨天有什么差别。Docker 把运行环境收成镜像:同一份 Dockerfile,在笔记本、实验机和华为云 ECS 上拉起来的是同一套进程。
这篇只做三件事:页面能打开、改动能复现、出错知道看哪里。系统以 Ubuntu 22.04 为例,本机或弹性云服务器都可以。
1. 准备一个单文件 HTML5 小游戏
游戏故意不做构建工具,避免把「容器问题」和「前端工程问题」搅在一起。在空目录里创建 game/index.html,这是一个方向键接球的小游戏:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>接球实验</title>
<style>
body { margin:0; background:#0f172a; color:#e2e8f0; font-family:sans-serif;
display:flex; flex-direction:column; align-items:center; }
canvas { background:#1e293b; border-radius:8px; margin-top:16px; }
</style>
</head>
<body>
<h1>接球:方向键或 A/D 移动挡板</h1>
<p id="score">得分 0</p>
<canvas id="c" width="480" height="320"></canvas>
<script>
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
const scoreEl = document.getElementById('score');
let x = 200, ballX = 80, ballY = 20, vx = 3, vy = 3, score = 0;
const keys = {};
addEventListener('keydown', e => keys[e.key] = true);
addEventListener('keyup', e => keys[e.key] = false);
function loop() {
if (keys.ArrowLeft || keys.a) x -= 6;
if (keys.ArrowRight || keys.d) x += 6;
x = Math.max(0, Math.min(400, x));
ballX += vx; ballY += vy;
if (ballX < 0 || ballX > 464) vx *= -1;
if (ballY < 0) vy *= -1;
if (ballY > 300) {
if (ballX > x && ballX < x + 80) { score++; vy = -Math.abs(vy); ballY = 290; }
else { score = 0; ballY = 20; ballX = 80; }
scoreEl.textContent = '得分 ' + score;
}
ctx.clearRect(0, 0, 480, 320);
ctx.fillStyle = '#38bdf8';
ctx.beginPath(); ctx.arc(ballX, ballY, 8, 0, Math.PI * 2); ctx.fill();
ctx.fillStyle = '#f8fafc';
ctx.fillRect(x, 300, 80, 10);
requestAnimationFrame(loop);
}
loop();
</script>
</body>
</html>
浏览器直接打开这个文件,确认挡板能动、漏接会清分,再进容器。先在宿主机验证,能少一轮「到底是页面坏了还是 Nginx 没配对」。
2. 用官方 Nginx 镜像发布
同级写 Dockerfile,不要自己从 Ubuntu 开始装包,官方镜像已经处理了 pid、日志和默认站点:
FROM nginx:1.27-alpine
COPY game/ /usr/share/nginx/html/
EXPOSE 80
然后构建并映射到 8080,避免和宿主机已经占用的 80 端口打架:
docker build -t html5-game:lab .
docker run -d --name game -p 8080:80 html5-game:lab
curl -I 本机8080端口
返回 HTTP/1.1 200 OK 后,用浏览器访问 「公网地坁:8080」。安全组只放通实验来源 IP 的 TCP 8080,做完删除规则。不要为了图省事把 0.0.0.0/0 同时开在 22 和 8080 上。
3. 改页面时不要进容器里改文件
docker exec 进去改 html,容器一删改动就没了,下次 build 还是旧页面。实验阶段用只读挂卷确认是源文件问题还是镜像问题:
docker rm -f game
docker run -d --name game-dev -p 8080:80 \
-v "$PWD/game":/usr/share/nginx/html:ro \
nginx:1.27-alpine
挂载加上 :ro,避免容器内进程改掉你的源文件。页面确认后,再 docker build 把文件打进镜像,这样换一台机器 docker run 不依赖你笔记本上的目录。
4. 排错只看三处
- docker ps 里 STATUS 不是 Up:看 docker logs game。常见是 8080 已被占用,或 Dockerfile 在错误的目录执行。
- 本机 curl 通、浏览器不通:优先查安全组、弹性公网 IP 和本机防火墙,不是 Nginx 配置。
- 打开是 Nginx 欢迎页:多半是 COPY 把文件放到了 /usr/share/nginx/html/game/index.html,站点根目录没有 index.html。用 docker exec game ls -l /usr/share/nginx/html 核对。
日志在容器的标准输出里,docker logs --tail 50 game 就能看到访问记录,不必再进机器找 /var/log/nginx/access.log,除非你改过官方镜像的日志配置。
5. 实验结束怎么收场
docker rm -f game game-dev
docker image rm html5-game:lab
镜像留着会占系统盘。若这次是为了走完「容器发布静态资源」的闭环,建议记下四样东西:Dockerfile、安全组端口、一次失败时的 docker logs、以及 curl 的状态码。比只留一张首页截图更能复盘。
静态小游戏没有后端,先不要加数据库。访问链路稳定之后,再考虑把镜像推到 SWR,用固定 tag 而不是 latest,交给单机 compose 或 CCE。端口、挂载、只读这三件事搞清楚,比一次装很多组件更有收获。
- 点赞
- 收藏
- 关注作者
评论(0)