fix: 서버 k3s/Traefik 인프라에 맞춰 매니페스트 재작성
Build & Deploy / build-and-deploy (push) Failing after 11s

- image: Gitea registry → 서버 로컬 registry(localhost:5000)로 변경
- Service: ClusterIP + Ingress → NodePort(30200/30201) + Traefik docker dynamic 파일
- deploy/traefik-dynamic.yml: /opt/docker/traefik/dynamic/insurance.yml 배치용
- scripts/deploy-remote.sh: 서버 수동 배포 스크립트 (build→push→k3s apply→traefik 설정)
- legacy ingress.yaml / ingressroute-traefik.yaml 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
chpark
2026-04-23 00:44:05 +09:00
parent f78949c21a
commit ff18784983
8 changed files with 145 additions and 113 deletions
+73
View File
@@ -0,0 +1,73 @@
#!/usr/bin/env bash
set -e
export KUBECONFIG=/home/chpark/.kube/config
SUDO="echo qlalfqjsgh11 | sudo -S"
cd /home/chpark
if [ -d insurance ]; then
echo "[*] Updating insurance repo"
cd insurance && git pull origin master
else
echo "[*] Cloning insurance repo"
git clone https://git.junggomoa.com/chpark/insurance.git
cd insurance
fi
echo "[*] Building web image"
docker build \
--build-arg EXPO_PUBLIC_API_BASE=https://api.insurance.junggomoa.com \
-t localhost:5000/insurance/web:latest \
-f Dockerfile .
echo "[*] Building api image"
docker build -t localhost:5000/insurance/api:latest -f server/Dockerfile server
echo "[*] Pushing to local registry"
docker push localhost:5000/insurance/web:latest
docker push localhost:5000/insurance/api:latest
echo "[*] Applying Kubernetes manifests"
kubectl apply -f deploy/k8s/namespace.yaml
POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-$(openssl rand -hex 24)}"
JWT_SECRET="${JWT_SECRET:-$(openssl rand -hex 32)}"
kubectl -n insurance create secret generic postgres-credentials \
--from-literal=username=insurance \
--from-literal=password="$POSTGRES_PASSWORD" \
--dry-run=client -o yaml | kubectl apply -f -
kubectl -n insurance create secret generic api-secrets \
--from-literal=jwtSecret="$JWT_SECRET" \
--from-literal=databaseUrl="postgresql://insurance:${POSTGRES_PASSWORD}@postgres:5432/insurance?schema=public" \
--dry-run=client -o yaml | kubectl apply -f -
kubectl apply -f deploy/k8s/postgres.yaml
kubectl -n insurance rollout status statefulset/postgres --timeout=180s
kubectl apply -f deploy/k8s/api.yaml
kubectl -n insurance rollout restart deployment/insurance-api || true
kubectl -n insurance rollout status deployment/insurance-api --timeout=240s
kubectl apply -f deploy/k8s/deployment.yaml
kubectl apply -f deploy/k8s/service.yaml
kubectl -n insurance rollout restart deployment/insurance-web || true
kubectl -n insurance rollout status deployment/insurance-web --timeout=180s
echo "[*] Installing Traefik dynamic routing"
eval "$SUDO cp deploy/traefik-dynamic.yml /opt/docker/traefik/dynamic/insurance.yml"
eval "$SUDO chmod 644 /opt/docker/traefik/dynamic/insurance.yml"
echo "[*] Saving secrets for reuse"
cat > /home/chpark/.insurance-secrets <<EOF
POSTGRES_PASSWORD=$POSTGRES_PASSWORD
JWT_SECRET=$JWT_SECRET
EOF
chmod 600 /home/chpark/.insurance-secrets
echo ""
echo "===== DEPLOY STATUS ====="
kubectl -n insurance get pods,svc
echo ""
echo "🚀 Web: https://insurance.junggomoa.com"
echo "🔌 API: https://api.insurance.junggomoa.com"
+36
View File
@@ -0,0 +1,36 @@
const { Client } = require('ssh2');
const HOST = process.env.SSH_HOST || '183.99.177.40';
const PORT = Number(process.env.SSH_PORT || 22);
const USER = process.env.SSH_USER || 'chpark';
const PASS = process.env.SSH_PASS || 'qlalfqjsgh11';
async function run(cmd, { silent = false } = {}) {
return new Promise((resolve, reject) => {
const conn = new Client();
let stdout = '';
let stderr = '';
conn
.on('ready', () => {
conn.exec(cmd, (err, stream) => {
if (err) { conn.end(); return reject(err); }
stream.on('close', (code) => { conn.end(); resolve({ code, stdout, stderr }); })
.on('data', (data) => { const s = data.toString(); stdout += s; if (!silent) process.stdout.write(s); })
.stderr.on('data', (data) => { const s = data.toString(); stderr += s; if (!silent) process.stderr.write(s); });
});
})
.on('error', reject)
.connect({ host: HOST, port: PORT, username: USER, password: PASS, readyTimeout: 30000 });
});
}
module.exports = { run };
if (require.main === module) {
const cmd = process.argv.slice(2).join(' ');
if (!cmd) {
console.error('usage: node ssh-run.js <command>');
process.exit(1);
}
run(cmd).then(r => process.exit(r.code)).catch(e => { console.error(e.message); process.exit(1); });
}