feat: add .gitignore and apps/template for new apps
This commit is contained in:
55
apps/template/README.md
Normal file
55
apps/template/README.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# 新增應用範本
|
||||
|
||||
## 使用步驟
|
||||
|
||||
1. **複製範本**
|
||||
```bash
|
||||
cp -r apps/template apps/your-app
|
||||
```
|
||||
|
||||
2. **替換佔位符**
|
||||
- `{{APP_NAME}}` → 應用名稱(如 `myapp`)
|
||||
- `{{IMAGE}}` → Docker 映像(如 `nginx`)
|
||||
- `{{TAG}}` → 版本標籤(如 `1.25`)
|
||||
- `{{PORT}}` → 容器端口(如 `80`)
|
||||
- `{{HOST}}` → 網域名稱(如 `app.example.com`)
|
||||
- `{{SIZE}}` → 儲存大小(如 `10Gi`)
|
||||
- `{{DATA_MOUNT_PATH}}` → 資料掛載路徑
|
||||
|
||||
3. **權限設定**
|
||||
```bash
|
||||
chmod +x apps/your-app/*.sh
|
||||
```
|
||||
|
||||
4. **部署**
|
||||
```bash
|
||||
cd apps/your-app
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
## 目錄結構
|
||||
|
||||
```
|
||||
apps/your-app/
|
||||
├── manifests/ # K8s YAML 檔案
|
||||
│ ├── app-deployment.yaml
|
||||
│ ├── app-pvc.yaml
|
||||
│ ├── app-ingress.yaml
|
||||
│ └── app-service.yaml
|
||||
├── deploy.sh # 部署腳本
|
||||
├── stop.sh # 停止腳本
|
||||
├── status.sh # 狀態檢查
|
||||
├── backup.sh # 備份腳本
|
||||
└── backup/ # 備份檔案目錄
|
||||
```
|
||||
|
||||
## 常見調整
|
||||
|
||||
### 有資料庫的應用
|
||||
在 `manifests/` 新增 `db-deployment.yaml`、`db-service.yaml`
|
||||
|
||||
### 需要密碼/金鑰
|
||||
在 `manifests/` 新增 `secret.yaml`(參考 `apps/codimd/manifests/01-codimd-secrets.yaml`)
|
||||
|
||||
### 需要特殊設定
|
||||
在 `manifests/` 新增 `configmap.yaml`
|
||||
30
apps/template/backup.sh
Executable file
30
apps/template/backup.sh
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
# 用途:備份 {{APP_NAME}} 資料
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
APP_NAME="{{APP_NAME}}"
|
||||
BASE_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
BACKUP_DIR="$BASE_DIR/backup"
|
||||
TIMESTAMP=$(date +%Y%m%d-%H%M)
|
||||
|
||||
echo "📦 備份 $APP_NAME..."
|
||||
|
||||
# 建立備份目錄
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# 取得 Pod 名稱
|
||||
POD=$(kubectl get pod -l "app=$APP_NAME" -o jsonpath="{.items[0].metadata.name}")
|
||||
|
||||
if [ -z "$POD" ]; then
|
||||
echo "❌ 找不到 $APP_NAME 的 Pod"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 備份 PVC 資料(範例:假設是檔案資料)
|
||||
echo "備份 PVC 資料..."
|
||||
kubectl exec $POD -- tar czf /tmp/backup.tar.gz {{DATA_MOUNT_PATH|/data}}
|
||||
kubectl cp $POD:/tmp/backup.tar.gz "$BACKUP_DIR/$APP_NAME-$TIMESTAMP.tar.gz"
|
||||
kubectl exec $POD -- rm /tmp/backup.tar.gz
|
||||
|
||||
echo "✅ 備份完成: $BACKUP_DIR/$APP_NAME-$TIMESTAMP.tar.gz"
|
||||
18
apps/template/deploy.sh
Executable file
18
apps/template/deploy.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
# 用途:部署 {{APP_NAME}} 到 K3s
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
BASE_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
MANIFESTS="$BASE_DIR/manifests"
|
||||
APP_NAME="{{APP_NAME}}"
|
||||
|
||||
echo "🚀 部署 $APP_NAME..."
|
||||
|
||||
# 依序套用 manifests(按檔名排序)
|
||||
kubectl apply -f "$MANIFESTS/"
|
||||
|
||||
echo "⏳ 等待 Pod 就緒..."
|
||||
kubectl rollout status deployment/$APP_NAME --timeout=120s
|
||||
|
||||
echo "✅ $APP_NAME 部署完成"
|
||||
55
apps/template/manifests/app-deployment.yaml
Normal file
55
apps/template/manifests/app-deployment.yaml
Normal file
@@ -0,0 +1,55 @@
|
||||
# Deployment 範本
|
||||
# 使用方式:複製此檔案,將 {{APP_NAME}} 替換為你的應用名稱
|
||||
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{APP_NAME}}
|
||||
namespace: default
|
||||
labels:
|
||||
app: {{APP_NAME}}
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: {{APP_NAME}}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: {{APP_NAME}}
|
||||
spec:
|
||||
containers:
|
||||
- name: {{APP_NAME}}
|
||||
image: {{IMAGE}}:{{TAG|latest}}
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{PORT|8080}}
|
||||
# 資源限制(建議設定)
|
||||
resources:
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "500m"
|
||||
requests:
|
||||
memory: "256Mi"
|
||||
cpu: "250m"
|
||||
# 健康檢查(可選)
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
volumeMounts:
|
||||
- name: data-vol
|
||||
mountPath: {{DATA_MOUNT_PATH|/data}}
|
||||
volumes:
|
||||
- name: data-vol
|
||||
persistentVolumeClaim:
|
||||
claimName: {{APP_NAME}}-pvc
|
||||
24
apps/template/manifests/app-ingress.yaml
Normal file
24
apps/template/manifests/app-ingress.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
# Ingress 範本 - Traefik
|
||||
# 使用方式:將 {{APP_NAME}}、{{HOST}} 替換為實際值
|
||||
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{APP_NAME}}-ingress
|
||||
labels:
|
||||
app: {{APP_NAME}}
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: web, websecure
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
rules:
|
||||
- host: {{HOST}}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{APP_NAME}}-service
|
||||
port:
|
||||
number: {{PORT|8080}}
|
||||
16
apps/template/manifests/app-pvc.yaml
Normal file
16
apps/template/manifests/app-pvc.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
# PVC 範本 - Longhorn 儲存
|
||||
# 使用方式:將 {{APP_NAME}} 替換為你的應用名稱
|
||||
# 儲存大小可調整:1Gi, 5Gi, 10Gi...
|
||||
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{APP_NAME}}-pvc
|
||||
namespace: default
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
storageClassName: longhorn
|
||||
resources:
|
||||
requests:
|
||||
storage: {{SIZE|5Gi}}
|
||||
18
apps/template/manifests/app-service.yaml
Normal file
18
apps/template/manifests/app-service.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
# Service 範本
|
||||
# 使用方式:將 {{APP_NAME}}、{{PORT}} 替換為實際值
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{APP_NAME}}-service
|
||||
namespace: default
|
||||
labels:
|
||||
app: {{APP_NAME}}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: {{APP_NAME}}
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: {{PORT|8080}
|
||||
31
apps/template/status.sh
Executable file
31
apps/template/status.sh
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env bash
|
||||
# 用途:檢查 {{APP_NAME}} 狀態
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
APP_NAME="{{APP_NAME}}"
|
||||
|
||||
echo "=== [ $APP_NAME 資源狀態 ] ==="
|
||||
echo ""
|
||||
|
||||
# 1. Pods
|
||||
echo "--- Pods ---"
|
||||
kubectl get pods -l "app=$APP_NAME" -o wide
|
||||
|
||||
echo ""
|
||||
|
||||
# 2. Services
|
||||
echo "--- Services ---"
|
||||
kubectl get svc -l "app=$APP_NAME"
|
||||
|
||||
echo ""
|
||||
|
||||
# 3. PVC
|
||||
echo "--- Storage (PVC) ---"
|
||||
kubectl get pvc | grep "$APP_NAME" || echo "無 PVC"
|
||||
|
||||
echo ""
|
||||
|
||||
# 4. Ingress
|
||||
echo "--- Access (Ingress) ---"
|
||||
kubectl get ingress -l "app=$APP_NAME" -o custom-columns=NAME:.metadata.name,HOSTS:.spec.rules[*].host,ADDRESS:.status.loadBalancer.ingress[*].ip
|
||||
15
apps/template/stop.sh
Executable file
15
apps/template/stop.sh
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
# 用途:停止 {{APP_NAME}}(保留資料)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
APP_NAME="{{APP_NAME}}"
|
||||
|
||||
echo "🛑 停止 $APP_NAME(保留 PVC 資料)..."
|
||||
|
||||
# 只刪除 Deployment 和 Service,PVC 會保留
|
||||
kubectl delete deployment/$APP_NAME --ignore-not-found
|
||||
kubectl delete service/$APP_NAME-service --ignore-not-found
|
||||
kubectl delete ingress/$APP_NAME-ingress --ignore-not-found
|
||||
|
||||
echo "✅ $APP_NAME 已停止,資料安全保留"
|
||||
Reference in New Issue
Block a user