Native vs container mode
Each micro in a scenario runs in one of two execution modes, and you choose it per micro:
| Mode | What it is | When |
|---|---|---|
| native | The micro starts as a process on your machine (with Maven, npm, uvicorn…) | The micro you’re working on: fast start, hot reload, easy debugging |
| container | The micro starts inside a Docker container | Background micros: isolated, reproducible environment, without cluttering your machine |
The usual combination is mixed: native for the one you develop, container for the ones you just need running for the flow to work.
Changing the mode
Section titled “Changing the mode”In the scenario’s Cards or Table views, each micro has a native/container toggle. You can also set a micro’s default mode in its editor (Micros section).
Container mode requires Docker to be started. Native mode uses the repo’s wrapper
(mvnw, .venv) or the binary on your PATH. If one is
missing (JDK, Maven, Gradle, Node, Go or the .NET SDK), Aseptic installs it in its own
folder (~/.aseptic/toolchains/), without admin rights and without touching the machine’s
PATH: the copilot, an MCP agent or aseptic toolchain install can ask for it. The one
you already have installed still takes precedence.
Native without a JDK or Maven: the tool container
Section titled “Native without a JDK or Maven: the tool container”A Spring Boot or Quarkus service with Maven, or a Node, Go, Python or .NET service, can
run in native mode without its tools on the machine (JDK and Maven, Node, Go, Python
or the .NET SDK): Aseptic runs
the same native command inside the official image of its stack, with the version the
service asks for (maven:3.9-eclipse-temurin-<java>, node:<version> from .nvmrc or
engines, golang:<version> from go.mod, python:<version> from .python-version or
requires-python, the .NET SDK from the project’s TargetFramework). That is
its tool container, and it is not container mode: the service stays native in
everything else (its configuration, its ports, debugging).
Each service decides where its tools come from in its editor (the Tools field of the local startup configuration):
| Option | What it does |
|---|---|
| Automatic (default) | Uses your machine’s if they are there; if one is missing and Docker is running, uses the tool container; without Docker it stays on the machine and the environment check offers to install what is missing |
| Machine | Always your machine’s |
| Container | Always the official image |
What you already have configured comes along: your settings.xml (and
settings-security.xml) read-only, the ${env.X} variables it cites and your company
CA from Settings, which is added to the image’s trust. Node also gets your .npmrc; Python, your pip.conf and
the PIP_INDEX_URL variables; .NET, your NuGet.Config; and Go, the variables of its
module proxy (GOPROXY, GOPRIVATE…). If you cannot pull from Docker
Hub, the image registry in Settings prepends the prefix of an internal mirror.
Even if you do not configure it, the container also trusts the CAs your system has beyond the default ones (the Windows store, the macOS keychain or /etc/ssl on Linux), which is where companies install the one of the proxy that inspects traffic: a service that resolves against the internal repository on your machine resolves the same way inside. In Java, the resulting store is saved and later starts just copy it. TLS verification is never turned off; if a build still does not trust a certificate, the service log explains it with a note instead of a bare PKIX.
Spring Boot and Quarkus with Gradle start with the repo’s wrapper (./gradlew bootRun or quarkusDev), without the daemon so that stopping the service also stops the application, and their configuration travels in the JAVA_TOOL_OPTIONS variable with the same -D as in Maven, without touching build.gradle. In their tool container they use the JDK image (eclipse-temurin:<java>) and a Gradle cache of their own. They are debugged just as with Maven; in Spring Boot, the debugger is added only to the application’s JVM through a Gradle init script that Aseptic passes at startup, without touching the repo.
On each start the repo is copied to a volume and built there, so there is no hot reload;
dependencies go to a shared volume filled once from your ~/.m2 (the first time
takes a while, and its progress shows in the log). The environment check lists the
services that will go to their container and why, the card and the table mark them, and
the decision is made again when the service restarts: install the JDK and it goes back
to your machine.
Many development servers (uvicorn, flask run, dotnet run with its
launchSettings.json, Vite) listen only on 127.0.0.1, and that port cannot be published
from inside a container. For those services a minimal companion container
(alpine/socat) starts next to theirs, publishes the port and forwards it to the
service without touching its command; it is removed with it. Angular front ends stay on
the machine: their --proxy-config is a file on your machine that does not exist inside
the container. Debugging in the tool container is only available on the JVM.
Customizing native startup
Section titled “Customizing native startup”Native-mode startup can be fine-tuned per micro (properties, arguments, database, command…) without touching the repo. See Customize startup.