S3 Core Workflow
LiveBucket create, object put/get, and ListObjectsV2 are part of the active s3-core-v1 gateway surface documented by ObjectDB.
Quickstart
Download the ObjectDB beta container, run it locally, create an S3 Core bucket, upload and read one object, list the bucket, and verify that a request outside the active S3 Core profile fails explicitly.
Current availability
Private Beta. Public beta is scheduled for .
You will have a local ObjectDB S3 Core workflow that installs from the beta image, creates objectdb-quickstart, writes raw/cat.txt, verifies the downloaded object body, lists the visible key, and confirms that bucket versioning returns a S3-shaped NotImplemented response.
Bucket create, object put/get, and ListObjectsV2 are part of the active s3-core-v1 gateway surface documented by ObjectDB.
This tutorial proves a local first-success path only. Broader durability, availability, performance, support, security, and scale claims still need review.
Required
docker --version or another Docker-compatible container runtime.curl --version for S3-shaped HTTP requests.mktemp, cmp, and grep from the standard shell toolset.Required
18080 available for the local container.${TMPDIR:-/tmp}; the service script creates its own data directory.Optional
jq is useful for later JSON examples, but this quickstart verifies XML and headers directly.See local prerequisites for the shared tool baseline.
Use a dedicated terminal for the ObjectDB container and keep it running while you complete the workflow from another terminal. Start from the customer beta image.
Service terminal
Use a fresh Bash service terminal. This sets the image only; the startup script creates its own temporary state.
export OBJECTDB_IMAGE=registry.stornamics.com/objectdb/objectdb:2026.09-public-betaOBJECTDB_IMAGE is set in the service terminal.Service terminal
Pull the beta image before starting the local service. If your evaluation package uses a private registry mirror, keep the same OBJECTDB_IMAGE value there.
docker pull "$OBJECTDB_IMAGE"The pull finishes with a digest for registry.stornamics.com/objectdb/objectdb:2026.09-public-beta.Service terminal
Save this complete file as start-objectdb.sh and run bash start-objectdb.sh in the service terminal after the image setup and download. Keep the script running. On exit or Ctrl-C, it asks Docker to stop its own container, waits up to five seconds before Docker can force termination, removes that container by its recorded ID, then deletes only its temporary data. Capture any needed results before stopping. If removal cannot be confirmed, the directory is retained and its location is printed.
#!/usr/bin/env bash
set -euo pipefail
: "${OBJECTDB_IMAGE:?Set OBJECTDB_IMAGE using the image setup step.}"
command -v docker >/dev/null
OBJECTDB_RUN_DIR="$(mktemp -d "${TMPDIR:-/tmp}/objectdb-quickstart.XXXXXX")"
readonly OBJECTDB_RUN_DIR
attach_pid=
create_attempted=0
cleanup() {
status=$?
trap - EXIT
trap '' INT TERM
removed=1
if [ -s "$OBJECTDB_RUN_DIR/container.id" ]; then
container_id="$(cat "$OBJECTDB_RUN_DIR/container.id")"
if ! docker stop --time 5 "$container_id" || ! docker rm "$container_id"; then
removed=0
fi
elif [ "$create_attempted" = 1 ]; then
removed=0
fi
if [ -n "$attach_pid" ]; then
kill -TERM "$attach_pid" 2>/dev/null || true
for attempt in 1 2 3 4 5; do
kill -0 "$attach_pid" 2>/dev/null || break
sleep 1
done
if kill -0 "$attach_pid" 2>/dev/null; then
kill -KILL "$attach_pid" 2>/dev/null || true
fi
wait "$attach_pid" 2>/dev/null || true
fi
if [ "$removed" = 1 ]; then
rm -rf -- "$OBJECTDB_RUN_DIR"
else
printf 'Container removal unconfirmed; retained state: %s\n' "$OBJECTDB_RUN_DIR" >&2
status=1
fi
exit "$status"
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
mkdir "$OBJECTDB_RUN_DIR/data"
printf 'Temporary ObjectDB state: %s\n' "$OBJECTDB_RUN_DIR"
create_attempted=1
docker create --cidfile "$OBJECTDB_RUN_DIR/container.id" \
--name "${OBJECTDB_RUN_DIR##*/}" \
-p 127.0.0.1:18080:18080 \
-v "$OBJECTDB_RUN_DIR/data:/var/lib/objectdb" \
-e OBJECTDB_BIND_ADDRESS=0.0.0.0:18080 \
-e OBJECTDB_DATA_DIR=/var/lib/objectdb \
"$OBJECTDB_IMAGE"
container_id="$(cat "$OBJECTDB_RUN_DIR/container.id")"
docker start --attach "$container_id" &
attach_pid=$!
status=0
wait "$attach_pid" || status=$?
attach_pid=
exit "$status"
Temporary ObjectDB state: /tmp/objectdb-quickstart.<unique>
<container ID>
ObjectDB starts on 0.0.0.0:18080 inside the container, published only at 127.0.0.1:18080.
The exact temporary path, container ID, and service logs vary.Workflow terminal
Open a separate Bash workflow terminal. It does not inherit variables from the service terminal; define its endpoint here and check readiness.
export OBJECTDB_ENDPOINT=http://127.0.0.1:18080
curl -fsS "$OBJECTDB_ENDPOINT/health""Healthy"Workflow terminal
Use the same workflow terminal as the readiness check, with no existing ObjectDB overrides. Allocate fresh local request/response files; do not rerun this setup in the same shell. Each file belongs to this workflow directory.
export OBJECTDB_ENDPOINT=http://127.0.0.1:18080
export OBJECTDB_BUCKET=objectdb-quickstart
export OBJECTDB_KEY=raw/cat.txt
OBJECTDB_WORK_DIR="$(mktemp -d "${TMPDIR:-/tmp}/objectdb-workflow.XXXXXX")"
: "${OBJECTDB_WORK_DIR:?Could not create the workflow directory.}"
readonly OBJECTDB_WORK_DIR
export OBJECTDB_BODY_FILE="$OBJECTDB_WORK_DIR/body.txt"
export OBJECTDB_DOWNLOAD_FILE="$OBJECTDB_WORK_DIR/download.txt"
export OBJECTDB_LIST_FILE="$OBJECTDB_WORK_DIR/list.xml"
printf 'object-body' > "$OBJECTDB_BODY_FILE"
printf 'Workflow files: %s\n' "$OBJECTDB_WORK_DIR"Workflow files: /tmp/objectdb-workflow.<unique>
The body file contains 11 bytes. The actual temporary path varies.Workflow terminal
Create one tutorial-scoped bucket through the path-style S3 Core route.
curl -i -X PUT \
-H "x-amz-request-id: objectdb-quickstart-create-bucket" \
"$OBJECTDB_ENDPOINT/$OBJECTDB_BUCKET"HTTP/1.1 200 OK
location: /objectdb-quickstart
x-objectdb-s3-profile: s3-core-v1
x-objectdb-s3-operation: CreateBucket
x-objectdb-s3-bucket-id: bucket-...Workflow terminal
Upload a small object with a request ID and content type. UNSIGNED-PAYLOAD keeps the copy/paste path focused on ObjectDB behavior instead of shell-specific checksum tools.
curl -i -X PUT \
-H "x-amz-request-id: objectdb-quickstart-put-object" \
-H "x-amz-content-sha256: UNSIGNED-PAYLOAD" \
-H "Content-Type: text/plain" \
--data-binary @"$OBJECTDB_BODY_FILE" \
"$OBJECTDB_ENDPOINT/$OBJECTDB_BUCKET/$OBJECTDB_KEY"HTTP/1.1 200 OK
x-objectdb-s3-operation: PutObject
x-objectdb-s3-body-streamed-bytes: 11
x-objectdb-s3-object-id: object-...
x-objectdb-s3-version-id: version-...
x-objectdb-s3-put-object-contract: objectdb-s3-put-object-2026-08Workflow terminal
Read the object back and save it to a file so the verification step can compare bytes.
curl -fsS -D - \
-H "x-amz-request-id: objectdb-quickstart-get-object" \
"$OBJECTDB_ENDPOINT/$OBJECTDB_BUCKET/$OBJECTDB_KEY" \
-o "$OBJECTDB_DOWNLOAD_FILE"HTTP/1.1 200 OK
content-length: 11
content-type: text/plain
x-objectdb-s3-operation: GetObject
x-objectdb-s3-logical-size-bytes: 11Workflow terminal
Use ListObjectsV2 with a prefix and save the XML body for the verification step.
curl -fsS -D - \
-H "x-amz-request-id: objectdb-quickstart-list-objects" \
"$OBJECTDB_ENDPOINT/$OBJECTDB_BUCKET?list-type=2&prefix=raw/" \
-o "$OBJECTDB_LIST_FILE"HTTP/1.1 200 OK
x-objectdb-s3-operation: ListObjectsV2
x-objectdb-s3-list-key-count: 1Workflow terminal
Compare the downloaded object with the uploaded file, then confirm the listing contains the expected key.
cmp -s "$OBJECTDB_BODY_FILE" "$OBJECTDB_DOWNLOAD_FILE" &&
printf 'Object payload verified\n'
grep -q "<Key>raw/cat.txt</Key>" "$OBJECTDB_LIST_FILE" &&
printf 'Bucket listing verified\n'Object payload verified
Bucket listing verifiedWorkflow terminal
Ask for bucket versioning to see how ObjectDB responds when a request is outside the active S3 Core profile.
curl -i \
-H "x-amz-request-id: objectdb-quickstart-versioning-boundary" \
"$OBJECTDB_ENDPOINT/$OBJECTDB_BUCKET?versioning"HTTP/1.1 501 Not Implemented
x-objectdb-s3-profile: s3-core-v1
x-objectdb-s3-operation: GetBucketVersioning
x-objectdb-s3-error-code: NotImplemented
<Code>NotImplemented</Code>The quickstart is successful when the downloaded GetObject body matches the uploaded file, ListObjectsV2 includes raw/cat.txt, and the unsupported versioning request returns NotImplemented instead of silently succeeding.
Workflow terminal
Remove the tutorial object before deleting the bucket.
curl -i -X DELETE \
-H "x-amz-request-id: objectdb-quickstart-delete-object" \
"$OBJECTDB_ENDPOINT/$OBJECTDB_BUCKET/$OBJECTDB_KEY"HTTP/1.1 204 No Content
x-objectdb-s3-operation: DeleteObject
x-objectdb-s3-delete-object-contract: objectdb-s3-delete-object-2026-08Workflow terminal
Delete the now-empty tutorial bucket.
curl -i -X DELETE \
-H "x-amz-request-id: objectdb-quickstart-delete-bucket" \
"$OBJECTDB_ENDPOINT/$OBJECTDB_BUCKET"HTTP/1.1 204 No Content
x-objectdb-s3-operation: DeleteBucket
x-objectdb-s3-bucket-id: bucket-...Workflow terminal
After the HTTP deletes above, remove only the three files allocated by this workflow. The final rmdir refuses to remove the directory if other files remain. Use the original workflow terminal so its private directory value is available.
(
set -eu
: "${OBJECTDB_WORK_DIR:?Return to the workflow terminal that created these files.}"
rm -f -- "$OBJECTDB_WORK_DIR/body.txt" "$OBJECTDB_WORK_DIR/download.txt" "$OBJECTDB_WORK_DIR/list.xml"
rmdir -- "$OBJECTDB_WORK_DIR"
)The three workflow files and their empty directory are removed. An unexpected extra file is preserved and makes rmdir report that the directory is not empty.Service terminal
Return to the service terminal and press Ctrl-C. The running script stops and removes only the container ID it created before deleting its temporary service directory. The downloaded image and saved script remain. If Docker cleanup fails or no container ID was recorded, the script exits with an error and prints the retained directory; inspect that directory and its container.id before attempting recovery. Do not delete data while container removal is unconfirmed.
# Press Ctrl-C in the service terminal running start-objectdb.sh.On successful cleanup, the owned container and temporary service directory are gone.
If cleanup cannot be confirmed: Container removal unconfirmed; retained state: <exact directory>| Symptom | How to recognize it | Likely cause | Fix |
|---|---|---|---|
| Service does not start | docker start reports that the address is already in use. | Another local process is using 127.0.0.1:18080. | Choose a different host port in the startup script's docker create -p value and update OBJECTDB_ENDPOINT to match. |
| Health check cannot connect | curl reports connection refused or times out. | The container stopped, is still starting, or is published on a different host port. | Check the service terminal output and the script's printed container ID, confirm the script is running, and re-check the endpoint value. |
Bucket create returns BucketAlreadyOwnedByYou | The response status is 409 Conflict with <Code>BucketAlreadyOwnedByYou</Code>. | The bucket name already exists in the current local service state. | Run cleanup or set OBJECTDB_BUCKET to a new tutorial-scoped name. |
Put object returns BadDigest | The response body contains <Code>BadDigest</Code>. | A supplied checksum header does not match the uploaded body. | Use x-amz-content-sha256: UNSIGNED-PAYLOAD for this quickstart, or regenerate the checksum for the exact file. |
Bucket delete returns BucketNotEmpty | The response status is 409 Conflict with <Code>BucketNotEmpty</Code>. | At least one current object remains visible in the bucket. | Delete raw/cat.txt, then retry the bucket delete command. |
Unsupported check does not return NotImplemented | The request does not show x-objectdb-s3-operation: GetBucketVersioning. | The query string or bucket endpoint is different from the documented ?versioning shape. | Reuse the exact unsupported-surface command and confirm OBJECTDB_BUCKET still names the tutorial bucket. |
| Workflow step | Proof | Status |
|---|---|---|
| Customer install and startup | The quickstart starts from the ObjectDB beta image and exposes readiness on the local loopback port. | Required beta publishing check before the October 12, 2026 public beta release. |
| Copy/paste command safety | The rendered quickstart commands are checked for shell syntax, public-safe values, and source-free ObjectDB startup. | Docs-owned rendering check. |
| PutObject and GetObject | The workflow uploads object-body, downloads it into a second file, and uses cmp -s to prove byte-for-byte equality. | Reader-verifiable in the quickstart. |
| ListObjectsV2 | The workflow saves the listing response and uses grep to prove raw/cat.txt appears in the bucket result. | Reader-verifiable in the quickstart. |
| Unsupported S3 surface | The workflow calls ?versioning and expects a S3-shaped NotImplemented response for GetBucketVersioning. | Reader-visible boundary check. |
This quickstart exercises bucket lifecycle basics, single-object put/get, and ListObjectsV2 in the active s3-core-v1 profile.
The workflow uses local service state and a disposable data directory. It does not make claims about other topologies or fault models.
Versioning, Object Lock, lifecycle, replication, inventory, notifications, SelectObjectContent, ACLs, and website hosting stay outside this quickstart.
Available now
Review ObjectDB limitsUse the limits and compatibility guidance before expanding ObjectDB compatibility or product claims.
Available now
Read tutorial prerequisitesCheck the local tool baseline and product-specific setup expectations for first-success tutorials.
Available
Adapt SDK examplesUse illustrative Python boto3 and AWS SDK for JavaScript v3 examples after completing the local curl workflow.
Available
Compare S3 Core behaviorUse the compatibility matrix to separate supported, partial, unsupported, preview, future, and product-bound S3 surfaces.