The server Going to production
Going to production
On this page
The list
secretlong and random (openssl rand -hex 32), the same in every process, from the environment, never in the code.identifyfrom your session, andauthorizewithbyRolesor rules of yours: nevereveryone().- The bucket’s rule of origins with your domains only,
ETagexposed (Storage). maxSizeand thequotaof each person in the settings;trashDaysso the trash empties itself.inspect: checkType()at least, and ClamAV for files from people you do not know (Checking uploads).- Postgres for more than one process (Metadata), with its backups.
- A lifecycle rule in the bucket, as below.
clientIpbehind your proxy, and alimiterof Redis for more than one process (Hooks, logs and limits).- HTTP/2 in front of it: each tab watching holds a connection, and over HTTP/1.1 a browser has six for a host. A tab not seen lets go of its own.
derive: deriveAll()with sharp and pdf.js installed, for the pictures and the text of what no page made (Previews).
Uploads left halfway
A page closed in the middle of an upload leaves its parts in the bucket, which cost space and are listed nowhere. The server sweeps them itself every ten minutes, as requests come: those older than the life of their tokens (a day) are aborted, under its prefix only, and on the disk their parts removed. A lifecycle rule of the bucket does the same without it:
{
"Rules": [
{ "ID": "abort-unfinished", "Status": "Enabled", "Filter": { "Prefix": "" },
"AbortIncompleteMultipartUpload": { "DaysAfterInitiation": 2 } }
]
}Backups
The entries are what says which bytes are which file: without them, the bucket is a heap of ids. Back them up as your database: pg_dump for Postgres, or for SQLite sqlite3 drive.sqlite ".backup backup.sqlite", which is safe while the server writes.
The bytes are never changed in place: a version is a new key. So versioning in the bucket is not needed for the drive, and a copy of the bucket (R2 to S3, rclone) is a backup that only grows. Delete in it only what the drive deleted.
Rotating keys
- The key of the bucket: make a new one, give it to every process, then revoke the old one once two hours have gone: an address to download lasts fifteen minutes, one to show a picture two hours.
- The
secret: a new one ends the uploads in progress (their tokens) and changes the addresses of links. Links made before stop working, as they are signed with it: make it at a quiet hour, and tell those who shared links.
Behind a proxy
location /api/files/ {
proxy_pass http://app;
proxy_request_buffering off; # the disk storage carries the bytes through the server
client_max_body_size 64m; # a part is 8 MiB, more for a file of over 80 GB
proxy_read_timeout 1h; # the events go on as long as the page watches
}With a bucket, the bytes do not pass through the proxy at all: only the requests of the drive, which are small, and the events, which last.
What to watch
The server writes to the console what it could not do and did not answer for: an activity not kept, onShare failed, uploads not swept, a file that could not be inspected. Each with the error. A 500 says nothing of the inside to the page; the console says it all.