From 60cd111172a5a91b6b2b3cc2a92a335c2cb50891 Mon Sep 17 00:00:00 2001 From: Joe Heck Date: Thu, 30 Jul 2026 15:06:39 -0700 Subject: [PATCH 1/3] makes a replica and replaces server guides with a Linux focused docc catalog - alphabetizes platforms within --- linux/Package.swift | 19 ++ linux/Snippets/.gitkeep | 0 .../Sources/SwiftLinux.docc/Documentation.md | 12 + linux/Sources/SwiftLinux.docc/ServerGuides.md | 9 + linux/Sources/SwiftLinux.docc/building.md | 246 +++++++++++++++ .../deploying-static-binaries.md | 173 +++++++++++ linux/Sources/SwiftLinux.docc/packaging.md | 293 ++++++++++++++++++ linux/Sources/_empty.swift | 13 + scripts/navigation.json | 10 +- scripts/sources.json | 6 +- 10 files changed, 773 insertions(+), 8 deletions(-) create mode 100644 linux/Package.swift create mode 100644 linux/Snippets/.gitkeep create mode 100644 linux/Sources/SwiftLinux.docc/Documentation.md create mode 100644 linux/Sources/SwiftLinux.docc/ServerGuides.md create mode 100644 linux/Sources/SwiftLinux.docc/building.md create mode 100644 linux/Sources/SwiftLinux.docc/deploying-static-binaries.md create mode 100644 linux/Sources/SwiftLinux.docc/packaging.md create mode 100644 linux/Sources/_empty.swift diff --git a/linux/Package.swift b/linux/Package.swift new file mode 100644 index 000000000..84bda31aa --- /dev/null +++ b/linux/Package.swift @@ -0,0 +1,19 @@ +// swift-tools-version: 6.2 + +import PackageDescription + +let package = Package( + name: "SwiftLinux", + products: [ + .library(name: "SwiftLinux", targets: ["SwiftLinux"]) + ], + dependencies: [ + .package(url: "https://github.com/swiftlang/swift-docc-plugin", from: "1.1.0") + ], + targets: [ + .target( + name: "SwiftLinux", + path: "Sources" + ) + ] +) diff --git a/linux/Snippets/.gitkeep b/linux/Snippets/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/linux/Sources/SwiftLinux.docc/Documentation.md b/linux/Sources/SwiftLinux.docc/Documentation.md new file mode 100644 index 000000000..0e60006ec --- /dev/null +++ b/linux/Sources/SwiftLinux.docc/Documentation.md @@ -0,0 +1,12 @@ +# ``SwiftLinux`` + +Build and host libraries, apps, and services on Linux. + +@Metadata { + @DisplayName("Linux") + @TitleHeading("") +} + +## Topics + +- diff --git a/linux/Sources/SwiftLinux.docc/ServerGuides.md b/linux/Sources/SwiftLinux.docc/ServerGuides.md new file mode 100644 index 000000000..4570265c0 --- /dev/null +++ b/linux/Sources/SwiftLinux.docc/ServerGuides.md @@ -0,0 +1,9 @@ +# Server Guides + +Build, package, and deploy Swift applications for Linux servers and cloud infrastructure. + +## Topics + +- +- +- diff --git a/linux/Sources/SwiftLinux.docc/building.md b/linux/Sources/SwiftLinux.docc/building.md new file mode 100644 index 000000000..a4ebdd4a1 --- /dev/null +++ b/linux/Sources/SwiftLinux.docc/building.md @@ -0,0 +1,246 @@ +# Building Swift Server Applications + +Assemble your server applications using Swift Package Manager. + +Use [Swift Package Manager](/documentation/package-manager/) to build server applications. +It provides a cross-platform foundation for building Swift code. +You can build using the command line or through an integrated development environment (IDE) such as Xcode or Visual Studio Code. + +## Choose a build configuration + +Swift Package Manager supports two distinct build configurations, each optimized for different stages of your development workflow. +The configurations are `debug`, frequently used during development, and `release`, which you use when profiling or creating production artifacts. + +### Use debug builds during development + +When you run `swift build` without additional flags, Swift Package Manager creates a debug build: + +```bash +swift build +``` + +Debug builds include full debugging symbols and runtime safety checks, which are essential during active development. +The compiler skips most optimizations to keep compilation times fast and preserve maximum debugging information. +This lets you quickly test changes and debug your app using lldb and breakpoints. +However, skipping optimizations can come at a significant cost to runtime performance. +Debug builds typically run more slowly than their release counterparts. + +### Create release builds for production + +For production deployments, use the release configuration by adding the `-c release` flag: + +```bash +swift build -c release +``` + +The release configuration turns on all compiler optimizations. +The trade-off is longer compilation times because the optimizer performs extensive analysis and transformations. +Release builds still include some debugging information for crash analysis, but omit development-only checks and assertions. + +## Optimize your builds + +Beyond choosing debug or release mode, several compiler flags can fine-tune your builds for specific scenarios. + +### Build specific products + +If your package defines multiple executables or library products, Swift Package Manager builds everything declared in the package by default. +Build only what you need using the `--product` flag: + +```bash +swift build --product MyAPIServer +``` + +Building a specific product is useful in monorepo setups or packages with multiple deployment targets. +It avoids compiling tools or test utilities you don't need for a given deployment. + +### Enable cross-module optimization + +Swift supports cross-module optimization, which lets the compiler optimize code across module boundaries: + +```bash +swift build -c release -Xswiftc -cross-module-optimization +``` + +The `-Xswiftc` flag passes options to the Swift compiler. +`-cross-module-optimization` tells the compiler to optimize across module boundaries. +By default, Swift optimizes each module in isolation. +Cross-module optimization removes this boundary, enabling techniques such as inlining function calls between modules. + +For code that frequently calls small functions across module boundaries, this can yield meaningful performance improvements. +However, results vary by project because optimizations are specific to your code. +Always benchmark your specific workload with and without this flag before deploying to production. + +## Review your build artifacts + +After compiling, locate your build artifacts. +Swift Package Manager places them in directories that vary by platform and architecture: + +```bash +# Show where debug build artifacts are located +swift build --show-bin-path + +# Show where release build artifacts are located +swift build --show-bin-path -c release +``` + +The build products are written to the scratch path, which defaults to `.build`, but the specific location can vary based on platform or Swift compiler. +Use the `--show-bin-path` flag in deployment scripts to locate the build product without hardcoding platform-specific paths. + +### Build services for other platforms + +Swift build artifacts are both platform- and architecture-specific. +Artifacts you create on macOS run only on macOS; those you create on Linux run only on Linux. +This creates a challenge when you work on macOS and deploy to Linux servers. + +You can use Xcode for development, but it can't produce Linux artifacts for deployment. +Swift provides two main approaches for cross-platform building. + +#### Build with Linux containers + +On macOS, you can use [Container](https://github.com/apple/container) or the Docker CLI to verify your project builds under Linux. +Apple publishes official Swift Docker images to [Docker Hub](https://hub.docker.com/_/swift), which provide complete Linux build environments. + +To build your application using the latest Swift release image: + +```bash +# Build with Container +container run -c 2 -m 8g --rm -it \ + -v "$PWD:/code" -w /code \ + swift:latest swift build + +# Build with Docker +docker run --rm -it \ + -v "$PWD:/code" -w /code \ + swift:latest swift build +``` + +These commands mount your current directory as `/code` in the container, set it as the working directory, and run `swift build` inside the Linux environment. +The `swift:latest` container image provides this environment and `swift build` produces Linux-compatible build artifacts. + +If you're on Apple silicon and need to target x86_64 Linux servers, you need to specify the target platform with the `--platform` option: + +```bash +# Build with Container +container run -c 2 -m 8g --rm -it \ + -v "$PWD:/code" -w /code \ + --platform linux/amd64 \ + -e QEMU_CPU=max \ + swift:latest swift build + +# Build with Docker +docker run --rm -it \ + -v "$PWD:/code" -w /code \ + --platform linux/amd64 \ + -e QEMU_CPU=max \ + swift:latest swift build +``` + +The `--platform` flag runs the container with QEMU emulation. +The `-e QEMU_CPU=max` environment variable enables the maximum set of CPU features within the emulated environment, giving your code access to the broadest instruction set the emulation supports. + +To build your code into a container, you typically use a container declaration — a Dockerfile or Containerfile — that specifies all the steps to assemble the container image holding your build artifacts. +Container-based builds work well in CI/CD pipelines and for validating that your code builds cleanly on Linux. +However, Docker container builds can be slower than native builds, especially on Apple silicon where x86_64 containers run through emulation. + +For more information on packaging your application or service, read [Packaging Swift Server Applications](./packaging.md). + +#### Choose static or dynamic linking for the standard library + +By default, Swift build artifacts link the standard library dynamically. +This keeps individual build artifacts smaller, and multiple programs can share a single copy of the Swift runtime. +However, dynamic linking requires the Swift runtime to be installed on your deployment target. + +For deployment scenarios where you want more self-contained build artifacts, statically link the Swift standard library: + +```bash +swift build -c release --static-swift-stdlib +``` + +The resulting build artifacts still dynamically link to glibc, but have fewer other dependencies on the target system. +These executables bundle the Swift runtime directly: + +| Aspect | Dynamic linking | Static linking | +|--------|----------------|----------------| +| Build artifact size | Smaller (runtime not included) | Larger (runtime included in binary) | +| Deployment complexity | Requires Swift runtime on target system | Self-contained, no runtime needed | +| Version management | Must match runtime version on system | Each artifact includes its own runtime version | + +For deploying to VMs or bare metal where you don't control the system configuration, static linking removes the dependency on a pre-installed Swift runtime. + +> Note: This technique doesn't apply on Apple platforms. + +#### Cross-compile with the Static Linux SDK + +If the performance overhead of Docker-based builds affects your workflow, Swift 5.9 and later provide Static Linux SDKs. +Find the link to install the static Linux SDK on the [install page at Swift.org](https://www.swift.org/install/), and detailed instructions in the article [Getting Started with the Static Linux SDK](https://www.swift.org/documentation/articles/static-linux-getting-started.html). +The SDK enables cross-compilation directly from macOS to Linux without using a container: + +```bash +# Build for x86_64 Linux +swift build -c release --swift-sdk x86_64-swift-linux-musl + +# Build for ARM64 Linux +swift build -c release --swift-sdk aarch64-swift-linux-musl +``` + +These SDK targets use musl libc (a lightweight C library) instead of glibc (the GNU C library) to produce statically linked build artifacts. +The resulting executables have minimal dependencies on the target Linux system, making them highly portable across Linux distributions. +However, the resulting executables are typically larger than dynamically linked equivalents. + +Cross-compilation runs natively on your Mac's architecture without emulation, so it's faster than Docker-based builds. +The trade-off is build environment fidelity: you verify that your code cross-compiles to Linux, not that it builds on an actual Linux system. +Cross-compilation also limits you to the static libraries available in the SDK; +your code can't use `dlopen` or similar mechanisms to dynamically load libraries available on the target system. + +For most projects, this distinction doesn't matter. +However, packages with complex C dependencies can behave differently when built natively on Linux versus cross-compiled. + + +### Build with VS Code using a Dev Container + +Visual Studio Code supports the Dev Container feature that lets you open, build, and debug your project within a container running on your local machine. +The Dev Container builds your code in the Linux environment that the container provides. +For more information on using a Dev Container, read [Visual Studio Code Dev Containers](https://docs.swift.org/vscode/documentation/userdocs/remote-dev/). + +### Inspect a binary + +If you're uncertain what platform a binary was built for, use the `file` command to inspect it: + +``` +file .build/debug/MyServer +``` + +Output from a debug build on macOS with Apple silicon: + +``` +.build/debug/MyServer: Mach-O 64-bit executable arm64 +``` + +Output from a debug build on Linux, built inside a container on Apple silicon: + +``` +.build/debug/MyServer: ELF 64-bit LSB pie executable, + ARM aarch64, version 1 (SYSV), dynamically linked, + interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, + BuildID[sha1]=ec68ac934b11eb7364fce53c95c42f5b83c3cb8d, + with debug_info, not stripped +``` + +Output from a debug build on macOS, built using the Container tool with x86_64 emulation: + +``` +.build/debug/MyServer: ELF 64-bit LSB pie executable, + x86-64, version 1 (SYSV), dynamically linked, + interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, + BuildID[sha1]=40357329617ac9629e934b94415ff4078681b45a, + with debug_info, not stripped +``` + +Output from a debug build using the static Linux SDK (`swift build --swift-sdk x86_64-swift-linux-musl`): + +``` +.build/debug/MyServer: ELF 64-bit LSB executable, + x86-64, version 1 (SYSV), statically linked, + BuildID[sha1]=04ae4f872265b1e0d85ff821fd26fc102993b9f2, + with debug_info, not stripped +``` diff --git a/linux/Sources/SwiftLinux.docc/deploying-static-binaries.md b/linux/Sources/SwiftLinux.docc/deploying-static-binaries.md new file mode 100644 index 000000000..58dd83235 --- /dev/null +++ b/linux/Sources/SwiftLinux.docc/deploying-static-binaries.md @@ -0,0 +1,173 @@ +# Deploying Swift services as static binaries + +Build fully self-contained Swift executables and deploy them +to minimal containers or directly to Linux machines. + +## Overview + +The Static Linux SDK produces Swift executables with no external dependencies — +not even the C library. +This lets you run the binary on any Linux machine regardless of distribution, +which opens deployment options that aren't possible with dynamically linked builds. + +You can copy the binary into a `scratch` or distroless container image that contains nothing but your executable. +Or skip containers entirely and copy the binary to a virtual machine. +Either way, the result is the smallest possible deployment artifact with the smallest possible attack surface. + +This article walks you through installing the SDK, building a static binary, and deploying it. + +### Install the Static Linux SDK + +The Static Linux SDK requires an open source Swift toolchain. +The toolchain bundled with Xcode doesn't support SDK-based cross-compilation. +Use `swiftly` to install an open source Swift toolchain, then install the Static Linux SDK for that toolchain. +Go to [swift.org](https://www.swift.org/install/) for the links and commands to install both. + +Install the SDK with `swift sdk install`, providing the URL for your Swift version. +The command follows this form: + +```bash +swift sdk install --checksum +``` + +After installation, verify the SDK is available: + +```bash +swift sdk list +``` + +The output includes SDK names like `x86_64-swift-linux-musl` +and `aarch64-swift-linux-musl` that you use in build commands. + +### Build a static binary + +Build your service with the `--swift-sdk` flag, +specifying the target architecture: + +```bash +swift build -c release --swift-sdk aarch64-swift-linux-musl +``` + +For x86_64 targets, use the corresponding SDK name: + +```bash +swift build -c release --swift-sdk x86_64-swift-linux-musl +``` + +This produces a statically linked ELF binary in `.build/release/` +that you can copy to any Linux system and run directly. +The SDK uses [Musl](https://musl.libc.org) instead of Glibc +and statically links everything the executable needs — +including the Swift standard library, Foundation, and system libraries +like libcurl and libxml2. + +> Note: Because Musl replaces Glibc, +> some packages that import C libraries need changes — +> for example, changing import lines from `Glibc` to `Musl`. +> The Swift standard library and Foundation handle this automatically. + +### Deploy to a distroless container image + +A distroless container image contains no operating system utilities — +no package manager, no shell, nothing but what you put in it. +This eliminates an entire class of potential vulnerabilities +because there are no extra programs an attacker could exploit. + +Because the Static Linux SDK cross-compiles from your development machine, +you don't need a multi-stage Dockerfile with a Swift SDK builder image. +Build the binary locally, then use a minimal `Dockerfile` +that copies the pre-built executable into a `scratch` image — +a completely empty base image: + +```bash +swift build -c release --swift-sdk aarch64-swift-linux-musl +``` + +```Dockerfile +FROM scratch +COPY .build/release/ / + +EXPOSE 8080 +ENTRYPOINT ["/"] +``` + +The final image contains a single file: your executable. + +If your service makes outbound TLS connections, +the image also needs CA certificates. +Copy them from any Linux image at build time: + +```Dockerfile +FROM ubuntu:noble AS certs +RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates + +FROM scratch +COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ +COPY .build/release/ / + +EXPOSE 8080 +ENTRYPOINT ["/"] +``` + +Build the container image: + +```bash +container build -t :latest . +``` + +> Note: A `scratch`-based image doesn't include a shell, +> so you can't use `container run --rm -it /bin/sh` to debug. +> If you need a shell for troubleshooting, +> use a slim base image during development and switch to `scratch` for production. + +### Build and publish with Swift Container Plugin + +The [Swift Container Plugin](https://github.com/apple/swift-container-plugin) +combines building, packaging, and pushing to a registry into a single command. +It builds your service with the Static Linux SDK, +packages the executable into a container image, +and publishes the image to a container registry — all without a Dockerfile. + +Add the plugin to your `Package.swift`: + +```swift +dependencies: [ + .package(url: "https://github.com/apple/swift-container-plugin", from: "0.1.0"), +], +``` + +Then build and publish: + +```bash +swift package --swift-sdk aarch64-swift-linux-musl \ + build-container-image --repository registry.example.com/my-app +``` + +The plugin produces a minimal image equivalent to one from a `scratch`-based Dockerfile +and pushes it to the specified registry. +Run the published image with any container runtime: + +```bash +container run -p 8080:8080 registry.example.com/my-app +``` + +> Tip: The container plugin is especially useful in CI pipelines +> where you want a single, repeatable command +> that produces a ready-to-deploy image. + +### Deploy directly to a Linux machine + +A static binary runs on any Linux machine, so you can copy it directly to a virtual machine or bare-metal server: + +```bash +scp .build/release/ user@server:/usr/local/bin/ +``` + +On the server, run the executable directly: + +```bash +ssh user@server /usr/local/bin/ +``` + +Use your preferred configuration management tool, such as Ansible, Chef, Puppet, or shell scripts, +to automate deployment across multiple hosts. diff --git a/linux/Sources/SwiftLinux.docc/packaging.md b/linux/Sources/SwiftLinux.docc/packaging.md new file mode 100644 index 000000000..de223ff27 --- /dev/null +++ b/linux/Sources/SwiftLinux.docc/packaging.md @@ -0,0 +1,293 @@ +# Packaging Swift services with containers + +Build a container that includes your Swift service with its resources and dependencies. + +## Overview + +Running your service in the cloud requires configuration, dependencies, and resources. +Containers provide a standard way to package your service along with everything it needs. +You build a container image using tools such as [Docker](https://www.docker.com) or [Container](https://github.com/apple/container), +then deploy that image to a virtual machine or cloud hosting infrastructure +such as a Kubernetes cluster. + +A container image packages everything your service needs to run into a single, portable artifact. +The image's filesystem contains: + +- The compiled executable for your service +- Linux system libraries and runtime dependencies +- Resources your service requires, such as configuration files or static assets + +The image also declares runtime metadata that controls how a container starts: + +- A default command to run +- Ports to expose for incoming network connections +- Default values for environment variables that configure your service + +A container image is built from layers of filesystem changes, stacked on top of each other. +Each layer is read-only and shared across images that use it, which makes images efficient to store and transfer. +When you run an image, the container runtime adds a writable layer on top and starts your service as a container: +a running instance of the image in its own isolated environment. + +At runtime, your deployment environment can mount additional filesystems +into a container, such as configuration maps or secrets, to provide values that vary between environments. + +### Swift container images + +The Swift project publishes container images on [Docker Hub](https://hub.docker.com/_/swift) that you can use to build and run your services. +These images come in two forms: + +- **Full SDK images** include the Swift compiler, standard library, and development tools. + For example, `swift:6.2-noble` provides Swift 6.2 on Ubuntu 24.04. + +- **Slim runtime images** include only the Swift runtime libraries on a minimal Linux distribution. + Use these as the final stage in a multi-stage build to keep your deployed image small. + For example, `swift:6.2-noble-slim` provides a minimal Ubuntu 24.04 image with the Swift runtime. + +You can also use a plain Linux distribution image, such as `ubuntu:noble`, as your base image when you statically link the Swift standard library. + +> Tip: Pin your images to a specific Swift version, such as `swift:6.2-noble`, rather than using the `latest` tag. +> Pinning the image makes your builds more reproducible and prevents unexpected changes when a new Swift release is published. + +Your organization may provide vetted base images that reflect its security policies and operational best practices. +If it does, build on those base images. + +### Build a container image + +A single-stage build compiles and packages your service in one image. +Create a file named `Dockerfile` at the root of your project: + +```Dockerfile +FROM swift:6.2-noble + +WORKDIR /workspace +COPY . /workspace + +RUN swift build -c release --static-swift-stdlib + +EXPOSE 8080 +CMD [".build/release/"] +``` + +The `EXPOSE` directive declares which port your service listens on. +It doesn't publish the port — you do that at runtime with `-p` — but it documents the intended network interface, and some orchestrators and tools use it. + +Build the image. +The `-t` flag tags the image with a name and version: + +```bash +container build -t :latest . +``` + +Tags identify images locally and determine where images go when you push them to a registry. +The convention is `:` — for example, `my-app:1.0` or `my-app:latest`. +Choose a name that matches your service and a version that reflects the build. +If you don't include `:` and a version string, the tools default to `:latest`. + +> Note: The examples in this guide use the `container` command from [Apple's container tool](https://github.com/apple/container). +> The `docker` command accepts the same arguments and works the same way. + +This approach works for a quick local build, +but the image includes the full Swift compiler and development tools, +which add hundreds of megabytes that your service never uses at runtime +and expand the attack surface of the deployed container. + +### Slim the image with a multi-stage build + +A [multi-stage build](https://docs.docker.com/build/building/multi-stage/) separates compilation from packaging. +The first stage compiles your service using the full SDK image. +The second stage copies only the compiled executable into a minimal runtime image, +producing a final image that is a fraction of the size. + +```Dockerfile +# Stage 1: Build +FROM swift:6.2-noble AS builder + +WORKDIR /workspace +COPY . /workspace + +RUN swift build -c release --static-swift-stdlib + +# Stage 2: Package +FROM ubuntu:noble +COPY --from=builder /workspace/.build/release/ / + +EXPOSE 8080 +CMD ["/"] +``` + +The `--static-swift-stdlib` flag links the Swift standard library into your executable, +so the final image doesn't need the Swift runtime installed. +If your service uses `FoundationNetworking` or `FoundationXML`, use `swift:6.2-noble-slim` instead of `ubuntu:noble` for the runtime image. +This image includes system libraries that those frameworks require: `libcurl` and `libxml2`. + +Build and run the image the same way: + +```bash +container build -t :latest . +``` + +> Tip: Create a `.dockerignore` file at the root of your project to exclude directories +> like `.build/` and `.git/` from the build context. +> Without it, `COPY . /workspace` sends everything to the build daemon, +> which slows builds and can bloat image layers. + +### Cache build artifacts to speed up rebuilds + +The Dockerfiles above copy all source files into the image and build from scratch every time. +For a small project, this is fine, but as your service grows, +rebuilding all dependencies on every change slows down the development cycle. + +[Docker BuildKit cache mounts](https://docs.docker.com/build/cache/) +persist directories across builds. +Swift Package Manager's resolved packages and compiled artifacts survive between invocations. +Bind mounts pass in only the files each step needs +without copying them into the image layer, +which keeps the cache effective even when source files change. + +The following Dockerfile resolves dependencies and builds in separate steps, +each with a cache mount for the build directory: + +```Dockerfile +# Stage 1: Build +FROM swift:6.2-noble AS builder + +WORKDIR /workspace + +# Resolve dependencies — re-runs only when Package.swift or Package.resolved change +RUN --mount=type=cache,target=/tmp/.build,sharing=locked \ + --mount=type=bind,source=Package.swift,target=Package.swift \ + --mount=type=bind,source=Package.resolved,target=Package.resolved \ + swift package resolve --force-resolved-versions --build-path /tmp/.build + +# Build the executable — reuses cached dependencies and prior compilation results +RUN --mount=type=cache,target=/tmp/.build,sharing=locked \ + --mount=type=bind,source=Package.swift,target=Package.swift \ + --mount=type=bind,source=Package.resolved,target=Package.resolved \ + --mount=type=bind,source=./Sources,target=./Sources \ + swift build -c release --static-swift-stdlib \ + --product --build-path /tmp/.build && \ + cp /tmp/.build/release/ /usr/local/bin/ + +# Stage 2: Package +FROM ubuntu:noble +COPY --from=builder /usr/local/bin/ / + +EXPOSE 8080 +CMD ["/"] +``` + +Cache mounts (`--mount=type=cache`) keep the `/tmp/.build` directory across builds. +Swift Package Manager reuses previously resolved packages and compiled modules. +Bind mounts (`--mount=type=bind`) pass specific files into each `RUN` step +without adding them to the image layer. +Changes to your source files don't invalidate the cache. + +Because cache mounts aren't part of the final image layer, +the build step explicitly copies the compiled binary to a known path +before the second stage picks it up. + +> Note: If your project includes a `Snippets/` directory or other non-source directories +> referenced by `Package.swift`, add additional bind mounts for those directories +> in the build step. + +### Build for a different platform + +If your development machine and deployment target use different CPU architectures — +for example, building on Apple Silicon (arm64) and deploying to x86_64 cloud infrastructure — +you need to specify the target platform when building the image. + +With `docker`, use the `--platform` flag: + +```bash +docker build --platform linux/amd64 -t :latest . +``` + +To build for multiple architectures in a single command, +use `docker buildx`, which produces a multi-architecture image manifest: + +```bash +docker buildx build --platform linux/amd64,linux/arm64 -t :latest . +``` + +See [Docker's multi-platform build documentation](https://docs.docker.com/build/building/multi-platform/) +for setup details, including creating a builder that supports cross-platform emulation. + +Apple's `container` tool builds for the host architecture by default. +To target a different architecture, use the `--arch` flag: + +```bash +container build --arch amd64 -t :latest . +``` + +> Note: Cross-platform builds use emulation, which is significantly slower than native builds. +> When possible, build on infrastructure that matches your deployment architecture, +> such as an x86_64 CI runner for x86_64 deployments. + +### Push to a registry + +A container registry stores and distributes images so that other systems can pull and run them. +To push an image, tag it with the registry's hostname and repository path, +then push the tagged image. + +Using [GitHub Container Registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry) as an example: + +```bash +container tag :latest ghcr.io//:latest +container push ghcr.io//:latest +``` + +Pushing requires authentication with the registry. +See [Docker's registry authentication documentation](https://docs.docker.com/reference/cli/docker/login/) +for how to log in from the command line. + +> Tip: If you're using `container` instead of `docker`, authenticate with `container registry login`. + +You can also apply the full registry tag directly during the build: + +```bash +container build -t ghcr.io//:1.0 . +container push ghcr.io//:1.0 +``` + +> Note: Your organization or cloud hosting provider may operate its own container registry. +> Check with your team for the correct registry hostname and authentication method. + +### Run locally to verify and debug + +Run a container from your image to verify it starts correctly: + +```bash +container run :latest +``` + +To expose a port from the container to your host machine, use the `-p` flag. +The first number is the host port, the second is the container port: + +```bash +container run -p 8080:8080 :latest +``` + +Pass environment variables with `-e` to configure your service without rebuilding: + +```bash +container run -p 8080:8080 -e LOG_LEVEL=debug :latest +``` + +Mount a local directory into the container with `-v` to provide configuration files +or inspect output your service writes to disk: + +```bash +container run -v "$PWD/config:/config" :latest +``` + +For interactive debugging, combine `--rm` and `-it`. +The `--rm` flag removes the container when it exits, so stopped containers don't accumulate. +The `-it` flags attach an interactive terminal. +You can interrupt the process with Control-C, or override the default command to explore the container's filesystem: + +```bash +container run --rm -it :latest /bin/sh +``` + +This drops you into a shell inside the container. +You can inspect the filesystem, check that files are in the expected locations, and verify the runtime environment. diff --git a/linux/Sources/_empty.swift b/linux/Sources/_empty.swift new file mode 100644 index 000000000..1830a90de --- /dev/null +++ b/linux/Sources/_empty.swift @@ -0,0 +1,13 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2026 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// diff --git a/scripts/navigation.json b/scripts/navigation.json index 4ec857e00..02e7f053b 100644 --- a/scripts/navigation.json +++ b/scripts/navigation.json @@ -18,21 +18,21 @@ { "title": "Tools", "modules": [ + { "source": "docc-documentation", "path": "/documentation/docc" }, { "source": "swiftpm", "path": "/documentation/packagemanagerdocs", "title": "Swift Package Manager" }, { "source": "swiftpm", "path": "/documentation/packagedescription" }, { "source": "swiftpm", "path": "/documentation/packageplugin" }, - { "source": "docc-documentation", "path": "/documentation/docc" }, - { "source": "vscode-swift", "path": "/documentation/userdocs", "title": "Swift for VS Code" }, + { "source": "vscode-swift", "path": "/documentation/userdocs", "title": "Swift extension for VS Code" }, { "source": "swiftly", "path": "/documentation/swiftlydocs", "title": "Swiftly" } ] }, { "title": "Platforms", "modules": [ - { "source": "embedded-swift", "path": "/documentation/embeddedswift", "title": "Embedded Swift" }, - { "source": "swift-wasm", "path": "/documentation/wasmguide", "title": "WebAssembly (Wasm)"}, { "source": "swift-android", "path": "/documentation/swiftandroid", "title": "Android" }, - { "source": "server-guides", "path": "/documentation/serverguides", "title": "Linux" } + { "source": "embedded-swift", "path": "/documentation/embeddedswift", "title": "Embedded Swift" }, + { "source": "swift-linux", "path": "/documentation/swiftlinux", "title": "Linux" }, + { "source": "swift-wasm", "path": "/documentation/wasmguide", "title": "WebAssembly (Wasm)"} ] }, { diff --git a/scripts/sources.json b/scripts/sources.json index 1a260a97a..0c0c58c8d 100644 --- a/scripts/sources.json +++ b/scripts/sources.json @@ -72,10 +72,10 @@ "targets": ["WasmGuide"] }, { - "id": "server-guides", + "id": "swift-linux", "type": "local", - "path": "server-guides", - "targets": ["ServerGuides"] + "path": "linux", + "targets": ["SwiftLinux"] }, { "id": "swift-android", From ee2687562c4f3243c1cafa35ea11efbc2097e687 Mon Sep 17 00:00:00 2001 From: Joe Heck Date: Thu, 30 Jul 2026 15:23:53 -0700 Subject: [PATCH 2/3] adds a prototype for 'official libraries' to the navigation for discoverability --- libraries/Package.swift | 19 ++++++++++ libraries/Snippets/.gitkeep | 0 .../OfficialLibraries.docc/Documentation.md | 38 +++++++++++++++++++ libraries/Sources/_empty.swift | 13 +++++++ scripts/navigation.json | 3 +- scripts/sources.json | 6 +++ 6 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 libraries/Package.swift create mode 100644 libraries/Snippets/.gitkeep create mode 100644 libraries/Sources/OfficialLibraries.docc/Documentation.md create mode 100644 libraries/Sources/_empty.swift diff --git a/libraries/Package.swift b/libraries/Package.swift new file mode 100644 index 000000000..8f6fb027e --- /dev/null +++ b/libraries/Package.swift @@ -0,0 +1,19 @@ +// swift-tools-version: 6.2 + +import PackageDescription + +let package = Package( + name: "OfficialLibraries", + products: [ + .library(name: "OfficialLibraries", targets: ["OfficialLibraries"]) + ], + dependencies: [ + .package(url: "https://github.com/swiftlang/swift-docc-plugin", from: "1.1.0") + ], + targets: [ + .target( + name: "OfficialLibraries", + path: "Sources" + ) + ] +) diff --git a/libraries/Snippets/.gitkeep b/libraries/Snippets/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/libraries/Sources/OfficialLibraries.docc/Documentation.md b/libraries/Sources/OfficialLibraries.docc/Documentation.md new file mode 100644 index 000000000..79dc51382 --- /dev/null +++ b/libraries/Sources/OfficialLibraries.docc/Documentation.md @@ -0,0 +1,38 @@ +# ``OfficialLibraries`` + +Official libraries maintained by the Swift project. + +@Metadata { + @DisplayName("Official Libraries") + @TitleHeading("") +} + +## Foundation + +- [swift-foundation](https://swiftpackageindex.com/swiftlang/swift-foundation) — The foundation project + +## Concurrency and process libraries + +- [swift-subprocess](https://swiftpackageindex.com/swiftlang/swift-subprocess) — Cross-platform process spawning package +- [swift-platform-executors](https://swiftpackageindex.com/swiftlang/swift-platform-executors) — Platform-native executors for Swift Concurrency +- [swift-corelibs-libdispatch](https://swiftpackageindex.com/swiftlang/swift-corelibs-libdispatch) — Grand Central Dispatch for multicore concurrency + +## Source parsing and text libraries + +- [swift-syntax](https://swiftpackageindex.com/swiftlang/swift-syntax) — Libraries for parsing/transforming Swift source code +- [swift-markdown](https://swiftpackageindex.com/swiftlang/swift-markdown) — Package for parsing/editing Markdown documents +- [swift-docc-symbolkit](https://swiftpackageindex.com/swiftlang/swift-docc-symbolkit) — Encodes/decodes Swift Symbol Graph files +- [swift-cmark](https://swiftpackageindex.com/swiftlang/swift-cmark) — CommonMark parsing and rendering library (fork) +- [swift-experimental-string-processing](https://swiftpackageindex.com/swiftlang/swift-experimental-string-processing) — Experimental pattern matching engine + +## Toolchain support libraries + +- [swift-tools-support-core](https://swiftpackageindex.com/swiftlang/swift-tools-support-core) — Shared infrastructural code for SwiftPM/llbuild +- [swift-tools-protocols](https://swiftpackageindex.com/swiftlang/swift-tools-protocols) — LSP/BSP support types +- [indexstore-db](https://swiftpackageindex.com/swiftlang/indexstore-db) — Index database library for sourcekit-lsp +- [swift-llvm-bindings](https://swiftpackageindex.com/swiftlang/swift-llvm-bindings) — Swift bindings for LLVM APIs + +## Interoperability libraries + +- [swift-java](https://swiftpackageindex.com/swiftlang/swift-java) — Java interoperability support for Swift +- [swift-java-jni-core](https://swiftpackageindex.com/swiftlang/swift-java-jni-core) — Core JNI support underlying swift-java diff --git a/libraries/Sources/_empty.swift b/libraries/Sources/_empty.swift new file mode 100644 index 000000000..1830a90de --- /dev/null +++ b/libraries/Sources/_empty.swift @@ -0,0 +1,13 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2026 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// diff --git a/scripts/navigation.json b/scripts/navigation.json index 02e7f053b..28aaa5538 100644 --- a/scripts/navigation.json +++ b/scripts/navigation.json @@ -12,7 +12,8 @@ "title": "Libraries", "modules": [ { "source": "swift-stdlib", "path": "/documentation/swift", "title": "Standard Library" }, - { "source": "swift-testing", "path": "/documentation/testing" } + { "source": "swift-testing", "path": "/documentation/testing" }, + { "source": "official-libraries", "path": "/documentation/officiallibraries", "title": "Official Libraries" } ] }, { diff --git a/scripts/sources.json b/scripts/sources.json index 0c0c58c8d..154a730be 100644 --- a/scripts/sources.json +++ b/scripts/sources.json @@ -77,6 +77,12 @@ "path": "linux", "targets": ["SwiftLinux"] }, + { + "id": "official-libraries", + "type": "local", + "path": "libraries", + "targets": ["OfficialLibraries"] + }, { "id": "swift-android", "type": "git", From 73e85b4b4d6ee652c649bf7c742fff88255d6efa Mon Sep 17 00:00:00 2001 From: Joe Heck Date: Thu, 30 Jul 2026 15:49:51 -0700 Subject: [PATCH 3/3] override nav title for TSPL - @DisplayName metadata doesn't effect article in bare docc catalog --- scripts/navigation.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/navigation.json b/scripts/navigation.json index 28aaa5538..fcfc59ab4 100644 --- a/scripts/navigation.json +++ b/scripts/navigation.json @@ -4,7 +4,7 @@ { "title": "Swift", "modules": [ - { "source": "swift-book", "path": "/documentation/the-swift-programming-language" }, + { "source": "swift-book", "path": "/documentation/the-swift-programming-language", "title": "The Swift Programming Language" }, { "source": "compiler-diagnostics", "path": "/documentation/diagnostics" } ] },