523 lines
19 KiB
Markdown
523 lines
19 KiB
Markdown
# 클라우드 서버 설정 가이드 (hz-prod-01)
|
||
|
||
> 시놀로지(Synology DSM)에서 클라우드 VPS(`178.104.200.7`)로 이전.
|
||
> 이 문서는 서버에서 실제 수집된 데이터 기반이며, 운영 하네스로 사용한다.
|
||
|
||
---
|
||
|
||
## 참조 인덱스
|
||
|
||
| # | 섹션 | 핵심 내용 |
|
||
|---|---|---|
|
||
| 1 | [서버 기본 정보](#1-서버-기본-정보) | 호스트명, IP, OS, CPU/RAM/디스크, 타임존 |
|
||
| 2 | [접속 정보](#2-접속-정보) | SSH 접속, 사용자, 인증 방식 |
|
||
| 3 | [소프트웨어 스택](#3-소프트웨어-스택) | Python, .NET, PG, Nginx, Docker Compose, fail2ban |
|
||
| 3.1 | [런타임](#31-런타임) | 버전/경로 일람 |
|
||
| 3.2 | [Python 가상 환경](#32-python-가상-환경) | `~/.venv`, `python3` 사용 규칙 |
|
||
| 3.3 | [주요 Python 패키지](#33-주요-python-패키지-시스템) | 시스템/venv 패키지 구분 |
|
||
| 4 | [서비스 아키텍처](#4-서비스-아키텍처) | 포트 맵, Nginx 리버스 프록시 |
|
||
| 4.1 | [포트 맵](#41-포트-맵) | 22, 80, 443, 2222, 3000, 5000, 5001, 5432 |
|
||
| 4.2 | [Nginx 리버스 프록시](#42-nginx-리버스-프록시) | 도메인 가상 호스트 기반 분기 |
|
||
| 5 | [Gitea](#5-gitea) | Docker Compose 설정, 시크릿, 데이터 경로 |
|
||
| 5.1 | [Docker Compose](#51-docker-compose) | `gitea:1.26.4`, PG 연동 |
|
||
| 5.2 | [시크릿 관리](#52-시크릿-관리) | `/opt/stacks/gitea/.env` |
|
||
| 5.3 | [데이터](#53-데이터) | Gitea 볼륨, `giteadb` |
|
||
| 6 | [Gitea Act Runner (CI)](#6-gitea-act-runner-ci) | 6× 러너, 네트워크, 구성 디렉토리 |
|
||
| 6.1 | [컨테이너 현황](#61-컨테이너-현황) | 러너 6개 실행 상태 |
|
||
| 6.2 | [러너 설정](#62-러너-설정) | `hz-prod-runner`, `gitea_default` 네트워크 |
|
||
| 6.3 | [러너 구성 디렉토리](#63-러너-구성-디렉토리) | `~/gitea-runner[-N]/` |
|
||
| 7 | [QuantEngine Blazor Admin](#7-quantengine-blazor-admin) | systemd, symlink 배포, DLL 구성 |
|
||
| 7.1 | [systemd 서비스](#71-systemd-서비스) | `quantengine.service` 전문 |
|
||
| 7.2 | [배포 구조](#72-배포-구조) | 타임스탬프 디렉토리 + symlink 교체 |
|
||
| 7.3 | [주요 DLL](#73-주요-dll) | Web, Core, Infrastructure, MudBlazor, Dapper |
|
||
| 8 | [PostgreSQL 18](#8-postgresql-18) | v18.4, `localhost` 바인드, Docker 연동 |
|
||
| 9 | [보안](#9-보안) | SSH hardening, UFW, fail2ban, 네트워크 격리 |
|
||
| 9.1 | [SSH 보안 설정](#91-ssh-보안-설정) | 공개키 전용, root 차단 |
|
||
| 9.2 | [UFW 방화벽](#92-ufw-방화벽) | `ENABLED=yes`, 포트 개방/차단 |
|
||
| 9.3 | [fail2ban](#93-fail2ban) | SSH 브루트포스 방어 |
|
||
| 9.4 | [Docker 네트워크 격리](#94-docker-네트워크-격리) | 로컬바인드 정책 |
|
||
| 10 | [디렉토리 맵](#10-디렉토리-맵) | `/home/kjh2064/`, `/opt/stacks/`, `/opt/backups/` |
|
||
| 11 | [시놀로지 → 클라우드 마이그레이션 매핑](#11-시놀로지--클라우드-마이그레이션-매핑) | 항목별 구↔신 비교표 |
|
||
| 12 | [운영 명령 치트시트](#12-운영-명령-치트시트) | 서비스 관리, 배포, 러너 등록, SSH |
|
||
| 13 | [검증 하네스](#13-검증-하네스) | 헬스체크, 엔드포인트, 마이그레이션 체크리스트 |
|
||
|
||
### 관련 문서 상호 참조
|
||
|
||
| 문서 | 역할 |
|
||
|---|---|
|
||
| [`AGENTS.md`](../AGENTS.md) | 운영 헌법, Directory Routing 인덱스 |
|
||
| [`GITEA_SECRETS_SETUP.md`](GITEA_SECRETS_SETUP.md) | Gitea 시크릿 설정/검증 가이드 |
|
||
| [`ROADMAP_WBS.md`](ROADMAP_WBS.md) | `.gs → Python` 및 `xlsx → sqlite` WBS |
|
||
| [`docs/GITEA_TOKEN_HOME_RUNBOOK.md`](GITEA_TOKEN_HOME_RUNBOOK.md) | Gitea 토큰 관리 런북 |
|
||
| [`spec/00_execution_contract.yaml`](../spec/00_execution_contract.yaml) | 실행 계약 원본 권위 |
|
||
| [`governance/agents_index.yaml`](../governance/agents_index.yaml) | 거버넌스 규칙 인덱스 |
|
||
|
||
---
|
||
|
||
## 1. 서버 기본 정보
|
||
|
||
| 항목 | 값 |
|
||
|---|---|
|
||
| **호스트명** | `hz-prod-01` |
|
||
| **IP** | `178.104.200.7` |
|
||
| **OS** | Ubuntu 26.04 LTS (Resolute Raccoon) |
|
||
| **커널** | `7.0.0-22-generic` (x86_64, PREEMPT_DYNAMIC) |
|
||
| **CPU** | AMD EPYC-Rome, 2 vCPU |
|
||
| **메모리** | 3.7 GiB (사용 ~958 MiB, 가용 ~2.8 GiB) |
|
||
| **스왑** | 2.0 GiB |
|
||
| **디스크** | `/dev/sda1` 38 GB (사용 8.5 GB / 28 GB 가용, 24%) |
|
||
| **타임존** | `Asia/Seoul` (KST, +0900), NTP 동기화 활성 |
|
||
|
||
## 2. 접속 정보
|
||
|
||
| 항목 | 값 |
|
||
|---|---|
|
||
| **SSH 접속** | `ssh kjh2064@178.104.200.7` |
|
||
| **SSH 포트** | 22 (기본) |
|
||
| **사용자** | `kjh2064` (uid=1000) |
|
||
| **그룹** | `kjh2064`, `sudo`, `users`, `docker` |
|
||
| **인증 방식** | 공개키 전용 (`PasswordAuthentication no`) |
|
||
| **Root 로그인** | 비활성 (`PermitRootLogin no`) |
|
||
| **Max Auth Tries** | 3 |
|
||
| **Keep-Alive** | `ClientAliveInterval 300`, `ClientAliveCountMax 2` |
|
||
|
||
## 3. 소프트웨어 스택
|
||
|
||
### 3.1. 런타임
|
||
|
||
| 소프트웨어 | 버전 | 경로 |
|
||
|---|---|---|
|
||
| **Python** | 3.14.4 | `/usr/bin/python3` |
|
||
| **.NET SDK** | 10.0.109 | `/usr/lib/dotnet/sdk` |
|
||
| **.NET Runtime** | ASP.NET Core 10.0.9 + NETCore 10.0.9 | `/usr/lib/dotnet/shared/` |
|
||
| **PostgreSQL** | 18.4 | `postgresql@18-main.service` |
|
||
| **Nginx** | 시스템 패키지 | `nginx.service` |
|
||
| **Docker Compose** | v5.2.0 | Docker 플러그인 |
|
||
| **fail2ban** | 1.1.0 | `fail2ban.service` |
|
||
|
||
### 3.2. Python 가상 환경
|
||
|
||
```
|
||
경로: ~/.venv
|
||
Python: 3.14.4
|
||
```
|
||
|
||
> **주의**: 이 서버에서는 `python3`을 사용한다 (시놀로지/Windows와 다름).
|
||
> CI 워크플로우와 로컬 서버 모두 `python3`을 사용하므로 통일됨.
|
||
|
||
### 3.3. 주요 Python 패키지 (시스템)
|
||
|
||
boto3, cryptography, Jinja2, jsonschema, fail2ban 등 시스템 레벨로 설치됨.
|
||
프로젝트 의존성은 `~/.venv`에 별도 관리.
|
||
|
||
## 4. 서비스 아키텍처
|
||
|
||
### 4.1. 포트 맵
|
||
|
||
| 포트 | 서비스 | 바인드 | 비고 |
|
||
|---|---|---|---|
|
||
| **22** | SSH | `0.0.0.0` | 공개키 전용 |
|
||
| **80** | Nginx (HTTP) | `0.0.0.0` | 443 HTTPS로 리다이렉트 |
|
||
| **443** | Nginx (HTTPS) | `0.0.0.0` | SSL 가상 호스트 진입점 |
|
||
| **2222** | Gitea SSH | `0.0.0.0` | Git SSH 접속 |
|
||
| **3000** | Gitea Web | `127.0.0.1` | Nginx 프록시 경유 (`gitea.taxbaik.com`) |
|
||
| **5000** | QuantEngine Blazor | `127.0.0.1` | Nginx 프록시 경유 (`quant.taxbaik.com`) |
|
||
| **5001** | TaxBaik 홈페이지 | `127.0.0.1` | Nginx 프록시 경유 (`taxbaik.com` / `www.taxbaik.com`) |
|
||
| **5432** | PostgreSQL | `127.0.0.1` + `172.17.0.1` | 로컬 + Docker 네트워크 |
|
||
|
||
### 4.2. Nginx 리버스 프록시
|
||
|
||
도메인 기반 가상 호스트(Virtual Host) 방식을 사용하여 각 도메인 요청을 내부 서비스로 연결하고, SSL(HTTPS)을 필수로 적용합니다. HTTP(80) 포트 요청은 자동으로 HTTPS(443)로 리다이렉트됩니다.
|
||
|
||
상세 Nginx 설정 백업은 `deploy/nginx-taxbaik-domains.conf`에 위치합니다.
|
||
|
||
#### 가상 호스트 설정 개요
|
||
- **TaxBaik 홈페이지** (`https://taxbaik.com`, `https://www.taxbaik.com`) ➜ `http://127.0.0.1:5001/taxbaik/`
|
||
- **Gitea (코드 저장소)** (`https://gitea.taxbaik.com`) ➜ `http://127.0.0.1:3000`
|
||
- **QuantEngine (Blazor Admin)** (`https://quant.taxbaik.com`) ➜ `http://127.0.0.1:5000/`
|
||
|
||
**라우팅 요약**:
|
||
- `https://taxbaik.com` & `https://www.taxbaik.com` ➜ TaxBaik 홈페이지 (통합 앱)
|
||
- `https://gitea.taxbaik.com` ➜ Gitea Web UI
|
||
- `https://quant.taxbaik.com` ➜ QuantEngine Blazor Admin
|
||
- `ssh://git@gitea.taxbaik.com:2222` ➜ Gitea Git SSH
|
||
|
||
## 5. Gitea
|
||
|
||
### 5.1. Docker Compose
|
||
|
||
```yaml
|
||
# /opt/stacks/gitea/docker-compose.yml
|
||
services:
|
||
gitea:
|
||
image: docker.gitea.com/gitea:1.26.4
|
||
container_name: gitea
|
||
restart: unless-stopped
|
||
extra_hosts:
|
||
- "host.docker.internal:host-gateway"
|
||
environment:
|
||
USER_UID: "1000"
|
||
USER_GID: "1000"
|
||
GITEA__database__DB_TYPE: postgres
|
||
GITEA__database__HOST: host.docker.internal:5432
|
||
GITEA__database__NAME: giteadb
|
||
GITEA__database__USER: gitea
|
||
GITEA__database__PASSWD: "${GITEA_DB_PASSWORD}"
|
||
GITEA__server__DOMAIN: "${SERVER_IP}"
|
||
GITEA__server__ROOT_URL: "http://${SERVER_IP}/"
|
||
GITEA__server__SSH_DOMAIN: "${SERVER_IP}"
|
||
GITEA__server__SSH_PORT: "2222"
|
||
GITEA__security__INSTALL_LOCK: "true"
|
||
GITEA__service__DISABLE_REGISTRATION: "true"
|
||
volumes:
|
||
- ./gitea:/data
|
||
- /etc/timezone:/etc/timezone:ro
|
||
- /etc/localtime:/etc/localtime:ro
|
||
ports:
|
||
- "127.0.0.1:3000:3000"
|
||
- "2222:22"
|
||
```
|
||
|
||
### 5.2. 시크릿 관리
|
||
|
||
- `.env` 파일: `/opt/stacks/gitea/.env` (소유자 전용, `600`)
|
||
- 포함 변수: `GITEA_DB_PASSWORD`, `SERVER_IP`
|
||
|
||
### 5.3. 데이터
|
||
|
||
- Gitea 데이터: `/opt/stacks/gitea/gitea/`
|
||
- DB: PostgreSQL `giteadb` (Docker → host.docker.internal:5432 경유)
|
||
|
||
## 6. Gitea Act Runner (CI)
|
||
|
||
### 6.1. 컨테이너 현황
|
||
|
||
| 이름 | 이미지 | 상태 |
|
||
|---|---|---|
|
||
| `gitea-runner` | `gitea/act_runner:latest` | 실행 중 |
|
||
| `gitea-runner-2` | `gitea/act_runner:latest` | 실행 중 |
|
||
| `gitea-runner-3` | `gitea/act_runner:latest` | 실행 중 |
|
||
| `hopeful_galileo` | `gitea/act_runner:latest` | 실행 중 |
|
||
| `jovial_bouman` | `gitea/act_runner:latest` | 실행 중 |
|
||
| `upbeat_chatelet` | `gitea/act_runner:latest` | 실행 중 |
|
||
|
||
> 총 6개 러너가 활성 상태. 네트워크는 `gitea_default` Docker 네트워크 사용.
|
||
|
||
### 6.4. CI / 배포 분리
|
||
|
||
- `.gitea/workflows/ci.yml`: 검증 전용. 스펙/공식/리포트/아티팩트 생성까지만 수행한다.
|
||
- `.gitea/workflows/snapshot_admin_deploy.yml`: 실배포 전용. `dotnet publish` 후 `tools/deploy_quantengine.sh`를 이용해 `/home/kjh2064/quantengine_active`로 반영한다.
|
||
- 공개 URL `/quant/` 갱신은 `snapshot_admin_deploy.yml`의 성공 여부를 기준으로 판단한다.
|
||
|
||
### 6.2. 러너 설정
|
||
|
||
```yaml
|
||
# ~/gitea-runner/config.yaml
|
||
container:
|
||
network: "gitea_default"
|
||
```
|
||
|
||
- 러너 이름: `hz-prod-runner`
|
||
- 러너 UUID: `d6d9120b-5070-4874-88d7-b86fe817d5a0`
|
||
- 러너 이미지: `docker.gitea.com/runner-images:ubuntu-latest` (2.33 GB)
|
||
|
||
### 6.3. 러너 구성 디렉토리
|
||
|
||
```
|
||
~/gitea-runner/ # 1번 러너
|
||
~/gitea-runner-2/ # 2번 러너
|
||
~/gitea-runner-3/ # 3번 러너
|
||
```
|
||
|
||
## 7. QuantEngine Blazor Admin
|
||
|
||
### 7.1. systemd 서비스
|
||
|
||
```ini
|
||
# /etc/systemd/system/quantengine.service
|
||
[Unit]
|
||
Description=Quant Engine Blazor Admin Web App (.NET 10)
|
||
After=network.target
|
||
|
||
[Service]
|
||
WorkingDirectory=/home/kjh2064/quantengine_active
|
||
ExecStart=/usr/bin/dotnet /home/kjh2064/quantengine_active/QuantEngine.Web.dll
|
||
Restart=always
|
||
RestartSec=10
|
||
KillSignal=SIGINT
|
||
SyslogIdentifier=quantengine
|
||
User=kjh2064
|
||
Environment=ASPNETCORE_ENVIRONMENT=Production
|
||
Environment=ASPNETCORE_URLS=http://127.0.0.1:5000
|
||
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
```
|
||
|
||
### 7.2. 배포 구조
|
||
|
||
```
|
||
~/quantengine_active → ~/deployments/quantengine_20260625_182821 (symlink)
|
||
~/deployments/
|
||
├── quantengine_20260625_155649/
|
||
├── quantengine_20260625_164548/
|
||
├── quantengine_20260625_164928/
|
||
└── quantengine_20260625_182821/ ← 현재 활성
|
||
```
|
||
|
||
**배포 방식**: 타임스탬프 디렉토리 생성 → symlink 교체 → `systemctl restart quantengine`
|
||
|
||
### 7.3. 주요 DLL
|
||
|
||
- `QuantEngine.Web.dll` — 웹 진입점
|
||
- `QuantEngine.Core.dll` — 핵심 도메인
|
||
- `QuantEngine.Application.dll` — 애플리케이션 서비스
|
||
- `QuantEngine.Infrastructure.dll` — 인프라 (DB, 외부 연동)
|
||
- `Npgsql.dll` — PostgreSQL 드라이버
|
||
- `MudBlazor.dll` — UI 컴포넌트
|
||
- `Dapper.dll` — 마이크로 ORM
|
||
|
||
## 8. PostgreSQL 18
|
||
|
||
| 항목 | 값 |
|
||
|---|---|
|
||
| **버전** | 18.4 (Ubuntu 패키지) |
|
||
| **서비스** | `postgresql@18-main.service` |
|
||
| **listen_addresses** | `localhost` (기본값, 로컬 전용) |
|
||
| **바인드** | `127.0.0.1:5432`, `172.17.0.1:5432` (Docker), `[::1]:5432` |
|
||
| **Gitea DB** | `giteadb` (사용자: `gitea`) |
|
||
|
||
> Docker 컨테이너는 `host.docker.internal:5432`로 호스트 PG에 접속.
|
||
> `listen_addresses`는 `postgresql.conf`에서 기본값 `localhost`로 설정됨 (외부 접속 차단).
|
||
|
||
## 9. 보안
|
||
|
||
### 9.1. SSH 보안 설정
|
||
|
||
```
|
||
PermitRootLogin no
|
||
PasswordAuthentication no
|
||
PubkeyAuthentication yes
|
||
KbdInteractiveAuthentication no
|
||
X11Forwarding no
|
||
MaxAuthTries 3
|
||
ClientAliveInterval 300
|
||
ClientAliveCountMax 2
|
||
```
|
||
|
||
### 9.2. UFW 방화벽
|
||
|
||
- **상태**: `ENABLED=yes` (`/etc/ufw/ufw.conf`)
|
||
- **로그 레벨**: `low`
|
||
- **외부 개방 포트**: 22 (SSH), 80 (HTTP), 443 (HTTPS), 2222 (Gitea SSH)
|
||
- **내부 전용**: 3000 (Gitea Web), 5000 (QuantEngine), 5001 (TaxBaik Web), 5432 (PostgreSQL)
|
||
|
||
> 상세 규칙 확인: `sudo ufw status numbered` (TTY + sudo 비밀번호 필요)
|
||
|
||
### 9.3. fail2ban
|
||
|
||
- `fail2ban.service` 활성 상태
|
||
- SSH 브루트포스 방어 활성
|
||
|
||
### 9.4. Docker 네트워크 격리
|
||
|
||
- Gitea Web: `127.0.0.1:3000` (로컬 전용)
|
||
- QuantEngine: `127.0.0.1:5000` (로컬 전용)
|
||
- TaxBaik Web: `127.0.0.1:5001` (로컬 전용)
|
||
- PostgreSQL: `127.0.0.1` + Docker bridge (`172.17.0.1`)
|
||
- 외부 노출: SSH(22), HTTP(80), HTTPS(443), Gitea SSH(2222)만 개방
|
||
|
||
## 10. 디렉토리 맵
|
||
|
||
```
|
||
/home/kjh2064/
|
||
├── quantengine_active → deployments/quantengine_YYYYMMDD_HHMMSS (symlink)
|
||
├── deployments/ # QuantEngine 배포 히스토리
|
||
│ └── quantengine_YYYYMMDD_HHMMSS/
|
||
│ └── wwwroot/
|
||
├── gitea-runner/ # Gitea Act Runner 1
|
||
├── gitea-runner-2/ # Gitea Act Runner 2
|
||
├── gitea-runner-3/ # Gitea Act Runner 3
|
||
├── apps/ # 추가 앱
|
||
│ └── python-test/.venv/
|
||
├── .venv/ # Python 3.14 가상 환경
|
||
├── tmp/ # 임시 작업
|
||
└── .ssh/ # SSH 키
|
||
|
||
/opt/stacks/
|
||
├── gitea/
|
||
│ ├── docker-compose.yml
|
||
│ ├── .env # GITEA_DB_PASSWORD, SERVER_IP
|
||
│ └── gitea/ # Gitea 데이터 볼륨
|
||
└── dotnet-app/ # .NET 관련
|
||
|
||
/opt/backups/ # 백업
|
||
```
|
||
|
||
## 11. 시놀로지 → 클라우드 마이그레이션 매핑
|
||
|
||
| 항목 | 시놀로지 (구) | 클라우드 (신) |
|
||
|---|---|---|
|
||
| **프로젝트 경로** | `/volume1/projects/data_feed` | 미배치 (TBD) |
|
||
| **Python** | `python3` (시스템) | `python3` (`/usr/bin/python3`, 3.14.4) |
|
||
| **Gitea** | Docker on DSM | Docker on Ubuntu (`gitea:1.26.4`) |
|
||
| **Gitea SSH** | 포트 변동 | `2222` 고정 |
|
||
| **CI Runner** | Synology Act Runner | 6× `act_runner:latest` (Docker) |
|
||
| **DB** | SQLite (파일 기반) | PostgreSQL 18 + SQLite (하이브리드) |
|
||
| **웹 Admin** | 없음 | QuantEngine Blazor (.NET 10, MudBlazor) |
|
||
| **리버스 프록시** | Synology 내장 | Nginx 도메인 가상 호스트 및 SSL (HTTPS) 적용 (`deploy/nginx-taxbaik-domains.conf`) |
|
||
| **보안** | DSM 방화벽 | fail2ban + SSH 공개키 + 서비스 로컬바인드 |
|
||
| **시크릿 관리** | `.secrets/kis_real.env` | `/opt/stacks/gitea/.env` |
|
||
| **OS** | Synology DSM 7.x | Ubuntu 26.04 LTS |
|
||
| **타임존** | (설정 의존) | `Asia/Seoul` (NTP 동기화) |
|
||
|
||
## 12. 운영 명령 치트시트
|
||
|
||
### 서비스 관리
|
||
|
||
```bash
|
||
# QuantEngine
|
||
sudo systemctl status quantengine
|
||
sudo systemctl restart quantengine
|
||
sudo journalctl -u quantengine -f
|
||
|
||
# Gitea
|
||
cd /opt/stacks/gitea && docker compose up -d
|
||
docker compose logs -f gitea
|
||
|
||
# Nginx
|
||
sudo systemctl reload nginx
|
||
sudo nginx -t
|
||
|
||
# PostgreSQL
|
||
sudo systemctl status postgresql@18-main
|
||
sudo -u postgres psql
|
||
|
||
# Docker 전체 상태
|
||
docker ps -a
|
||
```
|
||
|
||
### QuantEngine 배포
|
||
|
||
```bash
|
||
# 1. 새 배포 디렉토리 생성
|
||
DEPLOY_DIR=~/deployments/quantengine_$(date +%Y%m%d_%H%M%S)
|
||
mkdir -p "$DEPLOY_DIR"
|
||
|
||
# 2. 빌드 산출물 복사 (로컬에서 scp 또는 CI에서)
|
||
scp -r publish/* kjh2064@178.104.200.7:"$DEPLOY_DIR"/
|
||
|
||
# 3. symlink 교체
|
||
ln -sfn "$DEPLOY_DIR" ~/quantengine_active
|
||
|
||
# 4. 서비스 재시작
|
||
sudo systemctl restart quantengine
|
||
sudo systemctl status quantengine
|
||
```
|
||
|
||
### Gitea Act Runner 등록
|
||
|
||
```bash
|
||
# 새 러너 등록 (Gitea 웹 → Settings → Actions → Runners에서 토큰 복사)
|
||
docker run -d \
|
||
--name gitea-runner-N \
|
||
--restart unless-stopped \
|
||
--network gitea_default \
|
||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||
gitea/act_runner:latest
|
||
```
|
||
|
||
### SSH 접속 및 Git 원격 설정
|
||
|
||
```bash
|
||
# Windows 로컬에서 서버 SSH 접속
|
||
ssh kjh2064@178.104.200.7
|
||
|
||
# 로컬 프로젝트의 Git Remote URL 변경 (Gitea 도메인 기반 HTTPS 적용)
|
||
# 1) 현재 설정된 remote url 확인
|
||
git remote -v
|
||
# 2) 새로운 도메인 주소로 원격 URL 변경
|
||
git remote set-url origin https://gitea.taxbaik.com/kjh2064/QuantEngineByItz.git
|
||
|
||
# Gitea Git SSH 접속 (기존 2222 포트 유지)
|
||
git remote set-url origin ssh://git@gitea.taxbaik.com:2222/kjh2064/QuantEngineByItz.git
|
||
```
|
||
|
||
## 13. 검증 하네스
|
||
|
||
### 13.1. 서버 헬스 체크
|
||
|
||
```bash
|
||
ssh kjh2064@178.104.200.7 "
|
||
echo '=== Services ==='
|
||
systemctl is-active quantengine nginx docker postgresql@18-main fail2ban
|
||
echo '=== Docker ==='
|
||
docker ps --format '{{.Names}}: {{.Status}}'
|
||
echo '=== Disk ==='
|
||
df -h /
|
||
echo '=== Memory ==='
|
||
free -h | head -2
|
||
"
|
||
```
|
||
|
||
**기대 결과**:
|
||
- 5개 서비스 모두 `active`
|
||
- Docker 컨테이너 7개 (gitea + runner ×6) `Up`
|
||
- 디스크 사용률 < 80%
|
||
- 메모리 가용 > 1 GiB
|
||
|
||
### 13.2. 엔드포인트 접근 확인
|
||
|
||
```bash
|
||
# Gitea Web
|
||
curl -s -o /dev/null -w "%{http_code}" http://178.104.200.7/
|
||
# 기대: 200
|
||
|
||
# QuantEngine
|
||
curl -s -o /dev/null -w "%{http_code}" http://178.104.200.7/quant/
|
||
# 기대: 200
|
||
|
||
# Gitea SSH
|
||
ssh -T -p 2222 git@178.104.200.7 2>&1 | head -1
|
||
# 기대: "Hi there, ..." Gitea 응답
|
||
```
|
||
|
||
### 13.3. data_feed 프로젝트 마이그레이션 체크리스트
|
||
|
||
- [ ] 프로젝트 경로 결정 및 clone
|
||
- [ ] Python venv에 프로젝트 의존성 설치 (`pip install -r requirements.txt`)
|
||
- [ ] KIS 시크릿 설정 (`~/.secrets/kis_real.env`)
|
||
- [ ] crontab 또는 systemd timer 등록
|
||
- [ ] `GatherTradingData.json` 동기화 경로 확정
|
||
- [ ] SQLite canonical DB 경로 확정
|
||
- [ ] CI 워크플로우 러너 라벨 확인
|
||
- [ ] GAS 배포 스크립트 서버 경로 업데이트
|
||
|
||
---
|
||
|
||
## 14. 트러블슈팅 (Troubleshooting)
|
||
|
||
### 14.1. Certbot / APT 패키지 설치 시 Microsoft 리포지토리 404 오류
|
||
- **증상**: `sudo apt-get update` 실행 시 Microsoft 패키지 저장소에서 `404 Not Found` 에러가 발생하며 패키지 목록 갱신이 중단되고, 이로 인해 `certbot` 설치가 `sudo: certbot: command not found` 에러로 실패하는 현상.
|
||
- **원인**: Ubuntu 26.04 (Resolute) 환경에서 Microsoft의 잘못된 리포지토리(26.04 경로에 focal/20.04 릴리스가 설정된 상태)를 참조하여 발생.
|
||
- **해결 방안**:
|
||
1. 문제가 되는 Microsoft apt 소스 설정 파일을 삭제하거나 비활성화합니다.
|
||
```bash
|
||
sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
|
||
```
|
||
2. APT 패키지 목록을 다시 업데이트하고 Certbot 및 Nginx 플러그인을 설치합니다.
|
||
```bash
|
||
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
|
||
```
|
||
3. 인증서 발급 및 설정을 적용합니다.
|
||
```bash
|
||
sudo certbot --nginx -d taxbaik.com -d www.taxbaik.com -d gitea.taxbaik.com -d quant.taxbaik.com --register-unsafely-without-email --agree-tos --non-interactive
|
||
```
|
||
|
||
---
|
||
|
||
> **수집 일시**: 2026-06-26 09:55 KST (추가 업데이트: 2026-07-01)
|
||
> **수집 방법**: `ssh kjh2064@178.104.200.7` 라이브 명령 및 트러블슈팅 사례 수집
|
||
> **provenance**: 모든 값은 서버 실시간 명령 출력 및 실제 오류 대처 조치 로그에서 추출. 임의 값 없음.
|