[{"data":1,"prerenderedAt":547},["ShallowReactive",2],{"navigation_docs":3,"section-navigation-docs":130,"-docs-object-storage":164,"-docs-object-storage-surround":454,"doc-previews":459},[4,8,50,54,58,62,66,70,74,78,82,86,90,94,98,102,106,110,114,118,122,126],{"title":5,"path":6,"stem":7},"Quickstart","\u002Fdocs\u002Fquickstart","docs\u002F01.quickstart",{"title":9,"path":10,"stem":11,"children":12},"Guides","\u002Fdocs\u002Fguides","docs\u002F02.guides\u002Findex",[13,14,18,22,26,30,34,38,42,46],{"title":9,"path":10,"stem":11},{"title":15,"path":16,"stem":17},"Next.js","\u002Fdocs\u002Fguides\u002Fnextjs","docs\u002F02.guides\u002F1.nextjs",{"title":19,"path":20,"stem":21},"Nuxt","\u002Fdocs\u002Fguides\u002Fnuxt","docs\u002F02.guides\u002F2.nuxt",{"title":23,"path":24,"stem":25},"SvelteKit","\u002Fdocs\u002Fguides\u002Fsveltekit","docs\u002F02.guides\u002F3.sveltekit",{"title":27,"path":28,"stem":29},"Astro","\u002Fdocs\u002Fguides\u002Fastro","docs\u002F02.guides\u002F4.astro",{"title":31,"path":32,"stem":33},"Express","\u002Fdocs\u002Fguides\u002Fexpress","docs\u002F02.guides\u002F5.express",{"title":35,"path":36,"stem":37},"FastAPI","\u002Fdocs\u002Fguides\u002Ffastapi","docs\u002F02.guides\u002F6.fastapi",{"title":39,"path":40,"stem":41},"Django","\u002Fdocs\u002Fguides\u002Fdjango","docs\u002F02.guides\u002F7.django",{"title":43,"path":44,"stem":45},"Laravel","\u002Fdocs\u002Fguides\u002Flaravel","docs\u002F02.guides\u002F8.laravel",{"title":47,"path":48,"stem":49},"Go","\u002Fdocs\u002Fguides\u002Fgo","docs\u002F02.guides\u002F9.go",{"title":51,"path":52,"stem":53},"Services","\u002Fdocs\u002Fservices","docs\u002F03.services",{"title":55,"path":56,"stem":57},"Deployments","\u002Fdocs\u002Fdeployments","docs\u002F04.deployments",{"title":59,"path":60,"stem":61},"Builds","\u002Fdocs\u002Fbuilds","docs\u002F05.builds",{"title":63,"path":64,"stem":65},"Variables","\u002Fdocs\u002Fvariables","docs\u002F06.variables",{"title":67,"path":68,"stem":69},"Domains","\u002Fdocs\u002Fdomains","docs\u002F07.domains",{"title":71,"path":72,"stem":73},"PostgreSQL","\u002Fdocs\u002Fpostgres","docs\u002F08.postgres",{"title":75,"path":76,"stem":77},"Object storage","\u002Fdocs\u002Fobject-storage","docs\u002F09.object-storage",{"title":79,"path":80,"stem":81},"Volumes","\u002Fdocs\u002Fvolumes","docs\u002F10.volumes",{"title":83,"path":84,"stem":85},"Key-value store","\u002Fdocs\u002Fredis","docs\u002F11.redis",{"title":87,"path":88,"stem":89},"Workspaces","\u002Fdocs\u002Fworkspaces","docs\u002F12.workspaces",{"title":91,"path":92,"stem":93},"Projects","\u002Fdocs\u002Fprojects","docs\u002F13.projects",{"title":95,"path":96,"stem":97},"Environments","\u002Fdocs\u002Fenvironments","docs\u002F14.environments",{"title":99,"path":100,"stem":101},"Eject","\u002Fdocs\u002Feject","docs\u002F15.eject",{"title":103,"path":104,"stem":105},"API","\u002Fdocs\u002Fapi","docs\u002F16.api",{"title":107,"path":108,"stem":109},"CLI","\u002Fdocs\u002Fcli","docs\u002F17.cli",{"title":111,"path":112,"stem":113},"Claude Plugin & MCP","\u002Fdocs\u002Fclaude-plugin","docs\u002F18.claude-plugin",{"title":115,"path":116,"stem":117},"Metrics","\u002Fdocs\u002Fmetrics","docs\u002F19.metrics",{"title":119,"path":120,"stem":121},"Logs","\u002Fdocs\u002Flogs","docs\u002F20.logs",{"title":123,"path":124,"stem":125},"Billing","\u002Fdocs\u002Fbilling","docs\u002F21.billing",{"title":127,"path":128,"stem":129},"Self-hosting","\u002Fdocs\u002Fself-hosting","docs\u002F22.self-hosting",[131,132,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163],{"title":5,"path":6,"stem":7},{"title":9,"path":10,"stem":11,"children":133},[134,135,136,137,138,139,140,141,142,143],{"title":9,"path":10,"stem":11},{"title":15,"path":16,"stem":17},{"title":19,"path":20,"stem":21},{"title":23,"path":24,"stem":25},{"title":27,"path":28,"stem":29},{"title":31,"path":32,"stem":33},{"title":35,"path":36,"stem":37},{"title":39,"path":40,"stem":41},{"title":43,"path":44,"stem":45},{"title":47,"path":48,"stem":49},{"title":51,"path":52,"stem":53},{"title":55,"path":56,"stem":57},{"title":59,"path":60,"stem":61},{"title":63,"path":64,"stem":65},{"title":67,"path":68,"stem":69},{"title":71,"path":72,"stem":73},{"title":75,"path":76,"stem":77},{"title":79,"path":80,"stem":81},{"title":83,"path":84,"stem":85},{"title":87,"path":88,"stem":89},{"title":91,"path":92,"stem":93},{"title":95,"path":96,"stem":97},{"title":99,"path":100,"stem":101},{"title":103,"path":104,"stem":105},{"title":107,"path":108,"stem":109},{"title":111,"path":112,"stem":113},{"title":115,"path":116,"stem":117},{"title":119,"path":120,"stem":121},{"title":123,"path":124,"stem":125},{"title":127,"path":128,"stem":129},{"id":165,"title":75,"body":166,"description":447,"extension":448,"links":449,"meta":450,"navigation":451,"path":76,"seo":452,"stem":77,"__hash__":453},"docs\u002Fdocs\u002F09.object-storage.md",{"type":167,"value":168,"toc":436},"minimark",[169,173,176,181,193,201,205,216,219,290,315,322,328,335,339,342,351,354,358,365,372,378,381,385,392,396,399,413,417],[170,171,172],"p",{},"Object storage gives your services somewhere to put files, such as user uploads, generated PDFs and exports.",[170,174,175],{},"Buckets are S3-compatible, so the SDK you already use works unchanged. They are private by default, they connect to a service without you copying credentials around, and any of them can be switched to a public URL served from a CDN when the files are meant to be read by everyone.",[177,178,180],"h2",{"id":179},"provisioning","Provisioning",[170,182,183,184,188,189,192],{},"On the project canvas, click ",[185,186,187],"strong",{},"Create"," and choose ",[185,190,191],{},"Bucket",". Give it a name between 2 and 16 characters and confirm. It is ready as soon as it appears.",[170,194,195,196,200],{},"A bucket belongs to one ",[197,198,199],"a",{"href":96},"environment",", so development and production keep separate files. An environment can hold up to 10 buckets.",[177,202,204],{"id":203},"connect","Connect",[170,206,207,208,212,213,215],{},"A service reaches a bucket with S3 credentials, which you pass in as ",[197,209,211],{"href":210},"\u002Fdocs\u002Fvariables#dynamic-variables","dynamic variables"," rather than pasting them anywhere. Open the service's ",[185,214,63],{}," tab, add a key, click the link icon in the value field, and pick from the bucket's group.",[170,217,218],{},"A bucket exposes five values:",[220,221,222,235],"table",{},[223,224,225],"thead",{},[226,227,228,232],"tr",{},[229,230,231],"th",{},"Variable",[229,233,234],{},"What it is",[236,237,238,250,260,270,280],"tbody",{},[226,239,240,247],{},[241,242,243],"td",{},[244,245,246],"code",{},"bucket",[241,248,249],{},"The bucket name to address in API calls",[226,251,252,257],{},[241,253,254],{},[244,255,256],{},"endpoint",[241,258,259],{},"The S3 endpoint to point your client at",[226,261,262,267],{},[241,263,264],{},[244,265,266],{},"region",[241,268,269],{},"The region the bucket lives in",[226,271,272,277],{},[241,273,274],{},[244,275,276],{},"accessKeyId",[241,278,279],{},"Access key",[226,281,282,287],{},[241,283,284],{},[244,285,286],{},"secretAccessKey",[241,288,289],{},"Secret key",[170,291,292,293,296,297,300,301,300,304,300,307,310,311,314],{},"Name the keys whatever your library expects. The ",[197,294,295],{"href":6},"quickstart"," wires them up as ",[244,298,299],{},"S3_BUCKET",", ",[244,302,303],{},"S3_ENDPOINT",[244,305,306],{},"S3_REGION",[244,308,309],{},"S3_ACCESS_KEY_ID"," and ",[244,312,313],{},"S3_SECRET_ACCESS_KEY",".",[170,316,317,318,321],{},"The credentials are scoped to your ",[197,319,320],{"href":88},"workspace",". One access key covers every bucket in it, so a service holding one bucket's variables can reach the workspace's other buckets too, but nothing outside of it.",[170,323,324,325,327],{},"The bucket's ",[185,326,204],{}," tab shows these credentials, along with ready-made configuration for environment variables, the AWS CLI, rclone, Node and Python.",[329,330,331,332,334],"note",{},"Use path-style addressing in your client. The snippets on the ",[185,333,204],{}," tab already set it.",[177,336,338],{"id":337},"public-read","Public read",[170,340,341],{},"Buckets are private by default. Objects are reachable only with the credentials, which is what you want for anything belonging to a particular user.",[170,343,344,345,347,348,350],{},"For files meant to be served to everyone, such as avatars, product images and downloads, open the ",[185,346,204],{}," tab and switch ",[185,349,338],{}," on. The bucket gets a public HTTPS URL served from a CDN, shown on the same tab. Its certificate is issued in the background, so the URL can take a few minutes to start answering.",[170,352,353],{},"Switching it back off removes the public URL, and the objects go back to being reachable only with the credentials.",[177,355,357],{"id":356},"file-explorer","File explorer",[170,359,360,361,364],{},"The ",[185,362,363],{},"Files"," tab is a browser for the bucket. It lists objects and folders, walks into prefixes, and lets you create folders, upload (dropping files onto it works), download and delete without a client.",[170,366,367],{},[368,369],"img",{"alt":370,"src":371},"The Files tab of a bucket, listing the objects under a prefix","\u002Fimg\u002Fdocs\u002Fobject-storage\u002Ffiles-explorer.png",[170,373,374],{},[375,376,377],"em",{},"Browsing a prefix, with upload, download and delete in reach.",[170,379,380],{},"It is meant for checking that an upload landed where you expected, pulling a file out to look at, and seeding a development bucket with a handful of objects. For bulk work, use the credentials with the AWS CLI or rclone.",[177,382,384],{"id":383},"deleting-a-bucket","Deleting a bucket",[170,386,387,388,391],{},"Deleting is on the bucket's ",[185,389,390],{},"Settings"," tab, alongside its region, current size and object count. It destroys every object in it and the credentials' access to it, with no restore and no retention window, so a service still consuming its variables will start failing on its next request.",[177,393,395],{"id":394},"under-the-hood","Under the hood",[170,397,398],{},"Buckets are ordinary S3 buckets, currently hosted on OVHcloud object storage in Europe. Running storage hardware is out of scope for Lucity, so the platform provisions buckets from a provider rather than operating its own. The credentials are kept as a Kubernetes Secret in your environment's namespace, which is where dynamic variables read them from, and a public bucket is a CDN pull zone in front of a read-only view of it.",[170,400,401,402,405,406,412],{},"Nothing about that is Lucity-specific: an ",[197,403,404],{"href":100},"ejected"," project keeps its buckets and its credentials exactly as they are. If you would rather host the storage yourself, ",[197,407,411],{"href":408,"rel":409},"https:\u002F\u002Fgaragehq.deuxfleurs.fr",[410],"nofollow","Garage"," is a good S3-compatible target to move them to.",[177,414,416],{"id":415},"next-steps","Next steps",[418,419,420,426,431],"ul",{},[421,422,423,425],"li",{},[197,424,63],{"href":210}," for wiring a bucket into a service",[421,427,428,430],{},[197,429,79],{"href":80}," for when a service needs a real filesystem instead",[421,432,433,435],{},[197,434,71],{"href":72}," for the data that does not belong in a bucket",{"title":437,"searchDepth":438,"depth":438,"links":439},"",2,[440,441,442,443,444,445,446],{"id":179,"depth":438,"text":180},{"id":203,"depth":438,"text":204},{"id":337,"depth":438,"text":338},{"id":356,"depth":438,"text":357},{"id":383,"depth":438,"text":384},{"id":394,"depth":438,"text":395},{"id":415,"depth":438,"text":416},"S3-compatible buckets for uploads, exports and anything else your service needs to keep.","md",null,{},true,{"title":75,"description":447},"Yo783ZB1dlORaw4eFyyCGWkGzTS_z2sKKQUS-0ChZ90",[455,457],{"title":71,"path":72,"stem":73,"description":456,"children":-1},"Managed PostgreSQL databases, replicated and backed up, connected to your services without copying credentials.",{"title":79,"path":80,"stem":81,"description":458,"children":-1},"Persistent disks for services that need to keep state on the filesystem.",[460,463,465,468,471,474,477,480,483,486,489,492,495,497,499,501,503,505,506,507,508,510,512,514,516,518,520,522,524,526,528,530,532,535,539,543],{"path":6,"title":461,"description":462},"Deploy your first service","Deploy an app to Lucity, put it on a public domain, and connect a PostgreSQL database and an object storage bucket in about fifteen minutes.",{"path":464,"title":9,"description":449},"\u002Fdocs\u002Fguides\u002F.navigation",{"path":16,"title":466,"description":467},"Deploy a Next.js app","Deploy a Next.js app on Lucity, with a database, environment variables that behave, and no Dockerfile.",{"path":20,"title":469,"description":470},"Deploy a Nuxt app","Deploy a Nuxt app on Lucity. Nitro output, runtime config, and a database, with no preset to pick.",{"path":24,"title":472,"description":473},"Deploy a SvelteKit app","Deploy a SvelteKit app on Lucity. One adapter change stands between a fresh project and a running service.",{"path":28,"title":475,"description":476},"Deploy an Astro site","Deploy an Astro site on Lucity, static by default and server rendered when you add an adapter.",{"path":32,"title":478,"description":479},"Deploy an Express API","Deploy an Express API on Lucity. Three requirements, none of them platform-specific.",{"path":36,"title":481,"description":482},"Deploy a FastAPI service","Deploy a FastAPI service on Lucity. Detection is picky about layout, and the fix is one setting.",{"path":40,"title":484,"description":485},"Deploy a Django project","Deploy a Django project on Lucity, with migrations that run themselves and static files that do not.",{"path":44,"title":487,"description":488},"Deploy a Laravel application","Deploy a Laravel application on Lucity, with migrations, caches and a queue worker, and no server to configure.",{"path":48,"title":490,"description":491},"Deploy a Go service","Deploy a Go service on Lucity. Compiled in the build, shipped as a binary, nothing else in the image.",{"path":10,"title":493,"description":494},"Deploy your framework","Deploy guides for the frameworks people actually ship: Next.js, Nuxt, SvelteKit, Astro, Express, FastAPI, Django, Laravel, and Go.",{"path":52,"title":51,"description":496},"Services are the deployable units of a project: what they are, how they are configured, and how they scale.",{"path":56,"title":55,"description":498},"How a deployment goes live on Lucity, and the ways to trigger one.",{"path":60,"title":59,"description":500},"How Lucity turns your source code into a container image.",{"path":64,"title":63,"description":502},"Configuration for your services: service variables, shared variables, and dynamic variables.",{"path":68,"title":67,"description":504},"Put a service on the internet. Use a platform hostname for quick tests, or a domain you own.",{"path":72,"title":71,"description":456},{"path":76,"title":75,"description":447},{"path":80,"title":79,"description":458},{"path":84,"title":83,"description":509},"A Redis®-compatible key-value store for caching, sessions and queues.",{"path":88,"title":87,"description":511},"Workspaces represent your organization in Lucity, with their own members, isolation and billing.",{"path":92,"title":91,"description":513},"Projects group services, databases and the environments they run in.",{"path":96,"title":95,"description":515},"Development, staging, production: isolated copies of the same application.",{"path":100,"title":99,"description":517},"Download a project as a Helm chart and run it on a Kubernetes cluster of your own.",{"path":104,"title":103,"description":519},"The GraphQL API behind the dashboard, with an interactive playground.",{"path":108,"title":107,"description":521},"Deploy and manage your services from a terminal or a CI pipeline.",{"path":112,"title":111,"description":523},"Deploy and manage your services from Claude Code, Codex, Cursor or any other MCP client.",{"path":116,"title":115,"description":525},"CPU and memory for every service, and disk usage for every volume.",{"path":120,"title":119,"description":527},"What your services print while they run, and the output of every deployment step.",{"path":124,"title":123,"description":529},"Plans, resource usage, the free trial, and what happens when a payment fails.",{"path":128,"title":127,"description":531},"Run the whole platform on a Kubernetes cluster you own, using the same two Helm charts we run ourselves.",{"path":533,"title":534,"description":449},"\u002Flegal\u002F.navigation","Legal",{"path":536,"title":537,"description":538},"\u002Flegal\u002Fdata-processing-agreement","Data Processing Agreement","How Lucity processes personal data on your behalf.",{"path":540,"title":541,"description":542},"\u002Flegal\u002Fprivacy-policy","Privacy Policy","How Lucity handles your data.",{"path":544,"title":545,"description":546},"\u002Flegal\u002Fterms-of-use","Terms of Use","Terms governing your use of Lucity.",1791216728159]