Changelog
Each release, newest first: what changed, then under Upgrading what to change in commands, workspaces or clients that use the previous release. Releases up to 1.0.2 are described on GitHub Releases.
Version 1.4.0
Feast's MCP endpoint, pushing features over HTTP and from Flink, materialising from Airflow, and vector retrieval on PostgreSQL.
feast-serveserves an MCP endpoint athttp://127.0.0.1:6566/mcpwith each route of the feature server as a tool (Connect an MCP Client).- Push Features pushes a value to the feature server Over HTTP and From Flink SQL, then reads it back.
- On a Schedule materialises the feature view into Valkey from an Airflow DAG every hour.
- Vector Retrieval with Feast writes document embeddings to PostgreSQL with pgvector and retrieves the nearest rows.
feast applyin the Feast guide now runs with--skip-source-validation, so the same definitions work from your shell and from the Airflow container.
Upgrading
- A workspace made by
odctl initbefore 1.4.0 keeps itsfeast/feature_store.yamlwithout the MCP endpoint, and itsregistry.ymlwithout the MCP line inodctl explain feast. Runodctl init --forceto copy the new files (it replaces your edits), or add thefeature_serverblock yourself. Then runodctl recreate feast. - If you applied the guide's definitions before 1.4.0, their Iceberg source stores
endpoint, the catalog address of your shell, which the Airflow container cannot reach. Removeendpointfrom the source and runfeast apply --skip-source-validationagain before you run the DAG.
Version 1.3.0
Custom connectors for OpenMetadata, extra packages for its ingestion container, AutoPilot off by default, OpenMetadata 2.0.7, and newer Kafka and Metabase images.
- A Python connector uploaded to
s3://openmetadata/connectorsis importable in the ingestion container within about 15 seconds, and a change to it is used by the next agent run with no restart. Add a Custom Connector creates its service and agent through the API. - OpenMetadata's AutoPilot, which creates and runs default agents for a service added in the UI, is off by default. The new
.envkeyMETADATA_AUTOPILOTturns it on, and the newopenmetadata-initservice applies it each timemetadatastarts. See Register PostgreSQL as a Database Service. _METADATA_PIP_DEPSin.odctl/.envinstalls extra Python packages in theopenmetadata-ingestioncontainer, as_AIRFLOW_PIP_DEPSdoes for Airflow. See Examples.openmetadata-ingestionhas a healthcheck, soodctl upandodctl recreatereturn once its Airflow answers.- Where Data Lives shows the three profiles that read their code from a bucket:
airflow,feastandmetadata. - OpenMetadata and its ingestion container run 2.0.7, up from 2.0.1.
- On a new database the sign-in domain is
odctl.io, and a second adminuser@odctl.iohas the passwordpassword. The ingestion Airflow takesuserandpassword. - Kafka and Kafka Connect run
apache/kafka:4.3.2, up from 4.3.1. Metabase runs v0.64.3.5, up from v0.64.3.1. The deps image haslog4j-slf4j2-impl2.26.1, up from 2.23.1.
Upgrading
- The
metadataprofile now also startsstorage, SeaweedFS on 127.0.0.1 ports 8333, 8889 and 9333, from which the ingestion container takes connectors. - Two new
.envkeys,_METADATA_PIP_DEPSandMETADATA_AUTOPILOT, are written byodctl init. An existing.envworks without them: add the lines, or get them withodctl init --force. - AutoPilot is now off unless
METADATA_AUTOPILOT="true", so a service added in the OpenMetadata UI no longer gets default agents. An existing.envhas no key, which means off. SetMETADATA_AUTOPILOT="true"in.odctl/.envto keep the old behaviour. openmetadata-migraterunsopenmetadata-ops.sh migrateagainst your existing database on the next start ofmetadata, byodctl uporodctl recreate, for the move from 2.0.1 to 2.0.7. Going back to 2.0.1 afterwards is not tested.- The sign-in domain
odctl.ioand the passwordpasswordofuserapply to a new database only. A database from an earlier release keeps its usersadmin@open-data.localanduser@open-data.local, both with the passwordadmin, because the server restores a user's stored email on every update (UserRepository.java,entitySpecificUpdate, at2.0.7-release) and keeps a stored password. On that databaseadmin@odctl.ioanduser@odctl.iofail with HTTP 400, "You have entered an invalid username or password." - The ingestion Airflow login changes from
admin/admintouser/password. - A workspace made by
odctl initwith an earlier release keeps its oldcompose-metadata.yml,compose-infra.yml,compose-kafka.yml,compose-analytics.ymlandregistry.yml, has noopenmetadata/connector_sync.pyoropenmetadata/autopilot_init.py, and so has none of the changes above. Runodctl init --forceto copy the new files; it replaces your edits, so keep a copy of them. Then runodctl recreate metadata storage, andodctl recreatefor the Kafka and Metabase profiles you use, such asodctl recreate kafka-lite metabase.
Version 1.2.2
Newer images for Trino, Metabase and the observability stack.
- Trino runs 484, up from 483. Metabase runs v0.64.3.1, up from v0.63.19.3.
otel-lgtmrunsgrafana/otel-lgtm:0.37.0, up from 0.35.0. The deps image has the PostgreSQL JDBC driver 42.7.14, up from 42.7.13. - The Grafana dashboard descriptions no longer name the exact version of the component they show, so they stay true when an image is updated. They name a major version only where it tells two kinds apart: Flink 2, whose metrics differ from Flink 1, and OpenMetadata 2, which is maintained beside OpenMetadata 1.
Upgrading
- A workspace made by
odctl initwith an earlier release keeps its old compose files, and so the old images. Runodctl init --forceto copy the new files; it replaces your edits, so keep a copy of them. Then runodctl recreatefor the profiles you use, such asodctl recreate trino metabase.
Version 1.2.1
recreate, restart and logs work on profiles from several compose files, init and down can skip their prompt, and the docs show every command with a runnable example.
odctl recreate,odctl restartandodctl logswork on profiles from more than one compose file, such asodctl recreate storage kafka-lite. They ran every file as one project, sorecreatefailed withConflict. The container name "/seaweed" is already in use, andrestartandlogsleft out the containers of all but one file. Each file now runs as its own project, as withodctl up. Apply a Change usesodctl recreate.odctl init --force --yesandodctl down --all --volumes --yesrun without askingAre you sure?, for scripts and CI.-yis the short form. See Stop a Profile and Start Again.- Getting Started runs every command on
kafka-lite, with its output, and the home page lists each command with a link to its example. - Every guide ends with a Runnable Example that names the files to run. Rolling Windows is a page of its own, and the Flink push to Feast moved to From Flink SQL on the Feast guide.
- The animation on How It Works shows its four steps again. Since 1.1.0 it showed steps 1 to 3 for a moment each and then stayed on step 4, because one step was exported 2 pixels narrower and ffmpeg stopped at the change in size.
- The Labs page is hidden until its first lab is published.
Version 1.2.0
Flink can send rows to an HTTP API, Spark reads Kafka with no extra options, SeaweedFS survives uploads of large models, and the guides cover cases that real projects met.
- Flink's SQL client has the HTTP connector. From Flink SQL on the Feast guide pushes a feature value to Feast.
- Spark has the Kafka connector and the Avro module, so a job reads a topic, including Avro records written with the schema registry, with no
--packagesoption. See Read a Kafka Topic and Read Avro Records Written with the Schema Registry. - Keep Messages Longer shows the broker's one-day and 500 MB retention and how to turn both off for a topic. Troubleshooting lists the symptom.
seaweedsetsGOMEMLIMITto three quarters of its memory limit, so uploads of a model of a few hundred MB no longer end with HTTP 500 and a killed container. Troubleshooting says what to do when the limit is still reached, and How It Works changes both values together.- The MLflow guide has three new sections: Move the Alias to a New Version, which needs
odctl restart mlflow, Load a Model from Your Machine and Serve a Model That Reads Online Features. - The docs now say that the packages in
_MLOPS_PIP_DEPSare installed from PyPI again in every newmlflowandmlflow-servecontainer. How It Works lists when a new container is made. - How It Works shows how to create a bucket before its profile exists.
- Rolling Windows shows that Flink SQL refuses two different
OVERwindows in one streaming query, and the two ways around it. - The Evidently guide says what Evidently does not estimate and why NannyML needs Python 3.12.
Upgrading
- A workspace made by
odctl initwith an earlier release keeps its oldcompose-infra.yml, which has noGOMEMLIMITforseaweed. Runodctl init --forceto copy the new files; it replaces your edits, so keep a copy of them. Then runodctl recreate storage.
Version 1.1.0
Every service is now reachable from your machine only, and the docs have a Roadmap and a Changelog.
- Every published port binds to
127.0.0.1, on macOS, Linux and WSL2, so other machines on your network cannot reach the services. How You Reach a Service says how to open a port when you need to. - Kafka no longer publishes ports 29092, 29093 and 29094, which were listeners for a minikube cluster.
- An odctl skill and
llms.txthelp an AI assistant choose a profile and reach its services. See Use It with an AI Assistant. - Eight guides show in a diagram how data moves between their services, and How It Works shows what
odctl upchecks and the order it starts services in. The end-to-end tests run every command the guides show. - The tables of
odctl psandodctl explaindraw straight right borders on rows with port mappings. odctl down --helpsays what--volumesremoves.
Upgrading
- To reach a service from another machine, run
odctl init, remove127.0.0.1:from the service's port line in.odctl/compose-*.yml, and runodctl recreate <profile>. - A Kafka client in minikube cannot use
host.minikube.internal:29092any more. Add a listener for it to the Kafka service in.odctl/compose-kafka.yml. - A workspace made by
odctl initwith an earlier release keeps its old compose files, which publish on all interfaces and include port 29092. Runodctl init --forceto copy the new files; it replaces your edits.