Deploying Jay
What to expose
Section titled “What to expose”| Listener | Default | Expose to |
|---|---|---|
| S3 API | :9000 |
Whatever needs to store objects, including the public internet if that is your design |
| Admin API | :9001 |
Nothing outside your network. It creates accounts and tokens |
| Native protocol | :4444 |
Nothing outside your network, unless you give it TLS — the handshake carries the token secret in the clear by default |
If you do not use the native protocol, disable its listener entirely by setting
JAY_NATIVE_ADDR to an empty value. The startup line then reports
"native":"disabled".
Jay terminates TLS itself when you give it a certificate:
JAY_TLS_CERT=/etc/jay/fullchain.pemJAY_TLS_KEY=/etc/jay/privkey.pemThis covers the S3 and admin listeners. The native protocol has its own pair and is not covered by the one above:
JAY_NATIVE_TLS_CERT=/etc/jay/native-fullchain.pemJAY_NATIVE_TLS_KEY=/etc/jay/native-privkey.pemThey are separate so that turning on TLS for S3 cannot silently change the native transport and break clients already speaking to it in the clear. Setting one half of either pair without the other aborts startup rather than serving in the clear. Left unset, the native listener stays plaintext and belongs on an internal network — Jay says so in a startup warning.
Enable TLS if you use mc or warp. minio-go signs plaintext uploads with
SigV4’s streaming mode, which Jay refuses; over TLS the same clients upload
normally. See S3 compatibility.
Behind a reverse proxy
Section titled “Behind a reverse proxy”Jay does not trust forwarding headers by default, because a client that can
forge X-Forwarded-For can evade the pre-auth rate limiter and poison your
access logs.
JAY_TRUST_PROXY_HEADERS=trueWith this on, X-Forwarded-For and X-Real-IP are honoured only when the
direct TCP peer is loopback or RFC1918. A request arriving straight from the
internet carrying the header is still attributed to its real address.
Make sure your proxy does not buffer request bodies to disk if you upload large
objects, and that its own body-size limit is at or above
JAY_MAX_OBJECT_SIZE (5 GiB by default).
The whole state of the server is JAY_DATA_DIR. That does not mean copying
that directory backs Jay up — meta/jay.db is a live bbolt file, and a copy
taken from a running server can be unrestorable. See
Backup and restore.
Readiness fails when free space on that filesystem drops below
JAY_MIN_FREE_BYTES (500 MiB by default), which pulls the instance out of a
load balancer pool before the disk fills. A full disk corrupts bbolt; Jay would
rather stop serving than get there.
Backups
Section titled “Backups”Jay snapshots its bbolt metadata every hour, verifies each snapshot after writing it, keeps 24 and prunes after 7 days. A snapshot that fails verification is deleted — an unrestorable backup is worse than none, because it satisfies a retention policy while being useless.
Two things to be clear about:
- The snapshot covers metadata only. Object bytes are not in it and Jay
keeps no copy of them anywhere. Backing up
buckets/is your job, and Jay cannot be restored without it. APUTover an existing key also replaces the file, and the old bytes are gone — Jay has no versioning. JAY_METADATA_BACKUP_DIRdefaults to<JAY_DATA_DIR>/backups, which is the same disk. For real disaster recovery, point it at a separate volume. Jay warns at startup while it is not, and reports it in thedurabilityblock of/health/ready.
The full procedure — what to back up, in what order to restore it, and how to verify the result — is in Backup and restore.
Health probes
Section titled “Health probes”Both are on the admin port and need no authentication:
GET /health/live always 200 while the process is upGET /health/ready 200 once startup recovery has finishedReadiness is a live check, not a one-time flag. It fails if a bbolt read transaction does not complete within its timeout, or if free space drops below the floor. If readiness starts failing, look at the disk first.
Readiness also carries a durability block on every response, stating what this
instance has a recovery path for:
{ "status": "ready", "durability": { "metadata_backup": "hourly verified snapshot of meta/jay.db (bbolt): accounts, buckets, object records, tokens, multipart state", "object_bytes_backup": "none — object bytes under buckets/ — jay keeps no copy of them; back that directory up separately", "metadata_backup_dir": "/var/lib/jay/backups", "metadata_backup_shares_data_filesystem": true }}It never changes the status code. Object bytes having no backup is a property of Jay’s design, not a fault of the instance; failing readiness over it would pull a healthy server out of the pool forever.
Upgrades
Section titled “Upgrades”Jay is a single process over a single data directory. Stop it, replace the binary or image, start it. Startup recovery reconciles metadata against the files on disk before the server accepts traffic, so an unclean stop is a handled case rather than an incident.