diff --git a/dockerimg/dockerimg.go b/dockerimg/dockerimg.go
index d812987..a92fb92 100644
--- a/dockerimg/dockerimg.go
+++ b/dockerimg/dockerimg.go
@@ -72,12 +72,6 @@
 	// Host port for the container's ssh server
 	SSHPort int
 
-	// Public keys authorized to connect to the container's ssh server
-	SSHAuthorizedKeys []byte
-
-	// Private key used to identify the container's ssh server
-	SSHServerIdentity []byte
-
 	// Outside information to pass to the container
 	OutsideHostname   string
 	OutsideOS         string
@@ -262,9 +256,25 @@
 	}
 	sshHost, sshPort, err := net.SplitHostPort(localSSHAddr)
 	if err != nil {
-		fmt.Println("Error splitting ssh host and port:", err)
+		return appendInternalErr(fmt.Errorf("Error splitting ssh host and port: %w", err))
 	}
-	fmt.Printf("ssh into this container with: ssh root@%s -p %s\n", sshHost, sshPort)
+
+	cst, err := NewSSHTheather(cntrName, sshHost, sshPort)
+	if err != nil {
+		return appendInternalErr(fmt.Errorf("NewContainerSSHTheather: %w", err))
+	}
+
+	fmt.Printf(`Connect to this container via any of these methods:
+🖥️  ssh %s
+🖥️  code --remote ssh-remote+root@%s /app -n
+🔗 vscode://vscode-remote/ssh-remote+root@%s/app?n=true
+`, cntrName, cntrName, cntrName)
+
+	defer func() {
+		if err := cst.Cleanup(); err != nil {
+			appendInternalErr(err)
+		}
+	}()
 
 	// Tell the sketch container which git server port and commit to initialize with.
 	go func() {
@@ -273,7 +283,7 @@
 		// the scrollback (which is not good, but also not fatal).  I can't see why it does this
 		// though, since none of the calls in postContainerInitConfig obviously write to stdout
 		// or stderr.
-		if err := postContainerInitConfig(ctx, localAddr, commit, gitSrv.gitPort, gitSrv.pass, config.SSHServerIdentity, config.SSHAuthorizedKeys); err != nil {
+		if err := postContainerInitConfig(ctx, localAddr, commit, gitSrv.gitPort, gitSrv.pass, cst.serverIdentity, cst.userIdentity); err != nil {
 			slog.ErrorContext(ctx, "LaunchContainer.postContainerInitConfig", slog.String("err", err.Error()))
 			errCh <- appendInternalErr(err)
 		}
diff --git a/dockerimg/sshtheater.go b/dockerimg/sshtheater.go
new file mode 100644
index 0000000..31d1849
--- /dev/null
+++ b/dockerimg/sshtheater.go
@@ -0,0 +1,372 @@
+package dockerimg
+
+import (
+	"bufio"
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/x509"
+	"encoding/base64"
+	"encoding/pem"
+	"fmt"
+	"os"
+	"path/filepath"
+	"strings"
+
+	"github.com/kevinburke/ssh_config"
+	"golang.org/x/crypto/ssh"
+)
+
+const keyBitSize = 2048
+
+// SSHTheater does the necessary key pair generation, known_hosts updates, ssh_config file updates etc steps
+// so that ssh can connect to a locally running sketch container to other local processes like vscode without
+// the user having to run the usual ssh obstacle course.
+//
+// SSHTheater does not modify your default .ssh/config, or known_hosts files.  However, in order for you
+// to be able to use it properly you will have to make a one-time edit to your ~/.ssh/config file.
+//
+// In your ~/.ssh/config file, add the following line:
+//
+// Include $HOME/.sketch/ssh_config
+//
+// where $HOME is your home directory.
+type SSHTheater struct {
+	cntrName string
+	sshHost  string
+	sshPort  string
+
+	knownHostsPath     string
+	userIdentityPath   string
+	sshConfigPath      string
+	serverIdentityPath string
+
+	serverPublicKey ssh.PublicKey
+	serverIdentity  []byte
+	userIdentity    []byte
+}
+
+// NewSSHTheather will set up everything so that you can use ssh on localhost to connect to
+// the sketch container.  Call #Clean when you are done with the container to remove the
+// various entries it created in its known_hosts and ssh_config files. Also note that
+// this will generate key pairs for both the ssh server identity and the user identity, if
+// these files do not already exist.  These key pair files are not deleted by #Cleanup,
+// so they can be re-used across invocations of sketch. This means every sketch container
+// that runs on this host will use the same ssh server identity.
+//
+// If this doesn't return an error, you should be able to run "ssh <cntrName>"
+// in a terminal on your host machine to open a shell into the container without having
+// to manually accept changes to your known_hosts file etc.
+func NewSSHTheather(cntrName, sshHost, sshPort string) (*SSHTheater, error) {
+	base := filepath.Join(os.Getenv("HOME"), ".sketch")
+	cst := &SSHTheater{
+		cntrName:           cntrName,
+		sshHost:            sshHost,
+		sshPort:            sshPort,
+		knownHostsPath:     filepath.Join(base, "known_hosts"),
+		userIdentityPath:   filepath.Join(base, "container_user_identity"),
+		serverIdentityPath: filepath.Join(base, "container_server_identity"),
+		sshConfigPath:      filepath.Join(base, "ssh_config"),
+	}
+	if err := cst.addContainerToSSHConfig(); err != nil {
+		return nil, fmt.Errorf("couldn't add container to ssh_config: %w", err)
+	}
+
+	serverIdentity, err := os.ReadFile(cst.serverIdentityPath)
+	if err != nil {
+		return nil, fmt.Errorf("couldn't read container's ssh server identity: %w", err)
+	}
+	cst.serverIdentity = serverIdentity
+
+	serverPubKeyBytes, err := os.ReadFile(cst.serverIdentityPath + ".pub")
+	serverPubKey, _, _, _, err := ssh.ParseAuthorizedKey(serverPubKeyBytes)
+	if err != nil {
+		return nil, fmt.Errorf("couldn't read ssh server public key: %w", err)
+	}
+	cst.serverPublicKey = serverPubKey
+
+	userIdentity, err := os.ReadFile(cst.userIdentityPath + ".pub")
+	if err != nil {
+		return nil, fmt.Errorf("couldn't read ssh user identity: %w", err)
+	}
+	cst.userIdentity = userIdentity
+
+	return cst, nil
+}
+
+func removeFromHosts(cntrName string, cfgHosts []*ssh_config.Host) []*ssh_config.Host {
+	hosts := []*ssh_config.Host{}
+	for _, host := range cfgHosts {
+		if host.Matches(cntrName) || strings.Contains(host.String(), cntrName) {
+			continue
+		}
+		patMatch := false
+		for _, pat := range host.Patterns {
+			if strings.Contains(pat.String(), cntrName) {
+				patMatch = true
+			}
+		}
+		if patMatch {
+			continue
+		}
+
+		hosts = append(hosts, host)
+	}
+	return hosts
+}
+
+func generatePrivateKey(bitSize int) (*rsa.PrivateKey, error) {
+	privateKey, err := rsa.GenerateKey(rand.Reader, bitSize)
+	if err != nil {
+		return nil, err
+	}
+	return privateKey, nil
+}
+
+// generatePublicKey take a rsa.PublicKey and return bytes suitable for writing to .pub file
+// returns in the format "ssh-rsa ..."
+func generatePublicKey(privatekey *rsa.PublicKey) (ssh.PublicKey, error) {
+	publicRsaKey, err := ssh.NewPublicKey(privatekey)
+	if err != nil {
+		return nil, err
+	}
+
+	return publicRsaKey, nil
+}
+
+func encodePrivateKeyToPEM(privateKey *rsa.PrivateKey) []byte {
+	pemBlock := &pem.Block{
+		Type:  "RSA PRIVATE KEY",
+		Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
+	}
+	pemBytes := pem.EncodeToMemory(pemBlock)
+	return pemBytes
+}
+
+func writeKeyToFile(keyBytes []byte, filename string) error {
+	err := os.WriteFile(filename, keyBytes, 0o600)
+	return err
+}
+
+func createKeyPairIfMissing(idPath string) (ssh.PublicKey, error) {
+	if _, err := os.Stat(idPath); err == nil {
+		return nil, nil
+	}
+
+	privateKey, err := generatePrivateKey(keyBitSize)
+	if err != nil {
+		return nil, fmt.Errorf("Error generating private key: %w", err)
+	}
+
+	publicRsaKey, err := generatePublicKey(&privateKey.PublicKey)
+	if err != nil {
+		return nil, fmt.Errorf("Error generating public key: %w", err)
+	}
+
+	privateKeyPEM := encodePrivateKeyToPEM(privateKey)
+
+	err = writeKeyToFile(privateKeyPEM, idPath)
+	if err != nil {
+		return nil, fmt.Errorf("Error writing private key to file %w", err)
+	}
+	pubKeyBytes := ssh.MarshalAuthorizedKey(publicRsaKey)
+
+	err = writeKeyToFile([]byte(pubKeyBytes), idPath+".pub")
+	if err != nil {
+		return nil, fmt.Errorf("Error writing public key to file %w", err)
+	}
+	return publicRsaKey, nil
+}
+
+func (c *SSHTheater) addSketchHostMatchIfMissing(cfg *ssh_config.Config) error {
+	found := false
+	for _, host := range cfg.Hosts {
+		if strings.Contains(host.String(), "host=\"sketch-*\"") {
+			found = true
+			break
+		}
+	}
+	if !found {
+		hostPattern, err := ssh_config.NewPattern("host=\"sketch-*\"")
+		if err != nil {
+			return fmt.Errorf("couldn't add pattern to ssh_config: %w", err)
+		}
+
+		hostCfg := &ssh_config.Host{Patterns: []*ssh_config.Pattern{hostPattern}}
+		hostCfg.Nodes = append(hostCfg.Nodes, &ssh_config.KV{Key: "UserKnownHostsFile", Value: c.knownHostsPath})
+
+		if _, err := createKeyPairIfMissing(c.userIdentityPath); err != nil {
+			return fmt.Errorf("couldn't create user identity: %w", err)
+		}
+		hostCfg.Nodes = append(hostCfg.Nodes, &ssh_config.KV{Key: "IdentityFile", Value: c.userIdentityPath})
+
+		serverPubKey, err := createKeyPairIfMissing(c.serverIdentityPath)
+		if err != nil {
+			return fmt.Errorf("couldn't create server identity: %w", err)
+		}
+		if serverPubKey != nil {
+			c.serverPublicKey = serverPubKey
+			if err := c.addContainerToKnownHosts(); err != nil {
+				return fmt.Errorf("couldn't update known hosts: %w", err)
+			}
+		}
+		hostCfg.Nodes = append(hostCfg.Nodes, &ssh_config.Empty{})
+
+		cfg.Hosts = append([]*ssh_config.Host{hostCfg}, cfg.Hosts...)
+	}
+	return nil
+}
+
+func (c *SSHTheater) addContainerToSSHConfig() error {
+	dotSketchPath := filepath.Join(os.Getenv("HOME"), ".sketch")
+	if _, err := os.Stat(dotSketchPath); err != nil {
+		if err := os.Mkdir(dotSketchPath, 0o777); err != nil {
+			return fmt.Errorf("couldn't create %s: %w", dotSketchPath, err)
+		}
+	}
+
+	f, err := os.OpenFile(c.sshConfigPath, os.O_RDWR|os.O_CREATE, 0o644)
+	if err != nil {
+		return fmt.Errorf("couldn't open ssh_config: %w", err)
+	}
+	defer f.Close()
+
+	cfg, err := ssh_config.Decode(f)
+	if err != nil {
+		return fmt.Errorf("couldn't decode ssh_config: %w", err)
+	}
+	cntrPattern, err := ssh_config.NewPattern(c.cntrName)
+	if err != nil {
+		return fmt.Errorf("couldn't add pattern to ssh_config: %w", err)
+	}
+
+	// Remove any matches for this container if they already exist.
+	cfg.Hosts = removeFromHosts(c.cntrName, cfg.Hosts)
+
+	hostCfg := &ssh_config.Host{Patterns: []*ssh_config.Pattern{cntrPattern}}
+	hostCfg.Nodes = append(hostCfg.Nodes, &ssh_config.KV{Key: "HostName", Value: c.sshHost})
+	hostCfg.Nodes = append(hostCfg.Nodes, &ssh_config.KV{Key: "User", Value: "root"})
+	hostCfg.Nodes = append(hostCfg.Nodes, &ssh_config.KV{Key: "Port", Value: c.sshPort})
+	hostCfg.Nodes = append(hostCfg.Nodes, &ssh_config.KV{Key: "IdentityFile", Value: c.userIdentityPath})
+	hostCfg.Nodes = append(hostCfg.Nodes, &ssh_config.KV{Key: "UserKnownHostsFile", Value: c.knownHostsPath})
+
+	hostCfg.Nodes = append(hostCfg.Nodes, &ssh_config.Empty{})
+	cfg.Hosts = append(cfg.Hosts, hostCfg)
+
+	if err := c.addSketchHostMatchIfMissing(cfg); err != nil {
+		return fmt.Errorf("couldn't add missing host match: %w", err)
+	}
+
+	cfgBytes, err := cfg.MarshalText()
+	if err != nil {
+		return fmt.Errorf("couldn't marshal ssh_config: %w", err)
+	}
+	if err := f.Truncate(0); err != nil {
+		return fmt.Errorf("couldn't truncate ssh_config: %w", err)
+	}
+	if _, err := f.Seek(0, 0); err != nil {
+		return fmt.Errorf("couldn't seek to beginning of ssh_config: %w", err)
+	}
+	if _, err := f.Write(cfgBytes); err != nil {
+		return fmt.Errorf("couldn't write ssh_config: %w", err)
+	}
+
+	return nil
+}
+
+func (c *SSHTheater) addContainerToKnownHosts() error {
+	f, err := os.OpenFile(c.knownHostsPath, os.O_RDWR|os.O_CREATE, 0o644)
+	if err != nil {
+		return fmt.Errorf("couldn't open %s: %w", c.knownHostsPath, err)
+	}
+	defer f.Close()
+
+	line := strings.Join(
+		[]string{
+			fmt.Sprintf("[%s]:%s", c.sshHost, c.sshPort),
+			c.serverPublicKey.Type(),
+			base64.StdEncoding.EncodeToString(c.serverPublicKey.Marshal()),
+		}, " ")
+	if _, err := f.Write([]byte(line + "\n")); err != nil {
+		return fmt.Errorf("couldn't write new known_host entry to to %s: %w", c.knownHostsPath, err)
+	}
+
+	return nil
+}
+
+func (c *SSHTheater) removeContainerFromKnownHosts() error {
+	f, err := os.OpenFile(c.knownHostsPath, os.O_RDWR|os.O_CREATE, 0o644)
+	if err != nil {
+		return fmt.Errorf("couldn't open ssh_config: %w", err)
+	}
+	defer f.Close()
+	scanner := bufio.NewScanner(f)
+	lineToRemove := strings.Join(
+		[]string{
+			fmt.Sprintf("[%s]:%s", c.sshHost, c.sshPort),
+			c.serverPublicKey.Type(),
+			base64.StdEncoding.EncodeToString(c.serverPublicKey.Marshal()),
+		}, " ")
+
+	outputLines := []string{}
+	for scanner.Scan() {
+		if scanner.Text() == lineToRemove {
+			continue
+		}
+		outputLines = append(outputLines, scanner.Text())
+	}
+	if err := f.Truncate(0); err != nil {
+		return fmt.Errorf("couldn't truncate known_hosts: %w", err)
+	}
+	if _, err := f.Seek(0, 0); err != nil {
+		return fmt.Errorf("couldn't seek to beginning of known_hosts: %w", err)
+	}
+	if _, err := f.Write([]byte(strings.Join(outputLines, "\n"))); err != nil {
+		return fmt.Errorf("couldn't write updated known_hosts to to %s: %w", c.knownHostsPath, err)
+	}
+
+	return nil
+}
+
+func (c *SSHTheater) Cleanup() error {
+	if err := c.removeContainerFromSSHConfig(); err != nil {
+		return fmt.Errorf("couldn't remove container from ssh_config: %v\n", err)
+	}
+	if err := c.removeContainerFromKnownHosts(); err != nil {
+		return fmt.Errorf("couldn't remove container from ssh_config: %v\n", err)
+	}
+
+	return nil
+}
+
+func (c *SSHTheater) removeContainerFromSSHConfig() error {
+	f, err := os.OpenFile(c.sshConfigPath, os.O_RDWR|os.O_CREATE, 0o644)
+	if err != nil {
+		return fmt.Errorf("couldn't open ssh_config: %w", err)
+	}
+	defer f.Close()
+
+	cfg, err := ssh_config.Decode(f)
+	if err != nil {
+		return fmt.Errorf("couldn't decode ssh_config: %w", err)
+	}
+	cfg.Hosts = removeFromHosts(c.cntrName, cfg.Hosts)
+
+	if err := c.addSketchHostMatchIfMissing(cfg); err != nil {
+		return fmt.Errorf("couldn't add missing host match: %w", err)
+	}
+
+	cfgBytes, err := cfg.MarshalText()
+	if err != nil {
+		return fmt.Errorf("couldn't marshal ssh_config: %w", err)
+	}
+	if err := f.Truncate(0); err != nil {
+		return fmt.Errorf("couldn't truncate ssh_config: %w", err)
+	}
+	if _, err := f.Seek(0, 0); err != nil {
+		return fmt.Errorf("couldn't seek to beginning of ssh_config: %w", err)
+	}
+	if _, err := f.Write(cfgBytes); err != nil {
+		return fmt.Errorf("couldn't write ssh_config: %w", err)
+	}
+	return nil
+}
