🚀 從零打造自己的 AWS 股票看盤網站:EC2 + Ubuntu + Docker + Nginx + Node.js + K 線
最近想自己做一個可以放在網路上使用的股票 Dashboard,所以乾脆從零開始架一台 AWS EC2,自己建立 Linux Server,再把 Docker、Nginx、Node.js 和股票 API 串起來。
最後做出來的東西包含:
- 🇹🇼 台股即時股價
- 🇺🇸 美股即時股價
- 📈 股票 K 線
- 🔍 股票查詢
- ➕ 網頁新增股票
- 🗑️ 網頁刪除股票
- 📝 記事本
- 🧮 計算機
- 🔄 自動更新
- 🌐 使用瀏覽器直接開啟
- 🐳 Docker Container 化
- 🔀 Nginx Reverse Proxy
而且整套不是架在自己的電腦,而是放在 AWS EC2 上。
一、先了解最後的架構
最後整個系統大概長這樣:
Internet │ ▼ ┌─────────────────┐ │ AWS EC2 │ │ Ubuntu │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Nginx │ │ :80 │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Node.js │ │ :3000 │ └────────┬────────┘ │ ┌─────────┴─────────┐ ▼ ▼ Yahoo Finance 新聞 API API API │ ▼ 股票 / K線資料
使用者其實不需要知道 Node.js 的 3000 Port。
瀏覽器只需要:
http://EC2_PUBLIC_IP
Nginx 收到請求之後,再把 /api/... 的請求轉給 Node.js。
二、建立 AWS EC2
首先在 AWS 建立 EC2。
我選擇:
OS:Ubuntu 架構:64-bit
建立完成後會取得:
Public IPv4 Address
例如:
http://xxx.xxx.xxx.xxx
這個就是之後從 Windows 瀏覽器連進去的地址。
三、Windows 登入 Ubuntu
Windows 可以直接使用 SSH。
例如:
ssh -i "你的金鑰.pem" ubuntu@你的EC2_IP
成功後會看到類似:
ubuntu@ip-172-31-29-108:~$
這代表已經進入 AWS EC2。
四、第一次遇到的 Linux 權限問題
一開始執行:
apt update
結果出現:
Could not open lock file Permission denied
原因很簡單。
Ubuntu 一般使用者不能直接修改系統套件。
所以改成:
sudo apt update
以及:
sudo apt upgrade -y
這是一個很常見的 Linux 初學者問題。
五、安裝 Docker
接下來安裝 Docker。
安裝完成後確認:
docker --version
以及:
docker compose version
如果兩個都有版本號,就可以開始建立網站。
六、建立網站目錄
我把整個專案放在:
~/mywebsite
結構如下:
mywebsite/ │ ├── compose.yaml │ ├── nginx.conf │ ├── html/ │ └── index.html │ └── server/ ├── Dockerfile ├── package.json └── server.js
這樣前端和後端可以分開管理。
七、建立 Node.js API
Node.js 負責:
取得股票資料 ↓ 處理 Yahoo Finance API ↓ 提供自己的 API ↓ 讓前端呼叫
例如:
/api/quote /api/markets /api/chart /api/health
八、Dockerfile
Node.js 使用 Docker 包起來。
FROM node:22-alpine WORKDIR /app COPY package.json . RUN npm install --omit=dev COPY server.js . EXPOSE 3000 CMD ["node", "server.js"]
這樣 Node.js 就不需要直接安裝在 Ubuntu 主機上。
九、package.json
使用 Express:
{ "name": "market-api", "version": "1.0.0", "type": "module", "main": "server.js", "scripts": { "start": "node server.js" }, "dependencies": { "express": "^5.1.0" } }
十、第一次遇到 Docker 問題
一開始執行:
docker compose up -d --build
結果:
failed to read dockerfile: open Dockerfile: no such file or directory
這個錯誤其實非常直接。
Docker Compose 找不到:
server/Dockerfile
後來確認專案結構:
server/ ├── Dockerfile ├── package.json └── server.js
問題就解決了。
這也提醒了一件事情:
Docker 出錯時,不要只看最後一行,先確認檔案結構。
十一、股票 API
後端使用 Yahoo Finance Chart API 取得資料。
例如:
AAPL NVDA MSFT TSLA
台股則可以使用:
2330.TW 2317.TW 2454.TW
台灣加權指數:
^TWII
美國主要指數:
^GSPC ^IXIC
十二、即時股價 API
自己建立:
/api/quote
例如:
curl "http://localhost/api/quote?symbol=AAPL"
API 回傳:
{ "success": true, "symbol": "AAPL", "price": 309.35, "previousClose": 311.3, "change": -1.95, "changePercent": -0.626, "currency": "USD" }
這樣前端就不用直接碰 Yahoo。
架構變成:
Browser ↓ Nginx ↓ Node.js ↓ Yahoo Finance
十三、最重要的 K 線 API
一開始網站可以看到股價,但是:
K 線完全沒有。
後來發現前端呼叫:
/api/chart
但是 Node.js 根本沒有這個 API。
所以瀏覽器得到:
Cannot GET /api/chart
這就是非常典型的:
前端已經寫好了,但後端沒有對應 API。
後來在 Node.js 加入:
/api/chart
讓它支援:
1d 5d 1mo 6mo 1y 5y
例如:
curl "http://localhost/api/chart?symbol=AAPL&range=1y"
成功之後會得到:
{ "success": true, "symbol": "AAPL", "range": "1y", "interval": "1d", "data": [ { "time": "...", "open": 300, "high": 305, "low": 298, "close": 303, "volume": 123456 } ] }
前端再把這些資料畫成 K 線。
十四、又遇到一個很有趣的 Docker 問題
有一次:
curl "http://localhost:3000/api/chart?symbol=AAPL&range=1y"
結果:
curl: (7) Failed to connect to localhost port 3000
但是:
docker compose ps
卻顯示:
market-api ... 3000/tcp
注意這兩個不是同一件事情。
3000/tcp
代表:
Container 裡面有 3000 Port
不代表:
EC2:3000
已經開放。
十五、直接從 Container 裡測試
於是改成:
docker compose exec market-api \ wget -qO- \ "http://127.0.0.1:3000/api/health"
結果:
{ "status": "ok", "service": "market-api" }
這就證明:
Node.js 本身是正常的。
而且:
Market API listening on 0.0.0.0:3000
也確認 Node.js 正在監聽:
0.0.0.0:3000
十六、為什麼最後不用開 AWS 3000 Port?
因為我們使用 Nginx。
外部:
Browser ↓ EC2 :80
Nginx:
:80
再轉:
market-api:3000
所以 AWS Security Group 只需要讓網站使用:
80
Node.js 的:
3000
不需要直接暴露給 Internet。
這樣反而比較安全。
十七、Nginx 的角色
Nginx 在這個專案裡做兩件事。
第一:
提供 HTML
第二:
Reverse Proxy
例如:
/api/chart
會被轉給:
market-api:3000
而:
/
則直接提供:
html/index.html
十八、最後做出 Dashboard
前端最後整合:
┌────────────────────────────────────────┐ │ 📊 Market Dashboard │ ├────────────────────────────────────────┤ │ │ │ 🇹🇼 台股 │ │ │ │ 台積電 2330.TW +...% │ │ 鴻海 2317.TW +...% │ │ 聯發科 2454.TW -...% │ │ │ ├────────────────────────────────────────┤ │ │ │ 🇺🇸 美股 │ │ │ │ AAPL Apple +...% │ │ NVDA NVIDIA +...% │ │ MSFT Microsoft +...% │ │ TSLA Tesla -...% │ │ │ ├────────────────────────────────────────┤ │ │ │ 📈 AAPL │ │ │ │ 1D 5D 1M 6M 1Y 5Y │ │ │ │ 🕯️ K線圖 │ │ │ └────────────────────────────────────────┘
十九、增加網頁直接管理股票
後來又增加:
+ 新增股票
以及:
刪除
例如直接輸入:
NVDA NVIDIA
就可以新增。
股票清單則存在:
localStorage
因此不需要每次修改 Server。
二十、記事本
又加入一個簡單的記事本:
📝 我的記事本
可以記錄:
今天觀察台積電 AAPL 等待回檔 NVDA 注意成交量
資料存在瀏覽器的:
localStorage
二十一、計算機
Dashboard 裡面也加入:
🧮 計算機
支援:
+ - × ÷ % ()
所以看股票的時候可以直接計算:
100 × 1.08
或:
300000 × 0.05
二十二、目前完成的系統
到目前為止,這個小專案已經變成:
AWS EC2 │ └── Ubuntu │ └── Docker │ ├── Nginx │ │ │ └── HTML Dashboard │ └── Node.js │ ├── /api/health ├── /api/quote ├── /api/markets └── /api/chart │ └── Yahoo Finance
這已經不是單純的 HTML 網頁,而是一個真正的:
前端 + API Server + Reverse Proxy + Docker + Cloud Server
的小型 Web Application。
二十三、後來又準備加入即時新聞
下一步準備加入:
📰 即時新聞
架構會變成:
Browser ↓ Nginx ↓ Node.js ├── Yahoo Finance │ └── News API
新聞 API Key 不直接放在 HTML,而是放在 Docker 的:
.env
例如:
GNEWS_API_KEY=xxxxxxxx
這樣比較不容易把 API Key 直接暴露在前端。
二十四、這次最大的收穫
這次最大的收穫其實不是做出一個股票網站。
而是第一次完整走過:
Cloud ↓ Linux ↓ Docker ↓ Nginx ↓ Node.js ↓ API ↓ Frontend ↓ External API
每一層都有可能出問題。
例如:
Linux 權限
Permission denied
解決:
sudo apt update
Docker 找不到 Dockerfile
open Dockerfile: no such file or directory
解決:
確認專案目錄結構
Node API 不存在
Cannot GET /api/chart
解決:
增加 /api/chart
Container Port 問題
localhost:3000 Connection refused
解決:
docker compose exec
直接從 Container 裡確認 Node.js。
最後確認 API
docker compose exec market-api \ wget -qO- \ "http://127.0.0.1:3000/api/health"
看到:
{ "status": "ok", "service": "market-api" }
那一刻就代表:
我的 Node.js API 真的跑起來了。
二十五、下一步可以做到什麼?
目前這個架構還可以繼續往下發展。
例如:
☑ 台股 ☑ 美股 ☑ 即時報價 ☑ K線 ☑ Docker ☑ Nginx ☑ AWS EC2 ☑ 股票新增/刪除 ☑ 記事本 ☑ 計算機 ⬜ 即時新聞 ⬜ HTTPS ⬜ 自訂網域 ⬜ 使用者登入 ⬜ 個人自選股 ⬜ PostgreSQL / MySQL ⬜ Redis Cache ⬜ 股票價格警報 ⬜ Telegram / LINE 通知 ⬜ 財報資訊 ⬜ 技術指標
到這裡,就可以開始把它從「自己玩的股票 Dashboard」,慢慢變成一個真正的個人投資資訊平台。
結語
這次最大的感覺是:
自己架 Server 沒有想像中難。
真正困難的是第一次遇到錯誤時,不知道問題到底在:
AWS? Linux? Docker? Nginx? Node.js? API? 前端?
但只要一層一層拆開測試,其實就能慢慢找到問題。
例如:
docker compose ps
看 Container。
docker compose logs
看 Node.js。
curl
測 API。
docker compose exec
直接進 Container 測試。
這幾個指令,對之後維護 Docker Server 會非常常用。
最後從一台空白的 AWS Ubuntu:
AWS EC2 ↓ Ubuntu ↓ Docker ↓ Nginx ↓ Node.js ↓ Yahoo Finance ↓ 股票 Dashboard
一路做到可以直接用瀏覽器看台美股與 K 線。
這就是自己從零架一個 Web Application 最有趣的地方。 🚀
沒有留言:
張貼留言