From 96a98b071e832cd093bf10d42b750ed84d80623f Mon Sep 17 00:00:00 2001 From: "aspire-repo-bot[bot]" <268009190+aspire-repo-bot[bot]@users.noreply.github.com> Date: Sat, 3 Oct 2026 08:21:29 +0000 Subject: [PATCH] docs: update SQL Server REPL docs for direct sqlcmd invocation and wrapper scripts Documents changes from microsoft/aspire#20704: the REPL now invokes /opt/mssql-tools18/bin/sqlcmd directly instead of probing for a client, adds SqlServerReplOptions/SqlServerReplCommand to select Version17 for older images or a custom executable path, and supports wrapper scripts that run work before/after the interactive session. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../databases/sql-server/sql-server-host.mdx | 115 +++++++++++++++++- 1 file changed, 114 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/content/docs/integrations/databases/sql-server/sql-server-host.mdx b/src/frontend/src/content/docs/integrations/databases/sql-server/sql-server-host.mdx index f58d4d4ae..26075f879 100644 --- a/src/frontend/src/content/docs/integrations/databases/sql-server/sql-server-host.mdx +++ b/src/frontend/src/content/docs/integrations/databases/sql-server/sql-server-host.mdx @@ -590,7 +590,7 @@ builder.Build().Run(); The command is opt-in and available only in run mode while the container is running. The client runs inside the container as `sa`, connected to the `master` database, so no local SQL client is needed. It uses the configured password without putting it in command-line arguments and trusts the local server's self-signed certificate, matching the integration's local development connection string. -The command supports `/opt/mssql-tools18/bin/sqlcmd` in newer SQL Server images and `/opt/mssql-tools/bin/sqlcmd` in older images. Custom images must include one of these clients. +The command invokes `/opt/mssql-tools18/bin/sqlcmd` directly, matching the tools version included in the integration's default `2022-latest` image. It doesn't probe for another client or invoke a shell, so no override is needed when using the default image. Enter SQL statements followed by `GO` on its own line to execute a batch: @@ -605,6 +605,119 @@ Use `USE [db];` followed by `GO` to switch databases, and `QUIT` to exit before The client runs as `sa`, can modify or delete data, and can execute server-side operating system commands when enabled. Enable it only for trusted dashboard users, including anyone accessing the dashboard through a tunnel or remote development session. ::: +### Select the client executable + +:::note[Breaking change] +Older SQL Server images that only contain `/opt/mssql-tools/bin/sqlcmd` no longer get automatic client-path discovery. AppHosts pinned to one of those images must select `SqlServerReplCommand.Version17` explicitly, as shown below. The default image and the parameterless `WithRepl()` overload are unaffected. +::: + +When pinning an older image that includes `/opt/mssql-tools/bin/sqlcmd`, pass an `options` callback to `WithRepl()` and select the version 17 command: + + + + +```typescript title="apphost.mts" +import { SqlServerReplCommand } from './.aspire/modules/aspire.mjs'; + +await builder.addSqlServer('sql') + .withImageTag('') + .withRepl({ + configure: async options => { + await options.command.set(SqlServerReplCommand.Version17); + } + }); +``` + + + + +```csharp title="AppHost.cs" +builder.AddSqlServer("sql") + .WithImageTag("") + .WithRepl(options => options.Command = SqlServerReplCommand.Version17); +``` + + + + +`SqlServerReplCommand.Version17` and `SqlServerReplCommand.Version18` are string constants for the well-known `sqlcmd` executable paths. Choose based on the client tools installed in the image, not the SQL Server version — setting `Command` doesn't install tools or change the container image. + +`Command` also accepts a custom executable path, for an image that installs `sqlcmd` somewhere else: + + + + +```typescript +await sqlServer.withRepl({ + configure: async options => { + await options.command.set('/usr/local/bin/sqlcmd'); + } +}); +``` + + + + +```csharp +sqlServer.WithRepl(options => options.Command = "/usr/local/bin/sqlcmd"); +``` + + + + +### Run a wrapper script + +Set `Command` to an executable script inside the container to run work before and after the interactive SQL session. For example, place these two files in a `sql` directory under the AppHost directory: + +```dockerfile title="sql/Dockerfile" +FROM mcr.microsoft.com/mssql/server:2022-latest +COPY --chmod=755 sqlcmd-wrapper.sh /usr/local/bin/sqlcmd-wrapper +``` + +```sh title="sql/sqlcmd-wrapper.sh" +#!/bin/sh + +echo "Running pre-session work" + +/opt/mssql-tools18/bin/sqlcmd "$@" +status=$? + +echo "Running post-session work" + +exit "$status" +``` + +Replace the echoed messages with the work you want to run, then configure Aspire to build the image and launch the wrapper: + + + + +```typescript title="apphost.mts" +await builder.addSqlServer('sql') + .withDockerfile('sql') + .withRepl({ + configure: async options => { + await options.command.set('/usr/local/bin/sqlcmd-wrapper'); + } + }); +``` + + + + +```csharp title="AppHost.cs" +builder.AddSqlServer("sql") + .WithDockerfile("sql") + .WithRepl(options => options.Command = "/usr/local/bin/sqlcmd-wrapper"); +``` + + + + +The wrapper receives Aspire's usual `sqlcmd` arguments and the `SQLCMDPASSWORD` environment variable. Forward `"$@"` to preserve argument boundaries, and don't put the password in arguments or log it. The example above preserves `sqlcmd`'s exit code. + +Save the script with **LF line endings** and make it executable; the Dockerfile's `COPY --chmod=755` sets the permissions, and its `#!/bin/sh` line selects the interpreter when the script runs. Don't use `exec` to invoke `sqlcmd` if you need work to run afterward, because it replaces the wrapper process — post-session work runs only when `sqlcmd` returns, so forcibly stopping the container can prevent it. + ## Connection properties For the full reference of SQL Server connection properties — and how consuming apps in C#, TypeScript, Python, and Go read them — see [Connect to SQL Server](../sql-server-connect/).