[{"data":1,"prerenderedAt":1105},["ShallowReactive",2],{"navigation_docs":3,"section-navigation-docs":130,"-docs-eject":164,"-docs-eject-surround":1012,"doc-previews":1017},[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":99,"body":166,"description":1005,"extension":1006,"links":1007,"meta":1008,"navigation":1009,"path":100,"seo":1010,"stem":101,"__hash__":1011},"docs\u002Fdocs\u002F15.eject.md",{"type":167,"value":168,"toc":990},"minimark",[169,178,187,190,195,206,213,219,223,227,237,251,254,257,302,306,317,922,926,929,965,969,986],[170,171,172,173,177],"p",{},"Ejecting downloads a project as a standard Helm chart with one values file per environment. Install it with ",[174,175,176],"code",{},"helm"," on a Kubernetes cluster of your own and the same services, databases, key-value stores and volumes come up there, configured the way they run on Lucity, without any Lucity component involved.",[170,179,180,181,186],{},"It is a copy of the configuration, not a migration. Your data and the images Lucity built for you do not come along, and moving them is manual work, as the ",[182,183,185],"a",{"href":184},"#limitations","limitations"," below spell out.",[170,188,189],{},"Ejecting changes nothing on Lucity. The project keeps running, so you can eject to keep a copy, to try out your own cluster first, or to move for good.",[191,192,194],"h2",{"id":193},"downloading-a-project","Downloading a project",[170,196,197,198,201,202,205],{},"Open the project, click ",[199,200,99],"strong",{}," in the header, then ",[199,203,204],{},"Download .zip",". The archive covers every environment in the project that has something in it.",[170,207,208],{},[209,210],"img",{"alt":211,"src":212},"The Eject dialog, opened from the Eject button in the project header, with Download .zip at the bottom","\u002Fimg\u002Fdocs\u002Feject\u002Feject-dialog.png",[170,214,215],{},[216,217,218],"em",{},"Eject sits in the header of every project, next to Settings.",[220,221,222],"warning",{},"The archive holds your variables in plain text, secrets included, along with the passwords of your key-value stores. Keep it where you would keep a password, and out of public repositories.",[191,224,226],{"id":225},"whats-inside","What's inside",[228,229,235],"pre",{"className":230,"code":232,"language":233,"meta":234},[231],"language-text","shop-ejected\u002F\n├── README.md\n├── build.sh\n├── chart\u002F\n└── values\u002F\n    ├── development.yaml\n    └── production.yaml\n","text","",[174,236,232],{"__ignoreMap":234},[170,238,239,242,243,246,247,250],{},[174,240,241],{},"chart\u002F"," is the Helm chart every Lucity environment is deployed with. Each file in ",[174,244,245],{},"values\u002F"," describes one environment as it runs right now, from its services with their images, variables, replicas, resources and domains to its databases, key-value stores and volumes. ",[174,248,249],{},"build.sh"," rebuilds the images of services built from source, and the README has the install command and links back to this page.",[191,252,253],{"id":185},"Limitations",[170,255,256],{},"The archive covers configuration only. The rest is manual work:",[258,259,260,272,278,284,290,296],"ul",{},[261,262,263,266,267,271],"li",{},[199,264,265],{},"Data is not included."," Databases, key-value stores and volumes come up empty on your cluster, and bucket files stay in their buckets. You copy all of it yourself, as described under ",[182,268,270],{"href":269},"#move-your-data","move your data",".",[261,273,274,277],{},[199,275,276],{},"Volume contents have no export."," Lucity has no way to download a volume, so its files have to come out through your own service, for example by copying them into a bucket.",[261,279,280,283],{},[199,281,282],{},"Images built from source have to be rebuilt."," They sit in the platform's registry, which nothing outside Lucity can reach. The archive's build script rebuilds them, on a machine of yours with Docker.",[261,285,286,289],{},[199,287,288],{},"Moving means downtime."," There is no live migration. Writes have to stop while the data is copied, and custom domains wait a minute or two for new certificates after the DNS switch.",[261,291,292,295],{},[199,293,294],{},"Credentials change."," Databases get new passwords on your cluster, and bucket credentials are not in the archive. Services that read them through variables pick up the new ones, but anything holding a copied connection string needs updating.",[261,297,298,301],{},[199,299,300],{},"It is a snapshot."," The chart and values stay as they were when you downloaded them. Changes you make on Lucity afterwards need a fresh eject.",[191,303,305],{"id":304},"installing-on-your-own-cluster","Installing on your own cluster",[170,307,308,309,312,313,316],{},"The steps below install ",[174,310,311],{},"production"," of a project called ",[174,314,315],{},"shop",". Repeat them for every environment you want to run, each in its own namespace.",[318,319,321,326,329,439,442,459,463,466,476,499,524,540,554,558,561,604,608,619,741,744,787,794,797,801,804,822,886,895,901,907,911,914],"steps",{"level":320},"3",[322,323,325],"h3",{"id":324},"prerequisites","Prerequisites",[170,327,328],{},"What to install up front depends on what the project uses.",[330,331,332,345],"table",{},[333,334,335],"thead",{},[336,337,338,342],"tr",{},[339,340,341],"th",{},"If the project has",[339,343,344],{},"The cluster needs",[346,347,348,356,364,379,392,406,418],"tbody",{},[336,349,350,353],{},[351,352,51],"td",{},[351,354,355],{},"Kubernetes 1.33 or newer, on nodes that support user namespaces (Linux 6.3+, containerd 2.0+ or CRI-O)",[336,357,358,361],{},[351,359,360],{},"Databases, key-value stores or volumes",[351,362,363],{},"A default StorageClass",[336,365,366,369],{},[351,367,368],{},"PostgreSQL databases",[351,370,371,372,378],{},"The ",[182,373,377],{"href":374,"rel":375},"https:\u002F\u002Fcloudnative-pg.io",[376],"nofollow","CloudNativePG"," operator",[336,380,381,383],{},[351,382,67],{},[351,384,385,386,391],{},"A ",[182,387,390],{"href":388,"rel":389},"https:\u002F\u002Fgateway-api.sigs.k8s.io",[376],"Gateway API"," implementation and a Gateway reachable from the internet",[336,393,394,397],{},[351,395,396],{},"Custom domains",[351,398,399,400,405],{},"ListenerSet support on that Gateway, and ",[182,401,404],{"href":402,"rel":403},"https:\u002F\u002Fcert-manager.io",[376],"cert-manager"," 1.20+ with an HTTP-01 ClusterIssuer",[336,407,408,411],{},[351,409,410],{},"Autoscaling",[351,412,413],{},[182,414,417],{"href":415,"rel":416},"https:\u002F\u002Fgithub.com\u002Fkubernetes-sigs\u002Fmetrics-server",[376],"metrics-server",[336,419,420,423],{},[351,421,422],{},"A database with internet access",[351,424,425,430,431,434,435,438],{},[182,426,429],{"href":427,"rel":428},"https:\u002F\u002Ftraefik.io",[376],"Traefik"," with an entrypoint named ",[174,432,433],{},"postgres"," that receives the client's real address (PROXY protocol behind a load balancer), or delete ",[174,436,437],{},"publicAccess"," from the database's values",[170,440,441],{},"Every service runs in its own user namespace, so root inside a container is an unprivileged user on the node. That is where the node requirements come from.",[170,443,444,445,448,449,454,455,458],{},"Each custom domain brings its own listener and certificate. Your Gateway has to accept listeners from the environment's namespace, which is its ",[174,446,447],{},"allowedListeners"," setting, and cert-manager needs its ",[182,450,453],{"href":451,"rel":452},"https:\u002F\u002Fcert-manager.io\u002Fdocs\u002Fusage\u002Fgateway\u002F",[376],"Gateway API support"," switched on to answer the HTTP-01 challenge. If you would rather terminate TLS on your own Gateway listeners, delete a domain's ",[174,456,457],{},"listenerSet"," block and its route attaches to the Gateway directly.",[322,460,462],{"id":461},"rebuild-your-images","Rebuild your images",[170,464,465],{},"Services created from an image, such as Ghost from Docker Hub, keep pulling it from the same public registry and need no changes.",[170,467,468,469,471,472,475],{},"Services built from a repository point at the platform's own registry, which only Lucity's cluster can reach. ",[174,470,249],{}," builds them again and pushes them to a registry of yours. Log in to that registry with ",[174,473,474],{},"docker login"," first, then run:",[228,477,481],{"className":478,"code":479,"language":480,"meta":234,"style":234},"language-bash shiki shiki-themes gruvbox-dark-medium gruvbox-dark-medium gruvbox-dark-medium",".\u002Fbuild.sh production registry.example.com\u002Fshop\n","bash",[174,482,483],{"__ignoreMap":234},[484,485,488,492,496],"span",{"class":486,"line":487},"line",1,[484,489,491],{"class":490},"sX5TD",".\u002Fbuild.sh",[484,493,495],{"class":494},"sQLXx"," production",[484,497,498],{"class":494}," registry.example.com\u002Fshop\n",[170,500,501,502,505,506,511,512,515,516,519,520,523],{},"For every service in the environment that is built from a repository, the script clones the repository at the commit in the service's image ",[174,503,504],{},"tag"," and builds it with ",[182,507,510],{"href":508,"rel":509},"https:\u002F\u002Frailpack.com",[376],"Railpack",", in the version Lucity uses and with the service's variables. It pushes the result as ",[174,513,514],{},"registry.example.com\u002Fshop\u002F\u003Cservice>:\u003Ctag>"," and points the service's ",[174,517,518],{},"image"," in ",[174,521,522],{},"values\u002Fproduction.yaml"," at it. Add service names after the registry to build only those.",[170,525,526,527,532,533,536,537,271],{},"The script needs Docker, git and ",[182,528,531],{"href":529,"rel":530},"https:\u002F\u002Fgithub.com\u002Fmikefarah\u002Fyq",[376],"yq",", plus your own git credentials for private repositories. Images are built for ",[174,534,535],{},"linux\u002Famd64"," as on Lucity, which is emulated and slower on an Apple Silicon Mac. For an arm64 cluster, set ",[174,538,539],{},"BUILD_PLATFORM=linux\u002Farm64",[170,541,542,543,546,547,550,551,271],{},"If you would rather build another way, set the service's ",[174,544,545],{},"image.repository"," and ",[174,548,549],{},"image.tag"," to your image and delete its ",[174,552,553],{},"image.digest",[322,555,557],{"id":556},"update-the-values","Update the values",[170,559,560],{},"A few values name things that only exist on Lucity. Change them before installing:",[258,562,563,578,588,596],{},[261,564,565,570,571,546,574,577],{},[199,566,567],{},[174,568,569],{},"gateway"," is the Gateway your routes attach to. Set its ",[174,572,573],{},"name",[174,575,576],{},"namespace"," to yours.",[261,579,580,583,584,587],{},[199,581,582],{},"Platform domains",", the hostnames Lucity generated for your services, keep pointing at Lucity. Remove them from the service's ",[174,585,586],{},"domains",", or replace them with hostnames of your own. Variables that contain one, such as a frontend's API URL, need the new hostname as well.",[261,589,590,595],{},[199,591,592],{},[174,593,594],{},"issuerRef"," under each custom domain names the ClusterIssuer for its certificate. Use the name of yours.",[261,597,598,603],{},[199,599,600],{},[174,601,602],{},"imagePullSecrets"," names Lucity's registry credentials. Put the name of your own pull secret there, or remove it if your images are public.",[322,605,607],{"id":606},"install-the-chart","Install the chart",[170,609,610,611,614,615,618],{},"A service connected to a bucket reads the bucket's variables from a secret named ",[174,612,613],{},"lucity-bucket-\u003Cbucket>",", which is not part of the chart. Create it in the environment's namespace before installing, either with the bucket's current credentials from its ",[199,616,617],{},"Connect"," tab to keep using the bucket where it is, or with those of the storage you are moving to:",[228,620,622],{"className":478,"code":621,"language":480,"meta":234,"style":234},"kubectl create namespace shop-production\nkubectl create secret generic lucity-bucket-uploads -n shop-production \\\n  --from-literal=bucket=\u003Cbucket> \\\n  --from-literal=endpoint=\u003Cendpoint> \\\n  --from-literal=region=\u003Cregion> \\\n  --from-literal=accessKeyId=\u003Caccess-key-id> \\\n  --from-literal=secretAccessKey=\u003Csecret-access-key>\n",[174,623,624,638,664,682,697,712,727],{"__ignoreMap":234},[484,625,626,629,632,635],{"class":486,"line":487},[484,627,628],{"class":490},"kubectl",[484,630,631],{"class":494}," create",[484,633,634],{"class":494}," namespace",[484,636,637],{"class":494}," shop-production\n",[484,639,641,643,645,648,651,654,658,661],{"class":486,"line":640},2,[484,642,628],{"class":490},[484,644,631],{"class":494},[484,646,647],{"class":494}," secret",[484,649,650],{"class":494}," generic",[484,652,653],{"class":494}," lucity-bucket-uploads",[484,655,657],{"class":656},"s1Tsi"," -n",[484,659,660],{"class":494}," shop-production",[484,662,663],{"class":656}," \\\n",[484,665,667,670,674,677,680],{"class":486,"line":666},3,[484,668,669],{"class":656},"  --from-literal=bucket=",[484,671,673],{"class":672},"s3drp","\u003C",[484,675,676],{"class":656},"bucket",[484,678,679],{"class":672},">",[484,681,663],{"class":656},[484,683,685,688,690,693,695],{"class":486,"line":684},4,[484,686,687],{"class":656},"  --from-literal=endpoint=",[484,689,673],{"class":672},[484,691,692],{"class":656},"endpoint",[484,694,679],{"class":672},[484,696,663],{"class":656},[484,698,700,703,705,708,710],{"class":486,"line":699},5,[484,701,702],{"class":656},"  --from-literal=region=",[484,704,673],{"class":672},[484,706,707],{"class":656},"region",[484,709,679],{"class":672},[484,711,663],{"class":656},[484,713,715,718,720,723,725],{"class":486,"line":714},6,[484,716,717],{"class":656},"  --from-literal=accessKeyId=",[484,719,673],{"class":672},[484,721,722],{"class":656},"access-key-id",[484,724,679],{"class":672},[484,726,663],{"class":656},[484,728,730,733,735,738],{"class":486,"line":729},7,[484,731,732],{"class":656},"  --from-literal=secretAccessKey=",[484,734,673],{"class":672},[484,736,737],{"class":656},"secret-access-key",[484,739,740],{"class":672},">\n",[170,742,743],{},"The pull secret for a private registry goes into the same namespace. Then install the environment:",[228,745,747],{"className":478,"code":746,"language":480,"meta":234,"style":234},"helm upgrade --install lucity-app .\u002Fchart \\\n  -f values\u002Fproduction.yaml \\\n  -n shop-production --create-namespace\n",[174,748,749,767,777],{"__ignoreMap":234},[484,750,751,753,756,759,762,765],{"class":486,"line":487},[484,752,176],{"class":490},[484,754,755],{"class":494}," upgrade",[484,757,758],{"class":656}," --install",[484,760,761],{"class":494}," lucity-app",[484,763,764],{"class":494}," .\u002Fchart",[484,766,663],{"class":656},[484,768,769,772,775],{"class":486,"line":640},[484,770,771],{"class":656},"  -f",[484,773,774],{"class":494}," values\u002Fproduction.yaml",[484,776,663],{"class":656},[484,778,779,782,784],{"class":486,"line":666},[484,780,781],{"class":656},"  -n",[484,783,660],{"class":494},[484,785,786],{"class":656}," --create-namespace\n",[170,788,789,790,793],{},"The release has to be called ",[174,791,792],{},"lucity-app",". Every resource name derives from it, and the values refer to some of them by name, such as the secrets your variables are read from and the private hostnames services use to reach each other.",[170,795,796],{},"From here on the values file is your configuration. Edit it and run the same command to roll out a change.",[322,798,800],{"id":799},"move-your-data","Move your data",[170,802,803],{},"Databases, key-value stores and volumes come up empty on the new cluster. Copy their contents once nothing writes to the old ones anymore, or whatever is written in between stays behind.",[170,805,806,809,810,814,815,817,818,821],{},[199,807,808],{},"PostgreSQL."," Switch on ",[182,811,813],{"href":812},"\u002Fdocs\u002Fpostgres#public-access","internet access"," for the database and dump it with the connection string from its ",[199,816,617],{}," tab. Then restore the dump on the new database's first instance, whose pod is named ",[174,819,820],{},"lucity-app-pg-\u003Cdatabase>-1",":",[228,823,825],{"className":478,"code":824,"language":480,"meta":234,"style":234},"pg_dump --format=custom \"\u003Cconnection string>\" > main.dump\nkubectl exec -i -n shop-production lucity-app-pg-main-1 -- \\\n  pg_restore --dbname=app \u003C main.dump\n",[174,826,827,851,873],{"__ignoreMap":234},[484,828,829,832,835,839,842,845,848],{"class":486,"line":487},[484,830,831],{"class":490},"pg_dump",[484,833,834],{"class":656}," --format=custom",[484,836,838],{"class":837},"si-ur"," \"",[484,840,841],{"class":494},"\u003Cconnection string>",[484,843,844],{"class":837},"\"",[484,846,847],{"class":672}," >",[484,849,850],{"class":494}," main.dump\n",[484,852,853,855,858,861,863,865,868,871],{"class":486,"line":640},[484,854,628],{"class":490},[484,856,857],{"class":494}," exec",[484,859,860],{"class":656}," -i",[484,862,657],{"class":656},[484,864,660],{"class":494},[484,866,867],{"class":494}," lucity-app-pg-main-1",[484,869,870],{"class":656}," --",[484,872,663],{"class":656},[484,874,875,878,881,884],{"class":486,"line":666},[484,876,877],{"class":494},"  pg_restore",[484,879,880],{"class":656}," --dbname=app",[484,882,883],{"class":672}," \u003C",[484,885,850],{"class":494},[170,887,888,891,892,894],{},[199,889,890],{},"Buckets."," If the files are moving too, copy them with any S3 tool. The bucket's ",[199,893,617],{}," tab has a ready-made rclone configuration.",[170,896,897,900],{},[199,898,899],{},"Volumes."," With no download to fall back on, copy the files out from inside the service, for example into a bucket, and back in on the other side.",[170,902,903,906],{},[199,904,905],{},"Key-value stores."," Caches and sessions can start over. Anything you need to keep has to be copied from inside a service.",[322,908,910],{"id":909},"switch-over","Switch over",[170,912,913],{},"Once everything runs, point your custom domains' DNS at your Gateway. Their certificates can only be issued once the records point at your cluster, so HTTPS takes a minute or two to come up on the new side.",[170,915,916,917,921],{},"When nothing on Lucity is needed anymore, ",[182,918,920],{"href":919},"\u002Fdocs\u002Fprojects#deleting-a-project","delete the project",". Its buckets go with it, so move any bucket you are still using first.",[191,923,925],{"id":924},"what-you-take-over","What you take over",[170,927,928],{},"The archive is the deployment, not the platform around it. On your own cluster these are yours to run:",[258,930,931,941,953,959],{},[261,932,933,936,937,940],{},[199,934,935],{},"Builds and deploys."," A push no longer deploys anything. Build and run ",[174,938,939],{},"helm upgrade"," from your CI instead.",[261,942,943,946,947,952],{},[199,944,945],{},"Database backups."," Backups and point-in-time recovery are not part of the export. Configure ",[182,948,951],{"href":949,"rel":950},"https:\u002F\u002Fcloudnative-pg.io\u002Fdocs\u002F1.30\u002Fbackup",[376],"backups in CloudNativePG"," to get them back.",[261,954,955,958],{},[199,956,957],{},"Separation between environments."," Lucity keeps each environment on its own network and within a resource budget, and both live outside the chart. Add network policies and quotas of your own if environments share a cluster.",[261,960,961,964],{},[199,962,963],{},"Logs, metrics and the dashboard."," Bring the observability tools you already like.",[191,966,968],{"id":967},"next-steps","Next steps",[258,970,971,976,981],{},[261,972,973,975],{},[182,974,127],{"href":128}," for running the whole platform on your own infrastructure instead",[261,977,978,980],{},[182,979,71],{"href":812}," for reaching a database from outside Lucity",[261,982,983,985],{},[182,984,59],{"href":60}," for how Lucity turns a repository into an image",[987,988,989],"style",{},"html pre.shiki code .sX5TD, html code.shiki .sX5TD{--shiki-light:#FABD2F;--shiki-default:#FABD2F;--shiki-dark:#FABD2F}html pre.shiki code .sQLXx, html code.shiki .sQLXx{--shiki-light:#B8BB26;--shiki-default:#B8BB26;--shiki-dark:#B8BB26}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s1Tsi, html code.shiki .s1Tsi{--shiki-light:#D3869B;--shiki-default:#D3869B;--shiki-dark:#D3869B}html pre.shiki code .s3drp, html code.shiki .s3drp{--shiki-light:#8EC07C;--shiki-default:#8EC07C;--shiki-dark:#8EC07C}html pre.shiki code .si-ur, html code.shiki .si-ur{--shiki-light:#A89984;--shiki-default:#A89984;--shiki-dark:#A89984}",{"title":234,"searchDepth":640,"depth":640,"links":991},[992,993,994,995,1003,1004],{"id":193,"depth":640,"text":194},{"id":225,"depth":640,"text":226},{"id":185,"depth":640,"text":253},{"id":304,"depth":640,"text":305,"children":996},[997,998,999,1000,1001,1002],{"id":324,"depth":666,"text":325},{"id":461,"depth":666,"text":462},{"id":556,"depth":666,"text":557},{"id":606,"depth":666,"text":607},{"id":799,"depth":666,"text":800},{"id":909,"depth":666,"text":910},{"id":924,"depth":640,"text":925},{"id":967,"depth":640,"text":968},"Download a project as a Helm chart and run it on a Kubernetes cluster of your own.","md",null,{},true,{"title":99,"description":1005},"5An4jbvRzEgkyV7JzAjU7_UPDJkhHvhqwHQvgXDqwwg",[1013,1015],{"title":95,"path":96,"stem":97,"description":1014,"children":-1},"Development, staging, production: isolated copies of the same application.",{"title":103,"path":104,"stem":105,"description":1016,"children":-1},"The GraphQL API behind the dashboard, with an interactive playground.",[1018,1021,1023,1026,1029,1032,1035,1038,1041,1044,1047,1050,1053,1055,1057,1059,1061,1063,1065,1067,1069,1071,1073,1075,1076,1077,1078,1080,1082,1084,1086,1088,1090,1093,1097,1101],{"path":6,"title":1019,"description":1020},"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":1022,"title":9,"description":1007},"\u002Fdocs\u002Fguides\u002F.navigation",{"path":16,"title":1024,"description":1025},"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":1027,"description":1028},"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":1030,"description":1031},"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":1033,"description":1034},"Deploy an Astro site","Deploy an Astro site on Lucity, static by default and server rendered when you add an adapter.",{"path":32,"title":1036,"description":1037},"Deploy an Express API","Deploy an Express API on Lucity. Three requirements, none of them platform-specific.",{"path":36,"title":1039,"description":1040},"Deploy a FastAPI service","Deploy a FastAPI service on Lucity. Detection is picky about layout, and the fix is one setting.",{"path":40,"title":1042,"description":1043},"Deploy a Django project","Deploy a Django project on Lucity, with migrations that run themselves and static files that do not.",{"path":44,"title":1045,"description":1046},"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":1048,"description":1049},"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":1051,"description":1052},"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":1054},"Services are the deployable units of a project: what they are, how they are configured, and how they scale.",{"path":56,"title":55,"description":1056},"How a deployment goes live on Lucity, and the ways to trigger one.",{"path":60,"title":59,"description":1058},"How Lucity turns your source code into a container image.",{"path":64,"title":63,"description":1060},"Configuration for your services: service variables, shared variables, and dynamic variables.",{"path":68,"title":67,"description":1062},"Put a service on the internet. Use a platform hostname for quick tests, or a domain you own.",{"path":72,"title":71,"description":1064},"Managed PostgreSQL databases, replicated and backed up, connected to your services without copying credentials.",{"path":76,"title":75,"description":1066},"S3-compatible buckets for uploads, exports and anything else your service needs to keep.",{"path":80,"title":79,"description":1068},"Persistent disks for services that need to keep state on the filesystem.",{"path":84,"title":83,"description":1070},"A Redis®-compatible key-value store for caching, sessions and queues.",{"path":88,"title":87,"description":1072},"Workspaces represent your organization in Lucity, with their own members, isolation and billing.",{"path":92,"title":91,"description":1074},"Projects group services, databases and the environments they run in.",{"path":96,"title":95,"description":1014},{"path":100,"title":99,"description":1005},{"path":104,"title":103,"description":1016},{"path":108,"title":107,"description":1079},"Deploy and manage your services from a terminal or a CI pipeline.",{"path":112,"title":111,"description":1081},"Deploy and manage your services from Claude Code, Codex, Cursor or any other MCP client.",{"path":116,"title":115,"description":1083},"CPU and memory for every service, and disk usage for every volume.",{"path":120,"title":119,"description":1085},"What your services print while they run, and the output of every deployment step.",{"path":124,"title":123,"description":1087},"Plans, resource usage, the free trial, and what happens when a payment fails.",{"path":128,"title":127,"description":1089},"Run the whole platform on a Kubernetes cluster you own, using the same two Helm charts we run ourselves.",{"path":1091,"title":1092,"description":1007},"\u002Flegal\u002F.navigation","Legal",{"path":1094,"title":1095,"description":1096},"\u002Flegal\u002Fdata-processing-agreement","Data Processing Agreement","How Lucity processes personal data on your behalf.",{"path":1098,"title":1099,"description":1100},"\u002Flegal\u002Fprivacy-policy","Privacy Policy","How Lucity handles your data.",{"path":1102,"title":1103,"description":1104},"\u002Flegal\u002Fterms-of-use","Terms of Use","Terms governing your use of Lucity.",1791216728611]