Files
AriWeb-Suite/docs/verification/portal-hal21-link-2026-10-27.md

14 KiB
Raw Permalink Blame History

포털·hostinger Node Agent 제어 평면 이전 기록 — hal.ariweb.net → hal21.ariweb.net (2026-10-27, Hera)

대상: hostinger(srv1953374, 187.53.133.173)의 Ariweb Portal 0.1.1(https://my.ariweb.net)과 Node Agent 의 제어 평면을 hostinger 구 HAL(hal.ariweb.net)에서 bear HAL21(https://hal21.ariweb.net)로 옮기고 실제 readback 으로 증명한 기록. Webmaker·포털 데이터·고객 계정·사이트·세션·DB·Vault·DNS·TLS·메일은 변경하지 않았다. 비밀값은 어디에도 출력하지 않았다(파이프로만 이동).

1. 리비전

항목 값
작업 시작 origin/main(rebase 뒤) 0b9c70e90c7278e895de54e75e3d07f706c703bf (Neo 의 Webmaker 연동 커밋 12958ab·0b9c70e 포함 확인, worktree clean)
코드 커밋 = 배포한 HAL / 등록 릴리스 dfb708e933e524894822719bce0169008285f4fd — HAL CLI config-set·module-deploy·job + 테스트 3건
릴리스 manifest version 0.1.1, mainCommit dfb708e…, testsPassed=true, dirty=false. artifact sha256: hal 4e419a7293dc5be07936db58c8cf70dc1c7972f52c11787a9455029eff677377 · portal 32c76a6047b2a7d74de0929c993984040cb1263044af2593abd399ed7daff04e(05:28Z 등록본과 동일) · agent cf2e52fe23496b126248b65d3bb7e94106db573559392bd20f365f1b970e315f · webmaker 9490b59dc1aca3d953f907bb7e5b447901a4558a7275913ffb1cb03e2c944caa · arimail b22868c08d2551e7d10891cd4858ee0525ac6529e6ece965881d601c20bde983
포털 코드 운영 포털(2026-10-26 14:30:42Z 설치, 빌드 3951be5)과 HEAD 의 portal/lib/lang/catalog 경로 diff 없음 → 같은 0.1.1 재배포(제어 평면 이전 목적)
HAL21 이전 /srv/ariweb/hal/releases/0.1.1-12958ab6952e(Neo 09:02Z 수동 설치, PID 1314165), bootstrap mainCommit 12958ab…, releases 행 main_commit 79b45ca…(등록부와 실행본 불일치)
HAL21 이후 /srv/ariweb/hal/releases/0.1.1-dfb708e933e5 → current, ariweb-hal 09:31:52Z 재시작(재시작→/api/health 1.11초, PID 1360348, NRestarts 0, instanceId hal_01a17cb3add236d2c112f3df1a), bootstrap mainCommit dfb708e…/artifact 4e419a72…, releases 행 0.1.1 approved(by hera-portal-link 09:31:51.753Z), config portalUrl http://127.0.0.1:8910 → https://my.ariweb.net(감사 config.update, actor cli:hera-portal-link)
hostinger 포털 /srv/ariweb/portal/releases/0.1.1(REVISION installedAt 2026-10-27T09:33:50.021Z, by master) → current; 이전 릴리스 0.1.1.prev-20261027093350 보존(.previous.json), 유닛 ariweb-portal PID 1500968(09:33:50Z), 127.0.0.1:8910
hostinger Agent /srv/ariweb/agent/releases/0.1.1-12958ab6952e(Neo 09:03Z) 그대로, ag_01a17c99f0102ce24409dc258a → https://hal21.ariweb.net, PID 1483523, NRestarts 0

2. 읽기 전용 preflight(09:13~09:18Z)

  • DNS my.ariweb.net A 187.53.133.173 — 1.1.1.1·8.8.8.8·권한 서버 ns1/ns2.hosting.co.kr(TCP) 일치. hal21.ariweb.net 121.152.149.45. hal.ariweb.net 공개 A 없음(hostinger /etc/hosts 127.0.0.1 매핑만). TLS my: CN=*.ariweb.net 만료 2027-01-13T07:57:11Z verify 0; hal21: CN=hal21.ariweb.net 만료 2027-01-25T02:03:16Z.
  • hostinger 유닛(모두 active/enabled, NRestarts 0): ariweb-hal PID 1059540(10-26 14:33:18Z) · ariweb-portal PID 1059582(14:33:19Z, cwd /srv/ariweb/portal/current) · ariweb-agent PID 1483523(10-27 09:04:12Z) · webmaker PID 1041361(14:00:23Z) · arihakdang-mail PID 1046648(14:09:30Z). 리스너 127.0.0.1:8900/8910/8790/3080, nginx 80/443. /etc/hosts: 127.0.0.1 hal.ariweb.net my.ariweb.net webmail.ariweb.net mail.arihakdang.com.
  • Agent(hostinger) 연결 HAL: 이미 hal21(Neo 09:03:45.729Z 재등록, label srv1953374 (mail+webmaker), drop-in 90-hal21-webmaker.conf). hal21 의 jobs/agent_jobs 0건. 구 HAL: server srv_01a178829d5848f93a15f93a17 status offline(last_seen 09:03:14.274Z), agent ag_01a178829f1c3d88381d2c0c75 active(heartbeat 없음), 열린 jobs 0·agent_jobs 0, module_targets 7(목표 0.1.1), 운영자 ariweb-ops 1, vault 3(service:agent, service:portal, service:hal).
  • 포털 config.json 값(비밀 아님): mailer·mailFrom·operatorEmail 만 → halUrl 은 코드 기본값 https://hal.ariweb.net(=/etc/hosts → 구 HAL). 포털 vault 이름 11: service:hal, service:portal, sso:webmaker, mailer:resend-key, arimail:* 7.
  • 포털 DB(portal.sqlite, wal): integrity ok, 표 53, users 7(active), groups 10, memberships 13, sites 3, domains 6, mail_services 4(cancelled), mail_servers 1, mailboxes 6, jobs 4(failed 2 backup.scheduled, needs_user 2 mail.activate), sessions 7(live 7), audit_log 71, mail_usage_log 899.
  • HAL21 DB: integrity ok; 서버 2 모두 ready(hostinger 승인 09:04:02.227Z by cli:neo-webmaker-link, jitsi 07:21:53.138Z by op_01a17bae6c0b70acd18b16f029), bootstrap complete 07:21:53.139Z(firstAgent ag_01a17bd7201c9a73c157e29968, manual_install_locked 1); agents 2 active; module_targets 12(hostinger: agent·arimail·backup·hal·observability·portal·webmaker 모두 actual 0.1.1 ok); 운영자 admin-hal 1(세션 live 1, 마지막 09:08:59Z — 다른 세션 소유); mail_services 7.
  • Webmaker baseline(scripts/webmaker-inventory.mjs, 읽기 전용): 회원 12(고유 9·SSO 3), 프로젝트 10(배포 3), 도메인 2, 연결 3; 포털 users 7·groups 10·sites 3(linked 3)·domains 6·mailServices 4; 판정 linked_consistent 3·unlinked_native 7, 충돌 0·누락 0. 공개 사이트 디렉터리 10.

3. 백업(Gate 2, root 0700/0600, git 밖, sha256sum -c OK, stage 추출·readback 검증)

hostinger /srv/ariweb/backups/pre-hal21-migrate-20261027T092204Z/ (RESTORE.md 먼저 작성, 경로 존재 검증 12/12 ok)

  • archive.tgz dca689d8c0fcb5d38455351b5db102e31a5d846b4f4735992627edfa7751bf63 (21 entries: portal/agent/hal data 의 config·vault.json·vault.key·agent.json·jobs, 유닛 3+drop-in, nginx ariweb-portal.conf·ariweb-hal.conf, /etc/hosts)
  • db.tgz d36000015028b6cea72173a8365cbd388f3b17c8b81e7daecb942dd0ac038e9c (VACUUM INTO 일관 사본: portal.sqlite 1,028,096 B integrity ok 53표 — 원본 db 1,032,192 / wal 4,140,632 / shm 32,768 B; hal.sqlite 888,832 B ok 25표)
  • code.tgz 7a9c56e39a63ad79706eaa046869e122c135bb0aa85f7420d74d3536b2f7c08e (296 entries: portal·agent·hal current 실경로 트리), meta.tgz 7be814eb0030d3ccfc4b1fe1e4d778f70e3a56868158ed5ce66805a4ded2b76c, RESTORE.md 3954ce32299bc51c86c6ccb6e3a157730d4de11ec862ea10c12e404d578b1300, portal-verify.json aa212574b7d3dc1c7266c456379a89b0a71e3e1bf2eb00cfe92f248aae953788, hal-verify.json 91c33cc8b0d6155bd481b02ca7258f4f589884bb841b4de07e6ed067106eee55
  • stage 검증: portalVault 11 · agentVault 1 · halVault 3 · agent.json id ag_01a17c99… · 사본 integrity ok/ok. bear /srv/ariweb/backups/hal-pre-portal-link-20261027T092207Z/
  • archive.tgz 97b880370d4a94a64d712ba63d8b5ea072a847f893bf977435a1160d6dbcc9ed (6), db.tgz 1deb62fdca1a77792c3367cb27668d297a4ec5d83e41c0d6c256d7c3b9425a32 (hal.sqlite 548,864 B ok 28표), code.tgz e543244242541faadb067e66e48db32c128fcecfe23d3b1a15c830abb1f6d9ba (80), meta.tgz 4c1078937387148e69ed602be66a528de14187eb04040d2908a7744a3c8cbe5c, RESTORE.md b1245a65fc82ad8a38866211a3cb261069bd77ef928725fc4921838dcc313ec6, hal-verify.json aebb63337c569abc821a9b88750b48d9cd0df45acedb80466c2d97f74135961f; stage 검증 halVault 2 · servers 2 · configKeys publicUrl,portalUrl. source: origin/main 0b9c70e… git bundle(작업 PC scratchpad, 0600) sha256 d55c924495b08337efb6fb1a3385bf5648a07b97231284f4d123bba2080e67eb + clone. 구 HAL 등록 Agent 데이터는 Neo 백업 /srv/ariweb/backups/agent-pre-hal21-20261027T090325Z(RESTORE.md 의 B 절차가 가리킴).

4. 적용(모두 지원 경로, 직접 SQL 없음)

  1. 09:31:51Z bear: register-release --manifest … --approve --by hera-portal-link(artifact 5개 복사·등록부 갱신) → bootstrap-release --version 0.1.1 --commit dfb708e… --sha256 4e419a72… → config-set --portalUrl https://my.ariweb.net(감사) → current 전환·ariweb-hal 재시작(1.11초). 재시작 구간 외부 프로브 8회: my=200·mail=200·hal21=200·sample=200 전부, webmaker 302×6/000×2(프로브 4초 타임아웃; 직후 5회 재확인 302, 0.29초 — hostinger 호스트라 HAL 재시작과 무관). 두 Agent heartbeat 재개(09:32:29Z·09:32:45Z).
  2. 09:33:44Z link-portal(bear vault service:portal·service:hal 09:33:45.756Z 갱신) → stdout 을 sed 로 값만 추려 ssh 파이프로 hostinger lib/vault.mjs 에 전달 → 포털 vault service:hal 09:33:46.334Z 교체(replacedExisting true), 구 연동의 미사용 이름 service:portal 제거. 값은 화면·로그·셸 변수에 없음(두 node 프로세스 사이 파이프만).
  3. 09:33:46Z 포털 config.set({publicUrl:'https://my.ariweb.net', halUrl:'https://hal21.ariweb.net'}, 'cli:hera-portal-link')(config.json 198→292 B, 0600; webmakerUrl·arimailUrl 기본값 유지).
  4. 09:33:47Z bear module-deploy --module portal --version 0.1.1 --servers srv_01a17bd4dbcdb55877f2d9fcab --by hera-portal-link --reason … → HAL 작업 j_01a17cb5716c669450412967f7(module.deploy, created_by cli:hera-portal-link, actor operator) → 자식 j_01a17cb5719cc5385804317f08(module.deploy.target) → Agent 작업 aj_01a17cb573916795ab7bc67a54(module.install, 09:33:49.009→09:33:52.775Z). 결과: actualVersion 0.1.1, previousVersion 0.1.1.prev-20261027093350, health ok(200, 10 ms), releaseDir /srv/ariweb/portal/releases/0.1.1, runUser master; 부모 done 09:33:53.325Z(precheck→fanout→collect, overall done 1/1). 감사 deploy.module.request·deploy.module. 포털 재시작 09:33:50Z(vault 교체 뒤 4초 — 그 사이 포털→HAL 호출 없음, 포털 journal 오류 0).

5. readback

  • HAL21 module_targets.portal(hostinger): target 0.1.1 · actual 0.1.1 · health ok · last_job j_01a17cb5719cc5385804317f08 · last_check 09:34:45Z(heartbeat 로 계속 갱신). agent_jobs 1(done). jobs 2(done). outbox 0(운영자 작업은 포털 이벤트를 만들지 않음).
  • Portal→HAL21 인증 읽기(09:35:09Z, 포털의 실제 portal/hal/client.mjs + 실제 config.json·vault 로): /portal/v1/health ok(version 0.1.1, instanceId hal_01a17cb3…, bootstrap complete, mainCommit dfb708e…) · /portal/v1/servers 2건(둘 다 ready/ok, hostinger modules webmaker·arimail·hal·portal·agent·observability·backup = 0.1.1/ok) · POST /portal/v1/servers/pick {role:web} → null(§7 blocker) · GET /portal/v1/jobs/j_01a17cb5716c… 200 · GET /portal/v1/jobs/j_none → job_not_found 404(작업 계약). bear nginx access log: 187.53.133.173 → 위 5요청 200/200/200/200/404, Agent heartbeat 67회/5분. HAL21 journal 오류 0(재시작 이후).
  • 바이트 보존(sha256, 배포 전=후): 유닛 ef800cf0…1e59(Agent 가 템플릿으로 다시 썼으나 내용 동일, diff 없음) · nginx ariweb-portal.conf d7e8e1c7…7167 · fullchain 6650b903…b780 · portal vault.key 6a6af7d6…0094 · agent.json 335cc9e2…b524 · agent vault.json 393fe23d…4d64 · /etc/hosts eafc0116…6c02. config.json a703ce78…→66fcb558…, vault.json 8b3598bc…→a7e9e8ae… 는 3·2단계의 의도된 변경(배포 자체는 data 디렉터리를 건드리지 않음). DB 원본 크기 동일(1,032,192/4,140,632/32,768).
  • 포털 DB 전후: integrity ok/ok, 표 53/53, 차이는 mail_usage_log 899→915(사용량 수집 주기 작업)뿐; users 7·groups 10·memberships 13·sites 3·domains 6·mail_services 4·mailboxes 6·jobs 4·sessions 7(live 7) 동일. vault 이름 11→10(service:portal 제거·service:hal 교체), config 키 +publicUrl·+halUrl.
  • Webmaker 전후 동일(회원 12·프로젝트 10·배포 3·연결 3, linked_consistent 3·unlinked_native 7, 충돌 0·누락 0, apply no-op), webmaker PID 1041361·NRestarts 0 유지, 공개 사이트 10. AriMail health ok 1.0.11 domains 6, webmail.ibit.kr ok domains 1.
  • 외부(09:35Z): my http→301 https, https / →302 /login, /login 200 로그인 · Ariweb 고객 포털, /api/health ok 0.1.1, TLS verify 0; hal21 /api/health ok·/ops/ 200·/portal/v1/health(무인증) 401; webmaker 302, sample 200, guide 200, mail.arihakdang.com 200, webmail.ibit.kr 200. 유닛 6개 active/enabled NRestarts 0, nginx -t 성공, journal 오류: 포털 0, Agent 1(09:31:52 HAL 재시작 중 502 1회), 구 HAL 0, webmaker 0, mail 0.
  • 구 HAL(hostinger): 계속 실행 중(PID 1059540)이나 서버 offline(last_seen 09:03:14Z, Agent heartbeat 없음), 열린 작업 0 — hostinger Agent 의 active owner 아님.

6. 테스트·빌드

node test/run.mjs 22파일 149건 통과·실패 0(코드 커밋 뒤 release build 안에서 1회, 문서 커밋 뒤 재실행). 신규 test/hal-cli.test.mjs 3건. scripts/release.mjs build/verify 통과(artifact 5개 ✔). bash -n deploy/*.sh 통과, shellcheck 미설치.

7. 되돌리기·blocker

  • 되돌리기: hostinger RESTORE.md(A 포털 연결만 → B Agent 구 HAL 복귀(Neo 백업) → C 구 HAL 데이터 → D 유닛·nginx·hosts), bear RESTORE.md(vault·config·DB 사본·current 0.1.1-12958ab6952e), 포털 코드 ln -sfn /srv/ariweb/portal/releases/0.1.1.prev-20261027093350 /srv/ariweb/portal/current && systemctl restart ariweb-portal, HAL 작업 되돌리기는 운영자 콘솔 모듈 되돌리기.
  • blocker/unknown: (1) hal21 운영자 자격 증명 없음 — 서버 승인·역할 변경·콘솔 readback 은 수행하지 않음(승인·부트스트랩은 이미 완료 상태를 readback). (2) hostinger 서버 행 role 이 mail(메일 가져오기 때 생성) → pickServer(web) null → 포털 관리형 사이트 신규 배포·백업 저장 대상이 없다. 운영자가 PATCH /ops/api/servers/srv_01a17bd4dbcdb55877f2d9fcab {role:'control'}(재인증 필요)로 바꿔야 한다. (3) 구 HAL ariweb-hal(hostinger)은 중지하지 않았다(폐기·보존은 사람 결정). /etc/hosts 의 hal.ariweb.net 매핑도 그대로. (4) Agent 의 3개 보존 정책으로 코드 디렉터리 0.1.1.prev-20261026141643 가 정리됨(데이터 아님). (5) HAL→포털 이벤트 경로(/internal/hal-events)는 포털 발 작업이 없어 실측하지 못함(portalUrl 은 설정됨). (6) jitsi 서버의 module_targets.webmaker actual null(Neo 작업 범위).