[CLAUDE] Scripts: update cho SQLEXPRESS instance + Invoke-Sqlcmd (no sqlcmd.exe binary needed)
- setup-sql-db.ps1: Server=.\SQLEXPRESS default, dung Invoke-Sqlcmd (SqlServer PS module) voi credential + TrustServerCertificate - appsettings.Production.json.example: Server=.\SQLEXPRESS (voi escaped backslash JSON) - DB_CONNECTION Gitea secret da update (qua API) VPS Windows Server 2022 minimal, co VIETREPORT da chay 4 site, SQL instance SQLEXPRESS. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -1,42 +1,54 @@
|
|||||||
# Setup SQL Server DB cho SOLUTION_ERP trên VPS chia sẻ với VIETREPORT.
|
# Setup SQL Server DB cho SOLUTION_ERP trên VPS chia sẻ với VIETREPORT.
|
||||||
# Tạo database + grant quyền cho user vrapp (đã có sẵn trên server).
|
# Tạo database + grant quyền cho user vrapp (đã có sẵn trên server).
|
||||||
|
# Dùng Invoke-Sqlcmd (PowerShell SqlServer module) — không cần sqlcmd.exe binary.
|
||||||
# Idempotent: chạy lại không phá gì.
|
# Idempotent: chạy lại không phá gì.
|
||||||
#
|
#
|
||||||
# Usage (chạy trên VPS với admin privilege):
|
# Usage (chạy trên VPS với admin privilege):
|
||||||
|
# Install-Module SqlServer -Force -Scope AllUsers # 1 lần duy nhất nếu chưa có
|
||||||
# .\setup-sql-db.ps1 -SaPassword 'your-sa-password'
|
# .\setup-sql-db.ps1 -SaPassword 'your-sa-password'
|
||||||
#
|
#
|
||||||
# Prereq:
|
# Prereq:
|
||||||
# - SQL Server cài sẵn
|
# - SQL Server cài sẵn (mặc định instance SQLEXPRESS)
|
||||||
# - Login vrapp đã tồn tại (dùng chung với VIETREPORT)
|
# - Login vrapp đã tồn tại (dùng chung với VIETREPORT)
|
||||||
# - sqlcmd CLI available (đi kèm SQL Server)
|
# - Module SqlServer installed
|
||||||
|
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory=$true)] [string]$SaPassword,
|
[Parameter(Mandatory=$true)] [string]$SaPassword,
|
||||||
[string]$Server = ".",
|
[string]$Server = ".\SQLEXPRESS",
|
||||||
[string]$Database = "SolutionErp",
|
[string]$Database = "SolutionErp",
|
||||||
[string]$AppUser = "vrapp"
|
[string]$AppUser = "vrapp"
|
||||||
)
|
)
|
||||||
|
|
||||||
$ErrorActionPreference = 'Stop'
|
$ErrorActionPreference = 'Stop'
|
||||||
|
Import-Module SqlServer -ErrorAction Stop
|
||||||
|
|
||||||
function Invoke-Sql($query) {
|
$secureSa = ConvertTo-SecureString $SaPassword -AsPlainText -Force
|
||||||
$output = sqlcmd -S $Server -U sa -P $SaPassword -Q $query -b 2>&1
|
$creds = New-Object System.Management.Automation.PSCredential('sa', $secureSa)
|
||||||
if ($LASTEXITCODE -ne 0) {
|
|
||||||
throw "SQL fail (exit $LASTEXITCODE):`n$output"
|
function Invoke-Sql($query, [switch]$NoDb) {
|
||||||
|
$params = @{
|
||||||
|
ServerInstance = $Server
|
||||||
|
Credential = $creds
|
||||||
|
Query = $query
|
||||||
|
TrustServerCertificate = $true
|
||||||
|
ErrorAction = 'Stop'
|
||||||
}
|
}
|
||||||
return $output
|
if (-not $NoDb) { $params.Database = 'master' }
|
||||||
|
Invoke-Sqlcmd @params
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Host "==> Check SQL Server reachable"
|
Write-Host "==> Check SQL Server reachable ($Server)"
|
||||||
Invoke-Sql "SELECT @@VERSION" | Select-Object -First 2
|
$ver = Invoke-Sql "SELECT @@VERSION AS V" -NoDb
|
||||||
|
Write-Host " $($ver.V -split '`n' | Select-Object -First 1)"
|
||||||
|
|
||||||
Write-Host "`n==> Check login '$AppUser' exists"
|
Write-Host "`n==> Check login '$AppUser' exists"
|
||||||
$check = Invoke-Sql "SELECT name FROM sys.sql_logins WHERE name = '$AppUser'"
|
$check = Invoke-Sql "SELECT name FROM sys.sql_logins WHERE name = '$AppUser'"
|
||||||
if ($check -notmatch $AppUser) {
|
if (-not $check -or $check.name -ne $AppUser) {
|
||||||
Write-Error "Login '$AppUser' KHONG ton tai. Tao tay truoc: CREATE LOGIN [$AppUser] WITH PASSWORD='...'"
|
Write-Warning "Login '$AppUser' KHONG ton tai. Tao truoc voi:"
|
||||||
exit 1
|
Write-Warning " Invoke-Sqlcmd -ServerInstance '$Server' -Credential <sa-cred> -Query `"CREATE LOGIN [$AppUser] WITH PASSWORD='...', CHECK_POLICY=OFF;`""
|
||||||
|
throw "Login vrapp missing"
|
||||||
}
|
}
|
||||||
Write-Host " OK"
|
Write-Host " OK ($AppUser exists)"
|
||||||
|
|
||||||
Write-Host "`n==> Create database '$Database' (if not exists)"
|
Write-Host "`n==> Create database '$Database' (if not exists)"
|
||||||
Invoke-Sql @"
|
Invoke-Sql @"
|
||||||
@ -49,7 +61,7 @@ ELSE PRINT 'Database $Database already exists';
|
|||||||
"@
|
"@
|
||||||
|
|
||||||
Write-Host "`n==> Grant db_owner cho '$AppUser' tren '$Database'"
|
Write-Host "`n==> Grant db_owner cho '$AppUser' tren '$Database'"
|
||||||
Invoke-Sql @"
|
$grantQuery = @"
|
||||||
USE [$Database];
|
USE [$Database];
|
||||||
IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE name = '$AppUser')
|
IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE name = '$AppUser')
|
||||||
BEGIN
|
BEGIN
|
||||||
@ -61,14 +73,11 @@ ALTER ROLE db_owner ADD MEMBER [$AppUser];
|
|||||||
PRINT 'Added $AppUser to db_owner';
|
PRINT 'Added $AppUser to db_owner';
|
||||||
"@
|
"@
|
||||||
|
|
||||||
Write-Host "`n==> Verify kết nối với vrapp (test login)"
|
Invoke-Sqlcmd -ServerInstance $Server -Credential $creds -Database $Database -Query $grantQuery -TrustServerCertificate
|
||||||
Write-Host " (skip — tự test khi app chạy)"
|
|
||||||
|
|
||||||
Write-Host "`n==> Setup backup schedule"
|
|
||||||
Write-Host " Chạy: schtasks /Create /TN 'SolutionErp SQL Backup' /TR 'pwsh -File C:\solution-erp\scripts\backup-sql.ps1 -Server . -Database $Database' /SC DAILY /ST 02:00 /RU SYSTEM /F"
|
|
||||||
Write-Host " (hoặc tạo tay qua Task Scheduler)"
|
|
||||||
|
|
||||||
Write-Host "`n✅ SQL Server setup DONE" -ForegroundColor Green
|
Write-Host "`n✅ SQL Server setup DONE" -ForegroundColor Green
|
||||||
|
Write-Host " Server: $Server"
|
||||||
Write-Host " Database: $Database"
|
Write-Host " Database: $Database"
|
||||||
Write-Host " App user: $AppUser (db_owner)"
|
Write-Host " App user: $AppUser (db_owner)"
|
||||||
Write-Host " Connection string production: Server=localhost;Database=$Database;User Id=$AppUser;Password=***"
|
Write-Host " Connection string production:"
|
||||||
|
Write-Host " Server=$Server;Database=$Database;User Id=$AppUser;Password=***;MultipleActiveResultSets=true;TrustServerCertificate=true;Encrypt=true"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"Default": "Server=localhost;Database=SolutionErp;User Id=vrapp;Password=__SET_VIA_SECRETS__;MultipleActiveResultSets=true;TrustServerCertificate=true;Encrypt=true"
|
"Default": "Server=.\\SQLEXPRESS;Database=SolutionErp;User Id=vrapp;Password=__SET_VIA_SECRETS__;MultipleActiveResultSets=true;TrustServerCertificate=true;Encrypt=true"
|
||||||
},
|
},
|
||||||
"Jwt": {
|
"Jwt": {
|
||||||
"Issuer": "SolutionErp.Api",
|
"Issuer": "SolutionErp.Api",
|
||||||
|
|||||||
Reference in New Issue
Block a user