From 6508acea81c193580fe07b9a61170caa50ba9443 Mon Sep 17 00:00:00 2001 From: J Logan Date: Tue, 9 Jun 2026 15:51:25 -0700 Subject: [PATCH] Adds container machine example. (#1676) - Closes #1675. - Illustrates how to create a container machine image that you can use with the Visual Studio Code remote developement SSH plugin. --- examples/container-machine-vscode/Dockerfile | 35 +++ examples/container-machine-vscode/README.md | 220 +++++++++++++++++++ 2 files changed, 255 insertions(+) create mode 100644 examples/container-machine-vscode/Dockerfile create mode 100644 examples/container-machine-vscode/README.md diff --git a/examples/container-machine-vscode/Dockerfile b/examples/container-machine-vscode/Dockerfile new file mode 100644 index 00000000..33b87fda --- /dev/null +++ b/examples/container-machine-vscode/Dockerfile @@ -0,0 +1,35 @@ +FROM swift:6.3.2-noble + +# Install system dependencies for Swift + OpenSSH + systemd + containerization +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + curl ca-certificates git sudo systemd systemd-sysv openssh-server \ + binutils gpg vim libc6-dev libcurl4-openssl-dev libedit2 libgcc-s1 \ + unzip gnupg2 libgcc-13-dev libstdc++-13-dev libncurses-dev \ + libpython3-dev libsqlite3-0 libstdc++6 libxml2-dev libz3-dev \ + pkg-config tzdata zlib1g-dev \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +# Passwordless sudo for all users +RUN echo 'ALL ALL=(ALL:ALL) NOPASSWD: ALL' > /etc/sudoers.d/nopasswd \ + && chmod 0440 /etc/sudoers.d/nopasswd + +# Configure OpenSSH for local-only use: +# - Both password and public key auth enabled (no brute-force risk on loopback) +# - UseDNS no — skip reverse DNS lookup, avoids multi-second connect delay +# - GSSAPIAuthentication no — skip GSSAPI negotiation, faster handshake +RUN mkdir -p /var/run/sshd \ + && ssh-keygen -A \ + && sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config \ + && sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config \ + && sed -i 's/^#\?PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config \ + && echo 'UseDNS no' >> /etc/ssh/sshd_config \ + && echo 'GSSAPIAuthentication no' >> /etc/ssh/sshd_config \ + && systemctl enable ssh + +RUN systemctl mask getty@.service systemd-logind.service \ + apt-daily.timer apt-daily-upgrade.timer fstrim.timer || true + +EXPOSE 22 +STOPSIGNAL SIGRTMIN+3 +CMD ["/sbin/init"] diff --git a/examples/container-machine-vscode/README.md b/examples/container-machine-vscode/README.md new file mode 100644 index 00000000..bbf4e482 --- /dev/null +++ b/examples/container-machine-vscode/README.md @@ -0,0 +1,220 @@ +# Example: Develop Linux applications in a container machine with Visual Studio Code + +This example shows you how to use a container machine to develop for Linux on your Mac using Visual Studio Code and its SSH remote development extension. + +## Prerequisites + +Install and start before running the demo: + +- Apple `container` +- Microsoft Visual Studio Code, including the **Visual Studio Code Remote - SSH** extension + +## Container machine overview + +The `container machine` subcommand allows you to run fast, persistent Linux environments that integrate tightly with your macOS host. + +To create a container machine, all you need to do is provide a machine name, and a machine image reference: + +```console +% container machine create --name mymachine --set-default alpine:3.22 +mymachine +``` + +Display a list of container machines with: + +```console +% container machine ls +NAME CREATED IP CPUS MEMORY DISK STATE DEFAULT +mymachine 2026-06-03 15:56:14 192.168.71.15 8 64G 75M running * +``` + +Run individual Linux commands with `container machine run` and the command: + +```console +% container machine run uname -a +Linux mymachine-dce75a 6.18.15-cz-325d33a88139 #1 SMP Mon Apr 20 22:39:49 UTC 2026 aarch64 Linux +``` + +Display your macOS working directory and username, start a shell session in the container machine, and compare the working directory and username in the container machine: + +```console +% pwd +/Users/max-mustermann/projects/container/examples/container-machine-vscode +% whoami +john +% container machine run +$ pwd +/Users/max-mustermann/projects/container/examples/container-machine-vscode +$ whoami +john +$ exit +% +``` + +Typically, you'll keep container machines for longer than a typical container. When you're ready to delete a container machine and its persistent filesystem, run: + +```console +% container machine stop mymachine +mymachine +% container machine rm mymachine +mymachine +Deleted default container 'mymachine'. Set a new default with 'container machine set-default '. +``` + +## Develop in a container machine + +### SSH and DNS setup + +On your Mac, add an SSH configuration entry for the container machine, so that it will appear as an option when you connect to the container machine with Visual Studio Code later: + +```bash +cat >> ~/.ssh/config <` placeholder in the newly added launch configuration, so that it looks like: + +```json + { + "type": "swift", + "request": "launch", + "name": "Launch Swift Executable", + "program": "${workspaceRoot}/.build/debug/SwiftServerTodos", + "args": [], + "env": {}, + "cwd": "${workspaceRoot}" + }, +``` + +Run the application by selecting the Run and Debug sidebar, selecting the **Launch Swift Executable** item, and clicking the play button. + +Open the `Telemetry.swift` file and set a breakpoint on the innermost statement of the `RequestLoggerInjectionMiddleware.respond()` function. + +From a terminal on your Mac, try a request to the service: + +```bash +curl http://ubuntu.machine:8080/todos +``` + +Observe that the application hits the breakpoint and that you can inspect the request, and then remove the breakpoint and continue execution. + +On the terminal, you should see output similar to: + +```console +[{"id":"BDAD25BA-8F52-4A7A-B98D-319AD86179B7","contents":"example todo"}] +``` + +### Clean up + +When you're ready to dispose of your container machine, run on your Mac: + +```bash +container machine stop ubuntu +container machine rm ubuntu +container image rm ubuntu-machine:latest +``` + +Then remove the test project: + +```bash +rm -rf swift-server-todos-tutorial +``` + +To remove the entry from your SSH configuration file, run: + +```bash +awk -v h="ubuntu.machine" '/^Host /{skip=($2==h)} !skip' ~/.ssh/config > /tmp/.sshconf && mv /tmp/.sshconf ~/.ssh/config +``` + +To clean up the local DNS entry, run: + +```bash +sudo container system dns delete machine +```