Images are published as mikirisec/<name>. The tag latest is the current build. To install a fixed build, replace latest with the image tag.
Deploy PostgreSQL first, then API, then the agents that call the API. Put every container on one Docker network so they reach each other by container name:
docker network create mikiri-waf
Each Mikiri WAF image keeps its configuration and logs in one volume. The host directory is /opt/mikiri-waf/<name>, mounted at /<name> in the container.
Before the first start, create an empty file first-launch in that directory. The entrypoint copies the initial configuration into the volume, writes the package version to version and deletes first-launch. The next start uses the files in the volume.
The volume does not store the application code, the Python virtual environment, Nginx modules (*.so), or *.example files. Those stay in the image and are replaced when the image is updated.
When the package version in the new image differs from version, the entrypoint copies the current volume to old/ and leaves the working files in place. Check the working files after an update. The copy in old/ is a snapshot of the previous configuration.
API and WMC store their data in an external PostgreSQL database. The database is not part of the Mikiri WAF images.
API connects the agents, receives incidents and vulnerabilities and writes them to the database. The image runs Nginx, Memcached, mikiri-waf-api and mikiri-waf-api-aux. The published port is 8080.
WMC shows attacks and vulnerabilities and manages Mikiri WAF and Nginx settings. The image runs Nginx, Memcached, mikiri-waf-wmc and mikiri-waf-wmc-aux. Nginx listens on port 8080 and proxies requests to the backend on port 8000.
Filter analyzes requests and responses. The image mikirisec/mikiri-waf-filter-nginx also includes Nginx, Memcached, RabbitMQ, MLA and the API Firewall. The published ports are 80, 443 and 5672.
MLC builds behavioral models and detects brute-force, flood and DDoS attacks. The image runs Memcached and mikiri-waf-mlc. It has no published port. It connects to API and to RabbitMQ in the Filter container.
Scanner rechecks blocked attacks and runs scheduled scans. The image runs the Scanner process from the image. It has no published port. It receives its settings from API.
Mikiri WAF CAPTCHA asks a blocked visitor to solve a challenge. The image runs Memcached and mikiri-waf-captcha. It listens on port 8080 inside the Docker network. Publish that port only when Filter runs outside this network.
On the agent page, the update command creates the container again with the same name, network and volume and without first-launch. Do not delete the volume. After the package version changes, compare the working configuration with the copy in old/.
A container that exits on purpose after the first launch must not use a restart policy yet. unless-stopped would start it again before the configuration is filled in. Set the policy after the agent is configured:
docker update --restart unless-stopped <container name>