Environments
An environment is a container where a worktree's code runs. It needs podman or docker.
mia env up # start it
mia env shell # a shell inside
mia env browse # open the app in your browser
mia env down # stop it
mia env rm # remove itWhat a container is
One worktree, at most one container, named mia-<name>. It is a plain
Linux box with your code in it:
- Your files, live. The folder holding your worktrees is mounted at the
same path inside, so an edit on your computer is there at once and
gitworks inside too. - Nothing running by itself. The container only waits. Your shell, commands and services run in it through mia.
- No published ports. Each container listens on its own ports, so two
apps on port 5173 don't collide. You reach them at
<name>.mia. - Kept until removed.
mia env downstops it and keeps everything;mia env upstarts it again.mia env rmthrows it away, and the nextmia env upstarts fresh.
Setting one up
Start with nothing and add only what is missing.
1. Bring it up.
mia env upmia picks the image from the first of:
[env] imagein the config;- the
imagein.devcontainer/devcontainer.json; - an image for the project's language (
go.mod,Cargo.toml,package-lock.json,pyproject.toml,Gemfile, …); mcr.microsoft.com/devcontainers/base:ubuntu.
It prints which one it pulled and why.
2. Look around.
mia env shellInstall, run the app and the tests the way you would on a fresh computer. Whatever you had to type goes into one of two places.
3. System packages go in the image.
[env]
image_setup = ["sh", "-c", "apt-get update && apt-get install -y postgresql-client socat"]mia env image # build it once, on this machineThe built image is used from then on and survives mia env rm. Change
image_setup and build again for a new one.
4. The project's own install goes in setup.
[env]
setup = ["npm", "install"]
container_only = ["node_modules"]
cache = ["/root/.npm"]setup runs once in each new container; mia env setup runs it again.
container_only keeps a folder inside the container, so the Linux
node_modules never mixes with your computer's. cache is shared by all
the repository's containers, so the second install is fast.
Check it from scratch:
mia env rm && mia env up5. Start the app as a service.
[[service]]
id = "web"
run = ["npm", "run", "dev", "--", "--host", "0.0.0.0"]
autostart = trueServe on 0.0.0.0, not 127.0.0.1, so the gateway can reach it.
6. Open it.
mia env browse7. Reach your computer, if you need to. A database running on your computer, not in the container:
[env]
host_ports = [5432]Inside, 127.0.0.1:5432 reaches your computer's 5432. It needs socat in
the image.
A base configuration
All of the above in one file, for a web app. mia config opens it; copy
this and change what differs.
[env]
setup = ["npm", "install"]
container_only = ["node_modules"]
cache = ["/root/.npm"]
ports = [5173]
page = 5173
[[service]]
id = "web"
run = ["npm", "run", "dev", "--", "--host", "0.0.0.0"]
health = ["sh", "-c", "curl -fsS http://127.0.0.1:5173 >/dev/null"]
autostart = true
restart = "on-failure"For Python, the same shape:
[env]
setup = ["sh", "-c", "pip install -e ."]
cache = ["/root/.cache/pip"]
ports = [8000]
page = 8000
[[service]]
id = "api"
run = ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
autostart = trueMain's dev server
No container needed. If your dev server is already running in the main checkout, lend it a worktree's files:
mia dev monduli # main's dev server now shows monduli
mia dev monduli --follow # and keeps copying as you edit
mia dev # whose files main has
mia dev off # main gets its own files backThis is the only time mia writes into a working tree. It puts main's own
changes aside in a stash, then copies the worktree's files over main,
uncommitted ones included. Ignored files such as node_modules and .env
stay as they are, so the server keeps running and reloads. mia dev off
resets main and restores the stash. Don't commit in main while it is lent.
On the dashboard, v lends the selected worktree; v on main gives it back.
<name>.mia
Containers publish no ports. Open the app at https://<name>.mia:<port>/
instead of localhost:<port>. The gateway makes that work. It needs two
settings on your computer, once:
mia gateway setup # prints both
mia gateway trust # trusts mia's certificate (macOS)The other is pointing your system's automatic proxy setting at
http://127.0.0.1:7842/proxy.pac. mia env up starts the gateway.
Services
[[service]]
id = "web"
run = ["npm", "run", "dev", "--", "--host", "0.0.0.0"]
health = ["sh", "-c", "curl -fsS http://127.0.0.1:5173 >/dev/null"]
autostart = true
restart = "on-failure"autostart starts it with mia env up; health and restart keep it
running.
mia env service # each service and its state
mia env service logs webYour files
[tools] # in the repository's config
copy = ["~/.gitconfig"]
[dotfiles] # in ~/.config/mia/config.toml
env = ["~/.zshrc"]
shell = "zsh"[env] pass = ["NAME"] passes environment variables from your shell.
Other machines
mia machine add build me@build.example.com
mia env host build # move the environment there
mia env upThe URL stays the same. mia keeps a copy of the worktree there in sync with
mutagen.
mia env host local moves it back. An image built with mia env image is
built per machine: run it again there.