MixEngine 0.0.1

Servers, databases and caches

This handbook covers MixEngine through the mix command line. If you would rather work in a graphical interface, download the MixDB app at https://lab.mixnz.com/#mixdb. MixDB drives the same MixEngine, so everything in this handbook still applies.

Two words, kept apart the way MixEngine keeps them apart.

A package is a program MixEngine knows how to run — Caddy, MariaDB, Redis. Installing one puts a copy of it in MixEngine's own directory and does nothing else.

A service is a running instance of a package: a port, a data directory, a generated configuration, a log, and a state. mariadb@main and mariadb@legacy are two services of one package, with different ports, different data and possibly different versions.

What is on offer

ServiceDefault lineDefault port
Caddy2.x80 and 443 — the default front end
Nginx1.2780 and 443 — the alternative, one front end at a time
php-fpmone per installed PHPa socket, or a local port on Windows
MariaDB11.4 LTS3306
MySQL8.4 LTS3306 — a different product from MariaDB, not a version of it
PostgreSQL165432
Redis7.x6379
Memcached1.611211

Nothing arrives by itself. A fresh MixEngine has no web server until you install one, and "default" above means the one this project recommends when there is a choice, not the one that is already there.

Installing and creating

mix package available
mix package install mariadb 12.3.2
mix service create mariadb@main 12.3.2

The part of a service id before the @ is the package it is an instance of, which is why mix service create needs no separate argument for it. The part after the @ is yours: it is what tells two of them apart, and MixEngine attaches no meaning to the words. Caddy runs once for a whole MixEngine home, so its service is simply caddy with no @ at all.

The id cannot be changed afterwards — it is also the generated configuration directory, the log directory, the socket and the address the password is stored at — so renaming one means creating the other and deleting this one, which keeps the data.

Useful flags on mix service create:

FlagWhat it does
--portThe port it listens on. The recipe's own default when left out
--bindThe address it binds. 127.0.0.1 when left out
--data-dirWhere its data lives. A directory under the home when left out
--autostartStart it whenever the daemon starts

Who gets 3306

MariaDB and MySQL want the same port, and so do two instances of either. The rule is one rule: first created, first served. The first to ask for 3306 gets it; the next gets the first free port above. MixEngine reports the port it chose, because a port you did not pick is one you have to be told about.

A port you name explicitly is taken at your word, with no allocation at all.

One data directory, one service

mix service create refuses a --data-dir another service already holds, and names who holds it. Two servers over one set of files corrupt them, and that cost lands on your data rather than on a start that fails.

Running them

mix service list
mix service status mariadb@main
mix service start mariadb@main
mix service stop mariadb@main
mix service logs mariadb@main --follow

mix service status requires an id where start and the rest take an optional one: a status with no subject is a list typed wrongly, and answering it as a list would hide that.

Deleting a service takes the row and the configuration generated from it, and never the data — that is somebody's databases. The answer names the directory that was left, so nobody has to go looking:

mix service delete mariadb@legacy

Databases and accounts

Making a database is one command, and it starts the server if it is not running:

mix database create mariadb@main --name blog
mix database create mariadb@main --name shop --user shop_app

Nothing prints the password by default. It is generated and put into your operating system's own credential store — Credential Manager on Windows, the Keychain on macOS, the Secret Service on Linux — and what is printed is the address it was stored at, as the store's own name and key. That is what lets a client tell you "stored in your credential store as …" without anybody hardcoding MixEngine's naming.

When a project needs the password itself — most often for a .env file — mix database credentials prints it, and --password on create lets you choose it instead of letting MixEngine generate one:

mix database credentials mariadb@main --user blog
mix database create mariadb@main --name shop --user shop-app --password

Without a value, --password prompts and reads one line from standard input, so it also works piped: echo secret | mix database create … --password. Choosing a password for an account you already made changes what is stored, and the server is realigned to it the same way it already is when a password drifts — but an account already on the server that MixEngine holds no credential for is still refused, even with the correct password: knowing a password is not what makes it yours.

To open the database in a desktop client:

mix database client mariadb@main   # what is installed, and where this system looked
mix database open mariadb@main     # open it

client reads only: it starts nothing and opens nothing, and "no client installed" is an answer rather than a failure — it names where MixEngine looked and where to get one.

open starts the instance if it is stopped, reads the password from the credential store at that moment, and hands it to the client in that process's own environment. It is never printed, never put in an argument, and so never in your shell history.

What a service may take, and when it stops

mix service limits mariadb@main
mix service limits mariadb@main set --memory 512 --cpu 50
mix service idle mariadb@main --after 30m

limits with no subcommand reads; set replaces; clear removes. set replaces every field, not only the ones you nameset --cpu 50 clears a memory ceiling that was there — so it prints all three fields of the result, and a cleared limit is on your screen rather than a surprise. What your operating system will actually enforce differs, and the answer says which of the two you have: a hard ceiling is a wall — at it, the service is killed or its next allocation fails — while an advisory one is a watched line the service may cross, after which MixEngine warns and, where the recipe permits, restarts. A control drawn as a guarantee when it is advisory would be a lie about your data.

idle says when a service is stopped for being unused, and what is currently holding it open. Nothing idles by default: a stopped service stays stopped until you start it, so switching this on is a choice you make per service.

The generated configuration

MixEngine writes the configuration for every service it runs, out of what it knows. Those files are disposable — they are regenerated, never read back — so there is nothing there for you to edit and nothing to keep in sync. If a setting you need has no flag, that is a gap in MixEngine rather than an invitation to edit the file.


This page as Markdown: https://mixnz.github.io/mixengine/en/services.md