Skip to content

Commit d5474fd

Browse files
authored
Infra: Replace MinIO with RustFS (#3928)
* Infra: Replace MinIO with RustFS in the dev and integration stacks MinIO Community Edition stopped publishing images in October 2025 and the repository was archived in April 2026, so `minio/minio:latest` resolves to a frozen build that will not receive further security fixes (#2664). I'm choosing RustFS since that's what Polaris uses. * Infra: Rename the object store service to `object-store` Feedback from @kevinjqliu
1 parent 1652c1a commit d5474fd

7 files changed

Lines changed: 68 additions & 57 deletions

File tree

‎Makefile‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ test-integration-rebuild: ## Rebuild integration Docker services from scratch
129129
docker compose -f dev/docker-compose-integration.yml build --no-cache
130130

131131
test-s3: ## Run tests marked with @pytest.mark.s3
132-
sh ./dev/run-minio.sh
132+
sh ./dev/run-s3.sh
133133
$(TEST_RUNNER) pytest tests/ -m s3 $(PYTEST_ARGS)
134134

135135
test-adls: ## Run tests marked with @pytest.mark.adls

‎dev/docker-compose-integration.yml‎

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ services:
2828
depends_on:
2929
- rest
3030
- hive
31-
- minio
31+
- object-store
3232
ports:
3333
- 15002:15002 # Spark Connect
3434
- 4040:4040 # Spark UI
@@ -39,7 +39,7 @@ services:
3939
links:
4040
- rest:rest
4141
- hive:hive
42-
- minio:minio
42+
- object-store:object-store
4343
healthcheck:
4444
test: ["CMD", "sh", "-c", "netstat -an | grep 15002 | grep LISTEN"]
4545
interval: 30s
@@ -59,41 +59,51 @@ services:
5959
- AWS_REGION=us-east-1
6060
- CATALOG_WAREHOUSE=s3://warehouse/
6161
- CATALOG_IO__IMPL=org.apache.iceberg.aws.s3.S3FileIO
62-
- CATALOG_S3_ENDPOINT=http://minio:9000
62+
- CATALOG_S3_ENDPOINT=http://object-store:9000
6363
- CATALOG_JDBC_STRICT__MODE=true
64-
minio:
65-
image: minio/minio
66-
container_name: pyiceberg-minio
64+
object-store:
65+
image: rustfs/rustfs:1.0.0-rc.5
66+
container_name: pyiceberg-object-store
6767
networks:
6868
iceberg_net:
6969
aliases:
70-
- warehouse.minio
70+
- warehouse.object-store
7171
ports:
7272
- 9001:9001
7373
- 9000:9000
7474
environment:
75-
- MINIO_ROOT_USER=admin
76-
- MINIO_ROOT_PASSWORD=password
77-
- MINIO_DOMAIN=minio
78-
command: ["server", "/data", "--console-address", ":9001"]
79-
mc:
80-
image: minio/mc
81-
container_name: pyiceberg-mc
75+
- RUSTFS_ACCESS_KEY=admin
76+
- RUSTFS_SECRET_KEY=password
77+
- RUSTFS_VOLUMES=/data
78+
- RUSTFS_ADDRESS=:9000
79+
- RUSTFS_CONSOLE_ENABLE=true
80+
- RUSTFS_CONSOLE_ADDRESS=:9001
81+
# Resolves virtual-hosted-style `warehouse.object-store` to the warehouse
82+
# bucket. The port is required until rustfs/rustfs#7051 ships.
83+
- RUSTFS_SERVER_DOMAINS=object-store:9000
84+
healthcheck:
85+
test: ["CMD-SHELL", "curl --fail http://127.0.0.1:9000/health"]
86+
interval: 5s
87+
timeout: 5s
88+
retries: 10
89+
start_period: 5s
90+
aws-cli:
91+
image: amazon/aws-cli:2.36.40
92+
container_name: pyiceberg-aws-cli
8293
networks:
8394
iceberg_net:
8495
depends_on:
85-
- minio
96+
object-store:
97+
condition: service_healthy
8698
environment:
8799
- AWS_ACCESS_KEY_ID=admin
88100
- AWS_SECRET_ACCESS_KEY=password
89101
- AWS_REGION=us-east-1
90-
entrypoint: >
91-
/bin/sh -c "
92-
until (/usr/bin/mc alias set minio http://minio:9000 admin password) do echo '...waiting...' && sleep 1; done;
93-
/usr/bin/mc mb minio/warehouse;
94-
/usr/bin/mc policy set public minio/warehouse;
95-
tail -f /dev/null
96-
"
102+
- AWS_ENDPOINT_URL=http://object-store:9000
103+
entrypoint: /bin/sh
104+
command:
105+
- -c
106+
- "aws s3 rb s3://warehouse --force 2>/dev/null; aws s3 mb s3://warehouse"
97107
hive:
98108
image: pyiceberg-hive:latest
99109
build:

‎dev/docker-compose.yml‎

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,37 @@
1616
# under the License.
1717

1818
services:
19-
minio:
20-
image: minio/minio
21-
container_name: pyiceberg-minio
22-
environment:
23-
- MINIO_ROOT_USER=admin
24-
- MINIO_ROOT_PASSWORD=password
25-
- MINIO_DOMAIN=minio
19+
object-store:
20+
image: rustfs/rustfs:1.0.0-rc.5
21+
container_name: pyiceberg-object-store
2622
ports:
2723
- 9001:9001
2824
- 9000:9000
29-
command: ["server", "/data", "--console-address", ":9001"]
30-
mc:
25+
environment:
26+
- RUSTFS_ACCESS_KEY=admin
27+
- RUSTFS_SECRET_KEY=password
28+
- RUSTFS_VOLUMES=/data
29+
- RUSTFS_ADDRESS=:9000
30+
- RUSTFS_CONSOLE_ENABLE=true
31+
- RUSTFS_CONSOLE_ADDRESS=:9001
32+
healthcheck:
33+
test: ["CMD-SHELL", "curl --fail http://127.0.0.1:9000/health"]
34+
interval: 5s
35+
timeout: 5s
36+
retries: 10
37+
start_period: 5s
38+
aws-cli:
39+
image: amazon/aws-cli:2.36.40
40+
container_name: pyiceberg-aws-cli
3141
depends_on:
32-
- minio
33-
image: minio/mc
34-
container_name: pyiceberg-mc
42+
object-store:
43+
condition: service_healthy
3544
environment:
3645
- AWS_ACCESS_KEY_ID=admin
3746
- AWS_SECRET_ACCESS_KEY=password
3847
- AWS_REGION=us-east-1
39-
entrypoint: >
40-
/bin/sh -c "
41-
until (/usr/bin/mc alias set minio http://minio:9000 admin password) do echo '...waiting...' && sleep 1; done;
42-
/usr/bin/mc rm -r --force minio/warehouse;
43-
/usr/bin/mc mb minio/warehouse;
44-
/usr/bin/mc policy set public minio/warehouse;
45-
exit 0;
46-
"
48+
- AWS_ENDPOINT_URL=http://object-store:9000
49+
entrypoint: /bin/sh
50+
command:
51+
- -c
52+
- "aws s3 rb s3://warehouse --force 2>/dev/null; aws s3 mb s3://warehouse"

‎dev/hive/core-site.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
</property>
3333
<property>
3434
<name>fs.s3a.endpoint</name>
35-
<value>http://minio:9000</value>
35+
<value>http://object-store:9000</value>
3636
</property>
3737
<property>
3838
<name>fs.s3a.access.key</name>

dev/run-minio.sh renamed to dev/run-s3.sh

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,9 @@
2020

2121
set -ex
2222

23-
if [ $(docker ps -q --filter "name=pyiceberg-minio" --filter "status=running" ) ]; then
24-
echo "Minio backend running"
23+
if [ $(docker ps -q --filter "name=pyiceberg-object-store" --filter "health=healthy" ) ]; then
24+
echo "S3 backend running"
2525
else
2626
docker compose -f dev/docker-compose.yml kill
27-
docker compose -f dev/docker-compose.yml up -d
28-
while [ -z $(docker ps -q --filter "name=pyiceberg-minio" --filter "status=running" ) ]
29-
do
30-
echo "Waiting for Minio"
31-
sleep 1
32-
done
27+
docker compose -f dev/docker-compose.yml up -d --wait
3328
fi

‎dev/spark/spark-defaults.conf‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ spark.sql.catalog.rest.type rest
2323
spark.sql.catalog.rest.uri http://rest:8181
2424
spark.sql.catalog.rest.io-impl org.apache.iceberg.aws.s3.S3FileIO
2525
spark.sql.catalog.rest.warehouse s3://warehouse/rest/
26-
spark.sql.catalog.rest.s3.endpoint http://minio:9000
26+
spark.sql.catalog.rest.s3.endpoint http://object-store:9000
2727
spark.sql.catalog.rest.cache-enabled false
2828

2929
# Configure Iceberg Hive catalog
@@ -32,13 +32,13 @@ spark.sql.catalog.hive.type hive
3232
spark.sql.catalog.hive.uri thrift://hive:9083
3333
spark.sql.catalog.hive.io-impl org.apache.iceberg.aws.s3.S3FileIO
3434
spark.sql.catalog.hive.warehouse s3://warehouse/hive/
35-
spark.sql.catalog.hive.s3.endpoint http://minio:9000
35+
spark.sql.catalog.hive.s3.endpoint http://object-store:9000
3636

3737
# Configure Spark's default session catalog (spark_catalog) to use Iceberg backed by the Hive Metastore
3838
spark.sql.catalog.spark_catalog org.apache.iceberg.spark.SparkSessionCatalog
3939
spark.sql.catalog.spark_catalog.type hive
4040
spark.sql.catalog.spark_catalog.uri thrift://hive:9083
41-
spark.hadoop.fs.s3a.endpoint http://minio:9000
41+
spark.hadoop.fs.s3a.endpoint http://object-store:9000
4242
spark.sql.catalogImplementation hive
4343
spark.sql.warehouse.dir s3a://warehouse/hive/
4444

‎mkdocs/docs/contributing.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ For Python, `pytest` is used a testing framework in combination with `coverage`
155155
make test
156156
```
157157

158-
By default, S3 and ADLS tests are ignored because that require minio and azurite to be running.
158+
By default, S3 and ADLS tests are ignored because that require RustFS and azurite to be running.
159159
To run the S3 suite:
160160

161161
```bash
@@ -257,7 +257,7 @@ This command spins up the full integration test infrastructure via Docker Compos
257257
- **Spark** (with Spark Connect)
258258
- **Iceberg REST Catalog** (using the [`apache/iceberg-rest-fixture`](https://hub.docker.com/r/apache/iceberg-rest-fixture) image)
259259
- **Hive Metastore**
260-
- **S3-compatible object storage** (Minio)
260+
- **S3-compatible object storage** (RustFS)
261261

262262
**Spark Example Notebook** (`notebooks/spark_integration_example.ipynb`) is based on the [Spark Getting Started](https://iceberg.apache.org/docs/nightly/spark-getting-started/) guide. This notebook demonstrates how to work with PyIceberg alongside Spark, leveraging the Docker-based testing setup for a complete local development environment.
263263

0 commit comments

Comments
 (0)