Consolidated ASP Classic MVC framework from best components
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

8.9KB

IIS Deployment Guide

Deployment model

Production uses immutable release directories on the Windows host:

C:\inetpub\deployments\<site>\
  releases\
    <release-id>\
      app\
      core\
      db\
      public\        <- IIS physicalPath points here
      scripts\
      ...
  shared\
    public.web.config <- machine-owned configuration
  deployment-state.json

The complete repository is copied into each release. This is required because public/Default.asp includes files above public/, including ../core and ../app. IIS exposes only <release>\public; sibling source, scripts, tests, and database files are not web-root content.

Switching physicalPath from one release's public directory to another is the atomic-ish cutover. The app pool is recycled after the switch. If the smoke test fails, the installer restores the previous physical path and recycles again. The script does not stop the site for the normal copy/staging phase.

Why Gitea is not the runner

The repository server is Gitea 1.11.4, which predates Gitea Actions. Treat Gitea as the Git source only. Run scripts/deploy-iis-git.ps1 from one of:

  • a trusted external CI worker that checks out this repository;
  • a controlled operator workstation;
  • a separately managed scheduled task.

The worker must have Tailscale reachability and OpenSSH key-based access to webserver-1. No password, private key, database path, or connection string belongs in this repository.

Files

  • scripts/deploy-iis-git.ps1: controller/CI entry point. Validates branch and worktree state, packages the full source tree, hashes it, transfers it with scp, and invokes the host installer with ssh.
  • scripts/install-iis-release.ps1: elevated host-side installer. Performs preflight, preserves machine configuration, stages/releases, configures Classic ASP parent paths, switches IIS, smoke tests, and rolls back.

Both scripts target Windows PowerShell 5.1 syntax.

One-time host preparation

Complete these steps on webserver-1 before the first live deployment:

  1. Join the host and CI worker to the intended Tailscale tailnet. Confirm ACLs allow SSH only from the intended deploy identity.
  2. Install and configure Windows OpenSSH Server for key-based authentication. The deploy identity must be able to run an elevated, non-interactive PowerShell process; choose and audit the elevation mechanism locally.
  3. Install IIS, Classic ASP (IIS-ASP / Web-ASP), and IIS URL Rewrite.
  4. Create the IIS site and application pool. The scripts require an existing site and do not change its bindings, authentication, app-pool identity, or managed runtime.
  5. Ensure the site currently points at a valid public directory containing its machine-specific web.config. On first deployment this file is copied to shared\public.web.config and becomes the deployment-owned preserved copy.
  6. Put the production Access database and logs outside release directories. Grant the existing app-pool identity only the required permissions. The deployment scripts deliberately do not change app-pool identity or ACLs.
  7. Grant the deploy identity modify permission on the chosen deployment root and permission to update this IIS site's configuration.
  8. Back up IIS configuration and production data using the host's normal backup system before enabling unattended deployment.

Default deployment root:

C:\inetpub\deployments\<IIS site name>

Classic ASP parent paths are set explicitly at the site's location in applicationHost.config by install-iis-release.ps1:

system.webServer/asp enableParentPaths = true

This is intentional. The ASP section is commonly locked against web.config overrides, so the setting is applied at the host/site level rather than added to repository public/web.config.

Safe validation sequence

From a standalone checkout on a Windows worker, first validate without making a network connection:

.\scripts\deploy-iis-git.ps1 `
  -SiteName 'ttasp' `
  -RemoteTarget 'webserver-1' `
  -ExpectedBranch 'master' `
  -DryRun

-DryRun validates the local source, branch, dirty state, XML, package creation, and argument construction. It prints remote operations but does not run ssh or scp.

Next run a remote read-only preflight. This does connect to webserver-1, copies only the installer to a temporary directory, and checks the existing site, app pool, Classic ASP feature (when its feature cmdlet is available), URL Rewrite module, and availability of a preservable web.config:

.\scripts\deploy-iis-git.ps1 `
  -SiteName 'ttasp' `
  -RemoteTarget 'webserver-1' `
  -RemotePreflightOnly

For a normal deployment:

.\scripts\deploy-iis-git.ps1 `
  -SiteName 'ttasp' `
  -RemoteTarget 'webserver-1' `
  -ExpectedBranch 'master' `
  -BaseUrl 'http://127.0.0.1/'

Use a host header or HTTPS URL in -BaseUrl when the site's binding requires one. If no URL is supplied, the installer uses the first HTTP binding's port on 127.0.0.1. -SkipSmokeTest is an explicit exception and should not be used in unattended production CI.

Branch and artifact policy

The controller defaults to -ExpectedBranch master, matching the repository's actual default branch. It refuses a different branch or dirty worktree. External CI should:

  1. fetch from Gitea over its configured authenticated channel;
  2. check out the exact approved commit on master;
  3. run repository tests/static checks;
  4. call the deployment script from that standalone checkout;
  5. retain the commit ID, release ID, package SHA-256, and deployment output.

Use -AllowAnyBranch or -AllowDirty only for an intentional, reviewed manual exception. If SourcePath is not itself a Git root, -AllowAnyBranch is required because branch provenance cannot be proved.

A webhook receiver is not included. Gitea 1.11.4 can emit webhooks, but accepting and authenticating them safely is infrastructure-specific. Polling or a manually approved CI job is simpler unless an existing secured webhook runner is available.

Configuration preservation

The installer copies the current site's entire public\web.config to:

<DeployRoot>\shared\public.web.config

It then overwrites each staged release's repository version with that preserved file before cutover. This preserves all machine-specific values, especially:

  • ConnectionString and its Access Data Source path;
  • Environment;
  • ErrorLogPath and logging flags;
  • site-specific rewrite or app settings already present on the host.

The shared file is never automatically refreshed from repository content. To change production settings, edit the shared file under the host's normal change control, validate its XML, and deploy or roll back. Keep a protected backup. Do not commit production values.

Database migration policy

Deployments do not run migrations by default. The sample db directory is part of the complete release but the production connection string should point to data outside the release tree.

-RunMigrations is available only as an explicit operator choice. Before using it:

  1. take and verify a database backup;
  2. review every pending migration against the target schema;
  3. schedule downtime if the Access database requires exclusive access;
  4. understand that switching IIS back does not undo a database migration.

The old script's automatic legacy migrate_isbusiness_to_households.vbs path has been removed from deployment. Run one-off data repair scripts only under a separate reviewed procedure.

Rollback

List release IDs on the host under <DeployRoot>\releases, or use the value in deployment-state.json. Then run from the worker:

.\scripts\deploy-iis-git.ps1 `
  -SiteName 'ttasp' `
  -RemoteTarget 'webserver-1' `
  -Rollback `
  -RollbackTo '20260914-171500-a1b2c3d4e5f6' `
  -BaseUrl 'http://127.0.0.1/'

Rollback refreshes the target release's public\web.config from the preserved shared copy, switches physicalPath, recycles the app pool, and smoke tests. If that smoke test fails, it restores the pre-rollback path.

The installer reports releases older than -KeepReleases as retention candidates but does not delete them automatically. Delete only after confirming they are neither current nor required for rollback and that backups exist.

Failure and recovery behavior

  • Package extraction occurs in <release-id>.staging.
  • Layout and web.config XML are validated before promotion.
  • Promotion is a directory rename within the release volume.
  • IIS changes only after the final release directory exists.
  • Failed smoke tests restore the prior physicalPath.
  • Incomplete staging directories are retained for diagnosis.
  • Database changes, external file writes, and machine configuration outside the IIS path switch cannot be undone by release rollback.

Review Windows Event Log, IIS logs, app logs, the script transcript, and deployment-state.json after any failure.

Powered by TurnKey Linux.