[{"data":1,"prerenderedAt":2567},["ShallowReactive",2],{"doc:\u002Fdocs\u002Fgetting-started-docker-compose":3,"docs-nav":2359},{"id":4,"title":5,"body":6,"description":16,"extension":2351,"meta":2352,"navigation":2354,"path":2355,"seo":2356,"stem":2357,"__hash__":2358},"docs\u002Fdocs\u002Fgetting-started-docker-compose.md","Getting started with Docker Compose",{"type":7,"value":8,"toc":2335},"minimark",[9,13,17,36,46,116,120,134,166,181,187,272,278,288,350,353,380,394,400,403,406,429,439,463,466,473,476,492,518,528,531,548,551,565,608,611,634,641,737,740,754,761,771,787,793,796,801,815,834,860,904,910,918,922,929,935,938,941,948,973,991,997,1010,1037,1043,1088,1094,1120,1126,1165,1171,1177,1193,1236,1243,1249,1265,1284,1290,1317,1323,1326,1338,1344,1380,1394,1411,1417,1423,1426,1444,1459,1469,1482,1496,1509,1528,1581,1594,1597,1602,1608,1631,1640,1649,1675,1678,1699,1847,1853,1941,1953,1970,1989,1992,2026,2029,2032,2048,2056,2072,2090,2112,2117,2123,2138,2159,2185,2198,2218,2236,2261,2282,2309,2317,2331],[10,11,5],"h1",{"id":12},"getting-started-with-docker-compose",[14,15,16],"p",{},"From an empty machine to a first scheduled flow, in about half an hour. You install\nTabularia on one machine with Docker Compose, load the sample data, build a flow that\nfilters, computes and aggregates, publish its result as a datasource, and let it run\nevery night.",[14,18,19,20,24,25,29,30,35],{},"This is the ",[21,22,23],"strong",{},"trial stack",": it builds the images from the repository and runs the\n",[26,27,28],"code",{},"main"," branch with development settings. To run Tabularia for real, use Kubernetes and\nthe Helm chart: ",[31,32,34],"a",{"href":33},"\u002Fdocs\u002Fdeploy\u002Fkubernetes","Kubernetes and Helm",".",[14,37,38,39,42,43,45],{},"Every command and click below was run, in this order, on a clean machine (Docker in\nDocker, a fresh ",[26,40,41],{},"git clone"," of ",[26,44,28],{},"). The screenshots come from that run.",[47,48,49,56,62,68,74,80,86,92,98,104,110],"ul",{},[50,51,52],"li",{},[31,53,55],{"href":54},"#1-prerequisites","1. Prerequisites",[50,57,58],{},[31,59,61],{"href":60},"#2-get-the-code","2. Get the code",[50,63,64],{},[31,65,67],{"href":66},"#3-configure","3. Configure",[50,69,70],{},[31,71,73],{"href":72},"#4-start","4. Start",[50,75,76],{},[31,77,79],{"href":78},"#5-create-the-administrator","5. Create the administrator",[50,81,82],{},[31,83,85],{"href":84},"#6-load-some-data","6. Load some data",[50,87,88],{},[31,89,91],{"href":90},"#7-build-your-first-flow","7. Build your first flow",[50,93,94],{},[31,95,97],{"href":96},"#8-schedule-it","8. Schedule it",[50,99,100],{},[31,101,103],{"href":102},"#9-where-to-go-next","9. Where to go next",[50,105,106],{},[31,107,109],{"href":108},"#10-stop-update-back-up-reset","10. Stop, update, back up, reset",[50,111,112],{},[31,113,115],{"href":114},"#troubleshooting","Troubleshooting",[117,118,55],"h2",{"id":119},"1-prerequisites",[14,121,122,125,126,129,130,133],{},[21,123,124],{},"Docker."," Docker Engine with the Compose plugin, version 2.24 or later (the\n",[26,127,128],{},"docker compose"," command, not the old ",[26,131,132],{},"docker-compose","). This guide was run with Docker Engine 29 and Compose 5 on\nx86_64 Linux; Docker Desktop on macOS and Windows works the same way. Check:",[135,136,141],"pre",{"className":137,"code":138,"language":139,"meta":140,"style":140},"language-bash shiki shiki-themes github-dark-dimmed github-light","docker version\ndocker compose version\n","bash","",[26,142,143,156],{"__ignoreMap":140},[144,145,148,152],"span",{"class":146,"line":147},"line",1,[144,149,151],{"class":150},"sqRhv","docker",[144,153,155],{"class":154},"sXfbr"," version\n",[144,157,159,161,164],{"class":146,"line":158},2,[144,160,151],{"class":150},[144,162,163],{"class":154}," compose",[144,165,155],{"class":154},[14,167,168,171,172,176,177,180],{},[21,169,170],{},"git"," to get the code, or a browser: on GitHub, ",[173,174,175],"em",{},"Code → Download ZIP"," gives the same\nfiles (the folder is then ",[26,178,179],{},"Tabularia-main","). Nothing else: no key to generate, no file\nto edit.",[14,182,183,186],{},[21,184,185],{},"Resources."," Measured on the clean run:",[188,189,190,205],"table",{},[191,192,193],"thead",{},[194,195,196,199,202],"tr",{},[197,198],"th",{},[197,200,201],{},"Measured",[197,203,204],{},"Give Docker at least",[206,207,208,220,246,257],"tbody",{},[194,209,210,214,217],{},[211,212,213],"td",{},"CPU",[211,215,216],{},"8 cores used for the first build",[211,218,219],{},"4 cores",[194,221,222,225,228],{},[211,223,224],{},"Memory",[211,226,227],{},"2.6 GB at rest, with the sample data",[211,229,230,231,234,235,238,239,242,243],{},"8 GB. The engine and the two workers may grow to 4–6 GB each while they work (14 GB together): with less memory for Docker, lower ",[26,232,233],{},"BACKEND_MEM_LIMIT",", ",[26,236,237],{},"WORKER_MEM_LIMIT"," and ",[26,240,241],{},"PREVIEW_WORKER_MEM_LIMIT"," in ",[26,244,245],{},".env",[194,247,248,251,254],{},[211,249,250],{},"Disk",[211,252,253],{},"13.5 GB after the first start, with the sample data (images and build cache take most of it)",[211,255,256],{},"20 GB free",[194,258,259,262,269],{},[211,260,261],{},"Time",[211,263,264,265,268],{},"2 min 42 s for the first ",[26,266,267],{},"docker compose up -d"," (8 cores, a fast connection); then about 15 s until the sign-in page answers",[211,270,271],{},"count 5–15 minutes on a laptop or a slower link",[14,273,274,275,35],{},"With Docker Desktop the memory is set in ",[173,276,277],{},"Settings → Resources",[14,279,280,283,284,287],{},[21,281,282],{},"Free ports."," The stack publishes these ports ",[21,285,286],{},"on 127.0.0.1 only",": open the\nbrowser on the same machine.",[188,289,290,300],{},[191,291,292],{},[194,293,294,297],{},[197,295,296],{},"Port",[197,298,299],{},"Service",[206,301,302,310,318,326,334,342],{},[194,303,304,307],{},[211,305,306],{},"3000",[211,308,309],{},"the app",[194,311,312,315],{},[211,313,314],{},"8000",[211,316,317],{},"the gateway (the API the app calls)",[194,319,320,323],{},[211,321,322],{},"3001",[211,324,325],{},"Grafana",[194,327,328,331],{},[211,329,330],{},"9001 \u002F 9002",[211,332,333],{},"MinIO console \u002F MinIO S3 API",[194,335,336,339],{},[211,337,338],{},"5433",[211,340,341],{},"PostgreSQL (Tabularia's metadata)",[194,343,344,347],{},[211,345,346],{},"5434, 8124",[211,348,349],{},"the sample databases (PostgreSQL, ClickHouse), unless you leave the sample data out",[14,351,352],{},"On Linux, this prints the ones already taken (nothing printed: all free):",[135,354,356],{"className":137,"code":355,"language":139,"meta":140,"style":140},"ss -ltn | grep -E ':(3000|3001|8000|9001|9002|5433|5434|8124)\\b'\n",[26,357,358],{"__ignoreMap":140},[144,359,360,363,367,371,374,377],{"class":146,"line":147},[144,361,362],{"class":150},"ss",[144,364,366],{"class":365},"swcJU"," -ltn",[144,368,370],{"class":369},"s6PUj"," |",[144,372,373],{"class":150}," grep",[144,375,376],{"class":365}," -E",[144,378,379],{"class":154}," ':(3000|3001|8000|9001|9002|5433|5434|8124)\\b'\n",[381,382,383],"blockquote",{},[14,384,385,386,389,390,393],{},"On a remote server the browser needs both 3000 and 8000 on its own ",[26,387,388],{},"localhost",":\nthe app calls the gateway at ",[26,391,392],{},"http:\u002F\u002Flocalhost:8000",". Forwarding only 3000 is not\nenough.",[14,395,396,399],{},[21,397,398],{},"Architecture."," Compose builds the images for your machine's architecture. This guide\nwas run on amd64; the release images on Docker Hub are published for amd64 and arm64\nfrom the same Dockerfiles.",[117,401,61],{"id":402},"2-get-the-code",[14,404,405],{},"As your normal user (not root):",[135,407,409],{"className":137,"code":408,"language":139,"meta":140,"style":140},"git clone https:\u002F\u002Fgithub.com\u002FJumpAsAService\u002FTabularia.git\ncd Tabularia\u002Finfrastructure\n",[26,410,411,421],{"__ignoreMap":140},[144,412,413,415,418],{"class":146,"line":147},[144,414,170],{"class":150},[144,416,417],{"class":154}," clone",[144,419,420],{"class":154}," https:\u002F\u002Fgithub.com\u002FJumpAsAService\u002FTabularia.git\n",[144,422,423,426],{"class":146,"line":158},[144,424,425],{"class":365},"cd",[144,427,428],{"class":154}," Tabularia\u002Finfrastructure\n",[14,430,431,432,434,435,438],{},"Every ",[26,433,128],{}," command of this guide runs from this ",[26,436,437],{},"infrastructure"," folder.",[381,440,441],{},[14,442,443,446,447,450,451,454,455,458,459,462],{},[21,444,445],{},"Linux only."," The app container runs as user id 1000 and writes into the\n",[26,448,449],{},"frontend"," folder of your clone. If ",[26,452,453],{},"id -u"," prints something other than ",[26,456,457],{},"1000",", or\nyou cloned as root, give it that folder before starting:\n",[26,460,461],{},"sudo chown -R 1000:1000 ..\u002Ffrontend",". On macOS and Windows there is nothing to do.",[117,464,67],{"id":465},"3-configure",[14,467,468,469,472],{},"Nothing to do for a trial. At the first start the stack creates the key that encrypts\nthe passwords of your database connections (in the ",[26,470,471],{},"keys"," volume, kept with the data),\nand the sign-in page creates the administrator (step 5).",[14,474,475],{},"To change a setting later, for example the time zone of the schedules, copy the example\nsettings and edit the copy:",[135,477,479],{"className":137,"code":478,"language":139,"meta":140,"style":140},"cp .env.example .env\n",[26,480,481],{"__ignoreMap":140},[144,482,483,486,489],{"class":146,"line":147},[144,484,485],{"class":150},"cp",[144,487,488],{"class":154}," .env.example",[144,490,491],{"class":154}," .env\n",[135,493,497],{"className":494,"code":495,"language":496,"meta":140,"style":140},"language-dotenv shiki shiki-themes github-dark-dimmed github-light","# the time zone of the schedules: '0 6 * * *' means 06:00 here (an IANA name; default UTC)\nAPP__TIMEZONE=Europe\u002FRome\n","dotenv",[26,498,499,505],{"__ignoreMap":140},[144,500,501],{"class":146,"line":147},[144,502,504],{"class":503},"sgHix","# the time zone of the schedules: '0 6 * * *' means 06:00 here (an IANA name; default UTC)\n",[144,506,507,511,514],{"class":146,"line":158},[144,508,510],{"class":509},"sNjOc","APP__TIMEZONE",[144,512,513],{"class":369},"=",[144,515,517],{"class":516},"ssh_m","Europe\u002FRome\n",[14,519,520,521,523,524,35],{},"Then ",[26,522,267],{}," again. Dates on screen follow your browser. Every setting,\nwith its default: ",[31,525,527],{"href":526},"\u002Fdocs\u002Fconfiguration","Configuration reference",[117,529,73],{"id":530},"4-start",[135,532,534],{"className":137,"code":533,"language":139,"meta":140,"style":140},"docker compose up -d\n",[26,535,536],{"__ignoreMap":140},[144,537,538,540,542,545],{"class":146,"line":147},[144,539,151],{"class":150},[144,541,163],{"class":154},[144,543,544],{"class":154}," up",[144,546,547],{"class":365}," -d\n",[14,549,550],{},"The first time, Compose builds the images (the engine, the gateway, the app, the sample\ndata loader) and pulls\nthe others: 2–3 minutes on a fast machine, 5–15 on a laptop. The command returns when\nevery container has started. Then check:",[135,552,554],{"className":137,"code":553,"language":139,"meta":140,"style":140},"docker compose ps\n",[26,555,556],{"__ignoreMap":140},[144,557,558,560,562],{"class":146,"line":147},[144,559,151],{"class":150},[144,561,163],{"class":154},[144,563,564],{"class":154}," ps\n",[14,566,567,234,570,234,573,234,576,234,579,238,582,585,586,589,590,593,594,597,598,601,602,605,606,35],{},[26,568,569],{},"postgres",[26,571,572],{},"redis",[26,574,575],{},"minio",[26,577,578],{},"gateway",[26,580,581],{},"sampledb-postgres",[26,583,584],{},"sampledb-clickhouse","\nmust say ",[26,587,588],{},"(healthy)","; the others ",[26,591,592],{},"Up","\n(",[26,595,596],{},"cadvisor"," reports ",[26,599,600],{},"health: starting"," for its first minute). A container that says\n",[26,603,604],{},"Restarting"," has a problem: see ",[31,607,115],{"href":114},[14,609,610],{},"The logs of one service, for example the gateway:",[135,612,614],{"className":137,"code":613,"language":139,"meta":140,"style":140},"docker compose logs --tail 50 gateway\n",[26,615,616],{"__ignoreMap":140},[144,617,618,620,622,625,628,631],{"class":146,"line":147},[144,619,151],{"class":150},[144,621,163],{"class":154},[144,623,624],{"class":154}," logs",[144,626,627],{"class":365}," --tail",[144,629,630],{"class":365}," 50",[144,632,633],{"class":154}," gateway\n",[14,635,636,637,640],{},"The app compiles its pages when it starts: the sign-in page answers about 15 seconds\nafter ",[26,638,639],{},"up"," returns.",[188,642,643,655],{},[191,644,645],{},[194,646,647,649,652],{},[197,648,299],{},[197,650,651],{},"URL",[197,653,654],{},"Credentials",[206,656,657,672,685,711],{},[194,658,659,662,669],{},[211,660,661],{},"Tabularia",[211,663,664],{},[31,665,666],{"href":666,"rel":667},"http:\u002F\u002Flocalhost:3000",[668],"nofollow",[211,670,671],{},"the administrator you create at the first visit",[194,673,674,677,682],{},[211,675,676],{},"Gateway (API)",[211,678,679],{},[31,680,392],{"href":392,"rel":681},[668],[211,683,684],{},"through the app's sign-in, or an API token",[194,686,687,689,695],{},[211,688,325],{},[211,690,691],{},[31,692,693],{"href":693,"rel":694},"http:\u002F\u002Flocalhost:3001",[668],[211,696,697,698,701,702,704,705,242,708,710],{},"read-only without signing in; ",[26,699,700],{},"admin"," \u002F ",[26,703,700],{}," to edit (",[26,706,707],{},"GRAFANA_ADMIN_*",[26,709,245],{},"). The same dashboards are in the app, under Administration → Monitoring",[194,712,713,716,722],{},[211,714,715],{},"MinIO console",[211,717,718],{},[31,719,720],{"href":720,"rel":721},"http:\u002F\u002Flocalhost:9001",[668],[211,723,724,701,727,729,730,701,733,736],{},[26,725,726],{},"minioadmin",[26,728,726],{}," (",[26,731,732],{},"STORAGE__ACCESS_KEY",[26,734,735],{},"STORAGE__SECRET_KEY",")",[117,738,79],{"id":739},"5-create-the-administrator",[14,741,742,743,746,747,749,750,753],{},"Open ",[31,744,666],{"href":666,"rel":745},[668],". The first time, the page asks for the administrator: a name,\nan email and a password (at least 12 characters; ",[26,748,700],{}," and other well-known passwords\nare refused), typed twice. ",[21,751,752],{},"Create the administrator"," signs you in. The page appears\nonly while the installation has no account at all; from then on it is the ordinary\nsign-in, with that email and password.",[14,755,756],{},[757,758],"img",{"alt":759,"src":760},"Creating the administrator","\u002Fmedia\u002Fgetting-started\u002F01-sign-in.png",[14,762,763,764,767,768,438],{},"The installation opens on ",[21,765,766],{},"Explore",". The sample data (step 6) arrives a minute or two\nlater: reload the page to see the ",[26,769,770],{},"Sample",[14,772,773,776,777,780,781,238,784,35],{},[21,774,775],{},"Theme and language"," are in the gear at the top right: five themes (Dark, Light,\nDracula, Monokai, Imperium) and five languages (English, Italiano, Français, Deutsch,\nEspañol). The choice is kept by your browser. The same menu has ",[173,778,779],{},"Your sessions",",\n",[173,782,783],{},"API tokens",[173,785,786],{},"Sign out",[14,788,789],{},[757,790],{"alt":791,"src":792},"The settings menu","\u002Fmedia\u002Fgetting-started\u002F02-settings.png",[117,794,85],{"id":795},"6-load-some-data",[797,798,800],"h3",{"id":799},"a-the-sample-data-already-there","a. The sample data (already there)",[14,802,803,804,806,807,810,811,814],{},"A fictional cured-meats company: an ERP on PostgreSQL and a CRM on ClickHouse, with a\nready-made ",[26,805,770],{}," folder in Tabularia. It is part of the stack: three containers, the\ntwo databases and ",[26,808,809],{},"sampledb-init",", which fills them, waits for the administrator of\nstep 5, signs in as that administrator and builds the folder. At the ",[26,812,813],{},"small"," scale the\ndata takes seconds; the container then runs the eleven sample flows once and makes the\nviews, the reports and the dashboard, about two minutes. Follow it:",[135,816,818],{"className":137,"code":817,"language":139,"meta":140,"style":140},"docker compose logs -f sampledb-init\n",[26,819,820],{"__ignoreMap":140},[144,821,822,824,826,828,831],{"class":146,"line":147},[144,823,151],{"class":150},[144,825,163],{"class":154},[144,827,624],{"class":154},[144,829,830],{"class":365}," -f",[144,832,833],{"class":154}," sampledb-init\n",[14,835,836,837,844,845,848,849,852,853,856,857,859],{},"While no administrator exists it says ",[173,838,839,840,843],{},"waiting for the administrator: open\n",[31,841,666],{"href":666,"rel":842},[668]," and create it",". It ends with ",[26,846,847],{},"DONE. The «Sample» folder is ready: …","\nand exits; ",[26,850,851],{},"docker compose ps -a"," then shows it ",[26,854,855],{},"Exited (0)",", as it should. It runs again at\nevery ",[26,858,267],{}," and finds everything already there.",[14,861,862,863,865,866,780,869,872,873,238,876,593,879,883,884,593,887,891,892,895,896,899,900,903],{},"Reload Explore: the ",[26,864,770],{}," folder holds the two connections (",[173,867,868],{},"Sample ERP (Postgres)",[173,870,871],{},"Sample CRM (ClickHouse)","), four saved views, the reports ",[173,874,875],{},"Margin review",[173,877,878],{},"Agent scorecard",[31,880,882],{"href":881},"\u002Fdocs\u002Fcapabilities\u002Freports#the-sample-reports","Reports","), the dashboard ",[173,885,886],{},"Sales overview",[31,888,890],{"href":889},"\u002Fdocs\u002Fcapabilities\u002Fdashboards#example-sales-overview","Dashboards","), and three folders: ",[173,893,894],{},"Flows"," (eleven flows,\nthree of them scheduled), ",[173,897,898],{},"Private tables"," (the company's tables and the flows' results)\nand ",[173,901,902],{},"Public tables"," (a calendar, the regions).",[14,905,906],{},[757,907],{"alt":908,"src":909},"The Sample folder in Explore","\u002Fmedia\u002Fgetting-started\u002F03-sample-folder.png",[14,911,912,913,35],{},"The folder is created with no permissions on it: the administrator sees it, other users\nonly once the administrator shares it. More: ",[31,914,917],{"href":915,"rel":916},"https:\u002F\u002Fgithub.com\u002FJumpAsAService\u002FTabularia\u002Fblob\u002Fmain\u002Finfrastructure\u002Fsampledb\u002FREADME.md",[668],"the sample database",[797,919,921],{"id":920},"b-or-a-file-of-your-own","b. Or a file of your own",[14,923,924,925,928],{},"CSV, TSV, JSON, Excel and parquet files are loaded from the flow editor: in a new flow\n(step 7, first two clicks), ",[21,926,927],{},"Upload file"," in the toolbar. The file becomes the flow's\nsource and the preview shows it at once. An Excel workbook is read from its first visible\nsheet; when it has more than one, a window lists them and every sheet you tick becomes a\nsource of its own.",[14,930,931],{},[757,932],{"alt":933,"src":934},"A CSV uploaded as the source of a flow","\u002Fmedia\u002Fgetting-started\u002F14-upload-csv.png",[14,936,937],{},"An uploaded file belongs to that flow. To turn it into a datasource others can use,\npublish it with an Output node, as in step 7.",[117,939,91],{"id":940},"7-build-your-first-flow",[14,942,943,944,947],{},"The flow: from the sample ",[26,945,946],{},"orders"," table, keep the shipped orders, add the order year,\ncount the orders by sales channel and year, and publish the result as a datasource.\nWith your own file, the steps are the same with your columns.",[14,949,950,953,954,956,957,960,961,964,965,968,969,972],{},[21,951,952],{},"1. A folder."," In ",[21,955,766],{},", at ",[173,958,959],{},"All folders",", click ",[21,962,963],{},"New",", type ",[26,966,967],{},"My first flows","\nand click ",[21,970,971],{},"Create",". The new folder opens.",[14,974,975,978,979,982,983,986,987,990],{},[21,976,977],{},"2. A flow."," In the folder, ",[21,980,981],{},"New → New flow",", then pick the engine: ",[21,984,985],{},"Polars",". The\neditor opens with one empty ",[173,988,989],{},"Source"," node.",[14,992,993],{},[757,994],{"alt":995,"src":996},"New flow: pick the engine","\u002Fmedia\u002Fgetting-started\u002F04-new-flow.png",[14,998,999,1002,1003,1006,1007,35],{},[21,1000,1001],{},"3. Name it."," Click the name field at the top left (",[173,1004,1005],{},"Untitled flow",") and type\n",[26,1008,1009],{},"Orders by channel and year",[14,1011,1012,1015,1016,1018,1019,1022,1023,964,1026,1028,1029,1032,1033,1036],{},[21,1013,1014],{},"4. The source."," The ",[173,1017,989],{}," node is selected: in the right panel, under\n",[173,1020,1021],{},"or use a catalog datasource",", open ",[21,1024,1025],{},"choose a datasource…",[26,1027,946],{}," and pick\n",[21,1030,1031],{},"orders (30000 rows)"," ",[173,1034,1035],{},"Sample › Private tables",". The grid at the bottom previews the\ntable.",[14,1038,1039],{},[757,1040],{"alt":1041,"src":1042},"The source and its preview","\u002Fmedia\u002Fgetting-started\u002F05-source.png",[14,1044,1045,1048,1049,1052,1053,1056,1057,1060,1061,1064,1065,1068,1069,1032,1072,234,1075,1032,1078,234,1081,1032,1084,1087],{},[21,1046,1047],{},"5. A filter."," Click ",[21,1050,1051],{},"+ Operation"," in the toolbar. A new step appears after the\nselected node, already connected, as ",[173,1054,1055],{},"Change type"," with a red ",[173,1058,1059],{},"required parameter\nmissing: 'columns'",": it is waiting for its settings. In the right panel set ",[21,1062,1063],{},"Type"," to\n",[21,1066,1067],{},"Filter",", then ",[21,1070,1071],{},"Column",[26,1073,1074],{},"stato",[21,1076,1077],{},"Operator",[26,1079,1080],{},"equals",[21,1082,1083],{},"Value",[26,1085,1086],{},"evaso"," (shipped)\nand press Enter. The preview shows only shipped orders.",[14,1089,1090],{},[757,1091],{"alt":1092,"src":1093},"The filter","\u002Fmedia\u002Fgetting-started\u002F06-filter.png",[14,1095,1096,1032,1099,1101,1102,1104,1105,1108,1109,1112,1113,1116,1117,1119],{},[21,1097,1098],{},"6. A computed column.",[21,1100,1051],{}," again, ",[21,1103,1063],{}," → ",[21,1106,1107],{},"Computed column",". In the\nfirst box type the column name ",[26,1110,1111],{},"order_year",", in the second the SQL expression\n",[26,1114,1115],{},"EXTRACT(YEAR FROM data_ordine)",", then press Tab. The preview gains an ",[26,1118,1111],{},"\ncolumn. A wrong expression is reported in the preview while you type.",[14,1121,1122],{},[757,1123],{"alt":1124,"src":1125},"The computed column","\u002Fmedia\u002Fgetting-started\u002F07-computed-column.png",[14,1127,1128,1032,1131,234,1133,1104,1135,1138,1139,1142,1143,1145,1146,1149,1150,1153,1154,1157,1158,1161,1162,1164],{},[21,1129,1130],{},"7. A group by.",[21,1132,1051],{},[21,1134,1063],{},[21,1136,1137],{},"Group by",". Tick ",[26,1140,1141],{},"canale"," and\n",[26,1144,1111],{},". Under ",[173,1147,1148],{},"Aggregations"," click ",[21,1151,1152],{},"+ add",", choose the column ",[26,1155,1156],{},"id",", the function\n",[26,1159,1160],{},"count",", and type ",[26,1163,946],{}," as the alias. The preview now has one row per channel and\nyear.",[14,1166,1167],{},[757,1168],{"alt":1169,"src":1170},"The group by","\u002Fmedia\u002Fgetting-started\u002F08-group-by.png",[14,1172,1173,1176],{},[21,1174,1175],{},"Preview any step."," Click any node of the canvas: the grid shows that step's output.\nThe steps already computed are kept in a cache (the green glow), so going back to them\nis fast.",[14,1178,1179,1182,1183,1186,1187,1189,1190,1192],{},[21,1180,1181],{},"8. The output."," At the bottom of the left sidebar, drag ",[21,1184,1185],{},"Output (datasource \u002F\ndatabase)"," onto the canvas, to the right of ",[173,1188,1137],{},". Connect them: drag from the\nsmall dot on the right edge of ",[173,1191,1137],{}," to the dot on the left edge of the Output.\nWith the Output selected, in the right panel:",[47,1194,1195,1205,1214,1221,1229],{},[50,1196,1197,1200,1201,1204],{},[21,1198,1199],{},"Destination",": ",[173,1202,1203],{},"Tabularia Datasource"," (the default);",[50,1206,1207,1200,1210,1213],{},[21,1208,1209],{},"Datasource name",[26,1211,1212],{},"shipped_orders_by_channel_year",";",[50,1215,1216,1200,1219,1213],{},[21,1217,1218],{},"Folder",[26,1220,967],{},[50,1222,1223,1200,1226,1213],{},[21,1224,1225],{},"Description",[26,1227,1228],{},"Shipped orders per sales channel and year",[50,1230,1231,1232,1235],{},"tick ",[21,1233,1234],{},"Overwrite if it already exists",": every later run, the scheduled ones too,\nrefreshes the same datasource.",[14,1237,1238,1239,1242],{},"The wand button in the canvas controls (",[173,1240,1241],{},"Arrange the flow",") lines the nodes up.",[14,1244,1245],{},[757,1246],{"alt":1247,"src":1248},"The Output node","\u002Fmedia\u002Fgetting-started\u002F09-output.png",[14,1250,1251,1032,1254,1257,1258,1261,1262,35],{},[21,1252,1253],{},"9. Save.",[21,1255,1256],{},"Save"," in the toolbar (or Ctrl+S): ",[173,1259,1260],{},"Flow \"Orders by channel and year\"\nsaved",", and the address becomes ",[26,1263,1264],{},"\u002Feditor?flow=\u003Cid>",[14,1266,1267,1032,1270,1273,1274,1277,1278,1280,1281,35],{},[21,1268,1269],{},"10. Run.",[21,1271,1272],{},"Run"," in the toolbar opens ",[173,1275,1276],{},"Run flow",": the flow runs on the whole dataset,\non a worker, and launches one run per Output. Click ",[21,1279,1272],{},". A couple of seconds later\nthe toolbar and a notification say ",[173,1282,1283],{},"Datasource \"shipped_orders_by_channel_year\":\ncompleted: 20 rows → datasource \"shipped_orders_by_channel_year\"",[14,1285,1286],{},[757,1287],{"alt":1288,"src":1289},"The run, completed","\u002Fmedia\u002Fgetting-started\u002F10-run.png",[14,1291,1292,1032,1295,1298,1299,1302,1303,1306,1307,1310,1311,960,1314,35],{},[21,1293,1294],{},"11. The result.",[21,1296,1297],{},"Datasources"," in the top bar lists it (search ",[26,1300,1301],{},"shipped","); click it\nto read and edit its description and its fields' descriptions. ",[21,1304,1305],{},"Analysis → Viewer","\nopens it for filters, pivots and charts without changing it. ",[21,1308,1309],{},"Runs"," has the run: the\npage opens on ",[173,1312,1313],{},"Failed",[21,1315,1316],{},"All",[14,1318,1319],{},[757,1320],{"alt":1321,"src":1322},"The published datasource","\u002Fmedia\u002Fgetting-started\u002F11-datasources.png",[117,1324,97],{"id":1325},"8-schedule-it",[14,1327,1328,1330,1331,1333,1334,1337],{},[21,1329,894],{}," in the top bar lists every flow. On the row of ",[173,1332,1009],{},",\nclick the calendar button (",[21,1335,1336],{},"Schedule run",").",[14,1339,1340],{},[757,1341],{"alt":1342,"src":1343},"The schedule dialog","\u002Fmedia\u002Fgetting-started\u002F13-schedule.png",[47,1345,1346,1371],{},[50,1347,1348,1351,1352,1354,1355,780,1358,234,1361,234,1364,1367,1368,35],{},[21,1349,1350],{},"Cron expression",": minute, hour, day of month, month, day of week, read in the time\nzone of ",[26,1353,510],{}," (the dialog shows it). The presets fill it in: ",[173,1356,1357],{},"Every 15 min",[173,1359,1360],{},"Every hour",[173,1362,1363],{},"Every night (03:00)",[173,1365,1366],{},"Every Monday (06:00)",". Every day at 06:00 is\n",[26,1369,1370],{},"0 6 * * *",[50,1372,1373,1200,1376,1379],{},[21,1374,1375],{},"Engine for scheduled runs",[173,1377,1378],{},"same as development"," (the engine the flow was built\nwith) or another one, for example a ClickHouse or BigQuery engine once configured. The\neditor keeps working with the development engine.",[14,1381,1382,1383,1385,1386,1389,1390,1393],{},"Click ",[21,1384,1256],{},". The row gets a ",[21,1387,1388],{},"scheduled"," badge (hover it for the cron) and the\n",[173,1391,1392],{},"Schedule load"," panel above the list places the flow's runs on the coming week.",[14,1395,1396,1397,1400,1401,1403,1404,1406,1407,1410],{},"To see it fire now, set the cron two minutes ahead: at 18:11, ",[26,1398,1399],{},"13 18 * * *",". At 18:13\n(in ",[26,1402,510],{},") ",[21,1405,1309],{}," shows a new run whose author is ",[21,1408,1409],{},"schedule",". Then put\nthe real schedule back.",[14,1412,1413],{},[757,1414],{"alt":1415,"src":1416},"A scheduled run in Runs","\u002Fmedia\u002Fgetting-started\u002F12-runs.png",[14,1418,1419,1420,1422],{},"A scheduled run reads the whole table, never the development sample, and with\n",[173,1421,1234],{}," it refreshes the same datasource each time.",[117,1424,103],{"id":1425},"9-where-to-go-next",[14,1427,1428,1431,1432,1435,1436,1439,1440,35],{},[21,1429,1430],{},"Your databases."," In a folder, ",[21,1433,1434],{},"New → New connection",": PostgreSQL, MySQL, MariaDB,\nClickHouse, Trino, Oracle, Microsoft SQL Server, S3, SMTP, SharePoint, SFTP, HTTP API.\nThen ",[21,1437,1438],{},"New → Datasource from a database"," reads a table or a query into a snapshot that\nflows use and that you refresh by hand or on a schedule. The two sample connections are\nworking examples. SQL Server needs its driver in the image: ",[31,1441,1443],{"href":1442},"\u002Fdocs\u002Fsqlserver","Microsoft SQL Server",[14,1445,1446,1449,1450,1454,1455,35],{},[21,1447,1448],{},"Files on a server."," An SFTP connection reads the files of a folder that match a\npattern, stacks them into one table, and writes flow results back as files:\n",[31,1451,1453],{"href":1452},"\u002Fdocs\u002Fsftp","SFTP",". The same for a bucket: ",[31,1456,1458],{"href":1457},"\u002Fdocs\u002Fs3-datasource","S3 buckets",[14,1460,1461,1464,1465,35],{},[21,1462,1463],{},"An HTTP API."," A datasource «API call» turns the answers of a REST\u002FJSON API into a\ntable. The guide walks through free APIs field by field, starting with the ECB exchange\nrates from Frankfurter, no key needed:\n",[31,1466,1468],{"href":1467},"\u002Fdocs\u002Fapi-datasource#examples-three-free-apis-field-by-field","HTTP APIs, examples",[14,1470,1471,1032,1474,1477,1478,35],{},[21,1472,1473],{},"Dates that move by themselves.",[26,1475,1476],{},"{today-30}"," in an API path, a file name or an\noutput name becomes a date at each run, in the time zone you choose:\n",[31,1479,1481],{"href":1480},"\u002Fdocs\u002Fplaceholders","Dynamic dates in inputs and outputs",[14,1483,1484,1487,1488,1491,1492,35],{},[21,1485,1486],{},"SQL on the catalog."," Explore → New → ",[21,1489,1490],{},"SQL script",": SQL over the datasources you can\nread, run with Ctrl+Enter, saved with its versions in a folder and shared with it:\n",[31,1493,1495],{"href":1494},"\u002Fdocs\u002Fsql-scripts","SQL scripts",[14,1497,1498,1015,1501,1504,1505,35],{},[21,1499,1500],{},"Data contracts.",[21,1502,1503],{},"Data contract"," button of a datasource (in Datasources and\nExplore) declares its columns, types and rules on the values; every new load is checked,\nwith a warning or an error, and the contract exports to ODCS. See the\n",[31,1506,1508],{"href":1507},"\u002Fdocs\u002Foverview#what-you-get","overview",[14,1510,1511,1514,1515,1518,1519,1523,1524,35],{},[21,1512,1513],{},"Export to dbt."," On the Flows page, ",[21,1516,1517],{},"Export flow → dbt"," turns a flow into a dbt\nproject for your data team, with the data contract as tests. Read its\n",[31,1520,1522],{"href":1521},"\u002Fdocs\u002Fdbt-export#limits","limits"," before relying on it: ",[31,1525,1527],{"href":1526},"\u002Fdocs\u002Fdbt-export","Export to dbt",[14,1529,1530,1533,1534,238,1537,1540,1541,238,1544,1547,1548,1551,1552,1555,1556,1558,1559,1562,1563,1567,1568,1572,1573,238,1577,35],{},[21,1531,1532],{},"Python, R and your own images (Kubernetes only)."," The Script node (Python and R\ncode in environments an administrator builds), saved scripts and the Container node\n(images from your container registries) run as Kubernetes Jobs, so this stack does not\nhave them. You still see them, greyed out, with the reason when you point at them: the\n",[173,1535,1536],{},"Scripting environments",[173,1538,1539],{},"Container registries"," sections of Administration, the\n",[173,1542,1543],{},"Script",[173,1545,1546],{},"Container"," nodes in the editor's sidebar (they cannot be dragged), and\n",[21,1549,1550],{},"New → Script (Python or R)"," in Explore. A flow made on a cluster with these nodes\nopens and saves as it is; a run that reaches one of them fails, saying that scripting\nor containers are off on this installation. ",[21,1553,1554],{},"Administration → Backups",", the automatic\nbackups of the database, is greyed out as well: on this stack back up the ",[26,1557,569],{},"\nservice with its own ",[26,1560,1561],{},"pg_dump",". To try them on your own computer, use\n",[31,1564,1566],{"href":1565},"\u002Fdocs\u002Fdeploy\u002Fminikube","minikube"," or a ",[31,1569,1571],{"href":1570},"\u002Fdocs\u002Fdeploy\u002Fkind","kind"," cluster; what they do is in\n",[31,1574,1576],{"href":1575},"\u002Fdocs\u002Fscripting","Python and R in flows",[31,1578,1580],{"href":1579},"\u002Fdocs\u002Fcontainer-node","The Container node",[14,1582,1583,1586,1587,1589,1590,35],{},[21,1584,1585],{},"Production."," Kubernetes and the Helm chart: ",[31,1588,34],{"href":33},",\nthen the ",[31,1591,1593],{"href":1592},"\u002Fdocs\u002Fdeploy\u002Frelease-checklist","install and upgrade checklist",[117,1595,109],{"id":1596},"10-stop-update-back-up-reset",[14,1598,1599,1600,438],{},"All from the ",[26,1601,437],{},[14,1603,1604,1607],{},[21,1605,1606],{},"Stop and start again",", keeping everything:",[135,1609,1611],{"className":137,"code":1610,"language":139,"meta":140,"style":140},"docker compose stop\ndocker compose start\n",[26,1612,1613,1622],{"__ignoreMap":140},[144,1614,1615,1617,1619],{"class":146,"line":147},[144,1616,151],{"class":150},[144,1618,163],{"class":154},[144,1620,1621],{"class":154}," stop\n",[144,1623,1624,1626,1628],{"class":146,"line":158},[144,1625,151],{"class":150},[144,1627,163],{"class":154},[144,1629,1630],{"class":154}," start\n",[14,1632,1633,1636,1637,1639],{},[26,1634,1635],{},"docker compose down"," also removes the containers (not the data); ",[26,1638,267],{},"\ncreates them again.",[14,1641,1642,1645,1646,1648],{},[21,1643,1644],{},"Update"," to the latest ",[26,1647,28],{},":",[135,1650,1652],{"className":137,"code":1651,"language":139,"meta":140,"style":140},"git pull\ndocker compose up -d --build\n",[26,1653,1654,1661],{"__ignoreMap":140},[144,1655,1656,1658],{"class":146,"line":147},[144,1657,170],{"class":150},[144,1659,1660],{"class":154}," pull\n",[144,1662,1663,1665,1667,1669,1672],{"class":146,"line":158},[144,1664,151],{"class":150},[144,1666,163],{"class":154},[144,1668,544],{"class":154},[144,1670,1671],{"class":365}," -d",[144,1673,1674],{"class":365}," --build\n",[14,1676,1677],{},"Compose rebuilds what changed and recreates those containers; the gateway upgrades its\ndatabase schema by itself when it starts. With nothing new it takes seconds.",[14,1679,1680,1683,1684,1687,1688,1691,1692,1695,1696,1698],{},[21,1681,1682],{},"Back up."," The data lives in Docker volumes named after the folder:\n",[26,1685,1686],{},"infrastructure_postgres_data"," (users, flows, schedules, connections, runs),\n",[26,1689,1690],{},"infrastructure_minio_data"," (the datasets, as parquet files) and ",[26,1693,1694],{},"infrastructure_keys","\n(the key that encrypts the connection passwords: without it they cannot be read). Stop\nthe stack, archive the three, keep ",[26,1697,245],{}," with them if you made one, start again:",[135,1700,1702],{"className":137,"code":1701,"language":139,"meta":140,"style":140},"docker compose stop\nmkdir -p ~\u002Ftabularia-backup\nfor v in postgres_data minio_data keys; do\n  docker run --rm -v infrastructure_$v:\u002Fdata -v ~\u002Ftabularia-backup:\u002Fbackup alpine \\\n    tar czf \u002Fbackup\u002F$v.tgz -C \u002Fdata .\ndone\n[ -f .env ] && cp .env ~\u002Ftabularia-backup\u002Fenv\ndocker compose start\n",[26,1703,1704,1712,1723,1750,1786,1812,1818,1838],{"__ignoreMap":140},[144,1705,1706,1708,1710],{"class":146,"line":147},[144,1707,151],{"class":150},[144,1709,163],{"class":154},[144,1711,1621],{"class":154},[144,1713,1714,1717,1720],{"class":146,"line":158},[144,1715,1716],{"class":150},"mkdir",[144,1718,1719],{"class":365}," -p",[144,1721,1722],{"class":154}," ~\u002Ftabularia-backup\n",[144,1724,1726,1729,1732,1735,1738,1741,1744,1747],{"class":146,"line":1725},3,[144,1727,1728],{"class":369},"for",[144,1730,1731],{"class":516}," v ",[144,1733,1734],{"class":369},"in",[144,1736,1737],{"class":154}," postgres_data",[144,1739,1740],{"class":154}," minio_data",[144,1742,1743],{"class":154}," keys",[144,1745,1746],{"class":516},"; ",[144,1748,1749],{"class":369},"do\n",[144,1751,1753,1756,1759,1762,1765,1768,1771,1774,1776,1779,1782],{"class":146,"line":1752},4,[144,1754,1755],{"class":150},"  docker",[144,1757,1758],{"class":154}," run",[144,1760,1761],{"class":365}," --rm",[144,1763,1764],{"class":365}," -v",[144,1766,1767],{"class":154}," infrastructure_",[144,1769,1770],{"class":516},"$v",[144,1772,1773],{"class":154},":\u002Fdata",[144,1775,1764],{"class":365},[144,1777,1778],{"class":154}," ~\u002Ftabularia-backup:\u002Fbackup",[144,1780,1781],{"class":154}," alpine",[144,1783,1785],{"class":1784},"sxsTv"," \\\n",[144,1787,1789,1792,1795,1798,1800,1803,1806,1809],{"class":146,"line":1788},5,[144,1790,1791],{"class":154},"    tar",[144,1793,1794],{"class":154}," czf",[144,1796,1797],{"class":154}," \u002Fbackup\u002F",[144,1799,1770],{"class":516},[144,1801,1802],{"class":154},".tgz",[144,1804,1805],{"class":365}," -C",[144,1807,1808],{"class":154}," \u002Fdata",[144,1810,1811],{"class":154}," .\n",[144,1813,1815],{"class":146,"line":1814},6,[144,1816,1817],{"class":369},"done\n",[144,1819,1821,1824,1827,1830,1832,1835],{"class":146,"line":1820},7,[144,1822,1823],{"class":516},"[ ",[144,1825,1826],{"class":369},"-f",[144,1828,1829],{"class":516}," .env ] && ",[144,1831,485],{"class":150},[144,1833,1834],{"class":154}," .env",[144,1836,1837],{"class":154}," ~\u002Ftabularia-backup\u002Fenv\n",[144,1839,1841,1843,1845],{"class":146,"line":1840},8,[144,1842,151],{"class":150},[144,1844,163],{"class":154},[144,1846,1630],{"class":154},[14,1848,1849,1852],{},[21,1850,1851],{},"Restore"," into empty volumes (after a reset, or on another machine): create the\ncontainers and volumes without starting them, unpack, start.",[135,1854,1856],{"className":137,"code":1855,"language":139,"meta":140,"style":140},"docker compose create\nfor v in postgres_data minio_data keys; do\n  docker run --rm -v infrastructure_$v:\u002Fdata -v ~\u002Ftabularia-backup:\u002Fbackup alpine \\\n    tar xzf \u002Fbackup\u002F$v.tgz -C \u002Fdata\ndone\ndocker compose up -d\n",[26,1857,1858,1867,1885,1909,1927,1931],{"__ignoreMap":140},[144,1859,1860,1862,1864],{"class":146,"line":147},[144,1861,151],{"class":150},[144,1863,163],{"class":154},[144,1865,1866],{"class":154}," create\n",[144,1868,1869,1871,1873,1875,1877,1879,1881,1883],{"class":146,"line":158},[144,1870,1728],{"class":369},[144,1872,1731],{"class":516},[144,1874,1734],{"class":369},[144,1876,1737],{"class":154},[144,1878,1740],{"class":154},[144,1880,1743],{"class":154},[144,1882,1746],{"class":516},[144,1884,1749],{"class":369},[144,1886,1887,1889,1891,1893,1895,1897,1899,1901,1903,1905,1907],{"class":146,"line":1725},[144,1888,1755],{"class":150},[144,1890,1758],{"class":154},[144,1892,1761],{"class":365},[144,1894,1764],{"class":365},[144,1896,1767],{"class":154},[144,1898,1770],{"class":516},[144,1900,1773],{"class":154},[144,1902,1764],{"class":365},[144,1904,1778],{"class":154},[144,1906,1781],{"class":154},[144,1908,1785],{"class":1784},[144,1910,1911,1913,1916,1918,1920,1922,1924],{"class":146,"line":1752},[144,1912,1791],{"class":154},[144,1914,1915],{"class":154}," xzf",[144,1917,1797],{"class":154},[144,1919,1770],{"class":516},[144,1921,1802],{"class":154},[144,1923,1805],{"class":365},[144,1925,1926],{"class":154}," \u002Fdata\n",[144,1928,1929],{"class":146,"line":1788},[144,1930,1817],{"class":369},[144,1932,1933,1935,1937,1939],{"class":146,"line":1814},[144,1934,151],{"class":150},[144,1936,163],{"class":154},[144,1938,544],{"class":154},[144,1940,547],{"class":365},[14,1942,1943,1032,1946,1949,1950,1648],{},[21,1944,1945],{},"Reset.",[26,1947,1948],{},"down -v"," removes the containers ",[21,1951,1952],{},"and every volume",[135,1954,1956],{"className":137,"code":1955,"language":139,"meta":140,"style":140},"docker compose down -v\n",[26,1957,1958],{"__ignoreMap":140},[144,1959,1960,1962,1964,1967],{"class":146,"line":147},[144,1961,151],{"class":150},[144,1963,163],{"class":154},[144,1965,1966],{"class":154}," down",[144,1968,1969],{"class":365}," -v\n",[381,1971,1972],{},[14,1973,1974,1980,1981,1983,1984,234,1986,1988],{},[21,1975,1976,1979],{},[26,1977,1978],{},"-v"," deletes all the data",": users, flows, schedules, connections, run history,\nevery dataset, the sample databases. Only the images and your ",[26,1982,245],{}," remain. Without\n",[26,1985,1978],{},[26,1987,1635],{}," keeps the data.",[14,1990,1991],{},"To also free the disk the images and the build cache take (11–13 GB):",[135,1993,1995],{"className":137,"code":1994,"language":139,"meta":140,"style":140},"docker compose down -v --rmi all\ndocker builder prune -f\n",[26,1996,1997,2013],{"__ignoreMap":140},[144,1998,1999,2001,2003,2005,2007,2010],{"class":146,"line":147},[144,2000,151],{"class":150},[144,2002,163],{"class":154},[144,2004,1966],{"class":154},[144,2006,1764],{"class":365},[144,2008,2009],{"class":365}," --rmi",[144,2011,2012],{"class":154}," all\n",[144,2014,2015,2017,2020,2023],{"class":146,"line":158},[144,2016,151],{"class":150},[144,2018,2019],{"class":154}," builder",[144,2021,2022],{"class":154}," prune",[144,2024,2025],{"class":365}," -f\n",[117,2027,115],{"id":2028},"troubleshooting",[14,2030,2031],{},"The messages below are the real ones, reproduced on the clean run.",[14,2033,2034,2040,2041,2043,2044,2047],{},[21,2035,2036,2037,35],{},"The gateway never becomes healthy: ",[26,2038,2039],{},"SECURITY__FERNET_KEY is not valid"," A key was\nset in ",[26,2042,245],{}," but is not a key (typed by hand, cut short). ",[26,2045,2046],{},"docker compose logs gateway","\nshows:",[135,2049,2054],{"className":2050,"code":2052,"language":2053,"meta":140},[2051],"language-text","RuntimeError: SECURITY__FERNET_KEY is not valid (Fernet key must be 32 url-safe base64-encoded bytes.): …\n","text",[26,2055,2052],{"__ignoreMap":140},[14,2057,2058,2059,2062,2063,2065,2066,2069,2070,35],{},"Remove the ",[26,2060,2061],{},"SECURITY__FERNET_KEY="," value from ",[26,2064,245],{}," (the stack then uses the key it\ncreated) or generate a real one with ",[26,2067,2068],{},"openssl rand -base64 32 | tr '+\u002F' '-_'",", then\n",[26,2071,267],{},[14,2073,2074,2079,2080,2082,2083,2085,2086,2089],{},[21,2075,2036,2076,35],{},[26,2077,2078],{},"SECURITY__KEYS_DIR must be writable by the services"," The images were built before the ",[26,2081,471],{}," volume existed: ",[26,2084,267],{}," keeps the images it already has. Rebuild them; the ",[26,2087,2088],{},"keys-init"," container then gives\nthe volume to the services:",[135,2091,2092],{"className":137,"code":1651,"language":139,"meta":140,"style":140},[26,2093,2094,2100],{"__ignoreMap":140},[144,2095,2096,2098],{"class":146,"line":147},[144,2097,170],{"class":150},[144,2099,1660],{"class":154},[144,2101,2102,2104,2106,2108,2110],{"class":146,"line":158},[144,2103,151],{"class":150},[144,2105,163],{"class":154},[144,2107,544],{"class":154},[144,2109,1671],{"class":365},[144,2111,1674],{"class":365},[14,2113,2114],{},[21,2115,2116],{},"A port is already in use.",[135,2118,2121],{"className":2119,"code":2120,"language":2053,"meta":140},[2051],"Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint dataprep-frontend (…): failed to bind host port 127.0.0.1:3000\u002Ftcp: address already in use\n",[26,2122,2120],{"__ignoreMap":140},[14,2124,2125,2126,2129,2130,2133,2134,2137],{},"Another program holds the port (another Tabularia, another dev server). Stop it, then\nrecreate the container that failed: the container is left running ",[21,2127,2128],{},"without"," its port,\nand a plain ",[26,2131,2132],{},"up -d"," or ",[26,2135,2136],{},"restart"," does not bind it again.",[135,2139,2141],{"className":137,"code":2140,"language":139,"meta":140,"style":140},"docker compose up -d --force-recreate frontend\n",[26,2142,2143],{"__ignoreMap":140},[144,2144,2145,2147,2149,2151,2153,2156],{"class":146,"line":147},[144,2146,151],{"class":150},[144,2148,163],{"class":154},[144,2150,544],{"class":154},[144,2152,1671],{"class":365},[144,2154,2155],{"class":365}," --force-recreate",[144,2157,2158],{"class":154}," frontend\n",[14,2160,2161,2167,2168,2171,2172,1142,2175,2178,2179,2069,2182,35],{},[21,2162,2163,2164,35],{},"The app keeps restarting: ",[26,2165,2166],{},"EACCES: permission denied, mkdir '\u002Fapp\u002F.nuxt'"," On\nLinux, ",[26,2169,2170],{},"docker compose ps"," shows ",[26,2173,2174],{},"frontend  Restarting (1)",[26,2176,2177],{},"docker compose logs frontend"," this error. The clone belongs to a user other than id\n1000: see the note in ",[31,2180,2181],{"href":60},"step 2",[26,2183,2184],{},"docker compose up -d --force-recreate frontend",[14,2186,2187,2190,2191,2193,2194,2197],{},[21,2188,2189],{},"Not enough memory."," A worker that runs out of memory is killed and restarted:\n",[26,2192,2170],{}," shows it ",[26,2195,2196],{},"Restarting (137)",", previews or runs never answer, and",[135,2199,2201],{"className":137,"code":2200,"language":139,"meta":140,"style":140},"docker inspect -f '{{.State.OOMKilled}}' infrastructure-preview-worker-1\n",[26,2202,2203],{"__ignoreMap":140},[144,2204,2205,2207,2210,2212,2215],{"class":146,"line":147},[144,2206,151],{"class":150},[144,2208,2209],{"class":154}," inspect",[144,2211,830],{"class":365},[144,2213,2214],{"class":154}," '{{.State.OOMKilled}}'",[144,2216,2217],{"class":154}," infrastructure-preview-worker-1\n",[14,2219,2220,2221,2224,2225,2227,2228,234,2230,1142,2232,242,2234,35],{},"prints ",[26,2222,2223],{},"true",". Give Docker more memory (Docker Desktop: ",[173,2226,277],{},"); the\nceilings of the engine containers are ",[26,2229,233],{},[26,2231,237],{},[26,2233,241],{},[26,2235,245],{},[14,2237,2238,2244,2245,2247,2248,2250,2251,1746,2253,2256,2257,2260],{},[21,2239,2240,2241,35],{},"The browser says ",[173,2242,2243],{},"Unable to connect"," The app is not there yet: the first\n",[26,2246,267],{}," is still building (its output shows the build steps), or the app\nis still compiling its pages. Wait for the gateway to be ",[26,2249,588],{}," in\n",[26,2252,2170],{},[26,2254,2255],{},"docker compose logs --tail 5 frontend"," ends with\n",[26,2258,2259],{},"Nuxt Nitro server built"," when the app is ready.",[14,2262,2263,2269,2270,234,2272,1142,2275,2278,2279],{},[21,2264,2265,2266,35],{},"Sign-in fails: ",[173,2267,2268],{},"Incorrect email or password"," Sign in with the email and password\nof the administrator you created (or, if you set them in ",[26,2271,245],{},[26,2273,2274],{},"AUTH__ADMIN_EMAIL",[26,2276,2277],{},"AUTH__ADMIN_PASSWORD","). After repeated failures the sign-in is paused: ",[173,2280,2281],{},"Too many sign-in\nattempts. Try again in 60 seconds.",[14,2283,2284,1032,2289,2292,2293,2296,2297,2299,2300,2302,2303,2305,2306,2308],{},[21,2285,2286,2287,35],{},"The gateway does not become ",[26,2288,588],{},[26,2290,2291],{},"docker compose logs --tail 20 gateway","\nnames the reason. ",[173,2294,2295],{},"Cannot create the administrator"," means an ",[26,2298,2277],{}," set\nin ",[26,2301,245],{}," is ",[26,2304,700],{},", another well-known password or shorter than 12 characters: choose\nanother one, or remove the line to create the administrator at the sign-in page, and run\n",[26,2307,267],{}," again.",[14,2310,2311],{},[21,2312,2313,2314,2316],{},"The ",[26,2315,770],{}," folder does not appear.",[47,2318,2319,2328],{},[50,2320,2321,2322,2324,2325,1337],{},"The administrator was created a moment ago: ",[26,2323,809],{}," needs about two minutes\nmore (",[26,2326,2327],{},"docker compose logs -f sampledb-init",[50,2329,2330],{},"You are signed in as a user other than an administrator: the folder is shared with\nnobody until an administrator grants it.",[2332,2333,2334],"style",{},"html pre.shiki code .sqRhv, html code.shiki .sqRhv{--shiki-default:#F69D50;--shiki-light:#6F42C1}html pre.shiki code .sXfbr, html code.shiki .sXfbr{--shiki-default:#96D0FF;--shiki-light:#032F62}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 .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 pre.shiki code .swcJU, html code.shiki .swcJU{--shiki-default:#6CB6FF;--shiki-light:#005CC5}html pre.shiki code .s6PUj, html code.shiki .s6PUj{--shiki-default:#F47067;--shiki-light:#D73A49}html pre.shiki code .ssh_m, html code.shiki .ssh_m{--shiki-default:#ADBAC7;--shiki-light:#24292E}html pre.shiki code .sxsTv, html code.shiki .sxsTv{--shiki-default:#F47067;--shiki-light:#005CC5}html pre.shiki code .sgHix, html code.shiki .sgHix{--shiki-default:#768390;--shiki-light:#6A737D}html pre.shiki code .sNjOc, html code.shiki .sNjOc{--shiki-default:#F69D50;--shiki-light:#E36209}",{"title":140,"searchDepth":158,"depth":1725,"links":2336},[2337,2338,2339,2340,2341,2342,2346,2347,2348,2349,2350],{"id":119,"depth":158,"text":55},{"id":402,"depth":158,"text":61},{"id":465,"depth":158,"text":67},{"id":530,"depth":158,"text":73},{"id":739,"depth":158,"text":79},{"id":795,"depth":158,"text":85,"children":2343},[2344,2345],{"id":799,"depth":1725,"text":800},{"id":920,"depth":1725,"text":921},{"id":940,"depth":158,"text":91},{"id":1325,"depth":158,"text":97},{"id":1425,"depth":158,"text":103},{"id":1596,"depth":158,"text":109},{"id":2028,"depth":158,"text":115},"md",{"source":2353},"docs\u002Fgetting-started-docker-compose.md",true,"\u002Fdocs\u002Fgetting-started-docker-compose",{"title":5,"description":16},"docs\u002Fgetting-started-docker-compose","tmDCh5FFJu4j7CYJmWglDQw_GCfXstVzGNlHb2GbUCQ",[2360,2377,2427,2456,2486,2513,2539,2559],{"title":2361,"icon":2362,"intro":2363,"items":2364},"Getting started","start","Install it on one machine, learn the few ideas everything else is built on, and run a first flow.",[2365,2367,2369,2371,2374],{"path":2366,"title":2361},"\u002Fdocs\u002Fgetting-started",{"path":2355,"title":2368},"Walkthrough with Docker Compose",{"path":1565,"title":2370},"Try it on your computer (minikube)",{"path":2372,"title":2373},"\u002Fdocs\u002Fconcepts","Concepts",{"path":2375,"title":2376},"\u002Fdocs\u002Foverview","Overview (README)",{"title":2378,"icon":2379,"intro":2380,"items":2381},"Capabilities","capabilities","What you can build: visual flows, analysis on any step, AI questions, pixel-perfect reports, dashboards, Python, R and SQL scripts, containers and the orchestration that ties them together.",[2382,2385,2388,2391,2394,2397,2400,2402,2404,2405,2408,2410,2413,2416,2419,2421,2424],{"path":2383,"title":2384},"\u002Fdocs\u002Fcapabilities","All capabilities",{"path":2386,"title":2387},"\u002Fdocs\u002Fcapabilities\u002Fflows","Low-code flows",{"path":2389,"title":2390},"\u002Fdocs\u002Fcapabilities\u002Fpreview-and-analysis","Preview and analysis",{"path":2392,"title":2393},"\u002Fdocs\u002Fcapabilities\u002Fask-your-data","Ask your data with AI",{"path":2395,"title":2396},"\u002Fdocs\u002Fcapabilities\u002Freports","Pixel-perfect reports",{"path":2398,"title":2399},"\u002Fdocs\u002Fcapabilities\u002Freport-functions","Report functions",{"path":2401,"title":890},"\u002Fdocs\u002Fcapabilities\u002Fdashboards",{"path":1575,"title":2403},"Python and R",{"path":1494,"title":1495},{"path":2406,"title":2407},"\u002Fdocs\u002Fcapabilities\u002Fnotebooks","marimo notebooks as apps",{"path":1579,"title":2409},"Docker images in flows",{"path":2411,"title":2412},"\u002Fdocs\u002Fcapabilities\u002Fflow-groups","Flow groups: orchestration",{"path":2414,"title":2415},"\u002Fdocs\u002Fcapabilities\u002Fscheduling","Scheduling",{"path":2417,"title":2418},"\u002Fdocs\u002Fpushmail","Pushmail: datasources, reports and dashboards by email",{"path":1480,"title":2420},"Dynamic dates",{"path":2422,"title":2423},"\u002Fdocs\u002Fcapabilities\u002Fengines","Engines",{"path":2425,"title":2426},"\u002Fdocs\u002Fengines\u002Fengine-differences","Engine differences",{"title":2428,"icon":2429,"intro":2430,"items":2431},"Sources","sources","Every way data comes in: files, databases, buckets, SFTP folders, HTTP APIs, SharePoint, Google Sheets, and the results of your own flows.",[2432,2435,2438,2441,2442,2444,2447,2450,2453],{"path":2433,"title":2434},"\u002Fdocs\u002Fsources","All sources",{"path":2436,"title":2437},"\u002Fdocs\u002Fsources\u002Ffiles","Uploaded files",{"path":2439,"title":2440},"\u002Fdocs\u002Fsources\u002Fdatabases","Database tables and queries",{"path":1457,"title":1458},{"path":1452,"title":2443},"SFTP folders",{"path":2445,"title":2446},"\u002Fdocs\u002Fapi-datasource","HTTP APIs",{"path":2448,"title":2449},"\u002Fdocs\u002Fsources\u002Fsharepoint","Excel on SharePoint",{"path":2451,"title":2452},"\u002Fdocs\u002Fsources\u002Fgoogle-sheets","Google Sheets",{"path":2454,"title":2455},"\u002Fdocs\u002Fsources\u002Fflow-outputs","Results of flows and scripts",{"title":2457,"icon":2458,"intro":2459,"items":2460},"Connections","connections","The systems Tabularia reads from and writes to, how each connection is set up, and who may use it.",[2461,2464,2467,2469,2472,2474,2475,2477,2478,2481,2483],{"path":2462,"title":2463},"\u002Fdocs\u002Fconnections","All connections",{"path":2465,"title":2466},"\u002Fdocs\u002Fconnections\u002Fdatabases","Databases",{"path":1442,"title":2468},"Microsoft SQL Server driver",{"path":2470,"title":2471},"\u002Fdocs\u002Fconnections\u002Fs3","S3 and compatible storage",{"path":1452,"title":2473},"SFTP servers",{"path":2445,"title":2446},{"path":2448,"title":2476},"SharePoint",{"path":2451,"title":2452},{"path":2479,"title":2480},"\u002Fdocs\u002Fconnections\u002Fsmtp","SMTP email",{"path":2482,"title":1539},"\u002Fdocs\u002Fcontainer-registries",{"path":2484,"title":2485},"\u002Fdocs\u002Fconnections\u002Fdestinations","Writing data out",{"title":2487,"icon":2488,"intro":2489,"items":2490},"Integrations","integrations","How Tabularia fits your stack: AI providers, the REST API and webhooks, dbt, OpenLineage, single sign-on, SIEM and monitoring.",[2491,2494,2497,2500,2501,2504,2507,2510],{"path":2492,"title":2493},"\u002Fdocs\u002Fintegrations","All integrations",{"path":2495,"title":2496},"\u002Fdocs\u002Fintegrations\u002Fai","AI: where it is used",{"path":2498,"title":2499},"\u002Fdocs\u002Fapi","API, tokens and webhooks",{"path":1526,"title":1527},{"path":2502,"title":2503},"\u002Fdocs\u002Fopenlineage","OpenLineage",{"path":2505,"title":2506},"\u002Fdocs\u002Fsso-keycloak","Single sign-on with Keycloak",{"path":2508,"title":2509},"\u002Fdocs\u002Fsiem-splunk","Audit log to Splunk",{"path":2511,"title":2512},"\u002Fdocs\u002Fintegrations\u002Fmonitoring","Monitoring",{"title":2514,"icon":2515,"intro":2516,"items":2517},"Security & governance","governance","Who may see and do what, what is recorded, and how data quality and personal data are kept in check.",[2518,2521,2524,2527,2530,2533,2536],{"path":2519,"title":2520},"\u002Fdocs\u002Fgovernance","Overview",{"path":2522,"title":2523},"\u002Fdocs\u002Fgovernance\u002Fpermissions","Permissions",{"path":2525,"title":2526},"\u002Fdocs\u002Fgovernance\u002Faudit-log","Audit log",{"path":2528,"title":2529},"\u002Fdocs\u002Fgovernance\u002Fdata-contracts","Data contracts",{"path":2531,"title":2532},"\u002Fdocs\u002Fdesign\u002Fsso-group-mapping","SSO and group mapping",{"path":2534,"title":2535},"\u002Fdocs\u002Fexamples\u002Fkeycloak","Keycloak example on a laptop",{"path":2537,"title":2538},"\u002Fdocs\u002Fengines\u002Fclickhouse-ai-user","A ClickHouse user for the AI assistant",{"title":2540,"icon":2541,"intro":2542,"items":2543},"Install & operate","operate","Run it in production on Kubernetes, configure it, upgrade it and keep it healthy.",[2544,2545,2547,2550,2552,2553,2556],{"path":33,"title":34},{"path":1570,"title":2546},"A company-like cluster on one computer (kind)",{"path":2548,"title":2549},"\u002Fdocs\u002Fdeploy\u002Fupgrading","Upgrading, backups and restore",{"path":1592,"title":2551},"Install and upgrade checklist",{"path":526,"title":527},{"path":2554,"title":2555},"\u002Fdocs\u002Fengine-settings","Settings from the panel",{"path":2557,"title":2558},"\u002Fdocs\u002Fdatabase-migrations","Database migrations",{"title":2560,"icon":2561,"intro":2562,"items":2563},"Reference","reference","Release process and the remaining reference pages.",[2564],{"path":2565,"title":2566},"\u002Fdocs\u002Frelease-process","Release process",1793656372377]