[{"data":1,"prerenderedAt":3644},["ShallowReactive",2],{"/environment/how-to-set-up-stack-for-a-vibe-coded-app-with-docker/":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"head":10,"created":25,"tags":29,"chapters":32,"thumb":34,"contact":35,"feedback":35,"lead":35,"list":35,"index":35,"sitemap":35,"featured":35,"body":36,"_type":3638,"_id":3639,"_source":3640,"_file":3641,"_stem":3642,"_extension":3643},"/environment/how-to-set-up-stack-for-a-vibe-coded-app-with-docker","environment",false,"","How to set up stack for a vibe-coded app with Docker?","Learn how to set up an infrastructure for a solid vibe-coded application with Docker, Nuxt, Directus, MySQL, and RustFS for a clean local prototyping.",{"title":11,"link":12,"meta":16},"How to set up stack for a vibe-coded app with Docker? | pragmate.dev",[13],{"rel":14,"href":15},"canonical","https://pragmate.dev/environment/how-to-set-up-stack-for-a-vibe-coded-app-with-docker/",[17,20,23,26],{"name":18,"content":19},"twitter:creator","@przemekhernik",{"name":21,"content":22},"author","Przemysław Hernik",{"name":24,"content":25},"article:published_time","2026-08-12",{"name":27,"content":28},"og:image","https://cdn.pragmate.dev/wp-content/uploads/2026/08/cf5a8760-7f49-4a24-a130-fa0a82d02ebc.png",{"time":30,"level":31},"12 min","Easy",[33],"/environment/how-to-set-up-stack-for-a-vibe-coded-app-with-docker/","docker",true,{"type":37,"children":38,"toc":3622},"root",[39,45,52,68,72,76,83,88,143,148,151,157,170,179,191,199,202,208,245,258,271,443,463,471,474,480,515,636,671,698,930,943,946,952,966,981,1022,1441,1454,1457,1463,1490,1511,1684,1705,1708,1714,1743,1778,1929,1949,1952,1958,1963,2001,2006,3292,3313,3318,3355,3360,3363,3369,3374,3381,3409,3452,3458,3463,3494,3500,3512,3539,3544,3576,3579,3585,3590,3593,3616],{"type":40,"tag":41,"props":42,"children":44},"element","prose-video",{"thumbnail":28,"url":43},"https://www.youtube-nocookie.com/embed/DpxsQMhplak",[],{"type":40,"tag":46,"props":47,"children":48},"p",{},[49],{"type":50,"value":51},"text","Yes, a vibe-coded app can be solid. A lot of people hear that phrase and instantly assume ‘AI slop,’ often because they associate it with rushed or poorly projects made without technical knowledge. However, if the app is built on a clean structure and an easy-to-run setup, the code can move quickly while remaining solid, without turning into a big ball of mud later.",{"type":40,"tag":46,"props":53,"children":54},{},[55,57,66],{"type":50,"value":56},"In ",{"type":40,"tag":58,"props":59,"children":63},"a",{"href":60,"rel":61},"https://coditive.com/blog/stack-for-vibe-coded-app/",[62],"nofollow",[64],{"type":50,"value":65},"the previous article",{"type":50,"value":67},", I walked through the basic layers of the application and why each one matters while vibe-coding. In this one, I want to show the practical part. This guide shows how to set up a complete vibe-coded app stack with Docker, Nuxt, Directus, MySQL, and RustFS, so your prototype can run locally and then on production.",{"type":40,"tag":69,"props":70,"children":71},"cta",{},[],{"type":40,"tag":73,"props":74,"children":75},"hr",{},[],{"type":40,"tag":77,"props":78,"children":80},"h2",{"id":79},"what-to-know-first-before-starting",[81],{"type":50,"value":82},"What to know first before starting?",{"type":40,"tag":46,"props":84,"children":85},{},[86],{"type":50,"value":87},"This guide focuses on wiring the stack together with Docker, not on teaching every tool from scratch. Before following it, you should already understand the basics of Docker, Git, Nuxt, and Directus, or be ready to check their documentation when needed. It is worth knowing:",{"type":40,"tag":89,"props":90,"children":91},"ul",{},[92,103,113,123,133],{"type":40,"tag":93,"props":94,"children":95},"li",{},[96],{"type":40,"tag":58,"props":97,"children":100},{"href":98,"rel":99},"https://pragmate.dev/environment/how-to-create-docker-image-on-docker-hub/#how-to-prepare-the-environment",[62],[101],{"type":50,"value":102},"What do you need to run Docker?",{"type":40,"tag":93,"props":104,"children":105},{},[106],{"type":40,"tag":58,"props":107,"children":110},{"href":108,"rel":109},"https://nuxt.com/docs/getting-started/introduction",[62],[111],{"type":50,"value":112},"How to get started with Nuxt?",{"type":40,"tag":93,"props":114,"children":115},{},[116],{"type":40,"tag":58,"props":117,"children":120},{"href":118,"rel":119},"https://directus.com/docs/getting-started/create-a-project",[62],[121],{"type":50,"value":122},"How to get started with Directus?",{"type":40,"tag":93,"props":124,"children":125},{},[126],{"type":40,"tag":58,"props":127,"children":130},{"href":128,"rel":129},"https://dev.mysql.com/doc/mysql-getting-started/en/",[62],[131],{"type":50,"value":132},"How to get started with MySQL?",{"type":40,"tag":93,"props":134,"children":135},{},[136],{"type":40,"tag":58,"props":137,"children":140},{"href":138,"rel":139},"https://docs.rustfs.com/en",[62],[141],{"type":50,"value":142},"How to get started with RustFS?",{"type":40,"tag":46,"props":144,"children":145},{},[146],{"type":50,"value":147},"Before using this stack in a long-running project, check whether newer stable versions are available and update them intentionally. Some images are in alpha stages (RustFS), so they might not be best choice for large production apps, but they are fine enough to start.",{"type":40,"tag":73,"props":149,"children":150},{},[],{"type":40,"tag":77,"props":152,"children":154},{"id":153},"what-are-the-layers-of-a-solid-application",[155],{"type":50,"value":156},"What are the layers of a solid application?",{"type":40,"tag":46,"props":158,"children":159},{},[160,162,168],{"type":50,"value":161},"Let's assume that we're building a classic web application. That means a frontend for users, a backend for management and logic, a database for data storage, and storage for static files. ",{"type":40,"tag":163,"props":164,"children":165},"strong",{},[166],{"type":50,"value":167},"The goal is to keep every part in its own place so the app stays easier to develop and expand later.",{"type":50,"value":169}," If you remember the basic layers from the business article, this is where those layers become real containers instead of just a nice diagram.",{"type":40,"tag":46,"props":171,"children":172},{},[173],{"type":40,"tag":174,"props":175,"children":178},"img",{"alt":176,"src":177},"scheme presenting connections between frontend, storage, backoffice and database layer","https://cdn.pragmate.dev/wp-content/uploads/2026/08/4148856d-fb58-4455-98ec-ee4703c64c11.png",[],{"type":40,"tag":46,"props":180,"children":181},{},[182,184,189],{"type":50,"value":183},"In the tech stack I plan to use, ",{"type":40,"tag":163,"props":185,"children":186},{},[187],{"type":50,"value":188},"Nuxt handles the interface through the client layer and business logic through the server layer. Directus provides the management area and data exchange API endpoints. MySQL stores structured data, and RustFS stores static files",{"type":50,"value":190},". The benefit of this setup is that each part performs a single job. So, when something changes in one node, we don't need to rewrite the whole app.",{"type":40,"tag":46,"props":192,"children":193},{},[194],{"type":40,"tag":174,"props":195,"children":198},{"alt":196,"src":197},"scheme presenting docker infrastructure for 4 layers","https://cdn.pragmate.dev/wp-content/uploads/2026/08/ccb7115c-1808-4bbb-9b55-47b57dc086df.png",[],{"type":40,"tag":73,"props":200,"children":201},{},[],{"type":40,"tag":77,"props":203,"children":205},{"id":204},"how-to-initialize-a-docker-infrastructure-for-a-vibe-coded-app",[206],{"type":50,"value":207},"How to initialize a Docker infrastructure for a vibe-coded app?",{"type":40,"tag":46,"props":209,"children":210},{},[211,213,220,222,228,229,235,237,243],{"type":50,"value":212},"I choose the monorepo structure because it keeps the whole codebase in one place while still letting each layer live in its own directory. I create ",{"type":40,"tag":214,"props":215,"children":217},"code",{"className":216},[],[218],{"type":50,"value":219},"frontend",{"type":50,"value":221},", ",{"type":40,"tag":214,"props":223,"children":225},{"className":224},[],[226],{"type":50,"value":227},"backend",{"type":50,"value":221},{"type":40,"tag":214,"props":230,"children":232},{"className":231},[],[233],{"type":50,"value":234},"database",{"type":50,"value":236},", and ",{"type":40,"tag":214,"props":238,"children":240},{"className":239},[],[241],{"type":50,"value":242},"storage",{"type":50,"value":244}," directories in the project root. This makes the project easier to understand.",{"type":40,"tag":46,"props":246,"children":247},{},[248,250,256],{"type":50,"value":249},"The next step is creating a ",{"type":40,"tag":214,"props":251,"children":253},{"className":252},[],[254],{"type":50,"value":255},"docker-compose.yml",{"type":50,"value":257}," file, where we can configure the Docker setup. It defines the shape of the application: which services exist, ports they use, volumes they need, and how they connect. It’s the starting point that Docker uses when running the project.",{"type":40,"tag":46,"props":259,"children":260},{},[261,263,269],{"type":50,"value":262},"You should also create a ",{"type":40,"tag":214,"props":264,"children":266},{"className":265},[],[267],{"type":50,"value":268},".env",{"type":50,"value":270}," file to store system configuration and sensitive information. Create this file in the project root and fill it with the required details. Carefully replace the example values with your own ones, with randomly generated keys, secrets, and passwords.",{"type":40,"tag":272,"props":273,"children":277},"pre",{"className":274,"code":275,"filename":268,"language":276,"meta":7,"style":7},"language-txt shiki shiki-themes one-dark-pro","APP_URL=\"http://localhost:9000\"\nAPP_ENV=\"local\"\n\nDIRECTUS_KEY=\"19e7d44777ab45f2bff7bf2cfa2b2277\"\nDIRECTUS_SECRET=\"ec5c45511ea84300a30acc028c05b602\"\n\nDB_HOST=\"database\"\nDB_PORT=\"3306\"\nDB_USER=\"johndoe\"\nDB_PASSWORD=\"de95a8ac99d848b4b6fdb4d7d354c1a8\"\nDB_NAME=\"vibecode\"\nDB_ROOT_PASSWORD=\"cc0d6fd235dd4e53b8c5a028b68b8ca6\"\n\nS3_KEY=\"8b29c4079d6144c3bc609f4f081a9f26\"\nS3_SECRET=\"57bcaffaaf644de89ae6c225e70ad74a\"\nS3_BUCKET=\"default\"\nS3_REGION=\"fra1\"\nS3_ENDPOINT=\"http://storage:9000\"\n","txt",[278],{"type":40,"tag":214,"props":279,"children":280},{"__ignoreMap":7},[281,292,301,310,319,328,336,345,354,363,372,381,390,398,407,416,425,434],{"type":40,"tag":282,"props":283,"children":286},"span",{"class":284,"line":285},"line",1,[287],{"type":40,"tag":282,"props":288,"children":289},{},[290],{"type":50,"value":291},"APP_URL=\"http://localhost:9000\"\n",{"type":40,"tag":282,"props":293,"children":295},{"class":284,"line":294},2,[296],{"type":40,"tag":282,"props":297,"children":298},{},[299],{"type":50,"value":300},"APP_ENV=\"local\"\n",{"type":40,"tag":282,"props":302,"children":304},{"class":284,"line":303},3,[305],{"type":40,"tag":282,"props":306,"children":307},{"emptyLinePlaceholder":35},[308],{"type":50,"value":309},"\n",{"type":40,"tag":282,"props":311,"children":313},{"class":284,"line":312},4,[314],{"type":40,"tag":282,"props":315,"children":316},{},[317],{"type":50,"value":318},"DIRECTUS_KEY=\"19e7d44777ab45f2bff7bf2cfa2b2277\"\n",{"type":40,"tag":282,"props":320,"children":322},{"class":284,"line":321},5,[323],{"type":40,"tag":282,"props":324,"children":325},{},[326],{"type":50,"value":327},"DIRECTUS_SECRET=\"ec5c45511ea84300a30acc028c05b602\"\n",{"type":40,"tag":282,"props":329,"children":331},{"class":284,"line":330},6,[332],{"type":40,"tag":282,"props":333,"children":334},{"emptyLinePlaceholder":35},[335],{"type":50,"value":309},{"type":40,"tag":282,"props":337,"children":339},{"class":284,"line":338},7,[340],{"type":40,"tag":282,"props":341,"children":342},{},[343],{"type":50,"value":344},"DB_HOST=\"database\"\n",{"type":40,"tag":282,"props":346,"children":348},{"class":284,"line":347},8,[349],{"type":40,"tag":282,"props":350,"children":351},{},[352],{"type":50,"value":353},"DB_PORT=\"3306\"\n",{"type":40,"tag":282,"props":355,"children":357},{"class":284,"line":356},9,[358],{"type":40,"tag":282,"props":359,"children":360},{},[361],{"type":50,"value":362},"DB_USER=\"johndoe\"\n",{"type":40,"tag":282,"props":364,"children":366},{"class":284,"line":365},10,[367],{"type":40,"tag":282,"props":368,"children":369},{},[370],{"type":50,"value":371},"DB_PASSWORD=\"de95a8ac99d848b4b6fdb4d7d354c1a8\"\n",{"type":40,"tag":282,"props":373,"children":375},{"class":284,"line":374},11,[376],{"type":40,"tag":282,"props":377,"children":378},{},[379],{"type":50,"value":380},"DB_NAME=\"vibecode\"\n",{"type":40,"tag":282,"props":382,"children":384},{"class":284,"line":383},12,[385],{"type":40,"tag":282,"props":386,"children":387},{},[388],{"type":50,"value":389},"DB_ROOT_PASSWORD=\"cc0d6fd235dd4e53b8c5a028b68b8ca6\"\n",{"type":40,"tag":282,"props":391,"children":393},{"class":284,"line":392},13,[394],{"type":40,"tag":282,"props":395,"children":396},{"emptyLinePlaceholder":35},[397],{"type":50,"value":309},{"type":40,"tag":282,"props":399,"children":401},{"class":284,"line":400},14,[402],{"type":40,"tag":282,"props":403,"children":404},{},[405],{"type":50,"value":406},"S3_KEY=\"8b29c4079d6144c3bc609f4f081a9f26\"\n",{"type":40,"tag":282,"props":408,"children":410},{"class":284,"line":409},15,[411],{"type":40,"tag":282,"props":412,"children":413},{},[414],{"type":50,"value":415},"S3_SECRET=\"57bcaffaaf644de89ae6c225e70ad74a\"\n",{"type":40,"tag":282,"props":417,"children":419},{"class":284,"line":418},16,[420],{"type":40,"tag":282,"props":421,"children":422},{},[423],{"type":50,"value":424},"S3_BUCKET=\"default\"\n",{"type":40,"tag":282,"props":426,"children":428},{"class":284,"line":427},17,[429],{"type":40,"tag":282,"props":430,"children":431},{},[432],{"type":50,"value":433},"S3_REGION=\"fra1\"\n",{"type":40,"tag":282,"props":435,"children":437},{"class":284,"line":436},18,[438],{"type":40,"tag":282,"props":439,"children":440},{},[441],{"type":50,"value":442},"S3_ENDPOINT=\"http://storage:9000\"\n",{"type":40,"tag":46,"props":444,"children":445},{},[446,448,454,456,461],{"type":50,"value":447},"If you're going to use Git, you can also create a ",{"type":40,"tag":214,"props":449,"children":451},{"className":450},[],[452],{"type":50,"value":453},".gitignore",{"type":50,"value":455}," file. At this point, you can add ",{"type":40,"tag":214,"props":457,"children":459},{"className":458},[],[460],{"type":50,"value":268},{"type":50,"value":462}," to the list of ignored files because items with sensitive details should never be in the repo.",{"type":40,"tag":46,"props":464,"children":465},{},[466],{"type":40,"tag":174,"props":467,"children":470},{"alt":468,"src":469},"image presenting the minimum directory structure of a project","https://cdn.pragmate.dev/wp-content/uploads/2026/08/46483a32-c7ee-4d44-af63-054f5e824345.jpg",[],{"type":40,"tag":73,"props":472,"children":473},{},[],{"type":40,"tag":77,"props":475,"children":477},{"id":476},"how-to-create-a-docker-container-for-nuxt",[478],{"type":50,"value":479},"How to create a Docker container for Nuxt?",{"type":40,"tag":46,"props":481,"children":482},{},[483,490,492,497,499,505,507,513],{"type":40,"tag":58,"props":484,"children":487},{"href":485,"rel":486},"https://nuxt.com/docs/4.x/getting-started/installation",[62],[488],{"type":50,"value":489},"Initialize a Nuxt project",{"type":50,"value":491}," in the ",{"type":40,"tag":214,"props":493,"children":495},{"className":494},[],[496],{"type":50,"value":219},{"type":50,"value":498}," directory, then create a file named ",{"type":40,"tag":214,"props":500,"children":502},{"className":501},[],[503],{"type":50,"value":504},"Dockerfile",{"type":50,"value":506}," there. This file tells Docker how to set up the environment for Nuxt. It uses Node 24 as the base image, enables Corepack so ",{"type":40,"tag":214,"props":508,"children":510},{"className":509},[],[511],{"type":50,"value":512},"pnpm",{"type":50,"value":514}," is available, copies the cache and configuration files, installs dependencies, and starts the application in development mode.",{"type":40,"tag":272,"props":516,"children":519},{"className":274,"code":517,"filename":518,"language":276,"meta":7,"style":7},"FROM node:24.18.0-alpine\n\nWORKDIR /app\n\nRUN corepack enable\n\nCOPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./\n\nRUN pnpm install\n\nCOPY . .\n\nEXPOSE 3000\n\nCMD [\"sh\", \"-c\", \"pnpm install && exec pnpm dev\"]\n","frontend/Dockerfile",[520],{"type":40,"tag":214,"props":521,"children":522},{"__ignoreMap":7},[523,531,538,546,553,561,568,576,583,591,598,606,613,621,628],{"type":40,"tag":282,"props":524,"children":525},{"class":284,"line":285},[526],{"type":40,"tag":282,"props":527,"children":528},{},[529],{"type":50,"value":530},"FROM node:24.18.0-alpine\n",{"type":40,"tag":282,"props":532,"children":533},{"class":284,"line":294},[534],{"type":40,"tag":282,"props":535,"children":536},{"emptyLinePlaceholder":35},[537],{"type":50,"value":309},{"type":40,"tag":282,"props":539,"children":540},{"class":284,"line":303},[541],{"type":40,"tag":282,"props":542,"children":543},{},[544],{"type":50,"value":545},"WORKDIR /app\n",{"type":40,"tag":282,"props":547,"children":548},{"class":284,"line":312},[549],{"type":40,"tag":282,"props":550,"children":551},{"emptyLinePlaceholder":35},[552],{"type":50,"value":309},{"type":40,"tag":282,"props":554,"children":555},{"class":284,"line":321},[556],{"type":40,"tag":282,"props":557,"children":558},{},[559],{"type":50,"value":560},"RUN corepack enable\n",{"type":40,"tag":282,"props":562,"children":563},{"class":284,"line":330},[564],{"type":40,"tag":282,"props":565,"children":566},{"emptyLinePlaceholder":35},[567],{"type":50,"value":309},{"type":40,"tag":282,"props":569,"children":570},{"class":284,"line":338},[571],{"type":40,"tag":282,"props":572,"children":573},{},[574],{"type":50,"value":575},"COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./\n",{"type":40,"tag":282,"props":577,"children":578},{"class":284,"line":347},[579],{"type":40,"tag":282,"props":580,"children":581},{"emptyLinePlaceholder":35},[582],{"type":50,"value":309},{"type":40,"tag":282,"props":584,"children":585},{"class":284,"line":356},[586],{"type":40,"tag":282,"props":587,"children":588},{},[589],{"type":50,"value":590},"RUN pnpm install\n",{"type":40,"tag":282,"props":592,"children":593},{"class":284,"line":365},[594],{"type":40,"tag":282,"props":595,"children":596},{"emptyLinePlaceholder":35},[597],{"type":50,"value":309},{"type":40,"tag":282,"props":599,"children":600},{"class":284,"line":374},[601],{"type":40,"tag":282,"props":602,"children":603},{},[604],{"type":50,"value":605},"COPY . .\n",{"type":40,"tag":282,"props":607,"children":608},{"class":284,"line":383},[609],{"type":40,"tag":282,"props":610,"children":611},{"emptyLinePlaceholder":35},[612],{"type":50,"value":309},{"type":40,"tag":282,"props":614,"children":615},{"class":284,"line":392},[616],{"type":40,"tag":282,"props":617,"children":618},{},[619],{"type":50,"value":620},"EXPOSE 3000\n",{"type":40,"tag":282,"props":622,"children":623},{"class":284,"line":400},[624],{"type":40,"tag":282,"props":625,"children":626},{"emptyLinePlaceholder":35},[627],{"type":50,"value":309},{"type":40,"tag":282,"props":629,"children":630},{"class":284,"line":409},[631],{"type":40,"tag":282,"props":632,"children":633},{},[634],{"type":50,"value":635},"CMD [\"sh\", \"-c\", \"pnpm install && exec pnpm dev\"]\n",{"type":40,"tag":46,"props":637,"children":638},{},[639,641,646,648,653,655,661,663,669],{"type":50,"value":640},"Now it is time to tell Docker to use the defined environment when starting the frontend container. Create the ",{"type":40,"tag":214,"props":642,"children":644},{"className":643},[],[645],{"type":50,"value":219},{"type":50,"value":647}," service in ",{"type":40,"tag":214,"props":649,"children":651},{"className":650},[],[652],{"type":50,"value":255},{"type":50,"value":654},", give it a clear name, point it to the Dockerfile, and map the ports. This means that when you access ",{"type":40,"tag":214,"props":656,"children":658},{"className":657},[],[659],{"type":50,"value":660},"localhost:9000",{"type":50,"value":662}," in your browser, you will see what is on ",{"type":40,"tag":214,"props":664,"children":666},{"className":665},[],[667],{"type":50,"value":668},"localhost:3000",{"type":50,"value":670}," in the container.",{"type":40,"tag":46,"props":672,"children":673},{},[674,676,682,684,689,691,696],{"type":50,"value":675},"Mount the source code volume so changes in local files are reflected in the Docker container. It's also good to mount ",{"type":40,"tag":214,"props":677,"children":679},{"className":678},[],[680],{"type":50,"value":681},"node_modules",{"type":50,"value":683}," separately so the container keeps its own dependencies instead of conflicting with the host machine. You can use the ",{"type":40,"tag":214,"props":685,"children":687},{"className":686},[],[688],{"type":50,"value":5},{"type":50,"value":690}," key to define the environment variables that can be resolved automatically from the ",{"type":40,"tag":214,"props":692,"children":694},{"className":693},[],[695],{"type":50,"value":268},{"type":50,"value":697}," file in the root.",{"type":40,"tag":272,"props":699,"children":703},{"className":700,"code":701,"filename":255,"language":702,"meta":7,"style":7},"language-yaml shiki shiki-themes one-dark-pro","name: coditive-space\n\nservices:\n  frontend:\n    container_name: coditive-space-frontend\n    build:\n      context: ./frontend\n      dockerfile: Dockerfile\n    ports:\n      - \"9000:3000\"\n    volumes:\n      - ./frontend:/app:cached\n      - ./frontend/node_modules:/app/node_modules:delegated\n    environment:\n      NUXT_PUBLIC_APP_URL: ${APP_URL}\n      NUXT_PUBLIC_APP_ENV: ${APP_ENV}\n","yaml",[704],{"type":40,"tag":214,"props":705,"children":706},{"__ignoreMap":7},[707,728,735,748,760,777,789,806,823,835,848,860,872,884,896,913],{"type":40,"tag":282,"props":708,"children":709},{"class":284,"line":285},[710,716,722],{"type":40,"tag":282,"props":711,"children":713},{"style":712},"--shiki-default:#E06C75",[714],{"type":50,"value":715},"name",{"type":40,"tag":282,"props":717,"children":719},{"style":718},"--shiki-default:#ABB2BF",[720],{"type":50,"value":721},": ",{"type":40,"tag":282,"props":723,"children":725},{"style":724},"--shiki-default:#98C379",[726],{"type":50,"value":727},"coditive-space\n",{"type":40,"tag":282,"props":729,"children":730},{"class":284,"line":294},[731],{"type":40,"tag":282,"props":732,"children":733},{"emptyLinePlaceholder":35},[734],{"type":50,"value":309},{"type":40,"tag":282,"props":736,"children":737},{"class":284,"line":303},[738,743],{"type":40,"tag":282,"props":739,"children":740},{"style":712},[741],{"type":50,"value":742},"services",{"type":40,"tag":282,"props":744,"children":745},{"style":718},[746],{"type":50,"value":747},":\n",{"type":40,"tag":282,"props":749,"children":750},{"class":284,"line":312},[751,756],{"type":40,"tag":282,"props":752,"children":753},{"style":712},[754],{"type":50,"value":755},"  frontend",{"type":40,"tag":282,"props":757,"children":758},{"style":718},[759],{"type":50,"value":747},{"type":40,"tag":282,"props":761,"children":762},{"class":284,"line":321},[763,768,772],{"type":40,"tag":282,"props":764,"children":765},{"style":712},[766],{"type":50,"value":767},"    container_name",{"type":40,"tag":282,"props":769,"children":770},{"style":718},[771],{"type":50,"value":721},{"type":40,"tag":282,"props":773,"children":774},{"style":724},[775],{"type":50,"value":776},"coditive-space-frontend\n",{"type":40,"tag":282,"props":778,"children":779},{"class":284,"line":330},[780,785],{"type":40,"tag":282,"props":781,"children":782},{"style":712},[783],{"type":50,"value":784},"    build",{"type":40,"tag":282,"props":786,"children":787},{"style":718},[788],{"type":50,"value":747},{"type":40,"tag":282,"props":790,"children":791},{"class":284,"line":338},[792,797,801],{"type":40,"tag":282,"props":793,"children":794},{"style":712},[795],{"type":50,"value":796},"      context",{"type":40,"tag":282,"props":798,"children":799},{"style":718},[800],{"type":50,"value":721},{"type":40,"tag":282,"props":802,"children":803},{"style":724},[804],{"type":50,"value":805},"./frontend\n",{"type":40,"tag":282,"props":807,"children":808},{"class":284,"line":347},[809,814,818],{"type":40,"tag":282,"props":810,"children":811},{"style":712},[812],{"type":50,"value":813},"      dockerfile",{"type":40,"tag":282,"props":815,"children":816},{"style":718},[817],{"type":50,"value":721},{"type":40,"tag":282,"props":819,"children":820},{"style":724},[821],{"type":50,"value":822},"Dockerfile\n",{"type":40,"tag":282,"props":824,"children":825},{"class":284,"line":356},[826,831],{"type":40,"tag":282,"props":827,"children":828},{"style":712},[829],{"type":50,"value":830},"    ports",{"type":40,"tag":282,"props":832,"children":833},{"style":718},[834],{"type":50,"value":747},{"type":40,"tag":282,"props":836,"children":837},{"class":284,"line":365},[838,843],{"type":40,"tag":282,"props":839,"children":840},{"style":718},[841],{"type":50,"value":842},"      - ",{"type":40,"tag":282,"props":844,"children":845},{"style":724},[846],{"type":50,"value":847},"\"9000:3000\"\n",{"type":40,"tag":282,"props":849,"children":850},{"class":284,"line":374},[851,856],{"type":40,"tag":282,"props":852,"children":853},{"style":712},[854],{"type":50,"value":855},"    volumes",{"type":40,"tag":282,"props":857,"children":858},{"style":718},[859],{"type":50,"value":747},{"type":40,"tag":282,"props":861,"children":862},{"class":284,"line":383},[863,867],{"type":40,"tag":282,"props":864,"children":865},{"style":718},[866],{"type":50,"value":842},{"type":40,"tag":282,"props":868,"children":869},{"style":724},[870],{"type":50,"value":871},"./frontend:/app:cached\n",{"type":40,"tag":282,"props":873,"children":874},{"class":284,"line":392},[875,879],{"type":40,"tag":282,"props":876,"children":877},{"style":718},[878],{"type":50,"value":842},{"type":40,"tag":282,"props":880,"children":881},{"style":724},[882],{"type":50,"value":883},"./frontend/node_modules:/app/node_modules:delegated\n",{"type":40,"tag":282,"props":885,"children":886},{"class":284,"line":400},[887,892],{"type":40,"tag":282,"props":888,"children":889},{"style":712},[890],{"type":50,"value":891},"    environment",{"type":40,"tag":282,"props":893,"children":894},{"style":718},[895],{"type":50,"value":747},{"type":40,"tag":282,"props":897,"children":898},{"class":284,"line":409},[899,904,908],{"type":40,"tag":282,"props":900,"children":901},{"style":712},[902],{"type":50,"value":903},"      NUXT_PUBLIC_APP_URL",{"type":40,"tag":282,"props":905,"children":906},{"style":718},[907],{"type":50,"value":721},{"type":40,"tag":282,"props":909,"children":910},{"style":724},[911],{"type":50,"value":912},"${APP_URL}\n",{"type":40,"tag":282,"props":914,"children":915},{"class":284,"line":418},[916,921,925],{"type":40,"tag":282,"props":917,"children":918},{"style":712},[919],{"type":50,"value":920},"      NUXT_PUBLIC_APP_ENV",{"type":40,"tag":282,"props":922,"children":923},{"style":718},[924],{"type":50,"value":721},{"type":40,"tag":282,"props":926,"children":927},{"style":724},[928],{"type":50,"value":929},"${APP_ENV}\n",{"type":40,"tag":46,"props":931,"children":932},{},[933,935,941],{"type":50,"value":934},"When you start the Docker service, you'll be able to access Nuxt via ",{"type":40,"tag":214,"props":936,"children":938},{"className":937},[],[939],{"type":50,"value":940},"http://localhost:9000",{"type":50,"value":942},".",{"type":40,"tag":73,"props":944,"children":945},{},[],{"type":40,"tag":77,"props":947,"children":949},{"id":948},"how-to-create-a-docker-container-for-directus",[950],{"type":50,"value":951},"How to create a Docker container for Directus?",{"type":40,"tag":46,"props":953,"children":954},{},[955,957,964],{"type":50,"value":956},"For Directus, the setup is much simpler because I only need ",{"type":40,"tag":58,"props":958,"children":961},{"href":959,"rel":960},"https://directus.com/docs/tutorials/self-hosting#self-host-with-docker",[62],[962],{"type":50,"value":963},"the official image as the base",{"type":50,"value":965},". Since Directus already knows how to run its own app, I do not need to rebuild anything from scratch unless I want to add custom behavior and mechanisms.",{"type":40,"tag":272,"props":967,"children":970},{"className":274,"code":968,"filename":969,"language":276,"meta":7,"style":7},"FROM directus/directus:12.0.2\n","backend/Dockerfile",[971],{"type":40,"tag":214,"props":972,"children":973},{"__ignoreMap":7},[974],{"type":40,"tag":282,"props":975,"children":976},{"class":284,"line":285},[977],{"type":40,"tag":282,"props":978,"children":979},{},[980],{"type":50,"value":968},{"type":40,"tag":46,"props":982,"children":983},{},[984,985,990,992,997,999,1004,1006,1011,1013,1020],{"type":50,"value":56},{"type":40,"tag":214,"props":986,"children":988},{"className":987},[],[989],{"type":50,"value":255},{"type":50,"value":991},", add the ",{"type":40,"tag":214,"props":993,"children":995},{"className":994},[],[996],{"type":50,"value":227},{"type":50,"value":998}," service, configure it to use that Dockerfile, and map the required ports. Use the ",{"type":40,"tag":214,"props":1000,"children":1002},{"className":1001},[],[1003],{"type":50,"value":5},{"type":50,"value":1005}," key to define the database client with variables from the project's ",{"type":40,"tag":214,"props":1007,"children":1009},{"className":1008},[],[1010],{"type":50,"value":268},{"type":50,"value":1012}," file. Directus supports ",{"type":40,"tag":58,"props":1014,"children":1017},{"href":1015,"rel":1016},"https://directus.com/docs/configuration/files#storage-locations",[62],[1018],{"type":50,"value":1019},"several file storage methods",{"type":50,"value":1021},", but for this stack, configure it to use local S3. As a result, when uploading items in the CMS, they will land in the RustFS.",{"type":40,"tag":272,"props":1023,"children":1025},{"className":700,"code":1024,"filename":255,"language":702,"meta":7,"style":7},"backend:\n    container_name: coditive-space-backend\n    build:\n      context: ./backend\n      dockerfile: Dockerfile\n    ports:\n      - \"9001:8055\"\n    environment:\n      KEY: ${DIRECTUS_KEY}\n      SECRET: ${DIRECTUS_SECRET}\n      DB_CLIENT: mysql\n      DB_HOST: ${DB_HOST}\n      DB_PORT: ${DB_PORT}\n      DB_USER: ${DB_USER}\n      DB_PASSWORD: ${DB_PASSWORD}\n      DB_DATABASE: ${DB_NAME}\n      STORAGE_LOCATIONS: local\n      STORAGE_LOCAL_DRIVER: s3\n      STORAGE_LOCAL_ROOT:\n      STORAGE_LOCAL_KEY: ${S3_KEY}\n      STORAGE_LOCAL_SECRET: ${S3_SECRET}\n      STORAGE_LOCAL_BUCKET: ${S3_BUCKET}\n      STORAGE_LOCAL_REGION: ${S3_REGION}\n      STORAGE_LOCAL_ENDPOINT: ${S3_ENDPOINT}\n      STORAGE_LOCAL_ACL: private\n      STORAGE_LOCAL_FORCE_PATH_STYLE: \"true\"\n",[1026],{"type":40,"tag":214,"props":1027,"children":1028},{"__ignoreMap":7},[1029,1040,1056,1067,1083,1098,1109,1121,1132,1149,1166,1183,1200,1217,1234,1251,1268,1285,1302,1315,1333,1351,1369,1387,1405,1423],{"type":40,"tag":282,"props":1030,"children":1031},{"class":284,"line":285},[1032,1036],{"type":40,"tag":282,"props":1033,"children":1034},{"style":712},[1035],{"type":50,"value":227},{"type":40,"tag":282,"props":1037,"children":1038},{"style":718},[1039],{"type":50,"value":747},{"type":40,"tag":282,"props":1041,"children":1042},{"class":284,"line":294},[1043,1047,1051],{"type":40,"tag":282,"props":1044,"children":1045},{"style":712},[1046],{"type":50,"value":767},{"type":40,"tag":282,"props":1048,"children":1049},{"style":718},[1050],{"type":50,"value":721},{"type":40,"tag":282,"props":1052,"children":1053},{"style":724},[1054],{"type":50,"value":1055},"coditive-space-backend\n",{"type":40,"tag":282,"props":1057,"children":1058},{"class":284,"line":303},[1059,1063],{"type":40,"tag":282,"props":1060,"children":1061},{"style":712},[1062],{"type":50,"value":784},{"type":40,"tag":282,"props":1064,"children":1065},{"style":718},[1066],{"type":50,"value":747},{"type":40,"tag":282,"props":1068,"children":1069},{"class":284,"line":312},[1070,1074,1078],{"type":40,"tag":282,"props":1071,"children":1072},{"style":712},[1073],{"type":50,"value":796},{"type":40,"tag":282,"props":1075,"children":1076},{"style":718},[1077],{"type":50,"value":721},{"type":40,"tag":282,"props":1079,"children":1080},{"style":724},[1081],{"type":50,"value":1082},"./backend\n",{"type":40,"tag":282,"props":1084,"children":1085},{"class":284,"line":321},[1086,1090,1094],{"type":40,"tag":282,"props":1087,"children":1088},{"style":712},[1089],{"type":50,"value":813},{"type":40,"tag":282,"props":1091,"children":1092},{"style":718},[1093],{"type":50,"value":721},{"type":40,"tag":282,"props":1095,"children":1096},{"style":724},[1097],{"type":50,"value":822},{"type":40,"tag":282,"props":1099,"children":1100},{"class":284,"line":330},[1101,1105],{"type":40,"tag":282,"props":1102,"children":1103},{"style":712},[1104],{"type":50,"value":830},{"type":40,"tag":282,"props":1106,"children":1107},{"style":718},[1108],{"type":50,"value":747},{"type":40,"tag":282,"props":1110,"children":1111},{"class":284,"line":338},[1112,1116],{"type":40,"tag":282,"props":1113,"children":1114},{"style":718},[1115],{"type":50,"value":842},{"type":40,"tag":282,"props":1117,"children":1118},{"style":724},[1119],{"type":50,"value":1120},"\"9001:8055\"\n",{"type":40,"tag":282,"props":1122,"children":1123},{"class":284,"line":347},[1124,1128],{"type":40,"tag":282,"props":1125,"children":1126},{"style":712},[1127],{"type":50,"value":891},{"type":40,"tag":282,"props":1129,"children":1130},{"style":718},[1131],{"type":50,"value":747},{"type":40,"tag":282,"props":1133,"children":1134},{"class":284,"line":356},[1135,1140,1144],{"type":40,"tag":282,"props":1136,"children":1137},{"style":712},[1138],{"type":50,"value":1139},"      KEY",{"type":40,"tag":282,"props":1141,"children":1142},{"style":718},[1143],{"type":50,"value":721},{"type":40,"tag":282,"props":1145,"children":1146},{"style":724},[1147],{"type":50,"value":1148},"${DIRECTUS_KEY}\n",{"type":40,"tag":282,"props":1150,"children":1151},{"class":284,"line":365},[1152,1157,1161],{"type":40,"tag":282,"props":1153,"children":1154},{"style":712},[1155],{"type":50,"value":1156},"      SECRET",{"type":40,"tag":282,"props":1158,"children":1159},{"style":718},[1160],{"type":50,"value":721},{"type":40,"tag":282,"props":1162,"children":1163},{"style":724},[1164],{"type":50,"value":1165},"${DIRECTUS_SECRET}\n",{"type":40,"tag":282,"props":1167,"children":1168},{"class":284,"line":374},[1169,1174,1178],{"type":40,"tag":282,"props":1170,"children":1171},{"style":712},[1172],{"type":50,"value":1173},"      DB_CLIENT",{"type":40,"tag":282,"props":1175,"children":1176},{"style":718},[1177],{"type":50,"value":721},{"type":40,"tag":282,"props":1179,"children":1180},{"style":724},[1181],{"type":50,"value":1182},"mysql\n",{"type":40,"tag":282,"props":1184,"children":1185},{"class":284,"line":383},[1186,1191,1195],{"type":40,"tag":282,"props":1187,"children":1188},{"style":712},[1189],{"type":50,"value":1190},"      DB_HOST",{"type":40,"tag":282,"props":1192,"children":1193},{"style":718},[1194],{"type":50,"value":721},{"type":40,"tag":282,"props":1196,"children":1197},{"style":724},[1198],{"type":50,"value":1199},"${DB_HOST}\n",{"type":40,"tag":282,"props":1201,"children":1202},{"class":284,"line":392},[1203,1208,1212],{"type":40,"tag":282,"props":1204,"children":1205},{"style":712},[1206],{"type":50,"value":1207},"      DB_PORT",{"type":40,"tag":282,"props":1209,"children":1210},{"style":718},[1211],{"type":50,"value":721},{"type":40,"tag":282,"props":1213,"children":1214},{"style":724},[1215],{"type":50,"value":1216},"${DB_PORT}\n",{"type":40,"tag":282,"props":1218,"children":1219},{"class":284,"line":400},[1220,1225,1229],{"type":40,"tag":282,"props":1221,"children":1222},{"style":712},[1223],{"type":50,"value":1224},"      DB_USER",{"type":40,"tag":282,"props":1226,"children":1227},{"style":718},[1228],{"type":50,"value":721},{"type":40,"tag":282,"props":1230,"children":1231},{"style":724},[1232],{"type":50,"value":1233},"${DB_USER}\n",{"type":40,"tag":282,"props":1235,"children":1236},{"class":284,"line":409},[1237,1242,1246],{"type":40,"tag":282,"props":1238,"children":1239},{"style":712},[1240],{"type":50,"value":1241},"      DB_PASSWORD",{"type":40,"tag":282,"props":1243,"children":1244},{"style":718},[1245],{"type":50,"value":721},{"type":40,"tag":282,"props":1247,"children":1248},{"style":724},[1249],{"type":50,"value":1250},"${DB_PASSWORD}\n",{"type":40,"tag":282,"props":1252,"children":1253},{"class":284,"line":418},[1254,1259,1263],{"type":40,"tag":282,"props":1255,"children":1256},{"style":712},[1257],{"type":50,"value":1258},"      DB_DATABASE",{"type":40,"tag":282,"props":1260,"children":1261},{"style":718},[1262],{"type":50,"value":721},{"type":40,"tag":282,"props":1264,"children":1265},{"style":724},[1266],{"type":50,"value":1267},"${DB_NAME}\n",{"type":40,"tag":282,"props":1269,"children":1270},{"class":284,"line":427},[1271,1276,1280],{"type":40,"tag":282,"props":1272,"children":1273},{"style":712},[1274],{"type":50,"value":1275},"      STORAGE_LOCATIONS",{"type":40,"tag":282,"props":1277,"children":1278},{"style":718},[1279],{"type":50,"value":721},{"type":40,"tag":282,"props":1281,"children":1282},{"style":724},[1283],{"type":50,"value":1284},"local\n",{"type":40,"tag":282,"props":1286,"children":1287},{"class":284,"line":436},[1288,1293,1297],{"type":40,"tag":282,"props":1289,"children":1290},{"style":712},[1291],{"type":50,"value":1292},"      STORAGE_LOCAL_DRIVER",{"type":40,"tag":282,"props":1294,"children":1295},{"style":718},[1296],{"type":50,"value":721},{"type":40,"tag":282,"props":1298,"children":1299},{"style":724},[1300],{"type":50,"value":1301},"s3\n",{"type":40,"tag":282,"props":1303,"children":1305},{"class":284,"line":1304},19,[1306,1311],{"type":40,"tag":282,"props":1307,"children":1308},{"style":712},[1309],{"type":50,"value":1310},"      STORAGE_LOCAL_ROOT",{"type":40,"tag":282,"props":1312,"children":1313},{"style":718},[1314],{"type":50,"value":747},{"type":40,"tag":282,"props":1316,"children":1318},{"class":284,"line":1317},20,[1319,1324,1328],{"type":40,"tag":282,"props":1320,"children":1321},{"style":712},[1322],{"type":50,"value":1323},"      STORAGE_LOCAL_KEY",{"type":40,"tag":282,"props":1325,"children":1326},{"style":718},[1327],{"type":50,"value":721},{"type":40,"tag":282,"props":1329,"children":1330},{"style":724},[1331],{"type":50,"value":1332},"${S3_KEY}\n",{"type":40,"tag":282,"props":1334,"children":1336},{"class":284,"line":1335},21,[1337,1342,1346],{"type":40,"tag":282,"props":1338,"children":1339},{"style":712},[1340],{"type":50,"value":1341},"      STORAGE_LOCAL_SECRET",{"type":40,"tag":282,"props":1343,"children":1344},{"style":718},[1345],{"type":50,"value":721},{"type":40,"tag":282,"props":1347,"children":1348},{"style":724},[1349],{"type":50,"value":1350},"${S3_SECRET}\n",{"type":40,"tag":282,"props":1352,"children":1354},{"class":284,"line":1353},22,[1355,1360,1364],{"type":40,"tag":282,"props":1356,"children":1357},{"style":712},[1358],{"type":50,"value":1359},"      STORAGE_LOCAL_BUCKET",{"type":40,"tag":282,"props":1361,"children":1362},{"style":718},[1363],{"type":50,"value":721},{"type":40,"tag":282,"props":1365,"children":1366},{"style":724},[1367],{"type":50,"value":1368},"${S3_BUCKET}\n",{"type":40,"tag":282,"props":1370,"children":1372},{"class":284,"line":1371},23,[1373,1378,1382],{"type":40,"tag":282,"props":1374,"children":1375},{"style":712},[1376],{"type":50,"value":1377},"      STORAGE_LOCAL_REGION",{"type":40,"tag":282,"props":1379,"children":1380},{"style":718},[1381],{"type":50,"value":721},{"type":40,"tag":282,"props":1383,"children":1384},{"style":724},[1385],{"type":50,"value":1386},"${S3_REGION}\n",{"type":40,"tag":282,"props":1388,"children":1390},{"class":284,"line":1389},24,[1391,1396,1400],{"type":40,"tag":282,"props":1392,"children":1393},{"style":712},[1394],{"type":50,"value":1395},"      STORAGE_LOCAL_ENDPOINT",{"type":40,"tag":282,"props":1397,"children":1398},{"style":718},[1399],{"type":50,"value":721},{"type":40,"tag":282,"props":1401,"children":1402},{"style":724},[1403],{"type":50,"value":1404},"${S3_ENDPOINT}\n",{"type":40,"tag":282,"props":1406,"children":1408},{"class":284,"line":1407},25,[1409,1414,1418],{"type":40,"tag":282,"props":1410,"children":1411},{"style":712},[1412],{"type":50,"value":1413},"      STORAGE_LOCAL_ACL",{"type":40,"tag":282,"props":1415,"children":1416},{"style":718},[1417],{"type":50,"value":721},{"type":40,"tag":282,"props":1419,"children":1420},{"style":724},[1421],{"type":50,"value":1422},"private\n",{"type":40,"tag":282,"props":1424,"children":1426},{"class":284,"line":1425},26,[1427,1432,1436],{"type":40,"tag":282,"props":1428,"children":1429},{"style":712},[1430],{"type":50,"value":1431},"      STORAGE_LOCAL_FORCE_PATH_STYLE",{"type":40,"tag":282,"props":1433,"children":1434},{"style":718},[1435],{"type":50,"value":721},{"type":40,"tag":282,"props":1437,"children":1438},{"style":724},[1439],{"type":50,"value":1440},"\"true\"\n",{"type":40,"tag":46,"props":1442,"children":1443},{},[1444,1446,1452],{"type":50,"value":1445},"When you start the service, you'll be able to access Directus via ",{"type":40,"tag":214,"props":1447,"children":1449},{"className":1448},[],[1450],{"type":50,"value":1451},"http://localhost:9001",{"type":50,"value":1453}," URL.",{"type":40,"tag":73,"props":1455,"children":1456},{},[],{"type":40,"tag":77,"props":1458,"children":1460},{"id":1459},"how-to-create-a-docker-container-for-mysql",[1461],{"type":50,"value":1462},"How to create a Docker container for MySQL?",{"type":40,"tag":46,"props":1464,"children":1465},{},[1466,1468,1473,1475,1480,1482,1488],{"type":50,"value":1467},"For MySQL, we can use the image directly in ",{"type":40,"tag":214,"props":1469,"children":1471},{"className":1470},[],[1472],{"type":50,"value":255},{"type":50,"value":1474}," instead of in a ",{"type":40,"tag":214,"props":1476,"children":1478},{"className":1477},[],[1479],{"type":50,"value":504},{"type":50,"value":1481},". We do not need to customize the database image just to run MySQL, so using ",{"type":40,"tag":214,"props":1483,"children":1485},{"className":1484},[],[1486],{"type":50,"value":1487},"image: mysql:8.4",{"type":50,"value":1489}," keeps the setup clear and easy to follow.",{"type":40,"tag":46,"props":1491,"children":1492},{},[1493,1495,1502,1504,1509],{"type":50,"value":1494},"We also need to ",{"type":40,"tag":58,"props":1496,"children":1499},{"href":1497,"rel":1498},"https://docs.docker.com/engine/storage/bind-mounts/",[62],[1500],{"type":50,"value":1501},"mount a volume",{"type":50,"value":1503}," to store the database files. That part is important because it keeps the data on your disk. If the container restarts, the data remains. Otherwise, it would be reset every time the container starts. Add the contents of the mounted directory to ",{"type":40,"tag":214,"props":1505,"children":1507},{"className":1506},[],[1508],{"type":50,"value":453},{"type":50,"value":1510}," so they are not tracked by GIT.",{"type":40,"tag":272,"props":1512,"children":1514},{"className":700,"code":1513,"filename":255,"language":702,"meta":7,"style":7},"database:\n    container_name: coditive-space-database\n    image: mysql:8.4\n    ports:\n      - \"9002:3306\"\n    volumes:\n      - ./database:/var/lib/mysql\n    environment:\n      MYSQL_USER: ${DB_USER}\n      MYSQL_PASSWORD: ${DB_PASSWORD}\n      MYSQL_DATABASE: ${DB_NAME}\n      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}\n",[1515],{"type":40,"tag":214,"props":1516,"children":1517},{"__ignoreMap":7},[1518,1529,1545,1562,1573,1585,1596,1608,1619,1635,1651,1667],{"type":40,"tag":282,"props":1519,"children":1520},{"class":284,"line":285},[1521,1525],{"type":40,"tag":282,"props":1522,"children":1523},{"style":712},[1524],{"type":50,"value":234},{"type":40,"tag":282,"props":1526,"children":1527},{"style":718},[1528],{"type":50,"value":747},{"type":40,"tag":282,"props":1530,"children":1531},{"class":284,"line":294},[1532,1536,1540],{"type":40,"tag":282,"props":1533,"children":1534},{"style":712},[1535],{"type":50,"value":767},{"type":40,"tag":282,"props":1537,"children":1538},{"style":718},[1539],{"type":50,"value":721},{"type":40,"tag":282,"props":1541,"children":1542},{"style":724},[1543],{"type":50,"value":1544},"coditive-space-database\n",{"type":40,"tag":282,"props":1546,"children":1547},{"class":284,"line":303},[1548,1553,1557],{"type":40,"tag":282,"props":1549,"children":1550},{"style":712},[1551],{"type":50,"value":1552},"    image",{"type":40,"tag":282,"props":1554,"children":1555},{"style":718},[1556],{"type":50,"value":721},{"type":40,"tag":282,"props":1558,"children":1559},{"style":724},[1560],{"type":50,"value":1561},"mysql:8.4\n",{"type":40,"tag":282,"props":1563,"children":1564},{"class":284,"line":312},[1565,1569],{"type":40,"tag":282,"props":1566,"children":1567},{"style":712},[1568],{"type":50,"value":830},{"type":40,"tag":282,"props":1570,"children":1571},{"style":718},[1572],{"type":50,"value":747},{"type":40,"tag":282,"props":1574,"children":1575},{"class":284,"line":321},[1576,1580],{"type":40,"tag":282,"props":1577,"children":1578},{"style":718},[1579],{"type":50,"value":842},{"type":40,"tag":282,"props":1581,"children":1582},{"style":724},[1583],{"type":50,"value":1584},"\"9002:3306\"\n",{"type":40,"tag":282,"props":1586,"children":1587},{"class":284,"line":330},[1588,1592],{"type":40,"tag":282,"props":1589,"children":1590},{"style":712},[1591],{"type":50,"value":855},{"type":40,"tag":282,"props":1593,"children":1594},{"style":718},[1595],{"type":50,"value":747},{"type":40,"tag":282,"props":1597,"children":1598},{"class":284,"line":338},[1599,1603],{"type":40,"tag":282,"props":1600,"children":1601},{"style":718},[1602],{"type":50,"value":842},{"type":40,"tag":282,"props":1604,"children":1605},{"style":724},[1606],{"type":50,"value":1607},"./database:/var/lib/mysql\n",{"type":40,"tag":282,"props":1609,"children":1610},{"class":284,"line":347},[1611,1615],{"type":40,"tag":282,"props":1612,"children":1613},{"style":712},[1614],{"type":50,"value":891},{"type":40,"tag":282,"props":1616,"children":1617},{"style":718},[1618],{"type":50,"value":747},{"type":40,"tag":282,"props":1620,"children":1621},{"class":284,"line":356},[1622,1627,1631],{"type":40,"tag":282,"props":1623,"children":1624},{"style":712},[1625],{"type":50,"value":1626},"      MYSQL_USER",{"type":40,"tag":282,"props":1628,"children":1629},{"style":718},[1630],{"type":50,"value":721},{"type":40,"tag":282,"props":1632,"children":1633},{"style":724},[1634],{"type":50,"value":1233},{"type":40,"tag":282,"props":1636,"children":1637},{"class":284,"line":365},[1638,1643,1647],{"type":40,"tag":282,"props":1639,"children":1640},{"style":712},[1641],{"type":50,"value":1642},"      MYSQL_PASSWORD",{"type":40,"tag":282,"props":1644,"children":1645},{"style":718},[1646],{"type":50,"value":721},{"type":40,"tag":282,"props":1648,"children":1649},{"style":724},[1650],{"type":50,"value":1250},{"type":40,"tag":282,"props":1652,"children":1653},{"class":284,"line":374},[1654,1659,1663],{"type":40,"tag":282,"props":1655,"children":1656},{"style":712},[1657],{"type":50,"value":1658},"      MYSQL_DATABASE",{"type":40,"tag":282,"props":1660,"children":1661},{"style":718},[1662],{"type":50,"value":721},{"type":40,"tag":282,"props":1664,"children":1665},{"style":724},[1666],{"type":50,"value":1267},{"type":40,"tag":282,"props":1668,"children":1669},{"class":284,"line":383},[1670,1675,1679],{"type":40,"tag":282,"props":1671,"children":1672},{"style":712},[1673],{"type":50,"value":1674},"      MYSQL_ROOT_PASSWORD",{"type":40,"tag":282,"props":1676,"children":1677},{"style":718},[1678],{"type":50,"value":721},{"type":40,"tag":282,"props":1680,"children":1681},{"style":724},[1682],{"type":50,"value":1683},"${DB_ROOT_PASSWORD}\n",{"type":40,"tag":46,"props":1685,"children":1686},{},[1687,1689,1695,1697,1703],{"type":50,"value":1688},"When you start the service, you'll be able to access MySQL via ",{"type":40,"tag":214,"props":1690,"children":1692},{"className":1691},[],[1693],{"type":50,"value":1694},"localhost",{"type":50,"value":1696}," host with ",{"type":40,"tag":214,"props":1698,"children":1700},{"className":1699},[],[1701],{"type":50,"value":1702},"9002",{"type":50,"value":1704}," port.",{"type":40,"tag":73,"props":1706,"children":1707},{},[],{"type":40,"tag":77,"props":1709,"children":1711},{"id":1710},"how-to-create-a-docker-container-for-rustfs",[1712],{"type":50,"value":1713},"How to create a Docker container for RustFS?",{"type":40,"tag":46,"props":1715,"children":1716},{},[1717,1719,1724,1726,1733,1735,1741],{"type":50,"value":1718},"RustFS is the storage layer, and using the image directly in ",{"type":40,"tag":214,"props":1720,"children":1722},{"className":1721},[],[1723],{"type":50,"value":255},{"type":50,"value":1725}," is enough. ",{"type":40,"tag":58,"props":1727,"children":1730},{"href":1728,"rel":1729},"https://docs.rustfs.com/en/installation/container/docker",[62],[1731],{"type":50,"value":1732},"Tell the service",{"type":50,"value":1734}," to use the ",{"type":40,"tag":214,"props":1736,"children":1738},{"className":1737},[],[1739],{"type":50,"value":1740},"rustfs/rustfs:1.0.0-alpha.90",{"type":50,"value":1742}," image, map the ports - first for the API, which you use via an SDK, and second for the management via the browser.",{"type":40,"tag":46,"props":1744,"children":1745},{},[1746,1748,1754,1756,1762,1764,1769,1771,1776],{"type":50,"value":1747},"Then mount the file volume so anything that is put into S3 storage lands on your disk instead of resetting when the container stops. In the environment section, you can configure ",{"type":40,"tag":214,"props":1749,"children":1751},{"className":1750},[],[1752],{"type":50,"value":1753},"KEY",{"type":50,"value":1755}," and ",{"type":40,"tag":214,"props":1757,"children":1759},{"className":1758},[],[1760],{"type":50,"value":1761},"SECRET",{"type":50,"value":1763}," values, which you can use to authorize S3 requests in the JS SDK. Add ",{"type":40,"tag":214,"props":1765,"children":1767},{"className":1766},[],[1768],{"type":50,"value":242},{"type":50,"value":1770}," volume to a ",{"type":40,"tag":214,"props":1772,"children":1774},{"className":1773},[],[1775],{"type":50,"value":453},{"type":50,"value":1777}," file so the contents, like static assets uploaded there, are not tracked by GIT.",{"type":40,"tag":272,"props":1779,"children":1781},{"className":700,"code":1780,"filename":255,"language":702,"meta":7,"style":7},"storage:\n    container_name: coditive-space-storage\n    image: rustfs/rustfs:1.0.0-alpha.90\n    ports:\n      - \"9003:9000\"\n      - \"9004:9001\"\n    volumes:\n      - ./storage:/data\n    environment:\n      RUSTFS_ROOT_USER: ${S3_KEY}\n      RUSTFS_ROOT_PASSWORD: ${S3_SECRET}\n",[1782],{"type":40,"tag":214,"props":1783,"children":1784},{"__ignoreMap":7},[1785,1796,1812,1828,1839,1851,1863,1874,1886,1897,1913],{"type":40,"tag":282,"props":1786,"children":1787},{"class":284,"line":285},[1788,1792],{"type":40,"tag":282,"props":1789,"children":1790},{"style":712},[1791],{"type":50,"value":242},{"type":40,"tag":282,"props":1793,"children":1794},{"style":718},[1795],{"type":50,"value":747},{"type":40,"tag":282,"props":1797,"children":1798},{"class":284,"line":294},[1799,1803,1807],{"type":40,"tag":282,"props":1800,"children":1801},{"style":712},[1802],{"type":50,"value":767},{"type":40,"tag":282,"props":1804,"children":1805},{"style":718},[1806],{"type":50,"value":721},{"type":40,"tag":282,"props":1808,"children":1809},{"style":724},[1810],{"type":50,"value":1811},"coditive-space-storage\n",{"type":40,"tag":282,"props":1813,"children":1814},{"class":284,"line":303},[1815,1819,1823],{"type":40,"tag":282,"props":1816,"children":1817},{"style":712},[1818],{"type":50,"value":1552},{"type":40,"tag":282,"props":1820,"children":1821},{"style":718},[1822],{"type":50,"value":721},{"type":40,"tag":282,"props":1824,"children":1825},{"style":724},[1826],{"type":50,"value":1827},"rustfs/rustfs:1.0.0-alpha.90\n",{"type":40,"tag":282,"props":1829,"children":1830},{"class":284,"line":312},[1831,1835],{"type":40,"tag":282,"props":1832,"children":1833},{"style":712},[1834],{"type":50,"value":830},{"type":40,"tag":282,"props":1836,"children":1837},{"style":718},[1838],{"type":50,"value":747},{"type":40,"tag":282,"props":1840,"children":1841},{"class":284,"line":321},[1842,1846],{"type":40,"tag":282,"props":1843,"children":1844},{"style":718},[1845],{"type":50,"value":842},{"type":40,"tag":282,"props":1847,"children":1848},{"style":724},[1849],{"type":50,"value":1850},"\"9003:9000\"\n",{"type":40,"tag":282,"props":1852,"children":1853},{"class":284,"line":330},[1854,1858],{"type":40,"tag":282,"props":1855,"children":1856},{"style":718},[1857],{"type":50,"value":842},{"type":40,"tag":282,"props":1859,"children":1860},{"style":724},[1861],{"type":50,"value":1862},"\"9004:9001\"\n",{"type":40,"tag":282,"props":1864,"children":1865},{"class":284,"line":338},[1866,1870],{"type":40,"tag":282,"props":1867,"children":1868},{"style":712},[1869],{"type":50,"value":855},{"type":40,"tag":282,"props":1871,"children":1872},{"style":718},[1873],{"type":50,"value":747},{"type":40,"tag":282,"props":1875,"children":1876},{"class":284,"line":347},[1877,1881],{"type":40,"tag":282,"props":1878,"children":1879},{"style":718},[1880],{"type":50,"value":842},{"type":40,"tag":282,"props":1882,"children":1883},{"style":724},[1884],{"type":50,"value":1885},"./storage:/data\n",{"type":40,"tag":282,"props":1887,"children":1888},{"class":284,"line":356},[1889,1893],{"type":40,"tag":282,"props":1890,"children":1891},{"style":712},[1892],{"type":50,"value":891},{"type":40,"tag":282,"props":1894,"children":1895},{"style":718},[1896],{"type":50,"value":747},{"type":40,"tag":282,"props":1898,"children":1899},{"class":284,"line":365},[1900,1905,1909],{"type":40,"tag":282,"props":1901,"children":1902},{"style":712},[1903],{"type":50,"value":1904},"      RUSTFS_ROOT_USER",{"type":40,"tag":282,"props":1906,"children":1907},{"style":718},[1908],{"type":50,"value":721},{"type":40,"tag":282,"props":1910,"children":1911},{"style":724},[1912],{"type":50,"value":1332},{"type":40,"tag":282,"props":1914,"children":1915},{"class":284,"line":374},[1916,1921,1925],{"type":40,"tag":282,"props":1917,"children":1918},{"style":712},[1919],{"type":50,"value":1920},"      RUSTFS_ROOT_PASSWORD",{"type":40,"tag":282,"props":1922,"children":1923},{"style":718},[1924],{"type":50,"value":721},{"type":40,"tag":282,"props":1926,"children":1927},{"style":724},[1928],{"type":50,"value":1350},{"type":40,"tag":46,"props":1930,"children":1931},{},[1932,1934,1940,1942,1948],{"type":50,"value":1933},"When you start the service, you'll be able to access the RustFS API via ",{"type":40,"tag":214,"props":1935,"children":1937},{"className":1936},[],[1938],{"type":50,"value":1939},"http://localhost:9003",{"type":50,"value":1941},", and its browser interface via the ",{"type":40,"tag":214,"props":1943,"children":1945},{"className":1944},[],[1946],{"type":50,"value":1947},"http://localhost:9004",{"type":50,"value":942},{"type":40,"tag":73,"props":1950,"children":1951},{},[],{"type":40,"tag":77,"props":1953,"children":1955},{"id":1954},"how-to-run-the-docker-stack",[1956],{"type":50,"value":1957},"How to run the Docker stack?",{"type":40,"tag":46,"props":1959,"children":1960},{},[1961],{"type":50,"value":1962},"Once everything is in place, the full stack starts with one command:",{"type":40,"tag":272,"props":1964,"children":1968},{"className":1965,"code":1966,"language":1967,"meta":7,"style":7},"language-bash shiki shiki-themes one-dark-pro","docker compose up -d --build\n","bash",[1969],{"type":40,"tag":214,"props":1970,"children":1971},{"__ignoreMap":7},[1972],{"type":40,"tag":282,"props":1973,"children":1974},{"class":284,"line":285},[1975,1980,1985,1990,1996],{"type":40,"tag":282,"props":1976,"children":1978},{"style":1977},"--shiki-default:#61AFEF",[1979],{"type":50,"value":34},{"type":40,"tag":282,"props":1981,"children":1982},{"style":724},[1983],{"type":50,"value":1984}," compose",{"type":40,"tag":282,"props":1986,"children":1987},{"style":724},[1988],{"type":50,"value":1989}," up",{"type":40,"tag":282,"props":1991,"children":1993},{"style":1992},"--shiki-default:#D19A66",[1994],{"type":50,"value":1995}," -d",{"type":40,"tag":282,"props":1997,"children":1998},{"style":1992},[1999],{"type":50,"value":2000}," --build\n",{"type":40,"tag":46,"props":2002,"children":2003},{},[2004],{"type":50,"value":2005},"That command builds the custom images, starts the containers in the background, and brings the whole local environment online. After that, each service is available on its own port, so the frontend, backend, database, and storage can all be reached separately from your browser. Here’s how the full stack looks.",{"type":40,"tag":272,"props":2007,"children":2009},{"className":700,"code":2008,"language":702,"meta":7,"style":7},"name: coditive-space\n\nservices:\n  storage:\n    container_name: coditive-space-storage\n    image: rustfs/rustfs:1.0.0-alpha.90\n    ports:\n      - \"9003:9000\"\n      - \"9004:9001\"\n    volumes:\n      - ./storage:/data\n    environment:\n      RUSTFS_ROOT_USER: ${S3_KEY}\n      RUSTFS_ROOT_PASSWORD: ${S3_SECRET}\n    healthcheck:\n      test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:9000/health\"]\n      interval: 5s\n      timeout: 5s\n\n  database:\n    container_name: coditive-space-database\n    image: mysql:8.4\n    ports:\n      - \"9002:3306\"\n    volumes:\n      - ./database:/var/lib/mysql\n    environment:\n      MYSQL_USER: ${DB_USER}\n      MYSQL_PASSWORD: ${DB_PASSWORD}\n      MYSQL_DATABASE: ${DB_NAME}\n      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}\n    healthcheck:\n      test: [\"CMD\", \"mysqladmin\", \"ping\", \"-h\", \"localhost\", \"-P\", \"3306\"]\n      interval: 5s\n      timeout: 5s\n\n  backend:\n    container_name: coditive-space-backend\n    build:\n      context: ./backend\n      dockerfile: Dockerfile\n    ports:\n      - \"9001:8055\"\n    environment:\n      KEY: ${DIRECTUS_KEY}\n      SECRET: ${DIRECTUS_SECRET}\n      DB_CLIENT: mysql\n      DB_HOST: ${DB_HOST}\n      DB_PORT: ${DB_PORT}\n      DB_USER: ${DB_USER}\n      DB_PASSWORD: ${DB_PASSWORD}\n      DB_DATABASE: ${DB_NAME}\n      STORAGE_LOCATIONS: local\n      STORAGE_LOCAL_DRIVER: s3\n      STORAGE_LOCAL_ROOT:\n      STORAGE_LOCAL_KEY: ${S3_KEY}\n      STORAGE_LOCAL_SECRET: ${S3_SECRET}\n      STORAGE_LOCAL_BUCKET: ${S3_BUCKET}\n      STORAGE_LOCAL_REGION: ${S3_REGION}\n      STORAGE_LOCAL_ENDPOINT: ${S3_ENDPOINT}\n      STORAGE_LOCAL_ACL: private\n      STORAGE_LOCAL_FORCE_PATH_STYLE: \"true\"\n    depends_on:\n      database:\n        condition: service_healthy\n      storage:\n        condition: service_healthy\n\n  frontend:\n    container_name: coditive-space-frontend\n    build:\n      context: ./frontend\n      dockerfile: Dockerfile\n    ports:\n      - \"9000:3000\"\n    volumes:\n      - ./frontend:/app:cached\n      - ./frontend/node_modules:/app/node_modules:delegated\n    environment:\n      NUXT_PUBLIC_APP_URL: ${APP_URL}\n      NUXT_PUBLIC_APP_ENV: ${APP_ENV}\n    depends_on:\n      database:\n        condition: service_healthy\n      storage:\n        condition: service_healthy\n",[2010],{"type":40,"tag":214,"props":2011,"children":2012},{"__ignoreMap":7},[2013,2028,2035,2046,2058,2073,2088,2099,2110,2121,2132,2143,2154,2169,2184,2196,2246,2263,2279,2286,2298,2313,2328,2339,2350,2361,2372,2384,2400,2416,2432,2448,2460,2534,2550,2566,2574,2587,2603,2615,2631,2647,2659,2671,2683,2699,2715,2731,2747,2763,2779,2795,2811,2827,2843,2855,2871,2887,2903,2919,2935,2951,2967,2980,2993,3011,3024,3040,3048,3060,3076,3088,3104,3120,3132,3144,3156,3168,3180,3192,3208,3224,3236,3248,3264,3276],{"type":40,"tag":282,"props":2014,"children":2015},{"class":284,"line":285},[2016,2020,2024],{"type":40,"tag":282,"props":2017,"children":2018},{"style":712},[2019],{"type":50,"value":715},{"type":40,"tag":282,"props":2021,"children":2022},{"style":718},[2023],{"type":50,"value":721},{"type":40,"tag":282,"props":2025,"children":2026},{"style":724},[2027],{"type":50,"value":727},{"type":40,"tag":282,"props":2029,"children":2030},{"class":284,"line":294},[2031],{"type":40,"tag":282,"props":2032,"children":2033},{"emptyLinePlaceholder":35},[2034],{"type":50,"value":309},{"type":40,"tag":282,"props":2036,"children":2037},{"class":284,"line":303},[2038,2042],{"type":40,"tag":282,"props":2039,"children":2040},{"style":712},[2041],{"type":50,"value":742},{"type":40,"tag":282,"props":2043,"children":2044},{"style":718},[2045],{"type":50,"value":747},{"type":40,"tag":282,"props":2047,"children":2048},{"class":284,"line":312},[2049,2054],{"type":40,"tag":282,"props":2050,"children":2051},{"style":712},[2052],{"type":50,"value":2053},"  storage",{"type":40,"tag":282,"props":2055,"children":2056},{"style":718},[2057],{"type":50,"value":747},{"type":40,"tag":282,"props":2059,"children":2060},{"class":284,"line":321},[2061,2065,2069],{"type":40,"tag":282,"props":2062,"children":2063},{"style":712},[2064],{"type":50,"value":767},{"type":40,"tag":282,"props":2066,"children":2067},{"style":718},[2068],{"type":50,"value":721},{"type":40,"tag":282,"props":2070,"children":2071},{"style":724},[2072],{"type":50,"value":1811},{"type":40,"tag":282,"props":2074,"children":2075},{"class":284,"line":330},[2076,2080,2084],{"type":40,"tag":282,"props":2077,"children":2078},{"style":712},[2079],{"type":50,"value":1552},{"type":40,"tag":282,"props":2081,"children":2082},{"style":718},[2083],{"type":50,"value":721},{"type":40,"tag":282,"props":2085,"children":2086},{"style":724},[2087],{"type":50,"value":1827},{"type":40,"tag":282,"props":2089,"children":2090},{"class":284,"line":338},[2091,2095],{"type":40,"tag":282,"props":2092,"children":2093},{"style":712},[2094],{"type":50,"value":830},{"type":40,"tag":282,"props":2096,"children":2097},{"style":718},[2098],{"type":50,"value":747},{"type":40,"tag":282,"props":2100,"children":2101},{"class":284,"line":347},[2102,2106],{"type":40,"tag":282,"props":2103,"children":2104},{"style":718},[2105],{"type":50,"value":842},{"type":40,"tag":282,"props":2107,"children":2108},{"style":724},[2109],{"type":50,"value":1850},{"type":40,"tag":282,"props":2111,"children":2112},{"class":284,"line":356},[2113,2117],{"type":40,"tag":282,"props":2114,"children":2115},{"style":718},[2116],{"type":50,"value":842},{"type":40,"tag":282,"props":2118,"children":2119},{"style":724},[2120],{"type":50,"value":1862},{"type":40,"tag":282,"props":2122,"children":2123},{"class":284,"line":365},[2124,2128],{"type":40,"tag":282,"props":2125,"children":2126},{"style":712},[2127],{"type":50,"value":855},{"type":40,"tag":282,"props":2129,"children":2130},{"style":718},[2131],{"type":50,"value":747},{"type":40,"tag":282,"props":2133,"children":2134},{"class":284,"line":374},[2135,2139],{"type":40,"tag":282,"props":2136,"children":2137},{"style":718},[2138],{"type":50,"value":842},{"type":40,"tag":282,"props":2140,"children":2141},{"style":724},[2142],{"type":50,"value":1885},{"type":40,"tag":282,"props":2144,"children":2145},{"class":284,"line":383},[2146,2150],{"type":40,"tag":282,"props":2147,"children":2148},{"style":712},[2149],{"type":50,"value":891},{"type":40,"tag":282,"props":2151,"children":2152},{"style":718},[2153],{"type":50,"value":747},{"type":40,"tag":282,"props":2155,"children":2156},{"class":284,"line":392},[2157,2161,2165],{"type":40,"tag":282,"props":2158,"children":2159},{"style":712},[2160],{"type":50,"value":1904},{"type":40,"tag":282,"props":2162,"children":2163},{"style":718},[2164],{"type":50,"value":721},{"type":40,"tag":282,"props":2166,"children":2167},{"style":724},[2168],{"type":50,"value":1332},{"type":40,"tag":282,"props":2170,"children":2171},{"class":284,"line":400},[2172,2176,2180],{"type":40,"tag":282,"props":2173,"children":2174},{"style":712},[2175],{"type":50,"value":1920},{"type":40,"tag":282,"props":2177,"children":2178},{"style":718},[2179],{"type":50,"value":721},{"type":40,"tag":282,"props":2181,"children":2182},{"style":724},[2183],{"type":50,"value":1350},{"type":40,"tag":282,"props":2185,"children":2186},{"class":284,"line":409},[2187,2192],{"type":40,"tag":282,"props":2188,"children":2189},{"style":712},[2190],{"type":50,"value":2191},"    healthcheck",{"type":40,"tag":282,"props":2193,"children":2194},{"style":718},[2195],{"type":50,"value":747},{"type":40,"tag":282,"props":2197,"children":2198},{"class":284,"line":418},[2199,2204,2209,2214,2218,2223,2227,2232,2236,2241],{"type":40,"tag":282,"props":2200,"children":2201},{"style":712},[2202],{"type":50,"value":2203},"      test",{"type":40,"tag":282,"props":2205,"children":2206},{"style":718},[2207],{"type":50,"value":2208},": [",{"type":40,"tag":282,"props":2210,"children":2211},{"style":724},[2212],{"type":50,"value":2213},"\"CMD\"",{"type":40,"tag":282,"props":2215,"children":2216},{"style":718},[2217],{"type":50,"value":221},{"type":40,"tag":282,"props":2219,"children":2220},{"style":724},[2221],{"type":50,"value":2222},"\"curl\"",{"type":40,"tag":282,"props":2224,"children":2225},{"style":718},[2226],{"type":50,"value":221},{"type":40,"tag":282,"props":2228,"children":2229},{"style":724},[2230],{"type":50,"value":2231},"\"-f\"",{"type":40,"tag":282,"props":2233,"children":2234},{"style":718},[2235],{"type":50,"value":221},{"type":40,"tag":282,"props":2237,"children":2238},{"style":724},[2239],{"type":50,"value":2240},"\"http://localhost:9000/health\"",{"type":40,"tag":282,"props":2242,"children":2243},{"style":718},[2244],{"type":50,"value":2245},"]\n",{"type":40,"tag":282,"props":2247,"children":2248},{"class":284,"line":427},[2249,2254,2258],{"type":40,"tag":282,"props":2250,"children":2251},{"style":712},[2252],{"type":50,"value":2253},"      interval",{"type":40,"tag":282,"props":2255,"children":2256},{"style":718},[2257],{"type":50,"value":721},{"type":40,"tag":282,"props":2259,"children":2260},{"style":724},[2261],{"type":50,"value":2262},"5s\n",{"type":40,"tag":282,"props":2264,"children":2265},{"class":284,"line":436},[2266,2271,2275],{"type":40,"tag":282,"props":2267,"children":2268},{"style":712},[2269],{"type":50,"value":2270},"      timeout",{"type":40,"tag":282,"props":2272,"children":2273},{"style":718},[2274],{"type":50,"value":721},{"type":40,"tag":282,"props":2276,"children":2277},{"style":724},[2278],{"type":50,"value":2262},{"type":40,"tag":282,"props":2280,"children":2281},{"class":284,"line":1304},[2282],{"type":40,"tag":282,"props":2283,"children":2284},{"emptyLinePlaceholder":35},[2285],{"type":50,"value":309},{"type":40,"tag":282,"props":2287,"children":2288},{"class":284,"line":1317},[2289,2294],{"type":40,"tag":282,"props":2290,"children":2291},{"style":712},[2292],{"type":50,"value":2293},"  database",{"type":40,"tag":282,"props":2295,"children":2296},{"style":718},[2297],{"type":50,"value":747},{"type":40,"tag":282,"props":2299,"children":2300},{"class":284,"line":1335},[2301,2305,2309],{"type":40,"tag":282,"props":2302,"children":2303},{"style":712},[2304],{"type":50,"value":767},{"type":40,"tag":282,"props":2306,"children":2307},{"style":718},[2308],{"type":50,"value":721},{"type":40,"tag":282,"props":2310,"children":2311},{"style":724},[2312],{"type":50,"value":1544},{"type":40,"tag":282,"props":2314,"children":2315},{"class":284,"line":1353},[2316,2320,2324],{"type":40,"tag":282,"props":2317,"children":2318},{"style":712},[2319],{"type":50,"value":1552},{"type":40,"tag":282,"props":2321,"children":2322},{"style":718},[2323],{"type":50,"value":721},{"type":40,"tag":282,"props":2325,"children":2326},{"style":724},[2327],{"type":50,"value":1561},{"type":40,"tag":282,"props":2329,"children":2330},{"class":284,"line":1371},[2331,2335],{"type":40,"tag":282,"props":2332,"children":2333},{"style":712},[2334],{"type":50,"value":830},{"type":40,"tag":282,"props":2336,"children":2337},{"style":718},[2338],{"type":50,"value":747},{"type":40,"tag":282,"props":2340,"children":2341},{"class":284,"line":1389},[2342,2346],{"type":40,"tag":282,"props":2343,"children":2344},{"style":718},[2345],{"type":50,"value":842},{"type":40,"tag":282,"props":2347,"children":2348},{"style":724},[2349],{"type":50,"value":1584},{"type":40,"tag":282,"props":2351,"children":2352},{"class":284,"line":1407},[2353,2357],{"type":40,"tag":282,"props":2354,"children":2355},{"style":712},[2356],{"type":50,"value":855},{"type":40,"tag":282,"props":2358,"children":2359},{"style":718},[2360],{"type":50,"value":747},{"type":40,"tag":282,"props":2362,"children":2363},{"class":284,"line":1425},[2364,2368],{"type":40,"tag":282,"props":2365,"children":2366},{"style":718},[2367],{"type":50,"value":842},{"type":40,"tag":282,"props":2369,"children":2370},{"style":724},[2371],{"type":50,"value":1607},{"type":40,"tag":282,"props":2373,"children":2375},{"class":284,"line":2374},27,[2376,2380],{"type":40,"tag":282,"props":2377,"children":2378},{"style":712},[2379],{"type":50,"value":891},{"type":40,"tag":282,"props":2381,"children":2382},{"style":718},[2383],{"type":50,"value":747},{"type":40,"tag":282,"props":2385,"children":2387},{"class":284,"line":2386},28,[2388,2392,2396],{"type":40,"tag":282,"props":2389,"children":2390},{"style":712},[2391],{"type":50,"value":1626},{"type":40,"tag":282,"props":2393,"children":2394},{"style":718},[2395],{"type":50,"value":721},{"type":40,"tag":282,"props":2397,"children":2398},{"style":724},[2399],{"type":50,"value":1233},{"type":40,"tag":282,"props":2401,"children":2403},{"class":284,"line":2402},29,[2404,2408,2412],{"type":40,"tag":282,"props":2405,"children":2406},{"style":712},[2407],{"type":50,"value":1642},{"type":40,"tag":282,"props":2409,"children":2410},{"style":718},[2411],{"type":50,"value":721},{"type":40,"tag":282,"props":2413,"children":2414},{"style":724},[2415],{"type":50,"value":1250},{"type":40,"tag":282,"props":2417,"children":2419},{"class":284,"line":2418},30,[2420,2424,2428],{"type":40,"tag":282,"props":2421,"children":2422},{"style":712},[2423],{"type":50,"value":1658},{"type":40,"tag":282,"props":2425,"children":2426},{"style":718},[2427],{"type":50,"value":721},{"type":40,"tag":282,"props":2429,"children":2430},{"style":724},[2431],{"type":50,"value":1267},{"type":40,"tag":282,"props":2433,"children":2435},{"class":284,"line":2434},31,[2436,2440,2444],{"type":40,"tag":282,"props":2437,"children":2438},{"style":712},[2439],{"type":50,"value":1674},{"type":40,"tag":282,"props":2441,"children":2442},{"style":718},[2443],{"type":50,"value":721},{"type":40,"tag":282,"props":2445,"children":2446},{"style":724},[2447],{"type":50,"value":1683},{"type":40,"tag":282,"props":2449,"children":2451},{"class":284,"line":2450},32,[2452,2456],{"type":40,"tag":282,"props":2453,"children":2454},{"style":712},[2455],{"type":50,"value":2191},{"type":40,"tag":282,"props":2457,"children":2458},{"style":718},[2459],{"type":50,"value":747},{"type":40,"tag":282,"props":2461,"children":2463},{"class":284,"line":2462},33,[2464,2468,2472,2476,2480,2485,2489,2494,2498,2503,2507,2512,2516,2521,2525,2530],{"type":40,"tag":282,"props":2465,"children":2466},{"style":712},[2467],{"type":50,"value":2203},{"type":40,"tag":282,"props":2469,"children":2470},{"style":718},[2471],{"type":50,"value":2208},{"type":40,"tag":282,"props":2473,"children":2474},{"style":724},[2475],{"type":50,"value":2213},{"type":40,"tag":282,"props":2477,"children":2478},{"style":718},[2479],{"type":50,"value":221},{"type":40,"tag":282,"props":2481,"children":2482},{"style":724},[2483],{"type":50,"value":2484},"\"mysqladmin\"",{"type":40,"tag":282,"props":2486,"children":2487},{"style":718},[2488],{"type":50,"value":221},{"type":40,"tag":282,"props":2490,"children":2491},{"style":724},[2492],{"type":50,"value":2493},"\"ping\"",{"type":40,"tag":282,"props":2495,"children":2496},{"style":718},[2497],{"type":50,"value":221},{"type":40,"tag":282,"props":2499,"children":2500},{"style":724},[2501],{"type":50,"value":2502},"\"-h\"",{"type":40,"tag":282,"props":2504,"children":2505},{"style":718},[2506],{"type":50,"value":221},{"type":40,"tag":282,"props":2508,"children":2509},{"style":724},[2510],{"type":50,"value":2511},"\"localhost\"",{"type":40,"tag":282,"props":2513,"children":2514},{"style":718},[2515],{"type":50,"value":221},{"type":40,"tag":282,"props":2517,"children":2518},{"style":724},[2519],{"type":50,"value":2520},"\"-P\"",{"type":40,"tag":282,"props":2522,"children":2523},{"style":718},[2524],{"type":50,"value":221},{"type":40,"tag":282,"props":2526,"children":2527},{"style":724},[2528],{"type":50,"value":2529},"\"3306\"",{"type":40,"tag":282,"props":2531,"children":2532},{"style":718},[2533],{"type":50,"value":2245},{"type":40,"tag":282,"props":2535,"children":2537},{"class":284,"line":2536},34,[2538,2542,2546],{"type":40,"tag":282,"props":2539,"children":2540},{"style":712},[2541],{"type":50,"value":2253},{"type":40,"tag":282,"props":2543,"children":2544},{"style":718},[2545],{"type":50,"value":721},{"type":40,"tag":282,"props":2547,"children":2548},{"style":724},[2549],{"type":50,"value":2262},{"type":40,"tag":282,"props":2551,"children":2553},{"class":284,"line":2552},35,[2554,2558,2562],{"type":40,"tag":282,"props":2555,"children":2556},{"style":712},[2557],{"type":50,"value":2270},{"type":40,"tag":282,"props":2559,"children":2560},{"style":718},[2561],{"type":50,"value":721},{"type":40,"tag":282,"props":2563,"children":2564},{"style":724},[2565],{"type":50,"value":2262},{"type":40,"tag":282,"props":2567,"children":2569},{"class":284,"line":2568},36,[2570],{"type":40,"tag":282,"props":2571,"children":2572},{"emptyLinePlaceholder":35},[2573],{"type":50,"value":309},{"type":40,"tag":282,"props":2575,"children":2577},{"class":284,"line":2576},37,[2578,2583],{"type":40,"tag":282,"props":2579,"children":2580},{"style":712},[2581],{"type":50,"value":2582},"  backend",{"type":40,"tag":282,"props":2584,"children":2585},{"style":718},[2586],{"type":50,"value":747},{"type":40,"tag":282,"props":2588,"children":2590},{"class":284,"line":2589},38,[2591,2595,2599],{"type":40,"tag":282,"props":2592,"children":2593},{"style":712},[2594],{"type":50,"value":767},{"type":40,"tag":282,"props":2596,"children":2597},{"style":718},[2598],{"type":50,"value":721},{"type":40,"tag":282,"props":2600,"children":2601},{"style":724},[2602],{"type":50,"value":1055},{"type":40,"tag":282,"props":2604,"children":2606},{"class":284,"line":2605},39,[2607,2611],{"type":40,"tag":282,"props":2608,"children":2609},{"style":712},[2610],{"type":50,"value":784},{"type":40,"tag":282,"props":2612,"children":2613},{"style":718},[2614],{"type":50,"value":747},{"type":40,"tag":282,"props":2616,"children":2618},{"class":284,"line":2617},40,[2619,2623,2627],{"type":40,"tag":282,"props":2620,"children":2621},{"style":712},[2622],{"type":50,"value":796},{"type":40,"tag":282,"props":2624,"children":2625},{"style":718},[2626],{"type":50,"value":721},{"type":40,"tag":282,"props":2628,"children":2629},{"style":724},[2630],{"type":50,"value":1082},{"type":40,"tag":282,"props":2632,"children":2634},{"class":284,"line":2633},41,[2635,2639,2643],{"type":40,"tag":282,"props":2636,"children":2637},{"style":712},[2638],{"type":50,"value":813},{"type":40,"tag":282,"props":2640,"children":2641},{"style":718},[2642],{"type":50,"value":721},{"type":40,"tag":282,"props":2644,"children":2645},{"style":724},[2646],{"type":50,"value":822},{"type":40,"tag":282,"props":2648,"children":2650},{"class":284,"line":2649},42,[2651,2655],{"type":40,"tag":282,"props":2652,"children":2653},{"style":712},[2654],{"type":50,"value":830},{"type":40,"tag":282,"props":2656,"children":2657},{"style":718},[2658],{"type":50,"value":747},{"type":40,"tag":282,"props":2660,"children":2662},{"class":284,"line":2661},43,[2663,2667],{"type":40,"tag":282,"props":2664,"children":2665},{"style":718},[2666],{"type":50,"value":842},{"type":40,"tag":282,"props":2668,"children":2669},{"style":724},[2670],{"type":50,"value":1120},{"type":40,"tag":282,"props":2672,"children":2674},{"class":284,"line":2673},44,[2675,2679],{"type":40,"tag":282,"props":2676,"children":2677},{"style":712},[2678],{"type":50,"value":891},{"type":40,"tag":282,"props":2680,"children":2681},{"style":718},[2682],{"type":50,"value":747},{"type":40,"tag":282,"props":2684,"children":2686},{"class":284,"line":2685},45,[2687,2691,2695],{"type":40,"tag":282,"props":2688,"children":2689},{"style":712},[2690],{"type":50,"value":1139},{"type":40,"tag":282,"props":2692,"children":2693},{"style":718},[2694],{"type":50,"value":721},{"type":40,"tag":282,"props":2696,"children":2697},{"style":724},[2698],{"type":50,"value":1148},{"type":40,"tag":282,"props":2700,"children":2702},{"class":284,"line":2701},46,[2703,2707,2711],{"type":40,"tag":282,"props":2704,"children":2705},{"style":712},[2706],{"type":50,"value":1156},{"type":40,"tag":282,"props":2708,"children":2709},{"style":718},[2710],{"type":50,"value":721},{"type":40,"tag":282,"props":2712,"children":2713},{"style":724},[2714],{"type":50,"value":1165},{"type":40,"tag":282,"props":2716,"children":2718},{"class":284,"line":2717},47,[2719,2723,2727],{"type":40,"tag":282,"props":2720,"children":2721},{"style":712},[2722],{"type":50,"value":1173},{"type":40,"tag":282,"props":2724,"children":2725},{"style":718},[2726],{"type":50,"value":721},{"type":40,"tag":282,"props":2728,"children":2729},{"style":724},[2730],{"type":50,"value":1182},{"type":40,"tag":282,"props":2732,"children":2734},{"class":284,"line":2733},48,[2735,2739,2743],{"type":40,"tag":282,"props":2736,"children":2737},{"style":712},[2738],{"type":50,"value":1190},{"type":40,"tag":282,"props":2740,"children":2741},{"style":718},[2742],{"type":50,"value":721},{"type":40,"tag":282,"props":2744,"children":2745},{"style":724},[2746],{"type":50,"value":1199},{"type":40,"tag":282,"props":2748,"children":2750},{"class":284,"line":2749},49,[2751,2755,2759],{"type":40,"tag":282,"props":2752,"children":2753},{"style":712},[2754],{"type":50,"value":1207},{"type":40,"tag":282,"props":2756,"children":2757},{"style":718},[2758],{"type":50,"value":721},{"type":40,"tag":282,"props":2760,"children":2761},{"style":724},[2762],{"type":50,"value":1216},{"type":40,"tag":282,"props":2764,"children":2766},{"class":284,"line":2765},50,[2767,2771,2775],{"type":40,"tag":282,"props":2768,"children":2769},{"style":712},[2770],{"type":50,"value":1224},{"type":40,"tag":282,"props":2772,"children":2773},{"style":718},[2774],{"type":50,"value":721},{"type":40,"tag":282,"props":2776,"children":2777},{"style":724},[2778],{"type":50,"value":1233},{"type":40,"tag":282,"props":2780,"children":2782},{"class":284,"line":2781},51,[2783,2787,2791],{"type":40,"tag":282,"props":2784,"children":2785},{"style":712},[2786],{"type":50,"value":1241},{"type":40,"tag":282,"props":2788,"children":2789},{"style":718},[2790],{"type":50,"value":721},{"type":40,"tag":282,"props":2792,"children":2793},{"style":724},[2794],{"type":50,"value":1250},{"type":40,"tag":282,"props":2796,"children":2798},{"class":284,"line":2797},52,[2799,2803,2807],{"type":40,"tag":282,"props":2800,"children":2801},{"style":712},[2802],{"type":50,"value":1258},{"type":40,"tag":282,"props":2804,"children":2805},{"style":718},[2806],{"type":50,"value":721},{"type":40,"tag":282,"props":2808,"children":2809},{"style":724},[2810],{"type":50,"value":1267},{"type":40,"tag":282,"props":2812,"children":2814},{"class":284,"line":2813},53,[2815,2819,2823],{"type":40,"tag":282,"props":2816,"children":2817},{"style":712},[2818],{"type":50,"value":1275},{"type":40,"tag":282,"props":2820,"children":2821},{"style":718},[2822],{"type":50,"value":721},{"type":40,"tag":282,"props":2824,"children":2825},{"style":724},[2826],{"type":50,"value":1284},{"type":40,"tag":282,"props":2828,"children":2830},{"class":284,"line":2829},54,[2831,2835,2839],{"type":40,"tag":282,"props":2832,"children":2833},{"style":712},[2834],{"type":50,"value":1292},{"type":40,"tag":282,"props":2836,"children":2837},{"style":718},[2838],{"type":50,"value":721},{"type":40,"tag":282,"props":2840,"children":2841},{"style":724},[2842],{"type":50,"value":1301},{"type":40,"tag":282,"props":2844,"children":2846},{"class":284,"line":2845},55,[2847,2851],{"type":40,"tag":282,"props":2848,"children":2849},{"style":712},[2850],{"type":50,"value":1310},{"type":40,"tag":282,"props":2852,"children":2853},{"style":718},[2854],{"type":50,"value":747},{"type":40,"tag":282,"props":2856,"children":2858},{"class":284,"line":2857},56,[2859,2863,2867],{"type":40,"tag":282,"props":2860,"children":2861},{"style":712},[2862],{"type":50,"value":1323},{"type":40,"tag":282,"props":2864,"children":2865},{"style":718},[2866],{"type":50,"value":721},{"type":40,"tag":282,"props":2868,"children":2869},{"style":724},[2870],{"type":50,"value":1332},{"type":40,"tag":282,"props":2872,"children":2874},{"class":284,"line":2873},57,[2875,2879,2883],{"type":40,"tag":282,"props":2876,"children":2877},{"style":712},[2878],{"type":50,"value":1341},{"type":40,"tag":282,"props":2880,"children":2881},{"style":718},[2882],{"type":50,"value":721},{"type":40,"tag":282,"props":2884,"children":2885},{"style":724},[2886],{"type":50,"value":1350},{"type":40,"tag":282,"props":2888,"children":2890},{"class":284,"line":2889},58,[2891,2895,2899],{"type":40,"tag":282,"props":2892,"children":2893},{"style":712},[2894],{"type":50,"value":1359},{"type":40,"tag":282,"props":2896,"children":2897},{"style":718},[2898],{"type":50,"value":721},{"type":40,"tag":282,"props":2900,"children":2901},{"style":724},[2902],{"type":50,"value":1368},{"type":40,"tag":282,"props":2904,"children":2906},{"class":284,"line":2905},59,[2907,2911,2915],{"type":40,"tag":282,"props":2908,"children":2909},{"style":712},[2910],{"type":50,"value":1377},{"type":40,"tag":282,"props":2912,"children":2913},{"style":718},[2914],{"type":50,"value":721},{"type":40,"tag":282,"props":2916,"children":2917},{"style":724},[2918],{"type":50,"value":1386},{"type":40,"tag":282,"props":2920,"children":2922},{"class":284,"line":2921},60,[2923,2927,2931],{"type":40,"tag":282,"props":2924,"children":2925},{"style":712},[2926],{"type":50,"value":1395},{"type":40,"tag":282,"props":2928,"children":2929},{"style":718},[2930],{"type":50,"value":721},{"type":40,"tag":282,"props":2932,"children":2933},{"style":724},[2934],{"type":50,"value":1404},{"type":40,"tag":282,"props":2936,"children":2938},{"class":284,"line":2937},61,[2939,2943,2947],{"type":40,"tag":282,"props":2940,"children":2941},{"style":712},[2942],{"type":50,"value":1413},{"type":40,"tag":282,"props":2944,"children":2945},{"style":718},[2946],{"type":50,"value":721},{"type":40,"tag":282,"props":2948,"children":2949},{"style":724},[2950],{"type":50,"value":1422},{"type":40,"tag":282,"props":2952,"children":2954},{"class":284,"line":2953},62,[2955,2959,2963],{"type":40,"tag":282,"props":2956,"children":2957},{"style":712},[2958],{"type":50,"value":1431},{"type":40,"tag":282,"props":2960,"children":2961},{"style":718},[2962],{"type":50,"value":721},{"type":40,"tag":282,"props":2964,"children":2965},{"style":724},[2966],{"type":50,"value":1440},{"type":40,"tag":282,"props":2968,"children":2970},{"class":284,"line":2969},63,[2971,2976],{"type":40,"tag":282,"props":2972,"children":2973},{"style":712},[2974],{"type":50,"value":2975},"    depends_on",{"type":40,"tag":282,"props":2977,"children":2978},{"style":718},[2979],{"type":50,"value":747},{"type":40,"tag":282,"props":2981,"children":2983},{"class":284,"line":2982},64,[2984,2989],{"type":40,"tag":282,"props":2985,"children":2986},{"style":712},[2987],{"type":50,"value":2988},"      database",{"type":40,"tag":282,"props":2990,"children":2991},{"style":718},[2992],{"type":50,"value":747},{"type":40,"tag":282,"props":2994,"children":2996},{"class":284,"line":2995},65,[2997,3002,3006],{"type":40,"tag":282,"props":2998,"children":2999},{"style":712},[3000],{"type":50,"value":3001},"        condition",{"type":40,"tag":282,"props":3003,"children":3004},{"style":718},[3005],{"type":50,"value":721},{"type":40,"tag":282,"props":3007,"children":3008},{"style":724},[3009],{"type":50,"value":3010},"service_healthy\n",{"type":40,"tag":282,"props":3012,"children":3014},{"class":284,"line":3013},66,[3015,3020],{"type":40,"tag":282,"props":3016,"children":3017},{"style":712},[3018],{"type":50,"value":3019},"      storage",{"type":40,"tag":282,"props":3021,"children":3022},{"style":718},[3023],{"type":50,"value":747},{"type":40,"tag":282,"props":3025,"children":3027},{"class":284,"line":3026},67,[3028,3032,3036],{"type":40,"tag":282,"props":3029,"children":3030},{"style":712},[3031],{"type":50,"value":3001},{"type":40,"tag":282,"props":3033,"children":3034},{"style":718},[3035],{"type":50,"value":721},{"type":40,"tag":282,"props":3037,"children":3038},{"style":724},[3039],{"type":50,"value":3010},{"type":40,"tag":282,"props":3041,"children":3043},{"class":284,"line":3042},68,[3044],{"type":40,"tag":282,"props":3045,"children":3046},{"emptyLinePlaceholder":35},[3047],{"type":50,"value":309},{"type":40,"tag":282,"props":3049,"children":3051},{"class":284,"line":3050},69,[3052,3056],{"type":40,"tag":282,"props":3053,"children":3054},{"style":712},[3055],{"type":50,"value":755},{"type":40,"tag":282,"props":3057,"children":3058},{"style":718},[3059],{"type":50,"value":747},{"type":40,"tag":282,"props":3061,"children":3063},{"class":284,"line":3062},70,[3064,3068,3072],{"type":40,"tag":282,"props":3065,"children":3066},{"style":712},[3067],{"type":50,"value":767},{"type":40,"tag":282,"props":3069,"children":3070},{"style":718},[3071],{"type":50,"value":721},{"type":40,"tag":282,"props":3073,"children":3074},{"style":724},[3075],{"type":50,"value":776},{"type":40,"tag":282,"props":3077,"children":3079},{"class":284,"line":3078},71,[3080,3084],{"type":40,"tag":282,"props":3081,"children":3082},{"style":712},[3083],{"type":50,"value":784},{"type":40,"tag":282,"props":3085,"children":3086},{"style":718},[3087],{"type":50,"value":747},{"type":40,"tag":282,"props":3089,"children":3091},{"class":284,"line":3090},72,[3092,3096,3100],{"type":40,"tag":282,"props":3093,"children":3094},{"style":712},[3095],{"type":50,"value":796},{"type":40,"tag":282,"props":3097,"children":3098},{"style":718},[3099],{"type":50,"value":721},{"type":40,"tag":282,"props":3101,"children":3102},{"style":724},[3103],{"type":50,"value":805},{"type":40,"tag":282,"props":3105,"children":3107},{"class":284,"line":3106},73,[3108,3112,3116],{"type":40,"tag":282,"props":3109,"children":3110},{"style":712},[3111],{"type":50,"value":813},{"type":40,"tag":282,"props":3113,"children":3114},{"style":718},[3115],{"type":50,"value":721},{"type":40,"tag":282,"props":3117,"children":3118},{"style":724},[3119],{"type":50,"value":822},{"type":40,"tag":282,"props":3121,"children":3123},{"class":284,"line":3122},74,[3124,3128],{"type":40,"tag":282,"props":3125,"children":3126},{"style":712},[3127],{"type":50,"value":830},{"type":40,"tag":282,"props":3129,"children":3130},{"style":718},[3131],{"type":50,"value":747},{"type":40,"tag":282,"props":3133,"children":3135},{"class":284,"line":3134},75,[3136,3140],{"type":40,"tag":282,"props":3137,"children":3138},{"style":718},[3139],{"type":50,"value":842},{"type":40,"tag":282,"props":3141,"children":3142},{"style":724},[3143],{"type":50,"value":847},{"type":40,"tag":282,"props":3145,"children":3147},{"class":284,"line":3146},76,[3148,3152],{"type":40,"tag":282,"props":3149,"children":3150},{"style":712},[3151],{"type":50,"value":855},{"type":40,"tag":282,"props":3153,"children":3154},{"style":718},[3155],{"type":50,"value":747},{"type":40,"tag":282,"props":3157,"children":3159},{"class":284,"line":3158},77,[3160,3164],{"type":40,"tag":282,"props":3161,"children":3162},{"style":718},[3163],{"type":50,"value":842},{"type":40,"tag":282,"props":3165,"children":3166},{"style":724},[3167],{"type":50,"value":871},{"type":40,"tag":282,"props":3169,"children":3171},{"class":284,"line":3170},78,[3172,3176],{"type":40,"tag":282,"props":3173,"children":3174},{"style":718},[3175],{"type":50,"value":842},{"type":40,"tag":282,"props":3177,"children":3178},{"style":724},[3179],{"type":50,"value":883},{"type":40,"tag":282,"props":3181,"children":3183},{"class":284,"line":3182},79,[3184,3188],{"type":40,"tag":282,"props":3185,"children":3186},{"style":712},[3187],{"type":50,"value":891},{"type":40,"tag":282,"props":3189,"children":3190},{"style":718},[3191],{"type":50,"value":747},{"type":40,"tag":282,"props":3193,"children":3195},{"class":284,"line":3194},80,[3196,3200,3204],{"type":40,"tag":282,"props":3197,"children":3198},{"style":712},[3199],{"type":50,"value":903},{"type":40,"tag":282,"props":3201,"children":3202},{"style":718},[3203],{"type":50,"value":721},{"type":40,"tag":282,"props":3205,"children":3206},{"style":724},[3207],{"type":50,"value":912},{"type":40,"tag":282,"props":3209,"children":3211},{"class":284,"line":3210},81,[3212,3216,3220],{"type":40,"tag":282,"props":3213,"children":3214},{"style":712},[3215],{"type":50,"value":920},{"type":40,"tag":282,"props":3217,"children":3218},{"style":718},[3219],{"type":50,"value":721},{"type":40,"tag":282,"props":3221,"children":3222},{"style":724},[3223],{"type":50,"value":929},{"type":40,"tag":282,"props":3225,"children":3227},{"class":284,"line":3226},82,[3228,3232],{"type":40,"tag":282,"props":3229,"children":3230},{"style":712},[3231],{"type":50,"value":2975},{"type":40,"tag":282,"props":3233,"children":3234},{"style":718},[3235],{"type":50,"value":747},{"type":40,"tag":282,"props":3237,"children":3239},{"class":284,"line":3238},83,[3240,3244],{"type":40,"tag":282,"props":3241,"children":3242},{"style":712},[3243],{"type":50,"value":2988},{"type":40,"tag":282,"props":3245,"children":3246},{"style":718},[3247],{"type":50,"value":747},{"type":40,"tag":282,"props":3249,"children":3251},{"class":284,"line":3250},84,[3252,3256,3260],{"type":40,"tag":282,"props":3253,"children":3254},{"style":712},[3255],{"type":50,"value":3001},{"type":40,"tag":282,"props":3257,"children":3258},{"style":718},[3259],{"type":50,"value":721},{"type":40,"tag":282,"props":3261,"children":3262},{"style":724},[3263],{"type":50,"value":3010},{"type":40,"tag":282,"props":3265,"children":3267},{"class":284,"line":3266},85,[3268,3272],{"type":40,"tag":282,"props":3269,"children":3270},{"style":712},[3271],{"type":50,"value":3019},{"type":40,"tag":282,"props":3273,"children":3274},{"style":718},[3275],{"type":50,"value":747},{"type":40,"tag":282,"props":3277,"children":3279},{"class":284,"line":3278},86,[3280,3284,3288],{"type":40,"tag":282,"props":3281,"children":3282},{"style":712},[3283],{"type":50,"value":3001},{"type":40,"tag":282,"props":3285,"children":3286},{"style":718},[3287],{"type":50,"value":721},{"type":40,"tag":282,"props":3289,"children":3290},{"style":724},[3291],{"type":50,"value":3010},{"type":40,"tag":46,"props":3293,"children":3294},{},[3295,3297,3303,3305,3311],{"type":50,"value":3296},"The configuration file also adds ",{"type":40,"tag":214,"props":3298,"children":3300},{"className":3299},[],[3301],{"type":50,"value":3302},"healthcheck",{"type":50,"value":3304}," rules and ",{"type":40,"tag":214,"props":3306,"children":3308},{"className":3307},[],[3309],{"type":50,"value":3310},"depends_on",{"type":50,"value":3312}," conditions. Those are useful because they help Docker understand when MySQL and RustFS are actually ready before Directus and Nuxt try to use them. Without that, services can start in the wrong order.",{"type":40,"tag":46,"props":3314,"children":3315},{},[3316],{"type":50,"value":3317},"To confirm the setup works correctly, run the following tests after starting the application:",{"type":40,"tag":89,"props":3319,"children":3320},{},[3321,3333,3344],{"type":40,"tag":93,"props":3322,"children":3323},{},[3324,3326,3331],{"type":50,"value":3325},"Open ",{"type":40,"tag":214,"props":3327,"children":3329},{"className":3328},[],[3330],{"type":50,"value":940},{"type":50,"value":3332}," in a browser. You should see the Nuxt welcome screen. Modify layout and confirm the browser automatically reflects the changes.",{"type":40,"tag":93,"props":3334,"children":3335},{},[3336,3337,3342],{"type":50,"value":3325},{"type":40,"tag":214,"props":3338,"children":3340},{"className":3339},[],[3341],{"type":50,"value":1451},{"type":50,"value":3343}," in a browser. You should see the Directus screen to complete the installation. Once done, you should be able to log in to the panel.",{"type":40,"tag":93,"props":3345,"children":3346},{},[3347,3348,3353],{"type":50,"value":3325},{"type":40,"tag":214,"props":3349,"children":3351},{"className":3350},[],[3352],{"type":50,"value":1947},{"type":50,"value":3354}," in a browser. You should see the RustFS GUI for managing S3 storage. Log in with the credentials you set and try uploading a file. It should land in the defined space on disk.",{"type":40,"tag":3356,"props":3357,"children":3359},"prose-gallery",{":items":3358},"[\"https://cdn.pragmate.dev/wp-content/uploads/2026/08/d55b85d2-587b-4cf0-98f6-14840dc9ec11.jpg\",\"https://cdn.pragmate.dev/wp-content/uploads/2026/08/df1fb0d4-6380-4c22-a8ad-709b2e045ffd.jpg\",\"https://cdn.pragmate.dev/wp-content/uploads/2026/08/95cf9f51-782b-469b-9526-5541ffaf0001.jpg\",\"https://cdn.pragmate.dev/wp-content/uploads/2026/08/2d7c4b57-8c76-4e8b-8377-d4ad03a45c65.jpg\",\"https://cdn.pragmate.dev/wp-content/uploads/2026/08/a91abae0-c264-4832-9234-f6556f971971.jpg\"]",[],{"type":40,"tag":73,"props":3361,"children":3362},{},[],{"type":40,"tag":77,"props":3364,"children":3366},{"id":3365},"what-are-the-useful-docker-tricks",[3367],{"type":50,"value":3368},"What are the useful Docker tricks?",{"type":40,"tag":46,"props":3370,"children":3371},{},[3372],{"type":50,"value":3373},"Here are a few things that might help you reduce trouble when working with Docker. These are the ones I have often forgotten, especially when I was just getting started with Docker.",{"type":40,"tag":3375,"props":3376,"children":3378},"h3",{"id":3377},"how-to-run-commands-for-the-container",[3379],{"type":50,"value":3380},"How to run commands for the container?",{"type":40,"tag":46,"props":3382,"children":3383},{},[3384,3386,3392,3394,3400,3402,3407],{"type":50,"value":3385},"A common thing to miss is that the app runs inside a container. So when running commands for the app, you should run them in the container with ",{"type":40,"tag":214,"props":3387,"children":3389},{"className":3388},[],[3390],{"type":50,"value":3391},"docker compose exec",{"type":50,"value":3393}," command. For example, to install ",{"type":40,"tag":214,"props":3395,"children":3397},{"className":3396},[],[3398],{"type":50,"value":3399},"swiperjs",{"type":50,"value":3401}," package in the ",{"type":40,"tag":214,"props":3403,"children":3405},{"className":3404},[],[3406],{"type":50,"value":219},{"type":50,"value":3408}," container, you should run this command.",{"type":40,"tag":272,"props":3410,"children":3412},{"className":1965,"code":3411,"language":1967,"meta":7,"style":7},"docker compose exec frontend pnpm install swiperjs\n",[3413],{"type":40,"tag":214,"props":3414,"children":3415},{"__ignoreMap":7},[3416],{"type":40,"tag":282,"props":3417,"children":3418},{"class":284,"line":285},[3419,3423,3427,3432,3437,3442,3447],{"type":40,"tag":282,"props":3420,"children":3421},{"style":1977},[3422],{"type":50,"value":34},{"type":40,"tag":282,"props":3424,"children":3425},{"style":724},[3426],{"type":50,"value":1984},{"type":40,"tag":282,"props":3428,"children":3429},{"style":724},[3430],{"type":50,"value":3431}," exec",{"type":40,"tag":282,"props":3433,"children":3434},{"style":724},[3435],{"type":50,"value":3436}," frontend",{"type":40,"tag":282,"props":3438,"children":3439},{"style":724},[3440],{"type":50,"value":3441}," pnpm",{"type":40,"tag":282,"props":3443,"children":3444},{"style":724},[3445],{"type":50,"value":3446}," install",{"type":40,"tag":282,"props":3448,"children":3449},{"style":724},[3450],{"type":50,"value":3451}," swiperjs\n",{"type":40,"tag":3375,"props":3453,"children":3455},{"id":3454},"how-to-access-the-container-terminal",[3456],{"type":50,"value":3457},"How to access the container terminal?",{"type":40,"tag":46,"props":3459,"children":3460},{},[3461],{"type":50,"value":3462},"Sometimes, you may need to access the terminal of a specific container for longer. Maybe to search through files there, check logs, or run other tools directly in the container, as you would do on your host machine. You can get into the container with a command like this.",{"type":40,"tag":272,"props":3464,"children":3466},{"className":1965,"code":3465,"language":1967,"meta":7,"style":7},"docker compose exec frontend sh\n",[3467],{"type":40,"tag":214,"props":3468,"children":3469},{"__ignoreMap":7},[3470],{"type":40,"tag":282,"props":3471,"children":3472},{"class":284,"line":285},[3473,3477,3481,3485,3489],{"type":40,"tag":282,"props":3474,"children":3475},{"style":1977},[3476],{"type":50,"value":34},{"type":40,"tag":282,"props":3478,"children":3479},{"style":724},[3480],{"type":50,"value":1984},{"type":40,"tag":282,"props":3482,"children":3483},{"style":724},[3484],{"type":50,"value":3431},{"type":40,"tag":282,"props":3486,"children":3487},{"style":724},[3488],{"type":50,"value":3436},{"type":40,"tag":282,"props":3490,"children":3491},{"style":724},[3492],{"type":50,"value":3493}," sh\n",{"type":40,"tag":3375,"props":3495,"children":3497},{"id":3496},"how-to-reach-the-container-address",[3498],{"type":50,"value":3499},"How to reach the container address?",{"type":40,"tag":46,"props":3501,"children":3502},{},[3503,3505,3510],{"type":50,"value":3504},"A common thing with Docker is confusing a container's network context with the host. For example, if you want to access CMS, you use ",{"type":40,"tag":214,"props":3506,"children":3508},{"className":3507},[],[3509],{"type":50,"value":1451},{"type":50,"value":3511}," in your browser, it works. Then, inside the app, you use the same URL to query API endpoints, and it does not work.",{"type":40,"tag":46,"props":3513,"children":3514},{},[3515,3517,3522,3524,3530,3532,3537],{"type":50,"value":3516},"The key is that ",{"type":40,"tag":214,"props":3518,"children":3520},{"className":3519},[],[3521],{"type":50,"value":1694},{"type":50,"value":3523}," means different things depending on where you are. On your host, ",{"type":40,"tag":214,"props":3525,"children":3527},{"className":3526},[],[3528],{"type":50,"value":3529},"localhost:9001",{"type":50,"value":3531}," points to the host itself, so it may work in the browser. But inside a Docker container, ",{"type":40,"tag":214,"props":3533,"children":3535},{"className":3534},[],[3536],{"type":50,"value":1694},{"type":50,"value":3538}," refers to that container, so the same URL won’t work there.",{"type":40,"tag":46,"props":3540,"children":3541},{},[3542],{"type":50,"value":3543},"When container needs to access another service, it should use its name and internal port.",{"type":40,"tag":272,"props":3545,"children":3549},{"className":3546,"code":3547,"language":3548,"meta":7,"style":7},"language-js shiki shiki-themes one-dark-pro","fetch(`http://backend:8055/api/posts`)\n","js",[3550],{"type":40,"tag":214,"props":3551,"children":3552},{"__ignoreMap":7},[3553],{"type":40,"tag":282,"props":3554,"children":3555},{"class":284,"line":285},[3556,3561,3566,3571],{"type":40,"tag":282,"props":3557,"children":3558},{"style":1977},[3559],{"type":50,"value":3560},"fetch",{"type":40,"tag":282,"props":3562,"children":3563},{"style":718},[3564],{"type":50,"value":3565},"(",{"type":40,"tag":282,"props":3567,"children":3568},{"style":724},[3569],{"type":50,"value":3570},"`http://backend:8055/api/posts`",{"type":40,"tag":282,"props":3572,"children":3573},{"style":718},[3574],{"type":50,"value":3575},")\n",{"type":40,"tag":73,"props":3577,"children":3578},{},[],{"type":40,"tag":77,"props":3580,"children":3582},{"id":3581},"what-is-the-takeaway",[3583],{"type":50,"value":3584},"What is the takeaway?",{"type":40,"tag":46,"props":3586,"children":3587},{},[3588],{"type":50,"value":3589},"If you want a vibe-coded app to stay solid, you need a structure that is easy to run and understand. Docker Compose gives you that structure by keeping the frontend, backend, database, and storage in separate containers while still letting them work together as one system. That makes the whole stack easier to develop and much less painful to maintain.",{"type":40,"tag":73,"props":3591,"children":3592},{},[],{"type":40,"tag":46,"props":3594,"children":3595},{},[3596,3598,3605,3607,3614],{"type":50,"value":3597},"Thank you so much for joining me in today ❤️ Your support means a lot to me, and it keeps me motivated to create more content. If you enjoyed this video, please consider ",{"type":40,"tag":58,"props":3599,"children":3602},{"href":3600,"rel":3601},"https://www.youtube.com/@pragmatedev?sub_confirmation=1",[62],[3603],{"type":50,"value":3604},"subscribing to the channel",{"type":50,"value":3606}," and giving it a thumbs-up - it really helps spread the word. And if you need developers who truly care about quality and delivering great results, visit my company’s site: ",{"type":40,"tag":58,"props":3608,"children":3611},{"href":3609,"rel":3610},"https://coditive.com/?utm_source=www&utm_medium=content&utm_campaign=pragmate_dev",[62],[3612],{"type":50,"value":3613},"coditive.com",{"type":50,"value":3615}," or contact me with the form below. Thanks again and see you next time!",{"type":40,"tag":3617,"props":3618,"children":3619},"style",{},[3620],{"type":50,"value":3621},"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);}",{"title":7,"searchDepth":294,"depth":294,"links":3623},[3624,3625,3626,3627,3628,3629,3630,3631,3632,3637],{"id":79,"depth":294,"text":82},{"id":153,"depth":294,"text":156},{"id":204,"depth":294,"text":207},{"id":476,"depth":294,"text":479},{"id":948,"depth":294,"text":951},{"id":1459,"depth":294,"text":1462},{"id":1710,"depth":294,"text":1713},{"id":1954,"depth":294,"text":1957},{"id":3365,"depth":294,"text":3368,"children":3633},[3634,3635,3636],{"id":3377,"depth":303,"text":3380},{"id":3454,"depth":303,"text":3457},{"id":3496,"depth":303,"text":3499},{"id":3581,"depth":294,"text":3584},"markdown","content:environment:how-to-set-up-stack-for-a-vibe-coded-app-with-docker.md","content","environment/how-to-set-up-stack-for-a-vibe-coded-app-with-docker.md","environment/how-to-set-up-stack-for-a-vibe-coded-app-with-docker","md",1786533693450]