# S3

**Introduced:** 4.5



# S3

Lucee supports S3-compatible object storage through the S3 extension, which provides both a Virtual File System (VFS) using `s3://` paths and a set of native `s3*()` functions. It works with AWS S3 and any S3-compatible provider such as MinIO, Backblaze B2, or Wasabi.

## Installation

The S3 extension must be installed before use. Install it via the Lucee Administrator under **Extension > Applications**, or declare it in `.CFConfig.json`:

```json
{
  "extensions": [
    {
      "id": "17AB52DE-B300-A94B-E058BD978511E39E",
      "name": "S3 Extension"
    }
  ]
}
```

## Configuration

Credentials and connection settings can be configured in three ways, in order of precedence:

### Application.cfc

```javascript
component {
    this.name = "myapp";

    // configure S3 credentials and endpoint for all s3:// paths in this application
    this.vfs.s3.accessKeyId     = server.system.environment.LUCEE_S3_ACCESSKEYID;
    this.vfs.s3.awsSecretKey    = server.system.environment.LUCEE_S3_SECRETACCESSKEY;
    this.vfs.s3.host            = server.system.environment.LUCEE_S3_HOST;
    this.vfs.s3.defaultLocation = server.system.environment.LUCEE_S3_REGION;

    // required for self-hosted providers like MinIO that use path-style URLs
    this.vfs.s3.pathStyleAccess = true;

    // set to false for providers running over plain HTTP (e.g. local MinIO)
    this.vfs.s3.ssl             = false;
}
```

### Environment Variables / System Properties

| Environment Variable          | System Property                | Description                        |
|-------------------------------|--------------------------------|------------------------------------|
| `LUCEE_S3_ACCESSKEYID`        | `lucee.s3.accesskeyid`         | Access key ID                      |
| `LUCEE_S3_SECRETACCESSKEY`    | `lucee.s3.secretaccesskey`     | Secret access key                  |
| `LUCEE_S3_HOST`               | `lucee.s3.host`                | Custom endpoint host (non-AWS)     |
| `LUCEE_S3_REGION`             | `lucee.s3.region`              | Region or location                 |
| `LUCEE_S3_PATHSTYLEACCESS`    | `lucee.s3.pathstyleaccess`     | Force path-style URLs (`true`/`false`) |
| `LUCEE_S3_SSL`                | `lucee.s3.ssl`                 | Use SSL/HTTPS (`true`/`false`)     |

### Inline URL Credentials

Credentials can be embedded directly in the `s3://` URL. Useful for one-off operations or multiple accounts in the same application:

```
s3://{accessKeyId}:{secretKey}@{host}/{bucket}/path/to/file.txt
```

---

## Virtual File System (VFS)

With credentials configured in `Application.cfc` or via environment variables, all standard Lucee file functions work transparently against S3 using `s3:///` paths (three slashes — the third slash starts the bucket path):

```javascript
// read a file
content = fileRead("s3:///my-bucket/hello.txt");

// write a file
fileWrite("s3:///my-bucket/hello.txt", "Hello World");

// check existence
exists = fileExists("s3:///my-bucket/hello.txt");

// list a bucket
files = directoryList("s3:///my-bucket/", false, "query");

// copy between buckets
fileCopy("s3:///my-bucket/hello.txt", "s3:///other-bucket/hello.txt");

// delete
fileDelete("s3:///my-bucket/hello.txt");
```

---

## Native S3 Functions

The extension also provides native `s3*()` functions that expose S3-specific features not available through the generic VFS interface:

### Buckets

```javascript
// list all buckets
buckets = s3listBuckets();

// list objects in a bucket
objects = s3listBucket("my-bucket");
```

### Read and Write

```javascript
// read a text object
content = s3read("my-bucket", "hello.txt");

// read binary object
binary = s3readBinary("my-bucket", "image.png");

// write an object
s3write("my-bucket", "hello.txt", "Hello World");
```

### Copy, Move, Delete

```javascript
// copy object (within or between buckets)
s3copy("my-bucket", "hello.txt", "other-bucket", "hello-copy.txt");

// move object
s3move("my-bucket", "hello.txt", "other-bucket", "hello-moved.txt");

// check existence
exists = s3exists("my-bucket", "hello.txt");

// delete object
s3delete("my-bucket", "hello.txt");
```

### Metadata and ACL

```javascript
// get object metadata
meta = s3getMetaData("my-bucket", "hello.txt");

// set custom metadata
s3setMetaData("my-bucket", "hello.txt", { "x-custom-tag": "value" });

// get ACL
acl = s3getACL("my-bucket", "hello.txt");
```

### URLs

```javascript
// generate a presigned URL (expires in 1 hour)
url = s3generatePresignedUrl("my-bucket", "hello.txt", 3600);

// generate a permanent URI
uri = s3generateUri("my-bucket", "hello.txt");
```

---

## Self-Hosted Providers (MinIO, LocalStack)

Self-hosted S3-compatible providers require two additional settings:

- **`pathStyleAccess = true`** — Lucee automatically enables path-style for unrecognised hostnames, but set this explicitly to guarantee it regardless of hostname. Prevents the AWS SDK from constructing virtual-hosted style URLs (`bucket.host`) which fail DNS resolution on non-AWS hostnames
- **`ssl = false`** — disables HTTPS when the provider runs over plain HTTP

```javascript
// Application.cfc for MinIO
this.vfs.s3.accessKeyId     = "minioadmin";
this.vfs.s3.awsSecretKey    = "minioadmin";
this.vfs.s3.host            = "minio:9000";
this.vfs.s3.defaultLocation = "us-east-1";
this.vfs.s3.pathStyleAccess = true;
this.vfs.s3.ssl             = false;
```

---

## Available `this.vfs.s3` Settings

| Setting            | Type      | Default  | Description                                                   |
|--------------------|-----------|----------|---------------------------------------------------------------|
| `accessKeyId`      | `string`  | —        | Access key ID                                                 |
| `awsSecretKey`     | `string`  | —        | Secret access key                                             |
| `host`             | `string`  | AWS S3   | Custom endpoint host, e.g. `minio:9000`                      |
| `defaultLocation`  | `string`  | —        | Region, e.g. `us-east-1`                                      |
| `pathStyleAccess`  | `boolean` | `null`   | `true` = force path-style, `false` = force virtual-hosted, `null` = auto-detect |
| `ssl`              | `boolean` | `true`   | `false` = connect over plain HTTP                            |
| `acl`              | `string`  | —        | Default ACL for new objects, e.g. `public-read`              |
| `cacheRegion`      | `boolean` | `false`  | Cache bucket region lookups to reduce extra requests         |
| `cache`            | `timespan`| —        | Cache duration for object listings                           |

---

## See Also

- [Virtual File System](virtual-file-system.md)
- [File Functions](file-functions.md)
- [Extensions](extensions.md)

# Categories

[S3 ](../categories/s3.md)