{"version":"1.0","encoding":"UTF-8","feed":{"xmlns":"http://www.w3.org/2005/Atom","xmlns$openSearch":"http://a9.com/-/spec/opensearchrss/1.0/","xmlns$blogger":"http://schemas.google.com/blogger/2008","xmlns$georss":"http://www.georss.org/georss","xmlns$gd":"http://schemas.google.com/g/2005","xmlns$thr":"http://purl.org/syndication/thread/1.0","id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016"},"updated":{"$t":"2026-05-23T10:27:42.683-07:00"},"category":[{"term":"Backup"},{"term":"NAS"},{"term":"OMV"},{"term":"RAID"},{"term":"Raspberry PI 4"},{"term":"VibeEngineering"}],"title":{"type":"text","$t":"coding-mayhem"},"subtitle":{"type":"html","$t":""},"link":[{"rel":"http://schemas.google.com/g/2005#feed","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/posts\/default"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default?alt=json"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/"},{"rel":"hub","href":"http://pubsubhubbub.appspot.com/"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"generator":{"version":"7.00","uri":"http://www.blogger.com","$t":"Blogger"},"openSearch$totalResults":{"$t":"22"},"openSearch$startIndex":{"$t":"1"},"openSearch$itemsPerPage":{"$t":"25"},"entry":[{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-7069907650143637205"},"published":{"$t":"2026-05-23T08:33:13.074-07:00"},"updated":{"$t":"2026-05-23T10:27:42.683-07:00"},"category":[{"scheme":"http://www.blogger.com/atom/ns#","term":"VibeEngineering"}],"title":{"type":"text","$t":"Day 01 — Tearing Down the WordPress House"},"content":{"type":"html","$t":"\u003Ch3 style=\"text-align: left;\"\u003EDay 01 — Tearing Down the WordPress House\u003C\/h3\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhSWU3SJwC_AdP363kGd_DEjnXiArI-590wypUX0vPx4707EcUqR7_Y8giXG_Jpp2cn4TRqnuPCEpdRaX_g-yZVYL_aTbep84n3JUhLpyXZknyjFZrRIxtMUCk62TODZSCeX9MkRYMMbVyDITHyZhUj3tEUCQHUsfYc7vIkOclTXSwhIMrhQNEXLtzBftU\/s1536\/c5592c31-c7a3-480a-a99f-7af1f12437aa.png\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"1024\" data-original-width=\"1536\" height=\"213\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhSWU3SJwC_AdP363kGd_DEjnXiArI-590wypUX0vPx4707EcUqR7_Y8giXG_Jpp2cn4TRqnuPCEpdRaX_g-yZVYL_aTbep84n3JUhLpyXZknyjFZrRIxtMUCk62TODZSCeX9MkRYMMbVyDITHyZhUj3tEUCQHUsfYc7vIkOclTXSwhIMrhQNEXLtzBftU\/s320\/c5592c31-c7a3-480a-a99f-7af1f12437aa.png\" width=\"320\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cbr \/\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cp\u003E\u003Cb\u003EDate:\u003C\/b\u003E 2026-05-22\u0026nbsp;\u0026nbsp;\u003C\/p\u003E\u003Cp\u003E\u003Cb\u003EStatus at end of day:\u003C\/b\u003E Scaffold live. Payload admin at `\/admin` returns 200. Zero pages built.\u003C\/p\u003E\u003Ch3 style=\"text-align: left;\"\u003EWhy we're doing this\u003C\/h3\u003E\u003Cp\u003EA friend of mine has been running her food blog on WordPress for years. It works, mostly. But \"works, mostly\" starts to feel like a cage when you look at what it costs — not just in dollars (hosting renewals that only go up) but in the invisible tax of a platform you don't control. Slow admin. Plugin soup. A theme that fights you every time you try to change something. And 90% of the traffic is mobile, but the site wasn't really built for that.\u003C\/p\u003E\u003Cp\u003ESo we're rebuilding it from scratch. Custom Next.js app, Payload CMS, PostgreSQL, Tailwind CSS, Docker. The whole thing designed around how she actually uses it — she manages content herself and is technical enough to handle a real admin UI, she just doesn't want to write code.\u003C\/p\u003E\u003Cp\u003EAnd we're doing it with AI. Specifically, Claude Code doing most of the heavy lifting while I drive.\u003C\/p\u003E\u003Ch3 style=\"text-align: left;\"\u003EThe planning phase: where AI genuinely earns its keep\u003C\/h3\u003E\u003Cp\u003EBefore a single line of code was written, we spent time in a design session. And this is where AI-assisted development surprised me the most on day one — not in the code writing, but in the \u003Cb\u003Edecisions\u003C\/b\u003E.\u003C\/p\u003E\u003Cp\u003EI had a rough idea of what I wanted. Claude asked questions one at a time. Not \"what do you want to build?\" but specific things: what's her content management workflow, how technically capable is she, what are the monetisation constraints, what does the traffic look like. Each question built on the last.\u003C\/p\u003E\u003Cp\u003EBy the end of maybe 45 minutes of back-and-forth, we had:\u003C\/p\u003E\u003Cp\u003E\u003C\/p\u003E\u003Cul style=\"text-align: left;\"\u003E\u003Cli\u003EA full tech stack decision with reasoning for each choice\u003C\/li\u003E\u003Cli\u003EA rendering strategy per page (SSG vs ISR with specific revalidation times)\u003C\/li\u003E\u003Cli\u003EPayload CMS collections and globals defined\u003C\/li\u003E\u003Cli\u003EAPI routes listed\u003C\/li\u003E\u003Cli\u003EInfrastructure decisions made\u003C\/li\u003E\u003Cli\u003EA 4-plan implementation sequence with a separate content migration script\u003C\/li\u003E\u003C\/ul\u003E\u003Cp\u003EThat planning work lives in `docs\/superpowers\/specs\/` and `docs\/superpowers\/plans\/`. Reading it back, it's better documented than most professional projects I've worked on. The AI didn't just execute instructions — it pushed back, asked \"why\", and caught things I hadn't thought through.\u003C\/p\u003E\u003Cp\u003EOne example: early in the session I told Claude I wanted to move off SiteGround — shared hosting we don't control, costs that only go up, a platform that doesn't fit what we're building. That instruction got swallowed somewhere in context compaction. Claude kept planning as if we were staying on SiteGround. I had to say it again before the hosting conversation actually happened.\u003C\/p\u003E\u003Cp\u003EOnce it landed, we got to the right answer: Docker Compose + Caddy. The entire stack moves to any Linux box with a single `git pull` and `docker compose up`. SiteGround, a home server, a DigitalOcean droplet — doesn't matter. But I shouldn't have had to say it twice.\u003C\/p\u003E\u003Cp\u003E\u003Cb\u003EAI limitation: \u003C\/b\u003EContext compaction is real. In a long planning session, earlier instructions can get dropped from the active window. If something matters — a constraint, a direction, a decision — say it again when it becomes relevant, or write it down in a plan that gets committed to disk.\u003C\/p\u003E\u003Cp\u003E\u003Cb\u003EAI advantage: \u003C\/b\u003EOnce the context was right, the planning quality was high. Architecture documentation, rendering strategies, API routes, Payload collections — all thought through and committed in one session. Better-structured than most professional projects I've seen.\u003C\/p\u003E\u003Ch3 style=\"text-align: left;\"\u003EInfrastructure: the decision I didn't know I needed to make\u003C\/h3\u003E\u003Cp\u003EThe hosting conversation I'd tried to have earlier — the one context compaction had eaten — finally happened properly. Claude laid out three paths: Nginx + PM2 on the existing VPS (familiar, simple), Docker Compose + Caddy (portable, handles SSL automatically), or a managed platform like Vercel (easiest but locks you to a vendor and gets expensive).\u003C\/p\u003E\u003Cp\u003EI chose Docker. Not because I had a strong view — because the reasoning was clear. With Docker Compose, moving the whole stack is: update a GitHub secret with the new server IP, push a commit, done. No reinstalling Nginx. No regenerating SSL certificates. No PM2 config to redo.\u003C\/p\u003E\u003Cp\u003ECaddy was a new one for me. It's a reverse proxy that automatically obtains and renews Let's Encrypt certificates. The entire SSL config is one line:\u003C\/p\u003E\u003Cp\u003E```\u003C\/p\u003E\u003Cp\u003Eher-food-blog.com {\u003C\/p\u003E\u003Cp\u003E\u0026nbsp; \u0026nbsp; reverse_proxy app:3000\u003C\/p\u003E\u003Cp\u003E}\u003C\/p\u003E\u003Cp\u003E```\u003C\/p\u003E\u003Cp\u003EThat's it. Caddy handles everything else. No Certbot. No cron jobs. No certificate renewal panic emails.\u003C\/p\u003E\u003Cp\u003E\u003Cb\u003EAI advantage:\u003C\/b\u003E Surfacing options I wouldn't have compared side-by-side, explaining the trade-offs clearly, and being willing to recommend rather than just listing options neutrally.\u003C\/p\u003E\u003Ch3 style=\"text-align: left;\"\u003EDay one of actual building: where it got messy\u003C\/h3\u003E\u003Cp\u003EWith the plans written and committed, we started executing Plan 1 — scaffold the project, get the Payload admin running locally.\u003C\/p\u003E\u003Cp\u003EThis is where the AI went from \"impressive planner\" to \"frustrating sometimes, but honest about it.\"\u003C\/p\u003E\u003Ch4 style=\"text-align: left;\"\u003EFlop #1: The TTY problem\u003C\/h4\u003E\u003Cp\u003EThe first real task is running `create-payload-app` to scaffold the Next.js + Payload project. Claude tried to run it:\u003C\/p\u003E\u003Cp\u003E```bash\u003C\/p\u003E\u003Cp\u003Ecd \/tmp \u0026amp;\u0026amp; npx create-payload-app@latest mlob-scaffold --template blank --db postgres --no-deps-install\u003C\/p\u003E\u003Cp\u003E```\u003C\/p\u003E\u003Cp\u003EOutput:\u003C\/p\u003E\u003Cp\u003E```\u003C\/p\u003E\u003Cp\u003E■\u0026nbsp; TTY initialization failed: uv_tty_init returned EINVAL (invalid argument)\u003C\/p\u003E\u003Cp\u003E```\u003C\/p\u003E\u003Cp\u003EThe CLI needs an interactive terminal to display its setup wizard. The AI's Bash tool doesn't have one — it runs commands in a non-interactive shell. Claude caught this immediately: \"I can't run this one. You'll need to run it yourself in your terminal.\"\u003C\/p\u003E\u003Cp\u003EI ran it directly. It worked.\u003C\/p\u003E\u003Cp\u003EThis is a recurring pattern with AI-assisted development. The AI is great at running build commands, file edits, git operations, TypeScript checks. Anything that needs a real TTY — interactive CLIs, things with fancy terminal UIs — it can't touch. You just have to know which category you're in.\u003C\/p\u003E\u003Cp\u003E\u003Cb\u003EAI flop:\u003C\/b\u003E Silently failing on interactive CLIs. Not really Claude's fault — it's a fundamental constraint of how the tool works. But it's a speed bump you hit before you know to expect it.\u003C\/p\u003E\u003Ch4 style=\"text-align: left;\"\u003EFlop #2: The blank password problem\u003C\/h4\u003E\u003Cp\u003EOnce the scaffold was copied into the repo, we needed to start the PostgreSQL Docker container. Claude created the `docker-compose.yml` and ran:\u003C\/p\u003E\u003Cp\u003E```bash\u003C\/p\u003E\u003Cp\u003Edocker compose up -d db\u003C\/p\u003E\u003Cp\u003E```\u003C\/p\u003E\u003Cp\u003EWarning in the output: `The \"POSTGRES_PASSWORD\" variable is not set. Defaulting to a blank string.`\u003C\/p\u003E\u003Cp\u003EThe container started anyway... then immediately started restarting in a crash loop. Log:\u003C\/p\u003E\u003Cp\u003E```\u003C\/p\u003E\u003Cp\u003EError: Database is uninitialized and superuser password is not specified.\u003C\/p\u003E\u003Cp\u003EYou must specify POSTGRES_PASSWORD to a non-empty value for the superuser.\u003C\/p\u003E\u003Cp\u003E```\u003C\/p\u003E\u003Cp\u003EPostgreSQL refuses to start with a blank password. Fair enough. The problem was that we'd run `docker compose up` *before* creating the `.env` file.\u003C\/p\u003E\u003Cp\u003EHere's the thing that took a minute to debug: Docker Compose reads a `.env` file for variable substitution. Next.js reads `.env.local`. They're not the same file, and one does not substitute for the other. Claude had planned to create `.env.local` with the database credentials. What it had missed — and what wasn't in the original plan — is that `docker compose` needs its own `.env` file with `POSTGRES_PASSWORD` set.\u003C\/p\u003E\u003Cp\u003ESo now we have two env files:\u003C\/p\u003E\u003Cp\u003E- `.env` — just `POSTGRES_PASSWORD=mlob-dev-password` (for Docker Compose)\u003C\/p\u003E\u003Cp\u003E- `.env.local` — everything Next.js needs (DATABASE_URI, PAYLOAD_SECRET, etc.)\u003C\/p\u003E\u003Cp\u003EStop the container, delete the freshly-created volume (it was initialised with a blank password so it's poisoned), create both files, restart. Container came up healthy.\u003C\/p\u003E\u003Cp\u003E\u003Cb\u003EAI flop:\u003C\/b\u003E Missing the two-env-file requirement in the original plan. Not wrong, exactly — Next.js projects commonly use only `.env.local`. But the interaction with Docker Compose's variable substitution was a gap. Claude caught it during debugging and documented it immediately so it won't happen again.\u003C\/p\u003E\u003Ch4 style=\"text-align: left;\"\u003EFlop #3: The misnamed environment variable\u003C\/h4\u003E\u003Cp\u003EContainer healthy, `.env.local` created, `npm run dev` running, browser open at `http:\/\/localhost:3000\/admin`.\u003C\/p\u003E\u003Cp\u003E```\u003C\/p\u003E\u003Cp\u003E500 Internal Server Error\u003C\/p\u003E\u003Cp\u003E```\u003C\/p\u003E\u003Cp\u003EDev server log:\u003C\/p\u003E\u003Cp\u003E```\u003C\/p\u003E\u003Cp\u003EError: cannot connect to Postgres. Details: SASL: SCRAM-SERVER-FIRST-MESSAGE: client password must be a string\u003C\/p\u003E\u003Cp\u003E```\u003C\/p\u003E\u003Cp\u003E\"Client password must be a string\" means the password reached the database driver as `undefined` — not a wrong password, but *no* password.\u003C\/p\u003E\u003Cp\u003EThe `payload.config.ts` from the scaffold read `process.env.DATABASE_URL`. Our `.env.local` had `DATABASE_URI`. One letter difference: `URL` vs `URI`.\u003C\/p\u003E\u003Cp\u003EThis is a maddening class of bug. The application starts fine, no startup errors, no warnings about missing environment variables — it just silently gets `undefined` from `process.env.DATABASE_URL` and tries to connect with that. The error only surfaces when the first database query runs.\u003C\/p\u003E\u003Cp\u003EThe fix was one word:\u003C\/p\u003E\u003Cp\u003E```typescript\u003C\/p\u003E\u003Cp\u003E\/\/ Before (scaffold default)\u003C\/p\u003E\u003Cp\u003EconnectionString: process.env.DATABASE_URL || '',\u003C\/p\u003E\u003Cp\u003E\u003Cbr \/\u003E\u003C\/p\u003E\u003Cp\u003E\/\/ After (matches our spec)\u003C\/p\u003E\u003Cp\u003EconnectionString: process.env.DATABASE_URI || '',\u003C\/p\u003E\u003Cp\u003E```\u003C\/p\u003E\u003Cp\u003ERestart the dev server. `\/admin` returned 200.\u003C\/p\u003E\u003Cp\u003E\u003Cb\u003EAI flop:\u003C\/b\u003E The scaffold used `DATABASE_URL`; our plan specified `DATABASE_URI`. Claude generated the `.env.local` with `DATABASE_URI` (correct per our spec) without noticing the payload.config.ts disagreed. This is a subtle cross-file consistency issue — the kind that's easy to miss in a first-pass implementation and annoying to debug because nothing warns you.\u003C\/p\u003E\u003Cp\u003EThe positive: once the error appeared, Claude diagnosed it correctly within one look at the logs and the config file. The debugging was fast even if the bug shouldn't have existed.\u003C\/p\u003E\u003Ch3 style=\"text-align: left;\"\u003EThe win: Payload admin is live\u003C\/h3\u003E\u003Cp\u003EAfter fixing the env variable, `http:\/\/localhost:3000\/admin` loaded. Payload's first-run screen — create your admin user, set a password, log in. The admin dashboard appeared.\u003C\/p\u003E\u003Cp\u003EIt's a bare scaffold at this point. Two collections (Users and Media), nothing else. But the plumbing works: Next.js talking to Payload, Payload talking to PostgreSQL in Docker, all running locally, all wired together correctly.\u003C\/p\u003E\u003Cp\u003EFirst commit of actual code: `feat: scaffold Next.js 15 + Payload CMS v3 project`. 26 files changed.\u003C\/p\u003E\u003Cp\u003E\u003Cb\u003EAI advantage: \u003C\/b\u003EThe systematic approach to debugging. When `\/admin` returned 500, Claude didn't guess — it read the log, identified the exact error message, pulled up the relevant config file, and found the mismatch. The turnaround from \"500 error\" to \"fix committed\" was probably 10 minutes including the docker restart.\u003C\/p\u003E\u003Ch3 style=\"text-align: left;\"\u003EEnd of day: what's done, what's next\u003C\/h3\u003E\u003Cp\u003E\u003Cb\u003EDone:\u003C\/b\u003E\u003C\/p\u003E\u003Cp\u003E\u003C\/p\u003E\u003Cul style=\"text-align: left;\"\u003E\u003Cli\u003EFull architecture and implementation plans documented\u003C\/li\u003E\u003Cli\u003ENext.js 15 + Payload CMS v3 scaffold committed\u003C\/li\u003E\u003Cli\u003EPostgreSQL running in Docker\u003C\/li\u003E\u003Cli\u003EPayload admin accessible at `\/admin`\u003C\/li\u003E\u003Cli\u003EDesign tokens, gitignore, env file setup all sorted\u003C\/li\u003E\u003C\/ul\u003E\u003Cp\u003E\u003C\/p\u003E\u003Cp\u003E\u003Cb\u003ENot done:\u003C\/b\u003E\u003C\/p\u003E\u003Cp\u003E\u003C\/p\u003E\u003Cul style=\"text-align: left;\"\u003E\u003Cli\u003ETailwind CSS (next session: Task 2)\u003C\/li\u003E\u003Cli\u003EFonts\u003C\/li\u003E\u003Cli\u003EAny actual Payload collections for the real content (recipes, categories, workshops)\u003C\/li\u003E\u003Cli\u003EPages — zero public pages exist yet\u003C\/li\u003E\u003C\/ul\u003E\u003Cp\u003E\u003C\/p\u003E\u003Ch3 style=\"text-align: left;\"\u003EHonest take on day one\u003C\/h3\u003E\u003Cp\u003EThe AI was genuinely useful. The planning phase was better with Claude than it would have been alone — more thorough, faster, better documented. The debugging was efficient. The code it wrote was clean.\u003C\/p\u003E\u003Cp\u003EBut it makes mistakes. The two-env-file gap and the DATABASE_URL\/URI mismatch are both things a careful human would have caught in a review. The TTY limitation is a real friction point for CLIs.\u003C\/p\u003E\u003Cp\u003EThe pattern I'm settling into, and what I'll do differently going forward:\u003C\/p\u003E\u003Cp\u003E\u003Cb\u003EDetailed plans before any code.\u003C\/b\u003E The superpowers planning workflow — structured implementation plans committed to disk before touching the codebase — is the highest-leverage thing in this setup. Not because Claude can't improvise, but because plans on disk survive context compaction. When a new session starts and the first thing Claude reads is the plan, decisions from three sessions ago are still there.\u003C\/p\u003E\u003Cp\u003E\u003Cb\u003EMemory between sessions.\u003C\/b\u003E At the end of each session, ask Claude to save key decisions, gotchas, and context to memory files. That covers what plans don't — the \"we renamed DATABASE_URL to DATABASE_URI and here's why\" kind of context. Start each new session fresh; the memory carries what matters.\u003C\/p\u003E\u003Cp\u003E\u003Cb\u003ESmall chunks, always verify.\u003C\/b\u003E One task. One commit. One check before moving on. I ask verification questions at every step — what does the log actually say, what's the exact env var name, does this match what we planned. It slows the session down. It also catches the DATABASE_URL\/URI class of bug before it becomes a midnight debugging session.\u003C\/p\u003E\u003Cp\u003E\u003Cb\u003EThe AI isn't unreliable \u003C\/b\u003E— it's stateless. Build your workflow around that fact and it's a genuinely useful collaborator. Don't and you'll spend half your time re-explaining decisions you already made.\u003C\/p\u003E\u003Cp\u003E\u003Cb\u003EDay2:\u003C\/b\u003E Tailwind CSS v4 with design tokens, fonts, and the first real Payload collections.\u003C\/p\u003E\u003Cp\u003E\u003Ci\u003EThis is part of an ongoing series documenting the rebuild of a friend's food blog from WordPress to a custom Next.js stack, built with AI assistance.\u003C\/i\u003E\u003C\/p\u003E\u003Cp\u003E\u0026nbsp;\u003C\/p\u003E"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/7069907650143637205\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2026\/05\/day-01-tearing-down-wordpress-house.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/7069907650143637205"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/7069907650143637205"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2026\/05\/day-01-tearing-down-wordpress-house.html","title":"Day 01 — Tearing Down the WordPress House"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhSWU3SJwC_AdP363kGd_DEjnXiArI-590wypUX0vPx4707EcUqR7_Y8giXG_Jpp2cn4TRqnuPCEpdRaX_g-yZVYL_aTbep84n3JUhLpyXZknyjFZrRIxtMUCk62TODZSCeX9MkRYMMbVyDITHyZhUj3tEUCQHUsfYc7vIkOclTXSwhIMrhQNEXLtzBftU\/s72-c\/c5592c31-c7a3-480a-a99f-7af1f12437aa.png","height":"72","width":"72"},"thr$total":{"$t":"0"},"georss$featurename":{"$t":"Seattle, WA, USA"},"georss$point":{"$t":"47.6061389 -122.3328481"},"georss$box":{"$t":"19.295905063821152 -157.4890981 75.916372736178843 -87.1765981"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-6720892550572492297"},"published":{"$t":"2025-10-30T08:27:00.000-07:00"},"updated":{"$t":"2025-11-02T22:53:33.059-08:00"},"title":{"type":"text","$t":"Can GPT5 \/ Claude Sonet replace me and my team ?"},"content":{"type":"html","$t":"\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiyU4lfdaGf_e_QtEJwdo73KsC1RdNnLeugTDeEWUveWJfwtn9fFhk-QxdJfBQaUELLaFsVTXeS2iiGzPcsI8pQUPpxD_KxMQYFOrtNHl2x9eP3JRdndKNQGauxRoDD_a-M9UvdAYwSTCtr9pYvPN32ZIyIT_-fbOgBSFA6OFPgXdjTAF2H4tF3SmSZbew\/s1024\/IMG_0019.png\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"1024\" data-original-width=\"1024\" height=\"320\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiyU4lfdaGf_e_QtEJwdo73KsC1RdNnLeugTDeEWUveWJfwtn9fFhk-QxdJfBQaUELLaFsVTXeS2iiGzPcsI8pQUPpxD_KxMQYFOrtNHl2x9eP3JRdndKNQGauxRoDD_a-M9UvdAYwSTCtr9pYvPN32ZIyIT_-fbOgBSFA6OFPgXdjTAF2H4tF3SmSZbew\/s320\/IMG_0019.png\" width=\"320\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003ECan AI Agents replace my team including myself ?\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003ESeems to be the question on everyones mind lately. Well can they really ?. Let's find out shall we ?\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003ESpoiler alert, the answer is not a simple YES or NO.\u0026nbsp;\u003C\/div\u003E\u003Ch3 style=\"text-align: left;\"\u003EVibe Coding\u003C\/h3\u003E\u003Cdiv style=\"text-align: left;\"\u003ELets gets some things clarified. I'm not vibe coding here. I have strong opinions about the pitfalls of vibe coding in production systems. This is not the place to discuss that. I don't exactly know what to call this but to put things simply I'm using AI with well defined context to do this experiment.\u0026nbsp;\u003C\/div\u003E\u003Cdiv style=\"text-align: left;\"\u003E\u003Cdiv\u003E\u003Ch3 style=\"text-align: left;\"\u003ECredits\u003C\/h3\u003E\u003C\/div\u003E\u003Cdiv\u003EThis project is based on\u0026nbsp;\u003Ca href=\"https:\/\/www.linkedin.com\/in\/eddonner\/\" rel=\"nofollow\" target=\"_blank\"\u003EEd Donner's\u003C\/a\u003E\u0026nbsp;CrewAI project featured in\u0026nbsp;\u003Ca href=\"https:\/\/www.udemy.com\/course\/the-complete-agentic-ai-engineering-course\/?couponCode=MT251028G17\" rel=\"nofollow\" target=\"_blank\"\u003EThe Complete AI Engineering Course\u003C\/a\u003E, If you are interested in learning more you should check out the\u0026nbsp;\u003Ca href=\"https:\/\/www.udemy.com\/courses\/search\/?src=ukw\u0026amp;q=ed+donner\" rel=\"nofollow\" target=\"_blank\"\u003Elearning material\u003C\/a\u003E\u0026nbsp;by\u0026nbsp;\u003Ca href=\"https:\/\/www.linkedin.com\/in\/eddonner\/\" rel=\"nofollow\" target=\"_blank\"\u003EEd Donner\u003C\/a\u003E. I highly recommend them.\u0026nbsp;\u003C\/div\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: left;\"\u003E\u003Ch3\u003EThe Project\u003C\/h3\u003E\u003Cdiv\u003EIn order to test out this hypothesis I'm gonna use\u0026nbsp;\u003Ca href=\"https:\/\/www.crewai.com\/\" rel=\"nofollow\" target=\"_blank\"\u003ECrew AI\u0026nbsp;\u003C\/a\u003E. The title was a catchy one, the project however has a narrower context. I'm not trying to create an AI Engineering team to replace us humans, rather experimenting to see how we can use AI to boost our productivity.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EThe problem I have chosen, I believe is not too complex, not too simple. This will allow me to analyze the results easily and get a good baseline for further experimentation.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EThe task is to get a containerized solution up and running to a provided problem statement. Which is classified as an \"assignment\" in the below config. We'll go into details when analyzing the two different approaches.\u0026nbsp;\u003C\/div\u003E\u003Ch4 style=\"text-align: left;\"\u003E\n\n    Task Definitions\u003C\/h4\u003E\u003Cpre\u003E\u003Ccode\u003Edesign_task:\n  description: \u0026gt;\n    Create a solution determining what docker images can be used to solve the {assignment}\n    Follow docker and docker compose best practices\n    IMPORTANT: Output ONLY the raw markdown without any markdown formatting, code block delimiters, or backticks.\n    the current year is {current_year}.\n  expected_output: \u0026gt;\n    A docker compose file to do the {assignment}\n  agent: senior_engineer\n  output_file: output\/design.md\n\ncoding_task:\n  description: \u0026gt;\n    Create a docker compose file that implements the design described by senior_engineer, in order to achieve the requirements.\n    Here are the requirements: {assignment}\n    Follow docker and docker compose best practices\n    IMPORTANT: Output ONLY the raw docker compose code without any markdown formatting, code block delimiters, or backticks.\n    the current year is {current_year}.\n  expected_output: \u0026gt;\n    A docker compose file to do the {assignment}\n  agent: docker_engineer\n  context:\n    - design_task\n  output_file: output\/docker-compose.yml\n\ndocumentation_task:\n  description: \u0026gt;\n    Create a readme.md markdown file explaining the docker compose file and how to run it\n    IMPORTANT: Output ONLY the raw markdown code without any markdown formatting, code block delimiters, or backticks.\n    the current year is {current_year}.\n  expected_output: \u0026gt;\n    A readme.md file explaining the solution and how to run it\n  agent: docker_engineer\n  context:\n    - coding_task\n  output_file: output\/readme.md    \u003C\/code\u003E\u003C\/pre\u003E\n  \n\u003C\/div\u003E\u003Ch4 style=\"text-align: left;\"\u003EGive me the details, gimme, gimme\u003C\/h4\u003E\u003Cdiv style=\"text-align: left;\"\u003EI try two different approaches in this experiment. The first approach is to use a human senior engineer with an AI engineer to build the system. The human senior engineer is going to provide very prescriptive instructions for the AI engineer to complete the task in hand.\u0026nbsp;\u003C\/div\u003E\u003Cdiv style=\"text-align: left;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: left;\"\u003EIn the second approach we are going to use two different AI agents. One senior engineer which we will equip with design capabilities. We are gonna provide this agent with a problem statement with some guidelines. Then this senior AI agent is going to create the prescriptive instructions that will be used by the same AI engineer from the pervious\u0026nbsp; example to produce the code.\u0026nbsp;\u003C\/div\u003E\u003Ch4 style=\"text-align: left;\"\u003EModels Used\u003C\/h4\u003E\u003Cdiv style=\"text-align: left;\"\u003EI tried using different models to try out this concept\u003C\/div\u003E\u003Cdiv style=\"text-align: left;\"\u003E\u003Cul style=\"text-align: left;\"\u003E\u003Cli\u003EClaude Sonet 4 (claude-sonnet-4-20250514) by Anthropic\u003C\/li\u003E\u003Cli\u003Egpt-4.1 by OpenAI\u003C\/li\u003E\u003Cli\u003Egpt5 by OpenAI\u003C\/li\u003E\u003Cli\u003Edeepseek-chat by DeepSeek\u003C\/li\u003E\u003Cli\u003Ellama3.2 by Meta hosted with Ollama locally\u003C\/li\u003E\u003C\/ul\u003E\u003C\/div\u003E\u003Ch4 style=\"text-align: left;\"\u003EHuman Senior Engineer with an AI Engineering team\u003C\/h4\u003E\u003Cdiv style=\"text-align: left;\"\u003EIn the first approach we have a human senior engineer providing the detailed instructions to the AI engineering team. The senior engineer is going to provide a very prescriptive task for the AI engineers\u003C\/div\u003E\u003Cpre\u003E\u003Ccode\u003Eassignment = f\"\"\"Created a self hosted nextcloud instance. Use the docker hub image nextcloud:31.0.8-apache\nuse mariadb:10.11 as the database \nuse redis:alpine3.22 with nextcloud\ncreate separate containers for nextcloud and cron jobs\nUse jc21\/nginx-proxy-manager:latest as a reverse proxy to expose the nextcloud instance to the internet\n# \"\"\"\n\u003C\/code\u003E\u003C\/pre\u003E\n\u003Ch4 style=\"text-align: left;\"\u003EAI Senior Engineer with an AI Engineering Team\u003C\/h4\u003E\u003Cdiv style=\"text-align: left;\"\u003EIn the second approach the senior engineer is also replaced by an AI Agent. We provide the problem statement to the AI Senior Engineering Agent. This agent in turn is gonna provide a prescriptive task for the crew to generate the output\u003C\/div\u003E\u003Cpre\u003E\u003Ccode\u003Eassignment = f\"\"\"Created a self hosted nextcloud instance. \nThink about separation of concerns, maintainability and other software development best practices\nThe instance needs to be exposed to the internet\nThe same server that is going to host the nextcloud instance also has some simple websites exposed to the internet\nThe nextcloud instance and the other websites need their own ssl certificates \nThe server hosting all these is behind a pfsense firewall\n\"\"\"\n\u003C\/code\u003E\u003C\/pre\u003E\u003Ch4 style=\"text-align: left;\"\u003EAgent Definitions\u003C\/h4\u003E\u003Cpre\u003E\u003Ccode\u003Esenior_engineer:\n  role: \u0026gt;\n    Engineer with extensive knowledge about software development practices including web based security vulnerabilities\n  goal: \u0026gt;\n    Provide solutions for complex software problems\n  backstory: \u0026gt;\n    You're a tenured engineer with extensive knowledge about software engineering\n    You are able to create software designs that can guide other engineers in creating solutions\n  llm: anthropic\/claude-sonnet-4-20250514\n\ndocker_engineer:\n  role: \u0026gt;\n    Engineer with extensive knowledge about docker and docker compose\n  goal: \u0026gt;\n    Generate docker compose files with explanations\n  backstory: \u0026gt;\n    You're a tenured engineer with extensive knowledge about docker and docker compose. \n    You are able to create working docker compose files following best practices to fulfill the given requirements.\n  llm: anthropic\/claude-sonnet-4-20250514\u003C\/code\u003E\u003C\/pre\u003E\u003Ch3 style=\"text-align: left;\"\u003EOutput and Conclusions\u003C\/h3\u003E\u003Cdiv style=\"text-align: left;\"\u003ETo be honest this exercise is too narrow and simplistic to come to a concrete conclusion. It does show some good data points though. (Full outputs in appendix)\u003C\/div\u003E\u003Cdiv style=\"text-align: left;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: left;\"\u003EWhen it comes to agents I was not able to produce good results with deepseek-chat or llama3.2. Only the frontier models were able to provide good enough data points in this project.\u0026nbsp;\u003C\/div\u003E\u003Cdiv style=\"text-align: left;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: left;\"\u003EThe first approach created a good simple working solution sticking with the provided guidelines. The second approach created a novel solution which could be classified as overkill. Though on second thought narrowing down the requirements to specify the host environment would have generated better results.\u0026nbsp;\u003C\/div\u003E\u003Ch4 style=\"text-align: left;\"\u003ESome interesting observations include,\u0026nbsp;\u003C\/h4\u003E\u003Cdiv\u003EWhen acting as the Senior Engineer GPT 4.1 choose to use NGINX as the proxy where as GPT5 choose to use Traefik. According to Gemini, Traefik is more suitable for dynamic environments like Docker and Kubernetes. For the simple task definition NGINX would have been acceptable but I can't argue with using Traefik either. The problem statement didn't have enough information about the future extensibility or the available resourcing to lean towards one vs the other.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EAs the senior engineer GPT5 choose to use Postgress for the database where GPT 4.1 used MariaDB. The decision between these 2 also is a hard one. If you are curious\u0026nbsp;\u003Ca href=\"https:\/\/share.google\/aimode\/V2y8KJuXSQmluMyeI\" rel=\"nofollow\" target=\"_blank\"\u003Eread more here\u003C\/a\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EIn my opinion, both these decision differences indicate GPT5 chose the more modern options than GPT 4.1 in this particular problem. It could simply be due to the training data.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EClaude Sonet 4 failed to act as the senior engineer for my project. It kept giving me \"{type:error,error:{type:overloaded_error,message:Overloaded},request_id:null}\". I see this error often when I try to do tasks needing more tokens. This I believe is due to the basic plan I'm paying for, not due to the capabilities of the Model.\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EDeepSeek-Chat hallucinated and returned a template project. Llama 3.2 failed as well. Indicating I'm trying to do too much with them.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EWhen working with a human senior engineer the results were very similar across all frontier models.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003ECheck out the appendix section for detailed outputs.\u0026nbsp;\u003C\/div\u003E\u003Ch4 style=\"text-align: left;\"\u003EConclusion\u003C\/h4\u003E\u003Cdiv\u003EWell, AI has been a force multiplier when it comes to increasing my productivity. I'm not sold on the fact that AI will be able to completely replace us, however it sure is allowing us to do more with less. How that will pan out, only time will tell.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EI'm excited for the future. What mistakes we will create vibe coding, what we will learn from those mistakes. Potential innovations we will see with responsible AI usage.... etc... etc...\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Ch3 style=\"text-align: left;\"\u003EAppendix\u0026nbsp;\u003C\/h3\u003E\n\u003Ch4 style=\"text-align: left;\"\u003EGPT 4.1 output (ai senior engineer)\u003C\/h4\u003E\n\u003Cpre\u003E\u003Ccode\u003E\nversion: \"3.9\"\n\nservices:\n  nginx-proxy-manager:\n    image: jc21\/nginx-proxy-manager:2.11.2\n    container_name: nginx-proxy-manager\n    restart: unless-stopped\n    ports:\n      - \"80:80\"\n      - \"443:443\"\n      - \"81:81\"\n    volumes:\n      - npm_data:\/data\n      - npm_letsencrypt:\/etc\/letsencrypt\n    environment:\n      - TZ=UTC\n    networks:\n      - frontend\n\n  db:\n    image: mariadb:11\n    container_name: nextcloud-db\n    restart: unless-stopped\n    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW\n    environment:\n      - MYSQL_ROOT_PASSWORD=secure_root_password\n      - MYSQL_DATABASE=nextcloud\n      - MYSQL_USER=nextcloud\n      - MYSQL_PASSWORD=secure_nextcloud_password\n    volumes:\n      - db_data:\/var\/lib\/mysql\n    networks:\n      - backend\n\n  nextcloud:\n    image: nextcloud:28\n    container_name: nextcloud-app\n    restart: unless-stopped\n    expose:\n      - \"80\"\n    environment:\n      - MYSQL_PASSWORD=secure_nextcloud_password\n      - MYSQL_DATABASE=nextcloud\n      - MYSQL_USER=nextcloud\n      - MYSQL_HOST=db\n    volumes:\n      - nextcloud_data:\/var\/www\/html\n    depends_on:\n      - db\n    networks:\n      - frontend\n      - backend\n\n  web1:\n    image: nginx:1.25\n    container_name: simple-web1\n    restart: unless-stopped\n    volumes:\n      - .\/web1\/html:\/usr\/share\/nginx\/html:ro\n      - .\/web1\/nginx.conf:\/etc\/nginx\/nginx.conf:ro\n    expose:\n      - \"80\"\n    networks:\n      - frontend\n\n  web2:\n    image: nginx:1.25\n    container_name: simple-web2\n    restart: unless-stopped\n    volumes:\n      - .\/web2\/html:\/usr\/share\/nginx\/html:ro\n      - .\/web2\/nginx.conf:\/etc\/nginx\/nginx.conf:ro\n    expose:\n      - \"80\"\n    networks:\n      - frontend\n\nvolumes:\n  npm_data:\n  npm_letsencrypt:\n  db_data:\n  nextcloud_data:\n\nnetworks:\n  frontend:\n    driver: bridge\n  backend:\n    driver: bridge\n\u003C\/code\u003E\u003C\/pre\u003E\n\u003Ch4 style=\"text-align: left;\"\u003EGPT 5 output (ai senior engineer)\u003C\/h4\u003E\n\u003Cpre\u003E\u003Ccode\u003E\nname: selfhosted-apps\n\n# Compose Specification (no version field needed in modern Compose)\n# Requirements before use:\n# - Create a .env file with:\n#     TRAEFIK_ACME_EMAIL=you@example.com\n#     NEXTCLOUD_DOMAIN=cloud.example.com\n#     SITE1_DOMAIN=site1.example.com\n#     SITE2_DOMAIN=site2.example.com\n# - Create secrets\/nextcloud_db_password.txt with a strong DB password\n# - On pfSense: port-forward TCP 80 and 443 to this Docker host\n# - Ensure DNS A\/AAAA records for all domains point to your public IP\n\nservices:\n  # Reverse proxy and TLS termination with automatic per-domain certificates\n  traefik:\n    image: traefik:v3.1\n    command:\n      - --providers.docker=true\n      - --providers.docker.endpoint=tcp:\/\/docker-socket-proxy:2375\n      - --providers.docker.exposedbydefault=false\n      - --providers.docker.network=proxy\n      - --entrypoints.web.address=:80\n      - --entrypoints.web.http.redirections.entryPoint.to=websecure\n      - --entrypoints.web.http.redirections.entryPoint.scheme=https\n      - --entrypoints.websecure.address=:443\n      - --certificatesresolvers.letsencrypt.acme.email=${TRAEFIK_ACME_EMAIL}\n      - --certificatesresolvers.letsencrypt.acme.storage=\/letsencrypt\/acme.json\n      - --certificatesresolvers.letsencrypt.acme.httpchallenge=true\n      - --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web\n      - --log.level=INFO\n      - --accesslog=true\n    ports:\n      - 80:80\n      - 443:443\n    volumes:\n      - traefik_letsencrypt:\/letsencrypt\n    networks:\n      - proxy\n      - dockerproxy\n    depends_on:\n      - docker-socket-proxy\n    # Run as non-root with capability to bind low ports\n    user: \"65532:65532\"\n    cap_add:\n      - NET_BIND_SERVICE\n    security_opt:\n      - no-new-privileges:true\n    restart: unless-stopped\n    labels:\n      - traefik.enable=true\n      # Shared middlewares for security and compression\n      - traefik.http.middlewares.secure-headers.headers.stsSeconds=31536000\n      - traefik.http.middlewares.secure-headers.headers.stsIncludeSubdomains=true\n      - traefik.http.middlewares.secure-headers.headers.stsPreload=true\n      - traefik.http.middlewares.secure-headers.headers.referrerPolicy=no-referrer\n      - traefik.http.middlewares.secure-headers.headers.browserXssFilter=true\n      - traefik.http.middlewares.secure-headers.headers.contentTypeNosniff=true\n      - traefik.http.middlewares.compress.compress=true\n\n  # Safer Docker socket access for Traefik (principle of least privilege)\n  docker-socket-proxy:\n    image: tecnativa\/docker-socket-proxy:latest\n    environment:\n      - CONTAINERS=1\n      - SERVICES=1\n      - TASKS=1\n      - NETWORKS=1\n      - NODES=1\n      - INFO=1\n      - PING=1\n      - VERSION=1\n      - EVENTS=1\n    volumes:\n      - \/var\/run\/docker.sock:\/var\/run\/docker.sock:ro\n    expose:\n      - \"2375\"\n    networks:\n      - dockerproxy\n    read_only: true\n    security_opt:\n      - no-new-privileges:true\n    restart: unless-stopped\n\n  # Nextcloud application (Apache variant)\n  nextcloud:\n    image: nextcloud:29-apache # pin to a stable major\/minor; update intentionally\n    depends_on:\n      db:\n        condition: service_healthy\n      redis:\n        condition: service_started\n    environment:\n      - POSTGRES_HOST=db\n      - POSTGRES_DB=nextcloud\n      - POSTGRES_USER=nextcloud\n      - POSTGRES_PASSWORD_FILE=\/run\/secrets\/nextcloud_db_password\n      - REDIS_HOST=redis\n      - NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_DOMAIN}\n      - TRUSTED_PROXIES=traefik\n      - OVERWRITEPROTOCOL=https\n      - PHP_MEMORY_LIMIT=1024M\n      - PHP_UPLOAD_LIMIT=2048M\n    volumes:\n      # granular persistence for clean upgrades\n      - nextcloud_data:\/var\/www\/html\/data\n      - nextcloud_config:\/var\/www\/html\/config\n      - nextcloud_custom_apps:\/var\/www\/html\/custom_apps\n      - nextcloud_themes:\/var\/www\/html\/themes\n    labels:\n      - traefik.enable=true\n      - traefik.http.routers.nextcloud.rule=Host(`${NEXTCLOUD_DOMAIN}`)\n      - traefik.http.routers.nextcloud.entrypoints=websecure\n      - traefik.http.routers.nextcloud.tls.certresolver=letsencrypt\n      - traefik.http.services.nextcloud.loadbalancer.server.port=80\n      - traefik.http.routers.nextcloud.middlewares=secure-headers@docker,nextcloud-buffering\n      # Allow large uploads and streaming\n      - traefik.http.middlewares.nextcloud-buffering.buffering.maxRequestBodyBytes=0\n      - traefik.http.middlewares.nextcloud-buffering.buffering.memRequestBodyBytes=8388608\n      - traefik.http.middlewares.nextcloud-buffering.buffering.maxResponseBodyBytes=0\n    networks:\n      - proxy\n      - nextcloud\n    secrets:\n      - nextcloud_db_password\n    healthcheck:\n      test: [\"CMD-SHELL\", \"curl -fsS http:\/\/localhost\/status.php || exit 1\"]\n      interval: 30s\n      timeout: 10s\n      retries: 10\n    restart: unless-stopped\n\n  # Nextcloud cron (runs background jobs every 5 minutes)\n  nextcloud-cron:\n    image: nextcloud:29-apache\n    entrypoint: \/cron.sh\n    depends_on:\n      - nextcloud\n    volumes:\n      - nextcloud_data:\/var\/www\/html\/data\n      - nextcloud_config:\/var\/www\/html\/config\n      - nextcloud_custom_apps:\/var\/www\/html\/custom_apps\n      - nextcloud_themes:\/var\/www\/html\/themes\n    networks:\n      - nextcloud\n    restart: unless-stopped\n\n  # PostgreSQL database for Nextcloud\n  db:\n    image: postgres:16-alpine\n    environment:\n      - POSTGRES_DB=nextcloud\n      - POSTGRES_USER=nextcloud\n      - POSTGRES_PASSWORD_FILE=\/run\/secrets\/nextcloud_db_password\n    secrets:\n      - nextcloud_db_password\n    volumes:\n      - db_data:\/var\/lib\/postgresql\/data\n    networks:\n      - nextcloud\n    healthcheck:\n      test: [\"CMD-SHELL\", \"pg_isready -U nextcloud -d nextcloud || exit 1\"]\n      interval: 10s\n      timeout: 5s\n      retries: 10\n    restart: unless-stopped\n\n  # Redis for file locking and caching\n  redis:\n    image: redis:7-alpine\n    command: [\"redis-server\", \"--appendonly\", \"yes\"]\n    volumes:\n      - redis_data:\/data\n    networks:\n      - nextcloud\n    healthcheck:\n      test: [\"CMD-SHELL\", \"redis-cli ping | grep -q PONG\"]\n      interval: 10s\n      timeout: 5s\n      retries: 10\n    restart: unless-stopped\n\n  # Example simple website 1 (static content)\n  site1:\n    image: nginx:1.27-alpine\n    volumes:\n      - .\/sites\/site1:\/usr\/share\/nginx\/html:ro\n    labels:\n      - traefik.enable=true\n      - traefik.http.routers.site1.rule=Host(`${SITE1_DOMAIN}`)\n      - traefik.http.routers.site1.entrypoints=websecure\n      - traefik.http.routers.site1.tls.certresolver=letsencrypt\n      - traefik.http.services.site1.loadbalancer.server.port=80\n      - traefik.http.routers.site1.middlewares=secure-headers@docker,compress@docker\n    networks:\n      - proxy\n    read_only: true\n    tmpfs:\n      - \/var\/cache\/nginx\n      - \/var\/run\n    restart: unless-stopped\n\n  # Example simple website 2 (static content)\n  site2:\n    image: nginx:1.27-alpine\n    volumes:\n      - .\/sites\/site2:\/usr\/share\/nginx\/html:ro\n    labels:\n      - traefik.enable=true\n      - traefik.http.routers.site2.rule=Host(`${SITE2_DOMAIN}`)\n      - traefik.http.routers.site2.entrypoints=websecure\n      - traefik.http.routers.site2.tls.certresolver=letsencrypt\n      - traefik.http.services.site2.loadbalancer.server.port=80\n      - traefik.http.routers.site2.middlewares=secure-headers@docker,compress@docker\n    networks:\n      - proxy\n    read_only: true\n    tmpfs:\n      - \/var\/cache\/nginx\n      - \/var\/run\n    restart: unless-stopped\n\nsecrets:\n  nextcloud_db_password:\n    file: .\/secrets\/nextcloud_db_password.txt\n\nvolumes:\n  traefik_letsencrypt:\n  nextcloud_data:\n  nextcloud_config:\n  nextcloud_custom_apps:\n  nextcloud_themes:\n  db_data:\n  redis_data:\n\nnetworks:\n  proxy:\n    driver: bridge\n  nextcloud:\n    driver: bridge\n  dockerproxy:\n    driver: bridge\n\u003C\/code\u003E\u003C\/pre\u003E\n\u003Ch4 style=\"text-align: left;\"\u003EClaude Sonet 4 (human senior engineer)\u003C\/h4\u003E\n\u003Cpre\u003E\u003Ccode\u003E\nversion: '3.8'\n\nservices:\n  # Database service\n  db:\n    image: mariadb:10.11\n    container_name: nextcloud_db\n    restart: unless-stopped\n    environment:\n      - MYSQL_ROOT_PASSWORD=nextcloud_root_password\n      - MYSQL_DATABASE=nextcloud\n      - MYSQL_USER=nextcloud\n      - MYSQL_PASSWORD=nextcloud_password\n      - MARIADB_AUTO_UPGRADE=1\n      - MARIADB_DISABLE_UPGRADE_BACKUP=1\n    volumes:\n      - db_data:\/var\/lib\/mysql\n    networks:\n      - nextcloud_network\n    command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW\n    healthcheck:\n      test: [\"CMD\", \"healthcheck.sh\", \"--connect\", \"--innodb_initialized\"]\n      start_period: 1m\n      start_interval: 10s\n      interval: 1m\n      timeout: 5s\n      retries: 3\n\n  # Redis cache service\n  redis:\n    image: redis:alpine3.22\n    container_name: nextcloud_redis\n    restart: unless-stopped\n    networks:\n      - nextcloud_network\n    command: redis-server --requirepass redis_password\n    healthcheck:\n      test: [\"CMD\", \"redis-cli\", \"--raw\", \"incr\", \"ping\"]\n      interval: 30s\n      timeout: 3s\n      retries: 3\n      start_period: 30s\n\n  # Nextcloud application\n  nextcloud:\n    image: nextcloud:31.0.8-apache\n    container_name: nextcloud_app\n    restart: unless-stopped\n    depends_on:\n      db:\n        condition: service_healthy\n      redis:\n        condition: service_healthy\n    environment:\n      - MYSQL_HOST=db\n      - MYSQL_DATABASE=nextcloud\n      - MYSQL_USER=nextcloud\n      - MYSQL_PASSWORD=nextcloud_password\n      - REDIS_HOST=redis\n      - REDIS_HOST_PASSWORD=redis_password\n      - NEXTCLOUD_ADMIN_USER=admin\n      - NEXTCLOUD_ADMIN_PASSWORD=admin_password\n      - TRUSTED_PROXIES=nginx-proxy-manager\n      - OVERWRITEPROTOCOL=https\n      - OVERWRITECLIURL=https:\/\/your-domain.com\n      - APACHE_DISABLE_REWRITE_IP=1\n    volumes:\n      - nextcloud_data:\/var\/www\/html\n      - nextcloud_custom_apps:\/var\/www\/html\/custom_apps\n      - nextcloud_config:\/var\/www\/html\/config\n      - nextcloud_themes:\/var\/www\/html\/themes\n    networks:\n      - nextcloud_network\n      - proxy_network\n    healthcheck:\n      test: [\"CMD\", \"curl\", \"-f\", \"http:\/\/localhost\/status.php\"]\n      interval: 30s\n      timeout: 10s\n      retries: 3\n      start_period: 60s\n\n  # Nextcloud cron service\n  nextcloud_cron:\n    image: nextcloud:31.0.8-apache\n    container_name: nextcloud_cron\n    restart: unless-stopped\n    depends_on:\n      - nextcloud\n    environment:\n      - MYSQL_HOST=db\n      - MYSQL_DATABASE=nextcloud\n      - MYSQL_USER=nextcloud\n      - MYSQL_PASSWORD=nextcloud_password\n      - REDIS_HOST=redis\n      - REDIS_HOST_PASSWORD=redis_password\n    volumes:\n      - nextcloud_data:\/var\/www\/html\n      - nextcloud_custom_apps:\/var\/www\/html\/custom_apps\n      - nextcloud_config:\/var\/www\/html\/config\n      - nextcloud_themes:\/var\/www\/html\/themes\n    networks:\n      - nextcloud_network\n    entrypoint: \/cron.sh\n    user: www-data\n\n  # Nginx Proxy Manager\n  nginx-proxy-manager:\n    image: jc21\/nginx-proxy-manager:latest\n    container_name: nginx_proxy_manager\n    restart: unless-stopped\n    ports:\n      - \"80:80\"\n      - \"443:443\"\n      - \"81:81\"\n    environment:\n      - DB_SQLITE_FILE=\/data\/database.sqlite\n    volumes:\n      - npm_data:\/data\n      - npm_letsencrypt:\/etc\/letsencrypt\n    networks:\n      - proxy_network\n    healthcheck:\n      test: [\"CMD\", \"wget\", \"--no-verbose\", \"--tries=1\", \"--spider\", \"http:\/\/localhost:81\"]\n      interval: 30s\n      timeout: 10s\n      retries: 3\n      start_period: 60s\n\nvolumes:\n  db_data:\n    driver: local\n  nextcloud_data:\n    driver: local\n  nextcloud_custom_apps:\n    driver: local\n  nextcloud_config:\n    driver: local\n  nextcloud_themes:\n    driver: local\n  npm_data:\n    driver: local\n  npm_letsencrypt:\n    driver: local\n\nnetworks:\n  nextcloud_network:\n    driver: bridge\n    internal: true\n  proxy_network:\n    driver: bridge\n\u003C\/code\u003E\u003C\/pre\u003E\n\u003Ch4\u003EGPT 4.1 output (human senior engineer)\u003C\/h4\u003E\n\u003Cpre\u003E\u003Ccode\u003E\nversion: \"3.9\"\n\nservices:\n  nextcloud:\n    image: nextcloud:31.0.8-apache\n    restart: unless-stopped\n    depends_on:\n      - db\n      - redis\n    environment:\n      - MYSQL_HOST=db\n      - MYSQL_DATABASE=nextcloud\n      - MYSQL_USER=nextcloud\n      - MYSQL_PASSWORD=nextcloud_db_password\n      - REDIS_HOST=redis\n      - REDIS_HOST_PASSWORD=redis_password\n      - NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.example.com\n    volumes:\n      - nextcloud_data:\/var\/www\/html\n    networks:\n      - nextcloud_network\n\n  nextcloud-cron:\n    image: nextcloud:31.0.8-apache\n    restart: unless-stopped\n    entrypoint: \"\/cron.sh\"\n    depends_on:\n      - db\n      - redis\n    environment:\n      - MYSQL_HOST=db\n      - MYSQL_DATABASE=nextcloud\n      - MYSQL_USER=nextcloud\n      - MYSQL_PASSWORD=nextcloud_db_password\n      - REDIS_HOST=redis\n      - REDIS_HOST_PASSWORD=redis_password\n    volumes:\n      - nextcloud_data:\/var\/www\/html\n    networks:\n      - nextcloud_network\n\n  db:\n    image: mariadb:10.11\n    restart: unless-stopped\n    environment:\n      - MYSQL_ROOT_PASSWORD=strong_root_password\n      - MYSQL_DATABASE=nextcloud\n      - MYSQL_USER=nextcloud\n      - MYSQL_PASSWORD=nextcloud_db_password\n    volumes:\n      - nextcloud_db:\/var\/lib\/mysql\n    networks:\n      - nextcloud_network\n\n  redis:\n    image: redis:alpine3.22\n    restart: unless-stopped\n    command: [\"redis-server\", \"--requirepass\", \"redis_password\"]\n    volumes:\n      - nextcloud_redis:\/data\n    networks:\n      - nextcloud_network\n\n  nginx-proxy-manager:\n    image: jc21\/nginx-proxy-manager:latest\n    restart: unless-stopped\n    ports:\n      - \"80:80\"\n      - \"81:81\"\n      - \"443:443\"\n    volumes:\n      - npm_data:\/data\n      - npm_letsencrypt:\/etc\/letsencrypt\n    networks:\n      - nextcloud_network\n\nvolumes:\n  nextcloud_data:\n  nextcloud_db:\n  nextcloud_redis:\n  npm_data:\n  npm_letsencrypt:\n\nnetworks:\n  nextcloud_network:\n    driver: bridge\n\u003C\/code\u003E\u003C\/pre\u003E\n\u003Ch4 style=\"text-align: left;\"\u003EGPT 5 output (human senior engineer)\u003C\/h4\u003E\n\u003Cpre\u003E\u003Ccode\u003E\nname: nextcloud-stack\nservices:\n  db:\n    image: mariadb:10.11\n    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW --innodb-file-per-table=1 --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci\n    restart: unless-stopped\n    environment:\n      - MARIADB_DATABASE=nextcloud\n      - MARIADB_USER=nextcloud\n      - MARIADB_ROOT_PASSWORD_FILE=\/run\/secrets\/db_root_password\n      - MARIADB_PASSWORD_FILE=\/run\/secrets\/db_password\n    volumes:\n      - db_data:\/var\/lib\/mysql\n    secrets:\n      - db_root_password\n      - db_password\n    healthcheck:\n      test: [\"CMD-SHELL\", \"mysqladmin ping -h 127.0.0.1 -u root -p$(cat \/run\/secrets\/db_root_password) || exit 1\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n    networks:\n      - backend\n    logging:\n      driver: json-file\n      options:\n        max-size: \"10m\"\n        max-file: \"3\"\n\n  redis:\n    image: redis:alpine3.22\n    restart: unless-stopped\n    command: [\"redis-server\", \"--save\", \"\", \"--appendonly\", \"no\"]\n    healthcheck:\n      test: [\"CMD\", \"redis-cli\", \"ping\"]\n      interval: 10s\n      timeout: 3s\n      retries: 5\n    networks:\n      - backend\n    logging:\n      driver: json-file\n      options:\n        max-size: \"10m\"\n        max-file: \"3\"\n\n  app:\n    image: nextcloud:31.0.8-apache\n    restart: unless-stopped\n    depends_on:\n      db:\n        condition: service_healthy\n      redis:\n        condition: service_healthy\n    environment:\n      - MYSQL_HOST=db\n      - MYSQL_DATABASE=nextcloud\n      - MYSQL_USER=nextcloud\n      - MYSQL_PASSWORD_FILE=\/run\/secrets\/db_password\n      - REDIS_HOST=redis\n      - OVERWRITEPROTOCOL=https\n      - APACHE_DISABLE_REWRITE_IP=1\n    volumes:\n      - nextcloud:\/var\/www\/html\n    secrets:\n      - db_password\n    networks:\n      - backend\n      - frontend\n    healthcheck:\n      test: [\"CMD-SHELL\", \"php -r \\\"exit((int)!@fopen('http:\/\/127.0.0.1\/status.php', 'r'));\\\"\"]\n      interval: 30s\n      timeout: 10s\n      retries: 10\n    logging:\n      driver: json-file\n      options:\n        max-size: \"10m\"\n        max-file: \"3\"\n\n  cron:\n    image: nextcloud:31.0.8-apache\n    restart: unless-stopped\n    depends_on:\n      app:\n        condition: service_started\n    entrypoint: \/cron.sh\n    volumes:\n      - nextcloud:\/var\/www\/html\n    networks:\n      - backend\n    logging:\n      driver: json-file\n      options:\n        max-size: \"10m\"\n        max-file: \"3\"\n\n  npm:\n    image: jc21\/nginx-proxy-manager:latest\n    restart: unless-stopped\n    ports:\n      - \"80:80\"\n      - \"81:81\"\n      - \"443:443\"\n    volumes:\n      - npm_data:\/data\n      - npm_letsencrypt:\/etc\/letsencrypt\n    networks:\n      - frontend\n    logging:\n      driver: json-file\n      options:\n        max-size: \"10m\"\n        max-file: \"3\"\n\nvolumes:\n  nextcloud:\n  db_data:\n  npm_data:\n  npm_letsencrypt:\n\nsecrets:\n  db_root_password:\n    file: .\/secrets\/db_root_password.txt\n  db_password:\n    file: .\/secrets\/db_password.txt\n\nnetworks:\n  frontend:\n    driver: bridge\n  backend:\n    driver: bridge\n    internal: true\n\u003C\/code\u003E\u003C\/pre\u003E\n\u003Cdiv style=\"text-align: left;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: left;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: left;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: left;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: left;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: left;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: left;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: left;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: left;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: left;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: left;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003C\/div\u003E\n\n"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/6720892550572492297\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2025\/10\/can-gpt5-claude-sonet-4-replace-me-and.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/6720892550572492297"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/6720892550572492297"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2025\/10\/can-gpt5-claude-sonet-4-replace-me-and.html","title":"Can GPT5 \/ Claude Sonet replace me and my team ?"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiyU4lfdaGf_e_QtEJwdo73KsC1RdNnLeugTDeEWUveWJfwtn9fFhk-QxdJfBQaUELLaFsVTXeS2iiGzPcsI8pQUPpxD_KxMQYFOrtNHl2x9eP3JRdndKNQGauxRoDD_a-M9UvdAYwSTCtr9pYvPN32ZIyIT_-fbOgBSFA6OFPgXdjTAF2H4tF3SmSZbew\/s72-c\/IMG_0019.png","height":"72","width":"72"},"thr$total":{"$t":"0"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-6635671021202968763"},"published":{"$t":"2025-01-28T16:51:00.000-08:00"},"updated":{"$t":"2025-01-28T16:51:36.317-08:00"},"category":[{"scheme":"http://www.blogger.com/atom/ns#","term":"Backup"}],"title":{"type":"text","$t":"Backups \u0026 Snapshots"},"content":{"type":"html","$t":"\u003Cbr \/\u003E\u003Cp style=\"clear: both; text-align: left;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiktqDG5QJ4kesGRFawvehjon0jGr6Gf3Gj4sQfsuXIV1JeaTMLyoRraY5UTSUV3xgHCxWonZYS9pLHWqoCVzd_7SDi2OjczHjsUuzuKlnzqEY4-ASPnqIIxzd3O6Jt97Vb5qqnIfzlMq225uksXNz4leN1B8S8EQDx4_-PojrRxwl9ZaaTW99Z7dzb6jA\/s2048\/Gemini_Generated_Image_4rraly4rraly4rra%20(1).jpeg\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"2048\" data-original-width=\"2048\" height=\"200\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiktqDG5QJ4kesGRFawvehjon0jGr6Gf3Gj4sQfsuXIV1JeaTMLyoRraY5UTSUV3xgHCxWonZYS9pLHWqoCVzd_7SDi2OjczHjsUuzuKlnzqEY4-ASPnqIIxzd3O6Jt97Vb5qqnIfzlMq225uksXNz4leN1B8S8EQDx4_-PojrRxwl9ZaaTW99Z7dzb6jA\/w200-h200\/Gemini_Generated_Image_4rraly4rraly4rra%20(1).jpeg\" width=\"200\" \/\u003E\u003C\/a\u003E\u003C\/p\u003E\u003Cp style=\"text-align: justify;\"\u003EWhat if you loose all your photos, yes every single one of your photos in your phone, laptop, usb drive. Even worse imagine loosing every single bit of your digital data. What if you had to start from a fresh laptop, mobile phone. That's a pretty close explanation of what I had to go through in 2010.\u0026nbsp;\u003C\/p\u003E\u003Ch2 style=\"text-align: justify;\"\u003EOverview\u003C\/h2\u003E\u003Cp style=\"text-align: justify;\"\u003E\u0026nbsp;A few years ago, around 2010 to be exact I lost all my data due to a hard drive failure. I was able to recover some of it but to this day regret the incident. I was keeping all my data. on a single usb hard drive. I should have known better. Hindsight is 2020. Once bitten, twice shy, I have rotated between various complex, high maintenance solutions to the current compromise. In this article I will explain how I do this at present day.\u0026nbsp;\u003C\/p\u003E\u003Ch2 style=\"text-align: justify;\"\u003EBackups vs Snapshots\u003C\/h2\u003E\u003Cp style=\"text-align: justify;\"\u003EFirst lets talk about snapshots. Having backups is good but what if you need to recover a photo you deleted 2 weeks ago. What if you wanted to recover a version of a file you changed 2 days ago. This is where snapshots comes into play. The key is to find the right balance between snapshot cadence vs retention.\u003C\/p\u003E\u003Cp style=\"text-align: justify;\"\u003EI use\u0026nbsp;\u003Ca href=\"https:\/\/rsnapshot.org\/\" target=\"_blank\"\u003Ersnapshot\u003C\/a\u003E\u0026nbsp;to achieve this. It's available for most linux distributions. The one I use is\u0026nbsp;\u003Ca href=\"https:\/\/wiki.archlinux.org\/title\/Rsnapshot\" target=\"_blank\"\u003Ersnapshot for Arch\u003C\/a\u003E. The idea is to have a config for different snapshots. I have one for daily, weekly and monthly snapshots. Then choosing the right execution mechanism.\u0026nbsp;\u0026nbsp;\u003C\/p\u003E\u003Cp style=\"text-align: justify;\"\u003E\u003C\/p\u003E\u003Cul\u003E\u003Cli\u003EDaily snapshots kept for 7 days\u003C\/li\u003E\u003Cli\u003EWeekly snapshots kept for 5 weeks\u003C\/li\u003E\u003Cli\u003EMonthly shapshots kept for 12 months\u003C\/li\u003E\u003C\/ul\u003E\u003Ch2 style=\"text-align: left;\"\u003ESpace \/ Disk Capacity\u003C\/h2\u003E\u003Cdiv\u003EHaving many snapshots doesn't mean you are gonna have many duplicate copies of data. For example, having 7 daily snapshots doesn't mean you will have 7 copies of the same data.\u0026nbsp;\u003Ca href=\"https:\/\/rsnapshot.org\/\" style=\"text-align: justify;\" target=\"_blank\"\u003Ersnapshot\u003C\/a\u003E\u0026nbsp;is based on\u0026nbsp;\u003Ca href=\"https:\/\/en.wikipedia.org\/wiki\/Rsync\" target=\"_blank\"\u003Ersync\u003C\/a\u003E. It it only stores one full copy and then the deltas needed to generate the rest. If nothing changed the same source will be symlinked into all snapshots. This means the space usage is going to depend on the variation.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003ELets assume you only changed one file in your backup target within the last 7 days. This means the 7 days snapshots will have only 1 duplicate file. Thus this is relatively cheap on storage.\u0026nbsp;\u003C\/div\u003E\u003Ch2 style=\"text-align: left;\"\u003ESnapshot Executions\u003C\/h2\u003E\u003Cdiv\u003EI use a\u0026nbsp;\u003Ca href=\"https:\/\/systemd.io\/\" target=\"_blank\"\u003Esystemd\u003C\/a\u003E\u0026nbsp;based timer and a \u003Ca href=\"https:\/\/man.archlinux.org\/man\/systemd.service.5.en\" target=\"_blank\"\u003Eservice\u003C\/a\u003E to fire the snapshots. You can achieve the same using\u0026nbsp;\u003Ca href=\"https:\/\/en.wikipedia.org\/wiki\/Cron\" target=\"_blank\"\u003Ecron\u003C\/a\u003E\u0026nbsp;if thats your preference. I will post some examples towards the bottom.\u0026nbsp;\u003C\/div\u003E\u003Ch2 style=\"text-align: left;\"\u003EBackups\u0026nbsp;\u003C\/h2\u003E\u003Cdiv\u003EMy data lives on a nvme ssd attached to one of my servers. The snapshots live in a NAS drive. This does give some redundancy. To prepare for hardware failures I have another layer of protections. I keep a rsync based backup of the snapshots on 2 external usb ssd drives. One of those USB drives are stored outside of my home. Syncs on the hard drive kept away from my residence are only done a few times per annum. It still provides a reasonable redundant solution. It's all about the compromises ...\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003ELets get into some tech details now.\u003C\/div\u003E\u003Ch2 style=\"text-align: left;\"\u003ETechnical Details\u003C\/h2\u003E\u003Cdiv\u003EI'm not gonna talk about setting up\u0026nbsp;\u003Ca href=\"https:\/\/en.wikipedia.org\/wiki\/Rsync\" target=\"_blank\"\u003Ersync\u003C\/a\u003E,\u0026nbsp;\u003Ca href=\"https:\/\/en.wikipedia.org\/wiki\/Cron\" target=\"_blank\"\u003Ecron\u003C\/a\u003E. Nor wanna go into details of\u0026nbsp;\u003Ca href=\"https:\/\/systemd.io\/\" target=\"_blank\"\u003Esystemd\u003C\/a\u003E\u0026nbsp;services and \u003Ca href=\"https:\/\/man.archlinux.org\/man\/systemd.service.5.en\" target=\"_blank\"\u003Etimers\u003C\/a\u003E. That's a subject of its own. I will provide some sample scripts though.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EFor\u0026nbsp;\u003Ca href=\"https:\/\/rsnapshot.org\/\" style=\"text-align: justify;\" target=\"_blank\"\u003Ersnapshot\u003C\/a\u003E\u003Cspan style=\"text-align: justify;\"\u003E\u0026nbsp;I needed a configuration. The installation generally comes with a default well document config just as any good linux package.\u0026nbsp;\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003EExample Section\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgsRn7bD68x_Cb_WHOAqR0S1kZu4FyYvP_Kr_riZEXaOGwyCy_07rxjWxMqhv65QTzddRe3dVXE_V-qCiMViLcHsinuePOYOkWniP4HOz2ews77e0z7R_6859GO1lcKUYBW80P-c9PIxYkRIm_R1JsjqXnQjvuAUeCaCznRlOh6Z02sAzNyChJatqCRxe8\/s1072\/Screenshot%202025-01-22%20at%207.11.20%E2%80%AFAM.png\" style=\"clear: left; float: left; margin-bottom: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"496\" data-original-width=\"1072\" height=\"296\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgsRn7bD68x_Cb_WHOAqR0S1kZu4FyYvP_Kr_riZEXaOGwyCy_07rxjWxMqhv65QTzddRe3dVXE_V-qCiMViLcHsinuePOYOkWniP4HOz2ews77e0z7R_6859GO1lcKUYBW80P-c9PIxYkRIm_R1JsjqXnQjvuAUeCaCznRlOh6Z02sAzNyChJatqCRxe8\/w640-h296\/Screenshot%202025-01-22%20at%207.11.20%E2%80%AFAM.png\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cbr \/\u003E\u003Cspan style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003EThe settings are self explanatory. Some notable ones are explained hereafter.\u0026nbsp;\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"text-align: justify;\"\u003EBackup levels section was changed from the default \"alpha,beta....\" to read \"daily, weekly, monthly\" to increase readability. The number next to it denotes how many backups of each category are stored.\u0026nbsp;\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjDi5Sd3voMU-CYtK9IzPlch898JgeK2OZAWDd2i1tYiZu57kXtVnqf0kpVM0XlSF_pPYteESCavfNm-KWiMQ9U5mdMkpyz2hG3jJAPMncj4w8rztlrC8QaGJUeJRSsT8wKk8jk_as6-1pPVNkALV9uPS5Y2qjvoVy1ZvG7YpP1-s7ceZILoWOiTzH3DO0\/s678\/Screenshot%202025-01-22%20at%207.19.08%E2%80%AFAM.png\" style=\"clear: left; float: left; margin-bottom: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"402\" data-original-width=\"678\" height=\"238\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjDi5Sd3voMU-CYtK9IzPlch898JgeK2OZAWDd2i1tYiZu57kXtVnqf0kpVM0XlSF_pPYteESCavfNm-KWiMQ9U5mdMkpyz2hG3jJAPMncj4w8rztlrC8QaGJUeJRSsT8wKk8jk_as6-1pPVNkALV9uPS5Y2qjvoVy1ZvG7YpP1-s7ceZILoWOiTzH3DO0\/w400-h238\/Screenshot%202025-01-22%20at%207.19.08%E2%80%AFAM.png\" width=\"400\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003EThis means I have a in time snapshot of my data for the last 7 days. In time backup of my data for last 5 weeks etc.\u003Cbr \/\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EThe\u0026nbsp;\u003Ca href=\"https:\/\/systemd.io\/\" target=\"_blank\"\u003Esystemd\u003C\/a\u003E\u0026nbsp;service file thats used to run the snapshots are given below. The filename of the service is 'ranapshot@.service'. This becomes relevant when writing the systemd timers.\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: left;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEisQP4jlInzYO8zTM7uhVKdJfzqDi1gnxaNiaRPWIkyw0hzEsDnKESWBGXIp2kUhdViz_CDb2oil-2hcQ0tvBZO6g4Y8POKZSzEiFK3AHQMMTnfQcpU7URVJ4PSOePqVICm4Pr8xvfVkMWiA7_IrxHX4LqflwFVERxX3sgNrCaOw_-8TFymlZibFe0K-9w\/s564\/Screenshot%202025-01-22%20at%207.28.55%E2%80%AFAM.png\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"342\" data-original-width=\"564\" height=\"194\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEisQP4jlInzYO8zTM7uhVKdJfzqDi1gnxaNiaRPWIkyw0hzEsDnKESWBGXIp2kUhdViz_CDb2oil-2hcQ0tvBZO6g4Y8POKZSzEiFK3AHQMMTnfQcpU7URVJ4PSOePqVICm4Pr8xvfVkMWiA7_IrxHX4LqflwFVERxX3sgNrCaOw_-8TFymlZibFe0K-9w\/s320\/Screenshot%202025-01-22%20at%207.28.55%E2%80%AFAM.png\" width=\"320\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: left;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: left;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003EThen each snapshot has it's own timer set to run at the correct cadence\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgdywQCWxdnPTm6wKiwtA_Yn3K656CMoMN6H0Yq4_0bupXboqm2InJpPFWWXclJXZG6IZQsHFWrNO63EIsHJlJrPYEkEAA5FM3cms8G5b5ZGj3nTEImb-W3YMFBkHvD_AFnwHl0CL60_23oVmEG70z70ULvLQud2UeRT_cFaq10rPrVxDxWzgHYKsaH_oc\/s764\/Screenshot%202025-01-28%20at%207.29.12%E2%80%AFAM.png\" imageanchor=\"1\" style=\"clear: left; float: left; margin-bottom: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"458\" data-original-width=\"764\" height=\"240\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgdywQCWxdnPTm6wKiwtA_Yn3K656CMoMN6H0Yq4_0bupXboqm2InJpPFWWXclJXZG6IZQsHFWrNO63EIsHJlJrPYEkEAA5FM3cms8G5b5ZGj3nTEImb-W3YMFBkHvD_AFnwHl0CL60_23oVmEG70z70ULvLQud2UeRT_cFaq10rPrVxDxWzgHYKsaH_oc\/w400-h240\/Screenshot%202025-01-28%20at%207.29.12%E2%80%AFAM.png\" width=\"400\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cbr \/\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cp\u003E\u003C\/p\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EThat's a wrap forks. Hope you enjoyed.\u0026nbsp;\u003C\/div\u003E\u003Cbr \/\u003E\u003Cbr \/\u003E\u003Cbr \/\u003E\u003Cbr \/\u003E\u003Cbr \/\u003E\u003C\/div\u003E"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/6635671021202968763\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2025\/01\/backups-snapshots.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/6635671021202968763"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/6635671021202968763"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2025\/01\/backups-snapshots.html","title":"Backups \u0026 Snapshots"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiktqDG5QJ4kesGRFawvehjon0jGr6Gf3Gj4sQfsuXIV1JeaTMLyoRraY5UTSUV3xgHCxWonZYS9pLHWqoCVzd_7SDi2OjczHjsUuzuKlnzqEY4-ASPnqIIxzd3O6Jt97Vb5qqnIfzlMq225uksXNz4leN1B8S8EQDx4_-PojrRxwl9ZaaTW99Z7dzb6jA\/s72-w200-h200-c\/Gemini_Generated_Image_4rraly4rraly4rra%20(1).jpeg","height":"72","width":"72"},"thr$total":{"$t":"0"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-3182209324262181761"},"published":{"$t":"2024-10-18T10:17:00.000-07:00"},"updated":{"$t":"2024-10-18T10:19:45.536-07:00"},"title":{"type":"text","$t":"My Home Network Setup"},"content":{"type":"html","$t":"\u003Cdiv\u003EIt’s been 3 long years since I published anything to this blog …. 😳\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Ctable align=\"center\" cellpadding=\"0\" cellspacing=\"0\" class=\"tr-caption-container\" style=\"margin-left: auto; margin-right: auto;\"\u003E\u003Ctbody\u003E\u003Ctr\u003E\u003Ctd style=\"text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgghO7BY-wwYlL_DixM17Bj1hzWvXGszmbgI5yNQq2l0N99JTr65o1CpZ679rdni0g2LNkDB1Cbp5_cv71BLOrlq7ug3fg5ccmZlWavo7fzU3xJCs4Lrh3OTXestBFX5bXsrKKA_AOAvHUUrQPxN3Edjznyu8Zgy88eWzTRijI81ASyWz91Cm6xViO-imU\/s4032\/IMG_0537.jpeg\" style=\"margin-left: auto; margin-right: auto;\"\u003E\u003Cimg border=\"0\" data-original-height=\"3024\" data-original-width=\"4032\" height=\"240\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgghO7BY-wwYlL_DixM17Bj1hzWvXGszmbgI5yNQq2l0N99JTr65o1CpZ679rdni0g2LNkDB1Cbp5_cv71BLOrlq7ug3fg5ccmZlWavo7fzU3xJCs4Lrh3OTXestBFX5bXsrKKA_AOAvHUUrQPxN3Edjznyu8Zgy88eWzTRijI81ASyWz91Cm6xViO-imU\/s320\/IMG_0537.jpeg\" width=\"320\" \/\u003E\u003C\/a\u003E\u003C\/td\u003E\u003C\/tr\u003E\u003Ctr\u003E\u003Ctd class=\"tr-caption\" style=\"text-align: center;\"\u003E\u003Cspan style=\"font-size: x-small;\"\u003EThe not so pretty setup !\u003C\/span\u003E\u003C\/td\u003E\u003C\/tr\u003E\u003C\/tbody\u003E\u003C\/table\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EIn this article I’m gonna write about my home network setup. It’s important to note that the decisions and components used here were subjective to,\u003C\/div\u003E\u003Cdiv\u003E\u003Col\u003E\u003Cli\u003EReuse of components from the previous setup\u003C\/li\u003E\u003Cli\u003EWhat I could source conveniently without breaking the bank\u003C\/li\u003E\u003Cli\u003EMy technology preferences\u003C\/li\u003E\u003C\/ol\u003E\u003Cdiv\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EBefore I start rambling about the technicalities, let’s highlight what I needed the setup to do.\u003C\/div\u003E\u003Cdiv\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EThe basics like an internet connection, Wi-Fi for the mobile devices, Good connectivity throughout the house. Then the not so obvious need to run a lightweight web server, file server, different surveillance cameras, NVR system, IoT devices, home automation system, remote access for surveillance monitoring and lightweight administration. Let’s list them all.\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Col style=\"text-align: left;\"\u003E\u003Cli\u003EReliable internet connections with enough juice\u003C\/li\u003E\u003Cli\u003EMesh capable WiFi solution\u0026nbsp;\u003C\/li\u003E\u003Cli\u003EAbility to have multiple isolated networks\u0026nbsp;\u003C\/li\u003E\u003Cli\u003EEasily extensible for future use cases\u003C\/li\u003E\u003Cli\u003EShareable wired and wireless connectivity\u0026nbsp;\u003C\/li\u003E\u003Cli\u003EPower over Ethernet\u0026nbsp;\u003C\/li\u003E\u003Cli\u003ERemote access\u0026nbsp;\u003C\/li\u003E\u003C\/ol\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EWhat about privacy and security. When trying to achieve all the above mentioned requirements I’m exposing myself to a whole lot of privacy and security vulnerabilities. There’s no way of fully eliminating the risk. Well you simply cannot have the cake and eat it too. I had to find a good middle ground. This middle ground however is gonna be an ever changing one. With time new risks will emerge and will need mitigation. Here’s me hoping I won’t be finding those new risks the hard way. Fingers crossed.\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003ELet’s jump right into the components and software solutions I ended up using.\u003C\/div\u003E\u003Cdiv\u003E\u003Col style=\"text-align: left;\"\u003E\u003Cli\u003EpfSense open source software based router\u003C\/li\u003E\u003Cli\u003Ei5-5200U based mini pc with 4x 1gig network ports as the router host\u003C\/li\u003E\u003Cli\u003EUnify layer 2 switch (VLAN capable)\u003C\/li\u003E\u003Cli\u003EUnify wireless access points\u0026nbsp;\u003C\/li\u003E\u003Cli\u003ECAT6a shielded cabling\u0026nbsp;\u003C\/li\u003E\u003Cli\u003EBlue Iris Software based NVR\u003C\/li\u003E\u003Cli\u003ELow power CPU and a low power GPU with CUDA support (for AI)\u003C\/li\u003E\u003Cli\u003EHome Assistant open source home automation software\u003C\/li\u003E\u003Cli\u003EZigbee2MQTT bridge\u003C\/li\u003E\u003Cli\u003ERTSP compatible POE cameras\u003C\/li\u003E\u003Cli\u003EWireGuard, Suricata, \u0026nbsp;pfSense firewall for VPN, IPS, IDS\u003C\/li\u003E\u003C\/ol\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003ELooking into router solutions pfSense and OPNSense was the solutions that had the customizability I needed. It’s really hard to choose one over the other given they are both based on FreeBSD and had a shared codebase until OPNSense forked out on 2015. It came down to personal preference. Unify dream machine solutions was a close second but lacked the customizability and the flexibility of running on my own hardware.\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EI chose a i55200U based mini pc to keep the power consumption low while having enough power with AES-NI. The 4 1gig Intel NICs gave me enough isolated throughput.\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EUnify layer 2 switch gave me the ability to configure VLANs and port restrictions to keep different networks defined in the pfSense router secure and isolated. This also means I get a good ecosystem with my chosen unify access points. I couldn’t really find any alternative to this setup at a comparable price point.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EBlue Iris is a software based NVR. I’m not thrilled about having to run a windows machine for this purpose as Blue Iris only has a windows app. I was also looking into Synology NVRs. In the end the Blue Iris won due to the user base and price point.\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EI choose Suricata over Snort for IPS, IDS. I already had it running on my web server, thus had a good base configuration that would keep working with minor tweaks. I used a WireGuard tunnel for remote access over OpenVPN. \u0026nbsp;WireGuard had everything I needed and comes bundled in the FreeBSD kernel used in pfSense.\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EThat’s a wrap. In my next post I’m planning to cover how I’m using pfSense with the layer 2 switch and access points to achieve multiple isolated wireless and wired networks …\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003C\/div\u003E\u003C\/div\u003E\u003C\/div\u003E"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/3182209324262181761\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2024\/10\/my-home-network-setup.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/3182209324262181761"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/3182209324262181761"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2024\/10\/my-home-network-setup.html","title":"My Home Network Setup"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgghO7BY-wwYlL_DixM17Bj1hzWvXGszmbgI5yNQq2l0N99JTr65o1CpZ679rdni0g2LNkDB1Cbp5_cv71BLOrlq7ug3fg5ccmZlWavo7fzU3xJCs4Lrh3OTXestBFX5bXsrKKA_AOAvHUUrQPxN3Edjznyu8Zgy88eWzTRijI81ASyWz91Cm6xViO-imU\/s72-c\/IMG_0537.jpeg","height":"72","width":"72"},"thr$total":{"$t":"0"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-6454489257194893936"},"published":{"$t":"2021-03-27T17:01:00.060-07:00"},"updated":{"$t":"2021-03-27T17:24:04.888-07:00"},"title":{"type":"text","$t":"Nextcloud and PHP8"},"content":{"type":"html","$t":"\u003Cp\u003E\u0026nbsp;\u003C\/p\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiqMC_146qJJKGHqkwbj5QIMxJ3TGeibIvV9g-PidxQN9KIOyJrPl4QqJnsdbefs3PeEqawCKRdlEAhgkFMPYVwhkZRskhPoY5fVELAotJ8EVetew6WYVM0ENAYT5AbrJXOFAdXjw0E2m4\/s700\/nextcld.jpg\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"278\" data-original-width=\"700\" height=\"254\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiqMC_146qJJKGHqkwbj5QIMxJ3TGeibIvV9g-PidxQN9KIOyJrPl4QqJnsdbefs3PeEqawCKRdlEAhgkFMPYVwhkZRskhPoY5fVELAotJ8EVetew6WYVM0ENAYT5AbrJXOFAdXjw0E2m4\/w640-h254\/nextcld.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cbr \/\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Ch2 style=\"text-align: center;\"\u003EPHP8 broke my Nextcloud instance !!!\u003C\/h2\u003E\u003Cdiv style=\"text-align: justify;\"\u003EI run a \u003Ca href=\"https:\/\/nextcloud.com\/\" target=\"_blank\"\u003ENextcloud\u003C\/a\u003E instance on a self hosted \u003Ca href=\"https:\/\/archlinux.org\/\" target=\"_blank\"\u003EArch\u003C\/a\u003E\u0026nbsp;linux server. \u003Ca href=\"https:\/\/archlinux.org\/\" target=\"_blank\"\u003EArch\u003C\/a\u003E linux because I like the challenge 😁. \u003Ca href=\"https:\/\/nextcloud.com\/\" target=\"_blank\"\u003ENextcloud\u003C\/a\u003E due to privacy reasons. Recently Arch upgraded all php packages to \u003Ca href=\"https:\/\/www.php.net\/releases\/8.0\/en.php\" target=\"_blank\"\u003Ephp8\u003C\/a\u003E. Nextcloud 20.x, the version I'm using currently can't work on php8 thus my instance went offline. In this article I'm gonna describe how I managed to fix this issue.\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003EI run \u003Ca href=\"https:\/\/github.com\/teejee2008\/timeshift\" target=\"_blank\"\u003Etimeshift\u003C\/a\u003E in my server via the cli. So I could have downgraded the php version. That would mean I would have to refrain from updating php and risk zero day vulnerabilities. That would nullify the whole purpose of running a self hosted Nextcloud instance for my sensitive data. Instead I went with dual php versions. I run php-fpm with Apache in my server so now I have to figure out how to run Fast CGI process manager with 2 php versions in the same Apache server. If you are thinking \"well you are a SDE and you should know it\", let me start by saying I neither use PHP nor Apache in my day job. As a matter of fact none of the tech stacks mentioned here are used in my day job. The exception is linux of course.\u0026nbsp;\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003EArch \u003Ca href=\"https:\/\/archlinux.org\/news\/php-80-and-php-7-legacy-packages-are-available\/\" target=\"_blank\"\u003Eannounced\u003C\/a\u003E that PHP 7 legacy packages will be maintained with a limited support timeline. So I started by installing the required packages.\u0026nbsp;\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`sudo pacman -S php7 php7-fpm php7-gd php7-imagick php7-intl php7-apcu`\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003EConfirmed php7 is working by running \u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`php7 -v`\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003ENow I need to enable the needed extensions. Edit the ini \u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`sudo vim \/etc\/php7\/php.ini`\u003C\/i\u003E\u003C\/span\u003E and uncomment\/changed the following,\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Eextension=gd\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Eextension=iconv\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Eextension=pdo_mysql\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Eextension=bz2\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Eextension=bcmath\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Eextension=gmp\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Eextension=intl\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Eopcache.enable=1\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Ezend_extension=opcache\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Epocache.interned_strings_buffer=8\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Eopcache.max_accelerated_files=10000\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Eopcache.memory_consumpion=128\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Eopcache.save_comments=1\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Eopcache.revalidate_freq=1\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Ememory_limit = 2048\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Eoutput _buffering = off\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003EEnable imagick in systemd service. \u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E`sudo vim \/etc\/php7\/conf.d\/imagick.ini`\u003C\/span\u003E\u003C\/i\u003E and uncomment,\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Eextension=imagick\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003EEdit the php-fpm systemd service \u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`sudo vim \/etc\/php\/php-fpm.d\/www.conf`\u003C\/i\u003E\u003C\/span\u003E and uncomment\/change the following,\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Eenv[HOSTNAME] = $HOSTNAME\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Eenv[PATH] = \/usr\/local\/bin:\/usr\/bin:\/bin\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Eenv[TMP] = \/tmp\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Eenv[TMPDIR] = \/tmp\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Eenv[TEMP] = \/tmp\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Erequest_terminate_timeout = 3600\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epm=dynamic\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epm.max_children=120\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epm.start_servers=12\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epm.min_spare-servers=6\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epm.max_spare_servers=18\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003EAdd the apcu settings to the php systemd service. \u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E`sudo vim \/etc\/php7\/conf.d\/apcu.ini`\u003C\/span\u003E\u003C\/i\u003E and add\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Eextension=apcu\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Eapc.enable_cli=1\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Eapc.tl=7200\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003ENow I need to tell my nextcloud virtual host to use the correct php version. Edit \u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`\/etc\/httpd\/conf\/vhosts\/[my vhost].conf`\u003C\/i\u003E\u003C\/span\u003E and add the following,\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E\u0026lt;FilesMatch \\.php$\u0026gt;\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E\u0026nbsp; \u0026nbsp; \u0026nbsp; SetHandler \"proxy:unix:\/run\/php-fpm7\/php-fpm.sock|fcgi:\/\/localhost\"\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E\u0026lt;\/FilesMatch\u0026gt;\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003ERestart\/Start the systemd services\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`systemctl enable --now php-fpm7.service`\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`systemctl restart httpd`\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003EThat's it. My Nextcloud instance is up and running again. Most of the above settings\/configs are Nextcloud related optimizations I have done to my instance. I have a plan to write an article on setting up Nextcloud from scratch. Stay tuned...\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cp\u003E\u003C\/p\u003E"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/6454489257194893936\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2021\/03\/nextcloud-and-php8.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/6454489257194893936"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/6454489257194893936"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2021\/03\/nextcloud-and-php8.html","title":"Nextcloud and PHP8"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiqMC_146qJJKGHqkwbj5QIMxJ3TGeibIvV9g-PidxQN9KIOyJrPl4QqJnsdbefs3PeEqawCKRdlEAhgkFMPYVwhkZRskhPoY5fVELAotJ8EVetew6WYVM0ENAYT5AbrJXOFAdXjw0E2m4\/s72-w640-h254-c\/nextcld.jpg","height":"72","width":"72"},"thr$total":{"$t":"0"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-5665316921391109233"},"published":{"$t":"2021-02-27T19:23:00.141-08:00"},"updated":{"$t":"2021-03-10T20:11:22.038-08:00"},"title":{"type":"text","$t":"Minimalist Static Website "},"content":{"type":"html","$t":"\u003Cp style=\"text-align: justify;\"\u003E\u0026nbsp;I wanted to build a minimalistic static website as the root of my domain. I have designed and built countless web applications using modern frameworks but nothing this simple. I wanted to use the least amount of tooling and keep things as simple as they can be. What I wanted to achieve was,\u003C\/p\u003E\u003Cp style=\"text-align: justify;\"\u003E\u003C\/p\u003E\u003Cul\u003E\u003Cli\u003EA simple website as the root of my domain.\u0026nbsp;\u003C\/li\u003E\u003Cli\u003ENeeds to be mobile first and fully responsive.\u003C\/li\u003E\u003Cli\u003EModern design.\u003C\/li\u003E\u003Cli\u003EShould work reasonably well with at least 80% of current web browser versions \u003Ca href=\"https:\/\/caniuse.com\/\" target=\"_blank\"\u003E(caniuse)\u003C\/a\u003E\u003C\/li\u003E\u003Cli\u003EThis needs to load as fast as it can without any bloat.\u003C\/li\u003E\u003Cli\u003EThe purpose of this root website is to direct the users into my various projects and articles.\u003C\/li\u003E\u003Cli\u003EThis will be hosted on my home server. So every byte, every style, every transformation counts.\u003C\/li\u003E\u003C\/ul\u003E\u003Cp\u003E\u003C\/p\u003E\u003Cp style=\"text-align: justify;\"\u003EMy first approach was to find a boilerplate. I was not able to find anything to my liking so I decided to start from scratch. What I used,\u003C\/p\u003E\u003Cp style=\"text-align: justify;\"\u003E\u003C\/p\u003E\u003Cul\u003E\u003Cli\u003EModule bundler loader: \u003Ca href=\"https:\/\/webpack.js.org\/\" target=\"_blank\"\u003Ewebpack\u003C\/a\u003E\u003C\/li\u003E\u003Cli\u003EJS compiler: \u003Ca href=\"https:\/\/babeljs.io\/\" target=\"_blank\"\u003EBabel\u003C\/a\u003E\u003C\/li\u003E\u003Cli\u003ECSS preprocessor: \u003Ca href=\"https:\/\/sass-lang.com\/dart-sass\" target=\"_blank\"\u003EDart Sass\u003C\/a\u003E\u003C\/li\u003E\u003Cli\u003EDesign \/ UX : \u003Ca href=\"https:\/\/material.io\/\" target=\"_blank\"\u003EMaterial Design\u003C\/a\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cp style=\"text-align: left;\"\u003EThe code I'm discussing is available in\u0026nbsp;\u003Ca href=\"https:\/\/github.com\/kumudug\/static_web\" target=\"_blank\"\u003Egithub.com\/kumudug\/static_web\u003C\/a\u003E. (non production quick and dirty poc)\u003C\/p\u003E\u003Cp style=\"text-align: left;\"\u003ELive demo at :\u0026nbsp;\u003Ca href=\"https:\/\/coding-mayhem.com\/projects\/staticweb\" target=\"_blank\"\u003Ecoding-mayhem.com\/projects\/staticweb\u003C\/a\u003E\u003C\/p\u003E\u003Cp style=\"text-align: left;\"\u003ESince this is mostly a static website I'm not going to use any JS frameworks for functionality. When needed latest ES will be used with Babel. Different webpack entry points are used for modularization. The modules are combined into required pages by using\u0026nbsp;\u003Ca href=\"https:\/\/webpack.js.org\/plugins\/html-webpack-plugin\/\" target=\"_blank\"\u003EHtmlWebpackPlugin\u003C\/a\u003E. Each module would then compile their own styles, images, scripts into a single html file. Let me make the complex simple.\u003C\/p\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: left;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEinypfQgg7iaZwbou9JigpsNlFYlzFQUDiZaeuCCEgrLCAw_L7QcWvLtx6ITJRzKuguDLX0Vks74ka5aWWhDokRdAqrZdJ5UOFK_QGnr1NmIVMjb-VCHdjgV6-w3i7EhOCwWo9eO9Jt7Uo\/s397\/file_structure.jpg\" style=\"clear: left; float: left; margin-bottom: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"397\" data-original-width=\"150\" height=\"482\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEinypfQgg7iaZwbou9JigpsNlFYlzFQUDiZaeuCCEgrLCAw_L7QcWvLtx6ITJRzKuguDLX0Vks74ka5aWWhDokRdAqrZdJ5UOFK_QGnr1NmIVMjb-VCHdjgV6-w3i7EhOCwWo9eO9Jt7Uo\/w217-h482\/file_structure.jpg\" width=\"217\" \/\u003E\u003C\/a\u003E\u003Cspan style=\"text-align: justify;\"\u003EThe common styles are contained in the sass files in the \"src\" root directory. These contain\u003C\/span\u003E\u003C\/div\u003E\u003Cp style=\"text-align: justify;\"\u003E\u003C\/p\u003E\u003Cp\u003E\u003Cspan\u003E\u0026nbsp;\u0026nbsp; \u0026nbsp;\u003C\/span\u003E\u003Cspan\u003E\u0026nbsp;\u0026nbsp; \u0026nbsp;\u003C\/span\u003E\u003Cspan\u003E\u0026nbsp; \u0026nbsp; 1. Common colors\u003C\/span\u003E\u003Cbr \/\u003E\u003C\/p\u003E\u003Cp\u003E\u003Cspan\u003E\u003Cspan\u003E\u0026nbsp;\u0026nbsp; \u0026nbsp;\u003C\/span\u003E\u003Cspan\u003E\u0026nbsp;\u0026nbsp; \u0026nbsp;\u003C\/span\u003E\u003Cspan\u003E\u0026nbsp; \u0026nbsp; 2. Material theme and styles with customizations\u003C\/span\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/p\u003E\u003Cp\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u0026nbsp;\u0026nbsp; \u0026nbsp;\u003C\/span\u003E\u003Cspan\u003E\u0026nbsp;\u0026nbsp; \u0026nbsp;\u003C\/span\u003E\u003Cspan\u003E\u0026nbsp; \u0026nbsp; 3. Material component style imports (buttons, cards etc.)\u003C\/span\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/p\u003E\u003Cp\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u0026nbsp;\u0026nbsp; \u0026nbsp;\u003C\/span\u003E\u003Cspan\u003E\u0026nbsp;\u0026nbsp; \u0026nbsp;\u003C\/span\u003E\u003Cspan\u003E\u0026nbsp; \u0026nbsp; 4. Common application styles\u003C\/span\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/p\u003E\u003Cp style=\"text-align: justify;\"\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003EThese were all combined in \"app.scss\" and imported into a common module using the \"app.js\" file.\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/p\u003E\u003Cp style=\"text-align: justify;\"\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003EEach page is organized into a folder inside the root \"src\" folder. These folders contains,\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/p\u003E\u003Cp style=\"text-align: justify;\"\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u0026nbsp;\u0026nbsp; \u0026nbsp;\u003C\/span\u003E\u003Cspan\u003E\u0026nbsp;\u0026nbsp; \u0026nbsp;\u003C\/span\u003E\u003Cspan\u003E\u0026nbsp; \u0026nbsp; 1. Sass file containing the page styles\u003C\/span\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/p\u003E\u003Cp style=\"text-align: justify;\"\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u0026nbsp;\u0026nbsp; \u0026nbsp;\u003C\/span\u003E\u003Cspan\u003E\u0026nbsp;\u0026nbsp; \u0026nbsp;\u003C\/span\u003E\u003Cspan\u003E\u0026nbsp; \u0026nbsp; 2. JavaScript\u0026nbsp;file containing the page code\u003C\/span\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/p\u003E\u003Cp style=\"text-align: justify;\"\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u0026nbsp;\u0026nbsp; \u0026nbsp;\u003C\/span\u003E\u003Cspan\u003E\u0026nbsp;\u0026nbsp; \u0026nbsp;\u003C\/span\u003E\u003Cspan\u003E\u0026nbsp; \u0026nbsp; 3. Html file containing the page template\u003C\/span\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/p\u003E\u003Cp style=\"text-align: justify;\"\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003EThese are then combined using the \u003Ca href=\"https:\/\/webpack.js.org\/plugins\/html-webpack-plugin\/\" target=\"_blank\"\u003EHtmlWebpackPlugin\u003C\/a\u003E.\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/p\u003E\u003Cp style=\"text-align: justify;\"\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/p\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhGXbKsUSZYm1JViEf0BNfZ4K2viNfnL2T-xGVwFAinsDRzNXyulwQWyQkQiOVgFVgmuMMHFteS4Q2zWoQn0EuNdeonHPrz02hgxpdhJvSmUU3iCShV-4QFFrep3rHa0GNKyTEGhhHumjw\/s288\/home.jpg\" style=\"clear: right; float: right; margin-bottom: 1em; margin-left: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"134\" data-original-width=\"288\" height=\"186\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhGXbKsUSZYm1JViEf0BNfZ4K2viNfnL2T-xGVwFAinsDRzNXyulwQWyQkQiOVgFVgmuMMHFteS4Q2zWoQn0EuNdeonHPrz02hgxpdhJvSmUU3iCShV-4QFFrep3rHa0GNKyTEGhhHumjw\/w401-h186\/home.jpg\" width=\"401\" \/\u003E\u003C\/a\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003EApart from the above main concepts,\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Ca href=\"https:\/\/www.npmjs.com\/package\/html-webpack-inline-svg-plugin\" target=\"_blank\"\u003EHtmlWebpackInlineSvg\u003C\/a\u003E plugin was used to inline the SVG images. With SVGs inline it's possible to use sass to control svg properties.\u0026nbsp;\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Ca href=\"https:\/\/www.npmjs.com\/package\/eslint-webpack-plugin\" target=\"_blank\"\u003EEslintWebpackPlugin\u003C\/a\u003E is used for linting JavaScript.\u0026nbsp;\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Ca href=\"https:\/\/webpack.js.org\/plugins\/mini-css-extract-plugin\/\" target=\"_blank\"\u003EMiniCssExtractPlugin\u003C\/a\u003E is used to extract the styles out into separate files.\u0026nbsp;\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Ca href=\"https:\/\/www.npmjs.com\/package\/terser-webpack-plugin\" target=\"_blank\"\u003ETerserWebpackPlugin\u003C\/a\u003E to minify JavaScript.\u0026nbsp;\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003ESomething to note, The import and extension of Material is generally heavily dependent on the version used. Material tend to introduce breaking changes with every major release.\u0026nbsp;\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003EThe project contains several scripts\u0026nbsp;\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E1. `\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Enpm start\u003C\/i\u003E\u003C\/span\u003E` - Would run the project inside a dev server\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E2. `\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Enpm run build:dev\u003C\/span\u003E\u003C\/i\u003E` - Would build a development release package\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E3. `\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Enpm run build:prod\u003C\/span\u003E\u003C\/i\u003E` - Would build a prod release package\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003EThat's a wrap.\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cbr \/\u003E\u003Cspan\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003Cp\u003E\u003C\/p\u003E\u003Cp\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/p\u003E\u003Cp\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/p\u003E\u003Cp\u003E\u003C\/p\u003E\u003Cp style=\"text-align: left;\"\u003E\u003Cbr \/\u003E\u003C\/p\u003E\u003Cp\u003E\u003C\/p\u003E\u003Cp style=\"text-align: left;\"\u003E\u003Cbr \/\u003E\u003C\/p\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cp\u003E\u003C\/p\u003E\u003C\/div\u003E"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/5665316921391109233\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2021\/02\/minimalist-static-website.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/5665316921391109233"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/5665316921391109233"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2021\/02\/minimalist-static-website.html","title":"Minimalist Static Website "}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEinypfQgg7iaZwbou9JigpsNlFYlzFQUDiZaeuCCEgrLCAw_L7QcWvLtx6ITJRzKuguDLX0Vks74ka5aWWhDokRdAqrZdJ5UOFK_QGnr1NmIVMjb-VCHdjgV6-w3i7EhOCwWo9eO9Jt7Uo\/s72-w217-h482-c\/file_structure.jpg","height":"72","width":"72"},"thr$total":{"$t":"0"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-2238747154747798126"},"published":{"$t":"2020-12-29T17:17:00.000-08:00"},"updated":{"$t":"2020-12-29T17:17:27.406-08:00"},"title":{"type":"text","$t":"Arch Install Desktop vs Server Differences"},"content":{"type":"html","$t":"\u003Cp\u003E\u0026nbsp;\u003C\/p\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgOj0t3NkwYRU8Rwg_0LDp6CndOSLrlZqz-sB1XiOgL8XWY8cO7HUZ-MEJd3d6NnoFa4hH0wUGkJYu76dHbM5KnZkKglLHQEduW46I8KOQYx3rC9q1U3CrLn52Cb1zTH5f5Mb7Fcf4qUps\/s728\/archey.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"355\" data-original-width=\"728\" height=\"312\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgOj0t3NkwYRU8Rwg_0LDp6CndOSLrlZqz-sB1XiOgL8XWY8cO7HUZ-MEJd3d6NnoFa4hH0wUGkJYu76dHbM5KnZkKglLHQEduW46I8KOQYx3rC9q1U3CrLn52Cb1zTH5f5Mb7Fcf4qUps\/w640-h312\/archey.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cbr \/\u003E\u003Cp\u003E\u003C\/p\u003E\u003Cp\u003EIn my day to day life I use 4 devices running \u003Ca href=\"https:\/\/archlinux.org\/\" target=\"_blank\"\u003EArch Linux\u003C\/a\u003E.\u0026nbsp;\u003C\/p\u003E\u003Cp\u003E\u003C\/p\u003E\u003Cul style=\"text-align: left;\"\u003E\u003Cli\u003EXPS13 laptop\u003C\/li\u003E\u003Cli\u003ERyzen 7 3700X on a B550 itx system\u003C\/li\u003E\u003Cli\u003ERyzen 3 3100 on a A520 as my home server\u003C\/li\u003E\u003Cli\u003EXeon E3-1260L on a LGA 1155 running \u003Ca href=\"https:\/\/nextcloud.com\/\" target=\"_blank\"\u003ENext Cloud\u003C\/a\u003E and a web server\u003C\/li\u003E\u003C\/ul\u003E\u003Cdiv style=\"text-align: justify;\"\u003EIn this post I will outline the differences in my Arch Linux install among these devices. Before proceeding I should point out that using a rolling release on a server environment poses additional challenges that generally cannot be justified for production systems.\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003EThe first step is to boot using an Arch Linux USB. Then I generally start by creating a 260MB EFI partition using fdisk. The boot partition needs to be formatted as a Fat 32 partition.\u0026nbsp;\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Emkfs.fat -F32 \/dev\/sda1\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003EThe rest of the partitions are going to be on \u003Ca href=\"https:\/\/en.wikipedia.org\/wiki\/Logical_Volume_Manager_(Linux)#:~:text=In%20Linux%2C%20Logical%20Volume%20Manager,systems%20on%20a%20logical%20volume.\" target=\"_blank\"\u003ELVM\u003C\/a\u003E. First step is to create a partition in the remainder of the disk and choose LVM as the partition type. Once done I would create the physical volume and a volume group.\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epvcreate \/dev\/sda2\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Evgcreate vgmain \/dev\/sda2\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003ENow I would create the root partition in the volume group. For desktop installations the root partition is going to be LUKS encrypted. This ensures the os is encrypted at rest and tamper proof if physical access is compromised.\u0026nbsp;\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cul\u003E\u003Cli\u003EDesktop\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Elvcreate -L 30G vgmain -n cryptlvroot\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Ecryptsetup -u -v luksFormat \/dev\/vgmain\/cryptlvroot\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cli\u003EServer\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Elvcreate -L 30G vgmain -n lvroot\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003C\/ul\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003ENow I would proceed to format the root partition. For the desktop, the LUKS partition needs to be opened before it can be formatted\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cul\u003E\u003Cli\u003EDesktop\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Ecryptsetup open \/dev\/vgmain\/cryptlvroot root\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Emkfs.ext4 \/dev\/mapper\/root\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cli\u003EServer\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emkfs.ext4 \/dev\/vgmain\/lvroot\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003C\/ul\u003E\u003Cdiv\u003ENow I'm at the point of creating the data partition. For the desktop the data partition will be mounted as the home volume. For servers I generally create a different mount point for this. I always encrypt the data partition using LUKS.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Elvcreate -l +100%FREE vgmain -n lvdata\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Ecryptsetup -y -v luksFormat \/dev\/vgmain\/lvdata\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Ecryptsetup open \/dev\/vgmain\/lvdata encdata\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emkfs.ext4 \/dev\/mapper\/encdata\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EIt's time to mount all the file systems. Before that lets talk about the way the LUKS volumes are to be unlocked during boot.\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EFor the desktop installations I would configure a password prompt during initial ramdisk creation (explained later in this post). The password prompt will unlock the root encrypted volume. The data volume will them be unlocked using a key file stored within the root volume.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EFor server installations it doesn't make sense to keep the data partition key in the root volume as the root volume is not encrypted. I choose to store the key in a usb flash drive. This approach gives me a better chance of keeping the data encrypted at rest by removing the usb drive from the servers in case of a physical security compromise. I do take additional steps to protect the keys stored in the USB drive but these steps would fall under security by obscurity at best and is beyond the scope of this post.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003EDesktop\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Emount \/dev\/mapper\/root \/mnt\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Emkdir \/mnt\/boot\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Emount \/dev\/sda1 \/mnt\/boot\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Emkdir \/mnt\/home\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Emount \/dev\/mapper\/encdata \/mnt\/home\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cli\u003EServer\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emount \/dev\/vgmain\/lvroot \/mnt\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emkdir \/mnt\/boot\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emount \/dev\/sda1 \/mnt\/boot\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emkdir \/mnt\/data\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emount \/dev\/mapper\/encdata \/mnt\/data\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emkdir \/mnt\/keys\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emount \/dev\/sdc1 \/mnt\/keys\u003C\/span\u003E\u003C\/i\u003E (sdc1 is a usb flash drive)\u003C\/li\u003E\u003C\/ul\u003E\u003C\/ul\u003E\u003Cdiv\u003ENow that the partitions are mounted I'm ready to create the file system table.\u0026nbsp;\u003C\/div\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emkdir \/mnt\/etc\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Egenfstab -U \/mnt \u0026gt;\u0026gt; \/mnt\/etc\/fstab\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003ELets continue the installation. I'm gonna verify the UEFI boot was used by looking at efi vars.\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003Els \/sys\/firmware\/efi\/efivars\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EIn a desktop installation with wifi capabilities now would be the time to connect.\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Eiwctl\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Estation wlan0 connect [ssid]\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Estation wlan0 show\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Equit\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EVerify a live internet connection by pinging archlinux.org\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E\u0026nbsp;ping archlinux.org\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003ESet and check network time protocol\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Etimedatectl set-ntp true\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Etimedatectl status\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EInstall the essentials. For server environments I use the lts kernel. For desktop environments I use the latest kernel but still install the lts kernel which can be used to recover the system without using chroot.\u003C\/div\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003EServer\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epacstrap \/mnt base linux-lts linux-firmware linux-lts-headers\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cli\u003EDesktop\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epacstrap \/mnt base linux linux-firmware linux-headers linux-lts linux-lts-headers\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003C\/ul\u003E\u003Cdiv\u003ESwitch to the newly installed root and setup swap\u003C\/div\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Earch-chroot \/mnt\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Efree (check memory and decide how much swap you need)\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Edd if=\/dev\/zero of=\/swapfile bs=1M count=8192 status=progress\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Echmod 600 \/swapfile\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Emkswap \/swapfile\u0026nbsp;\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Eecho '\/swapfile none swap 0 0' | tee -a \/etc\/fstab\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003ESetup auto mounting of the encrypted data volume by creating a key and adding it to crypttab. Install editors and lvm packages as well\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Epacman -Sy vim nano lvm2\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Edd if=\/dev\/urandom of=\/keys\/data-key bs=512 count=8\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Ecryptsetup luksAddKey \/dev\/vgmain\/lvdata \/keys\/data-key\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EUse \u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`lsblk -a`\u003C\/i\u003E\u003C\/span\u003E to find the UUID fo the encrypted data partition and add it to the \/etc\/crypttab file\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Eencdata UUID=[xxxxx-xxxxx-xxxx...] \/keys\/data-key\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003ESet timezone and locale\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Eln -sf \/usr\/share\/zoneinfo\/America\/Los_Angeles \/etc\/localtime\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Ehwclock --systohc\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Evim \/etc\/locale.gen\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003EUncomment your locale. Ex: \u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Een_US.UTF-8 UTF-8\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Elocale-gen\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Evim \/etc\/locale.conf\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003EEnter your locale. Ex: \u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003ELANG=en_US.UTF-8\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003ENetwork config\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Evim \/etc\/hostname\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003EEnter \u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E[name]\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Evim \/etc\/hosts\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003EEnter\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E127.0.0.1\u003Cspan\u003E\u0026nbsp; \u0026nbsp; localhost\u003C\/span\u003E\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E::1\u003Cspan\u003E\u0026nbsp;\u0026nbsp; \u0026nbsp;\u003C\/span\u003E\u003Cspan\u003E\u0026nbsp;\u0026nbsp; \u0026nbsp;\u003C\/span\u003E\u003Cspan\u003E\u0026nbsp;\u0026nbsp; \u0026nbsp;\u003C\/span\u003E\u003Cspan\u003E\u0026nbsp; \u0026nbsp;localhost\u003C\/span\u003E\u003C\/span\u003E\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E127.0.1.1\u003Cspan\u003E\u0026nbsp; \u0026nbsp; [name].localdomain [name]\u003C\/span\u003E\u003C\/span\u003E\u003C\/i\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003ESetting root password and creating additional\u0026nbsp;users\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epasswd - enter root password\u003C\/span\u003E\u003C\/i\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Euseradd -g users -G power,storage,wheel -m [youradminaccount]\u003C\/span\u003E\u003C\/i\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epasswd [youradminaccount]\u003C\/span\u003E\u003C\/i\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003EInstall and configure sudo so that everyone in wheel user group can sudo after confirming password.\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Epacman -S sudo\u003C\/i\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Evisudo\u003C\/i\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003EUncomment \u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E%wheel ALL=(ALL) ALL\u003C\/span\u003E\u003C\/i\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003EInstall network tools and base dev tools. Enable systemd services for networking\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epacman -S base-devel networkmanager dialog\u003C\/span\u003E\u003C\/i\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Esystemctl enable NetworkManager\u003C\/span\u003E\u003C\/i\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Esystemctl enable systemd-networkd.service\u003C\/span\u003E\u003C\/i\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Esystemctl enable systemd-resolved.service\u003C\/span\u003E\u003C\/i\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003EConfigure initial ram disk creation. For desktop environments we need to configure luks and lvm as we need to unlock the LUKS encrypted root volume in the lvm partition. For server environments we only need to configure lvm.\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003EServer\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Evim \/etc\/mkinitcpio.conf\u003C\/span\u003E\u003C\/i\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003EInsert lvm2 bwetween block and filesystem\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003EHOOKS=(base udev autodetect modconf block __lvm2__ filesystems keyboard fsck)\u003C\/span\u003E\u003C\/i\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003ERecreate initramfs image\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emkinitcpio -P linux-lts\u003C\/span\u003E\u003C\/i\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cli\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003EDesktiop\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Evim \/etc\/mkinitcpio.conf\u003C\/span\u003E\u003C\/i\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003EInsert lvm2 and encrypt hooks like so\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003EHOOKS=(base udev autodetect __keyboard__ consolefont modconf block __lvm2__ __encrypt__ filesystems fsck)\u003C\/span\u003E\u003C\/i\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003ERecreate initramfs images for lts and general kernel\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emkinitcpio -P linux-lts\u003C\/span\u003E\u003C\/i\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emkinitcpio -P linux\u003C\/span\u003E\u003C\/i\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003C\/ul\u003E\u003Cdiv\u003EInstall the processor microcode\u003C\/div\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Epacman -S intel-ucode\u003C\/i\u003E\u003C\/span\u003E OR \u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epacman -S amd-ucode\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EInstall bootloader\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epacman -S grub efibootmgr mtools\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003ESet the kernel parameters for grub\u003C\/div\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003EServer\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Evim \/etc\/default\/grub\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Eroot=dev\/vgmain\/lvroot\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003EThis needs to be added to\u0026nbsp;\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003EGRUB_CMDLINE_LINUX\u003C\/span\u003E\u003C\/i\u003E\u0026nbsp;section\u003C\/li\u003E\u003C\/ul\u003E\u003Cli\u003EDesktop\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Evim \/etc\/default\/grub\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Ecryptdevice=UUID=xxxx-xxxx-xxxx-xxxxxx:root root=\/dev\/mapper\/root\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003EThe UUID is of the cryptlvroot logical volume. This needs to be added to\u0026nbsp;\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003EGRUB_CMDLINE_LINUX\u003C\/span\u003E\u003C\/i\u003E section\u003C\/li\u003E\u003Cli\u003EYou can also add \u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Elvm\u003C\/span\u003E\u003C\/i\u003E to\u0026nbsp;\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003EGRUB_PRELOAD_MODULES\u003C\/i\u003E\u003C\/span\u003E section, but this is optional as we will be using \u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Egrub-mkconfig\u003C\/i\u003E\u003C\/span\u003E later\u003C\/li\u003E\u003C\/ul\u003E\u003C\/ul\u003E\u003Cdiv\u003ESetup GRUB\u003C\/div\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Egrub-install --target=x86_64-efi --efi-directory=\/boot --bootloader-id=GRUB\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Egrub-mkconfig -o \/boot\/grub\/grub.cfg\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cdiv\u003ETime to reboot into the new system\u003C\/div\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Eexit\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Eumount -a\u003C\/span\u003E\u003C\/i\u003E [Safe to ignore any errors saying the system is busy]\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Ereboot\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cdiv\u003EThat's a wrap. :)\u003C\/div\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cp\u003E\u003C\/p\u003E"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/2238747154747798126\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2020\/12\/arch-install-desktop-vs-server.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/2238747154747798126"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/2238747154747798126"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2020\/12\/arch-install-desktop-vs-server.html","title":"Arch Install Desktop vs Server Differences"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgOj0t3NkwYRU8Rwg_0LDp6CndOSLrlZqz-sB1XiOgL8XWY8cO7HUZ-MEJd3d6NnoFa4hH0wUGkJYu76dHbM5KnZkKglLHQEduW46I8KOQYx3rC9q1U3CrLn52Cb1zTH5f5Mb7Fcf4qUps\/s72-w640-h312-c\/archey.jpg","height":"72","width":"72"},"thr$total":{"$t":"0"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-4828370950034223991"},"published":{"$t":"2020-11-26T12:36:00.001-08:00"},"updated":{"$t":"2020-11-26T12:36:12.828-08:00"},"title":{"type":"text","$t":"How I used Udev with systemd to configure an AIO water cooler in Linux"},"content":{"type":"html","$t":"\u003Cp\u003E\u0026nbsp;Let me start by telling a little bit of the back story. Recently I build a mini ITX desktop PC to help me with my more resource intensive programming work. I used a all in one liquid cooler in this PC. (\u003Ca href=\"https:\/\/www.nzxt.com\/products\/kraken-x63\" target=\"_blank\"\u003EKraken X63\u003C\/a\u003E). Setting something like this in Windows is quite straight forward, not so much in Linux. In this article I will detail what I did to get it working the way I wanted.\u0026nbsp;\u003C\/p\u003E\u003Cp\u003EFirst problem to solve was to find a driver\/controller software for the cooler, that works in Linux. These coolers come with only windows driver\/controller software with no official Linux support. Thanks to the awesome open source community there is a cross platform tool that I can use to talk to the API of the liquid cooler which is called \u003Ca href=\"https:\/\/github.com\/jonasmalacofilho\/liquidctl\" target=\"_blank\"\u003Eliquidctl\u003C\/a\u003E. To be more specific I had to use an experimental \u003Ca href=\"https:\/\/github.com\/jonasmalacofilho\/liquidctl\/tree\/1.4.x-branch\" target=\"_blank\"\u003Ebranch\u003C\/a\u003E of this tool that supported the API version of my hardware.\u0026nbsp;\u003C\/p\u003E\u003Cp\u003EInstallation is quite straight forward. My preferred Linux distro is \u003Ca href=\"https:\/\/www.archlinux.org\/\" target=\"_blank\"\u003EArch\u003C\/a\u003E. I used an already ported AUR repository of the mainline and switched to the branch I needed before building the source.\u0026nbsp;\u003C\/p\u003E\u003Cp\u003E\u003C\/p\u003E\u003Cul style=\"text-align: left;\"\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`git clone https:\/\/aur.archlinux.org\/liquidctl.git `\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`git checkout -b 1.4.x`\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`makepkg –sic`\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cdiv\u003EThat's it for installation. Now to test it out\u003C\/div\u003E\u003Cdiv\u003E\u003Cul style=\"text-align: left;\"\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E`sudo liquidctl status`\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cdiv\u003E[image]\u003C\/div\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EThis is the default settings. Now I need to configure the cooler with values I need. I wanted to change 2 configuration options\u003C\/div\u003E\u003Cdiv\u003E\u003Cul style=\"text-align: left;\"\u003E\u003Cli\u003EThe cooler pump speed relative to the coolant temperature\u003C\/li\u003E\u003Cli\u003ESwitch off the decorative RGB lighting of the cooler\u003C\/li\u003E\u003C\/ul\u003E\u003Cdiv\u003EAfter referencing the API details given in the \u003Ca href=\"https:\/\/github.com\/jonasmalacofilho\/liquidctl\" target=\"_blank\"\u003Eliquidctl\u003C\/a\u003E package. I narrowed down the API calls I needed to do.\u003C\/div\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cul style=\"text-align: left;\"\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`liquidctl set pump speed 25 25 30 30 34 80 40 90 50 100 `\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`liquidctl set ring color off`\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`liquidctl set logo color off`\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cdiv\u003ENow that I have a way to control the cooler the next step is automating it. The cooler is not able to persist it's settings, so I need set these settings after every system boot. The way to do that is using \u003Ca href=\"https:\/\/en.wikipedia.org\/wiki\/Systemd\" target=\"_blank\"\u003Esystemd\u003C\/a\u003E. The steps involved are,\u003C\/div\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003ECreate a systemd unit\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E`sudo vim \/etc\/systemd\/system\/liquidcfg.service`\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cli\u003EContents of the file\u003C\/li\u003E\u003C\/ul\u003E\u003C\/div\u003E\u003C\/div\u003E\u003Cp\u003E\u003C\/p\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E[Unit]\u0026nbsp;\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cdiv\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003EDescription=AIO startup service\u0026nbsp;\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E\u003Cbr \/\u003E\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E[Service]\u0026nbsp;\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003EType=oneshot\u0026nbsp;\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003EExecStart=liquidctl set pump speed 25 25 30 30 34 80 40 90 50 100\u0026nbsp;\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003EExecStart=liquidctl set ring color off\u0026nbsp;\u0026nbsp;\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003EExecStart=liquidctl set logo color off\u0026nbsp;\u0026nbsp;\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003ERemainAfterExit=yes\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E\u0026nbsp;\u0026nbsp;\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E[Install]\u0026nbsp;\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003EWantedBy=default.target\u0026nbsp;\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cul style=\"text-align: left;\"\u003E\u003Cli\u003ESetup the newly created unit to run on every boot\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`systemctl daemon-reload`\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`systemctl start liquidcfg`\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`systemctl enable liquidcfg`\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003C\/ul\u003E\u003C\/div\u003E\u003Cdiv\u003EI thought that was all I needed to do. After a few restarts I started noticing the configurations failed to reflect intermittently. The root cause was a race condition. The cooler exposes it's API via an USB interface. If the interface drivers was loaded when the new systemd service executes everything goes smoothly not so otherwise. Thus simply running the systemd unit during startup is not an option. I used Udev to solve this race condition.\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ca href=\"https:\/\/en.wikipedia.org\/wiki\/Udev\" target=\"_blank\"\u003EUdev\u003C\/a\u003E is the device manager for the Linux kernal. As mentioned the cooler has a internal usb connection. If I try to set the configuration before this connection is established the race condition occurs. Using Udev I can identify and trigger the settings change after the USB connection is established.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EFirst of all I needed to find the USB connection details. I used \u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`lsusb`\u003C\/i\u003E\u003C\/span\u003E command. I had to install \u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`usbutils`\u003C\/i\u003E\u003C\/span\u003E package to get this. If you are in a \u003Ca href=\"https:\/\/www.debian.org\/\" target=\"_blank\"\u003Edebian\u003C\/a\u003E based distro you probably will have this package already installed. \u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`lsusb`\u003C\/i\u003E\u003C\/span\u003E gave me the following info about the device,\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003EBus 001 Device 004: ID 1e71:2007 NZXT NZXT USB Device\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EUsing the above information I created a new Udev rule file \u003Cspan style=\"color: #666666;\"\u003E`\/lib\/udev\/rules.d\/99-z-kraken.rules`\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003ESUBSYSTEM==\"usb\", ATTRS{idVendor}==\"1e71\", ATTRS{idProduct}==\"2007\", MODE=\"0666\", TAG+=\"systemd\", ENV{SYSTEMD_WANTS}+=\"liquidcfg.service\"\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003ESUBSYSTEM==\"hidraw\", SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"1e71\", ATTRS{idProduct}==\"2007\", MODE=\"0666\", TAG+=\"systemd\", ENV{SYSTEMD_WANTS}+=\"liquidcfg.service\"\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003ENow I disabled the previous systemd service from automatically starting at startup\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`systemctl disable liquidcfg`\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EAfterwords reload the udev rules so that my new rule will take effect\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E`udevadm control --reload`\u003C\/i\u003E\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EThat solved the race condition. Now I can view the status of the cooling system using `liquidctl status`\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEizcxssGU_KfwxriTM1CKbDaje3JObxYCWmN0TcAekP_kD7r4sXSREVMSGXH5YGtojCRmc-b1fE33WkVnkndZRhdWzPNQp-MFHoX7NWgH4SfD0mfzNj22MF2vjW2KehkZemVGT9kg5co3A\/s380\/status.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"102\" data-original-width=\"380\" height=\"172\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEizcxssGU_KfwxriTM1CKbDaje3JObxYCWmN0TcAekP_kD7r4sXSREVMSGXH5YGtojCRmc-b1fE33WkVnkndZRhdWzPNQp-MFHoX7NWgH4SfD0mfzNj22MF2vjW2KehkZemVGT9kg5co3A\/w640-h172\/status.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EThat's a wrap.\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003C\/div\u003E\u003Cp\u003E\u003Cbr \/\u003E\u003C\/p\u003E"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/4828370950034223991\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2020\/11\/how-i-used-udev-with-systemd-to.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/4828370950034223991"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/4828370950034223991"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2020\/11\/how-i-used-udev-with-systemd-to.html","title":"How I used Udev with systemd to configure an AIO water cooler in Linux"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEizcxssGU_KfwxriTM1CKbDaje3JObxYCWmN0TcAekP_kD7r4sXSREVMSGXH5YGtojCRmc-b1fE33WkVnkndZRhdWzPNQp-MFHoX7NWgH4SfD0mfzNj22MF2vjW2KehkZemVGT9kg5co3A\/s72-w640-h172-c\/status.jpg","height":"72","width":"72"},"thr$total":{"$t":"0"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-8049446503363794677"},"published":{"$t":"2020-09-27T10:36:00.010-07:00"},"updated":{"$t":"2020-10-04T16:51:11.893-07:00"},"title":{"type":"text","$t":"Nextcloud on Arch Linux (Encrypted System) [Part 01 - Preparation]"},"content":{"type":"html","$t":"\u003Cp style=\"text-align: justify;\"\u003E\u0026nbsp;In this series of posts I'm going to outline the process I used to create my own \u003Ca href=\"https:\/\/nextcloud.com\/\" target=\"_blank\"\u003ENextcloud\u003C\/a\u003E server.\u0026nbsp;\u003C\/p\u003E\u003Ch2 style=\"text-align: left;\"\u003ENetwork Setup\u003C\/h2\u003E\u003Cp style=\"text-align: justify;\"\u003EFirst step is to prepare my network. I'm planning to host this at home. Due to obvious security concerns I don't want to host this on my home network. I used \u003Ca href=\"https:\/\/www.pfsense.org\/\" target=\"_blank\"\u003EpfSense\u003C\/a\u003E\u0026nbsp;to achieve what I want. The pfSense setup is outside the scope of this post. If you do need help or is curious about setting up pfSense let me know. Given below is an overview diagram of my network,\u0026nbsp;\u003C\/p\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEg71wE2wfWQQ9cNUPp9YUGvvJcpnSyElF3wIbOAg5jt8pBElZQ2JgOWrzdldPdbK1BcqBNLrn0PxxrrOFFRQlm1ffiECb1MJhiKeu862HrPjZYgUzS1WMqHPnTBxpybOK9O-ARZy7YWV-Q\/s752\/network.jpg\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"752\" data-original-width=\"718\" height=\"640\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEg71wE2wfWQQ9cNUPp9YUGvvJcpnSyElF3wIbOAg5jt8pBElZQ2JgOWrzdldPdbK1BcqBNLrn0PxxrrOFFRQlm1ffiECb1MJhiKeu862HrPjZYgUzS1WMqHPnTBxpybOK9O-ARZy7YWV-Q\/w612-h640\/network.jpg\" width=\"612\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cbr \/\u003E\u003Cp style=\"text-align: justify;\"\u003EThe basic firewall rules in this network are\u003C\/p\u003E\u003Cp style=\"text-align: justify;\"\u003E\u003C\/p\u003E\u003Cul\u003E\u003Cli\u003EServer can't talk to the switch.\u0026nbsp;\u003C\/li\u003E\u003Cli\u003EServer can't talk to the pfSense router interface\u003C\/li\u003E\u003Cli\u003EServer interface has \u003Ca href=\"https:\/\/suricata-ids.org\/\" target=\"_blank\"\u003ESuricata\u003C\/a\u003E IDS\/IPS running.\u0026nbsp;\u003C\/li\u003E\u003C\/ul\u003E\u003Cp\u003E\u003C\/p\u003E\u003Ch2 style=\"text-align: left;\"\u003EDrive Preparation and Encryption\u003C\/h2\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ciframe allowfullscreen=\"\" class=\"BLOG_video_class\" height=\"266\" src=\"https:\/\/www.youtube.com\/embed\/cxMYR617a5E\" width=\"320\" youtube-src-id=\"cxMYR617a5E\"\u003E\u003C\/iframe\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Ch3 style=\"text-align: left;\"\u003ESecure erase the drive.\u0026nbsp;\u003C\/h3\u003E\u003Cdiv\u003E\u003Cb\u003ENote: The drive I used was an old HDD. What I didn't notice was that the partition table was of type DOS. Had to change that to GPT and repeat this process in order for it to work.\u003C\/b\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EI'm going to use a 250GB HDD for my instalation (not a SSD). First step is to secure erase the drive. \u003Ca href=\"https:\/\/wiki.archlinux.org\/index.php\/Dm-crypt\/Drive_preparation\" target=\"_blank\"\u003E(ref)\u003C\/a\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cul style=\"text-align: left;\"\u003E\u003Cli\u003EUse `\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Elsblk\u003C\/span\u003E\u003C\/i\u003E` to identify the drive\u0026nbsp;\u003C\/li\u003E\u003C\/ul\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjv_ud8-Nsc5bq6Vr5_bBR8xFY2CeJkwOlSIJ50MarcJOr-rBukSRiUZ2RfQ6b8MEqwUe6NO5CM0eyt8hJImnEyIqDkFj82qMyLOM2EkeuUaPTbJsrNxtJPbcfYuyCftGn78AIBRiPy8vg\/s591\/blog_01.jpg\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"402\" data-original-width=\"591\" height=\"435\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjv_ud8-Nsc5bq6Vr5_bBR8xFY2CeJkwOlSIJ50MarcJOr-rBukSRiUZ2RfQ6b8MEqwUe6NO5CM0eyt8hJImnEyIqDkFj82qMyLOM2EkeuUaPTbJsrNxtJPbcfYuyCftGn78AIBRiPy8vg\/w640-h435\/blog_01.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cul style=\"text-align: left;\"\u003E\u003Cli\u003ECreate a temporary container across the whole drive using `\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Ecryptsetup open --type plain -d \/dev\/random \/dev\/sda wipe\u003C\/span\u003E\u003C\/i\u003E`\u003C\/li\u003E\u003C\/ul\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEj3CHA6hbiSva5g6gilPkRJOitG9vtNqtppXdjX-Kv11CjXne_SYpq8AyGHJZ0-aI6J2T-mPFHA1SdhLm7GtzdMmEUO23xZV28AdhWpLDHlGyta-Pzgr-DY81iWqW9avvrNeQ11ypWDgn8\/s702\/blog_02.jpg\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"345\" data-original-width=\"702\" height=\"314\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEj3CHA6hbiSva5g6gilPkRJOitG9vtNqtppXdjX-Kv11CjXne_SYpq8AyGHJZ0-aI6J2T-mPFHA1SdhLm7GtzdMmEUO23xZV28AdhWpLDHlGyta-Pzgr-DY81iWqW9avvrNeQ11ypWDgn8\/w640-h314\/blog_02.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cul style=\"text-align: left;\"\u003E\u003Cli\u003EWipe the container with zeroes using `\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Edd if=\/dev\/zero of=\/dev\/mapper\/wipe status=progress bs=1M\u003C\/span\u003E\u003C\/i\u003E`. According to the \u003Ca href=\"https:\/\/wiki.archlinux.org\/index.php\/Dm-crypt\/Drive_preparation\" target=\"_blank\"\u003Edm-crypt documentation\u003C\/a\u003E\u0026nbsp;use of \u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Eif=\/dev\/urandom\u003C\/span\u003E\u003C\/i\u003E is not required as the encryption cipher is used for randomness.\u003C\/li\u003E\u003C\/ul\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjGxBArnm3pwX_hTTwYXl5_iaxpQwLgnrZlwFR_YoOm7BjCe3V8TxWC0jn8eAF4dyjTxEjtygJqiT3gD6zepcBoTI-KekHTfyHENeAeLWJWzjDWH4wVBDM7-FW7YGxzjlrmEeRn3oLOg2Y\/s619\/blog_03.jpg\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"242\" data-original-width=\"619\" height=\"250\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjGxBArnm3pwX_hTTwYXl5_iaxpQwLgnrZlwFR_YoOm7BjCe3V8TxWC0jn8eAF4dyjTxEjtygJqiT3gD6zepcBoTI-KekHTfyHENeAeLWJWzjDWH4wVBDM7-FW7YGxzjlrmEeRn3oLOg2Y\/w640-h250\/blog_03.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cul style=\"text-align: left;\"\u003E\u003Cli\u003EClose the temporary container using `\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Ecryptsetup close wipe\u003C\/span\u003E\u003C\/i\u003E`\u003C\/li\u003E\u003C\/ul\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhOaidkqmjzCzxEWnIaIuIkC1Ibe2elkIXq9YjC8grQWk98cqqstPQhAK-zl4oscC_uNSsm1sQH0NcJZWVhO8Iy5eTPjdL9f-s9ATtia1rALnjUAEefpFOji6oMXYl2gie1hjf_MepcIHg\/s865\/blog_04.jpg\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"519\" data-original-width=\"865\" height=\"384\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhOaidkqmjzCzxEWnIaIuIkC1Ibe2elkIXq9YjC8grQWk98cqqstPQhAK-zl4oscC_uNSsm1sQH0NcJZWVhO8Iy5eTPjdL9f-s9ATtia1rALnjUAEefpFOji6oMXYl2gie1hjf_MepcIHg\/w640-h384\/blog_04.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cul style=\"text-align: left;\"\u003E\u003Cli\u003EReboot and confirm that the drive is now empty and all the previous partitions are gone.\u003C\/li\u003E\u003C\/ul\u003E\u003C\/div\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjD10V98TzvDu3F69wYjNHqAt896IbovfJifnX1whUAuQKylQivRnwWkTXB2oi_yWu6gTC7dNI7cFSgz_QBFMe5bHTxbjB7ZS8aLX9XVrLuizmCTUQwuNxlT9794QRjCMpm1aX5OWhjrJQ\/s600\/blog_05.jpg\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"363\" data-original-width=\"600\" height=\"388\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjD10V98TzvDu3F69wYjNHqAt896IbovfJifnX1whUAuQKylQivRnwWkTXB2oi_yWu6gTC7dNI7cFSgz_QBFMe5bHTxbjB7ZS8aLX9XVrLuizmCTUQwuNxlT9794QRjCMpm1aX5OWhjrJQ\/w640-h388\/blog_05.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Ch3 style=\"text-align: left;\"\u003ECreate efi boot and LUKS encrypted root partition\u003C\/h3\u003E\u003Cp\u003ENow that the partition table of the drive is empty, I first created 2 partitions for the efi boot (512MB) and root(50GB). The efi boot partitions type was set to \"ef\". (step by step shown in the video). The boot partition is the only partition that won't be encrypted in this system. USB and other boot options will be disabled in bios, and password protected. This will prevent bootable media attacks.\u0026nbsp;\u003C\/p\u003E\u003Cp\u003E\u003C\/p\u003E\u003Cul style=\"text-align: left;\"\u003E\u003Cli\u003ESince the efi boot partition won't be encrypted it can be directly formatted by using `\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emkfs.fat -F32 \/dev\/sda1\u003C\/span\u003E\u003C\/i\u003E`\u003C\/li\u003E\u003C\/ul\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEg5otiK83kVI_8sXBCdlg_jgG4THBSwDNQhGjFCuuIx_nBjfHoic5sRJwmxMJSccjojDCG4p1gVMp0rKPYqYAYczD6dPv7AyQ2Lf7IFvFeKFEwuK_O5sOgsBm-Th_wirAAlcd1QBZZ7tGA\/s526\/blog_06.jpg\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"203\" data-original-width=\"526\" height=\"246\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEg5otiK83kVI_8sXBCdlg_jgG4THBSwDNQhGjFCuuIx_nBjfHoic5sRJwmxMJSccjojDCG4p1gVMp0rKPYqYAYczD6dPv7AyQ2Lf7IFvFeKFEwuK_O5sOgsBm-Th_wirAAlcd1QBZZ7tGA\/w640-h246\/blog_06.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cul style=\"text-align: left;\"\u003E\u003Cli\u003EThen I created the LUKS encrypted partition inside the previously created root partition using `\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Ecryptsetup -y -v luksFormat \/dev\/sda2\u003C\/span\u003E\u003C\/i\u003E`.\u0026nbsp;\u003C\/li\u003E\u003C\/ul\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhnQ7dMZHljlq0Lo2pS2JTWzNGLTys52rCQwo-so7HSx1Cy3DuZwSxHbS1qCV-AwgYIVGK67_a0zvfR-biGddb6trd3WuX1sWGTKQLosFnCnANl3bE0al7I4ZUiVJ6r_Spk5_Ha-_WtaM8\/s700\/blog_07.jpg\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"410\" data-original-width=\"700\" height=\"374\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhnQ7dMZHljlq0Lo2pS2JTWzNGLTys52rCQwo-so7HSx1Cy3DuZwSxHbS1qCV-AwgYIVGK67_a0zvfR-biGddb6trd3WuX1sWGTKQLosFnCnANl3bE0al7I4ZUiVJ6r_Spk5_Ha-_WtaM8\/w640-h374\/blog_07.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cul style=\"text-align: left;\"\u003E\u003Cli\u003EThe newly created encrypted root needs to be opened and formatted. The paraphrase is needed for this operation. Afterwords it can be mounted.\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003EOpen: `\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Ecryptsetup open \/dev\/sda2 cryptroot\u003C\/span\u003E\u003C\/i\u003E`\u003C\/li\u003E\u003Cli\u003EFormat: `\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emkfs.ext4 \/dev\/mapper\/cryptroot\u003C\/span\u003E\u003C\/i\u003E`\u003C\/li\u003E\u003Cli\u003EMount: `\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emount \/dev\/mapper\/cryptroot \/mnt\u003C\/span\u003E\u003C\/i\u003E`\u003C\/li\u003E\u003C\/ul\u003E\u003Cli\u003ENow I\"m going to unmount and close the encrypted root and use it during the OS install.\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003EUnmount: `\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Eumount \/mnt\u003C\/span\u003E\u003C\/i\u003E`\u003C\/li\u003E\u003Cli\u003EClose: `\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Ecryptsetup close cryptroot\u003C\/span\u003E\u003C\/i\u003E`\u003C\/li\u003E\u003C\/ul\u003E\u003C\/ul\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgUBLBjmRBzPmfQz-xOCXnbr9tbWJytYUqZN2ATtkBhFM-punFizi6zPBLsnc2aTcOXaiy_Dds7IBc5_UdMOhe8CtteEKU6QWRLX5ikigkLg5WPQfzUXQYOUILdSror-zmrhju6z6gUSc0\/s906\/blog.08.jpg\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"906\" data-original-width=\"719\" height=\"640\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgUBLBjmRBzPmfQz-xOCXnbr9tbWJytYUqZN2ATtkBhFM-punFizi6zPBLsnc2aTcOXaiy_Dds7IBc5_UdMOhe8CtteEKU6QWRLX5ikigkLg5WPQfzUXQYOUILdSror-zmrhju6z6gUSc0\/w508-h640\/blog.08.jpg\" width=\"508\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Ch2 style=\"text-align: left;\"\u003ENext Steps\u003C\/h2\u003E\u003Cdiv\u003E\u003Cul style=\"text-align: left;\"\u003E\u003Cli\u003EInstalling the OS\u003C\/li\u003E\u003Cli\u003ESetting up Dropbear so the encrypted root can be unlocked headless\u003C\/li\u003E\u003Cli\u003ESetting up encrypted data partitions\u003C\/li\u003E\u003Cli\u003EConfiguring Nextcloud\u003C\/li\u003E\u003C\/ul\u003E\u003Cdiv\u003EStay tuned...\u003C\/div\u003E\u003C\/div\u003E"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/8049446503363794677\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2020\/09\/nextcloud-on-arch-linux-encrypted.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/8049446503363794677"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/8049446503363794677"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2020\/09\/nextcloud-on-arch-linux-encrypted.html","title":"Nextcloud on Arch Linux (Encrypted System) [Part 01 - Preparation]"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEg71wE2wfWQQ9cNUPp9YUGvvJcpnSyElF3wIbOAg5jt8pBElZQ2JgOWrzdldPdbK1BcqBNLrn0PxxrrOFFRQlm1ffiECb1MJhiKeu862HrPjZYgUzS1WMqHPnTBxpybOK9O-ARZy7YWV-Q\/s72-w612-h640-c\/network.jpg","height":"72","width":"72"},"thr$total":{"$t":"0"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-1136148174127275583"},"published":{"$t":"2020-09-25T18:50:00.001-07:00"},"updated":{"$t":"2020-09-25T18:50:44.040-07:00"},"title":{"type":"text","$t":"Arch Linux install on XP3 13 9300 (Dual boot with Windows 10)"},"content":{"type":"html","$t":"\u003Cp\u003E\u0026nbsp;In this article I will detail the steps I followed to install Arch Linux in my XPS 13 9300. It came with windows 10 preinstalled.\u0026nbsp;\u003C\/p\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEioLITtkc5ymzyn1iyoHzD0Tjx4bCQIuPmjMXmHji6F8RoMxs-HqDg5PF8UMjC044q4T9e6muYQe8ZKrq5AECg7pXLP8a90dZs1oRaY3zA0saRCUWfcRz3MbvkRHhck8TT4I9bK0wqh3tc\/s740\/archey3.jpg\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"353\" data-original-width=\"740\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEioLITtkc5ymzyn1iyoHzD0Tjx4bCQIuPmjMXmHji6F8RoMxs-HqDg5PF8UMjC044q4T9e6muYQe8ZKrq5AECg7pXLP8a90dZs1oRaY3zA0saRCUWfcRz3MbvkRHhck8TT4I9bK0wqh3tc\/s16000\/archey3.jpg\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cbr \/\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EMy main references during the process was,\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ca href=\"https:\/\/wiki.archlinux.org\/index.php\/installation_guide\" target=\"_blank\"\u003Einstallation_guide [Arch Wiki]\u003C\/a\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Ca href=\"https:\/\/wiki.archlinux.org\/index.php\/Dell_XPS_13_(9300)\" target=\"_blank\"\u003EDell_XPS_13_(9300) [Arch Wiki]\u003C\/a\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Ch2 style=\"text-align: left;\"\u003EPrerequisites\u003C\/h2\u003E\u003Cdiv style=\"text-align: justify;\"\u003EThe first step is to change the SATA mode from \"RAID\" to \"AHCI\". Without doing this the linux installation can't identify the nvme drive on the laptop. This involves going through a few steps.\u0026nbsp;\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cul\u003E\u003Cli\u003EBoot into windows and run the following commands\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003EOpen a command promt with admin rights\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #999999;\"\u003Ebcdedit \/set {current} safeboot minimal\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003ERestart into bios and change the SATA mode to AHCI\u003C\/li\u003E\u003Cli\u003EBoot back to windows and open an admin command prompt\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Ebcdedit \/deletevalue {current} safeboot\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003EWhen I run\u0026nbsp;\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Ebcdedit \/enum\u003C\/span\u003E\u003C\/i\u003E it doesn't show \"safeboot\" any more.\u0026nbsp;\u003C\/li\u003E\u003C\/ul\u003E\u003C\/ul\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjBl3v0_reVjm8eQwHCzkpkbtSlg2sNb5pU8AL8SL4U-iWCEUTfUueFCBQU_uMDWppyHbZR-YRNggPPIZutEe-NxmJwyRKLNexpdWYMRX8PPTyuAj31xmmjt6n_KyplEZ8X-HzFZMTu4I0\/s687\/bcdedit.jpg\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"687\" data-original-width=\"527\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjBl3v0_reVjm8eQwHCzkpkbtSlg2sNb5pU8AL8SL4U-iWCEUTfUueFCBQU_uMDWppyHbZR-YRNggPPIZutEe-NxmJwyRKLNexpdWYMRX8PPTyuAj31xmmjt6n_KyplEZ8X-HzFZMTu4I0\/s16000\/bcdedit.jpg\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cbr \/\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003ENext I disabled fast startup on windows. I'm doing this as I may choose to mount windows partitions when I'm on linux, and fast startup setting is known to cause issues. I only use windows to play games which I rarely do these days. So windows taking a few more seconds to load is not of a concern to me. So I disabled fast startup via \"Power and sleep settings\" -\u0026gt; \"Additional power settings\"\u003C\/div\u003E\u003Ch2\u003EInstallation media\u003C\/h2\u003E\u003Cdiv\u003ENext I prepared an Arch installation media. I did this on my old laptop which was running Ubuntu. I used \u003Ca href=\"https:\/\/www.balena.io\/etcher\/\"\u003EEtcher\u003C\/a\u003E to write the downloaded iso to a USB. I also used the following commands to verify the integrity of the downloaded iso file.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Esha1sum archlinux-2020.08.01-x86_64.iso\u0026nbsp;\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emd5sum archlinux-2020.08.01-x86_64.iso\u003C\/span\u003E\u003C\/i\u003E\u0026nbsp;\u003C\/li\u003E\u003C\/ul\u003E\u003C\/div\u003E\u003C\/div\u003E\u003Ch2\u003EPartitioning\u003C\/h2\u003E\u003Cdiv\u003EAfter that I booted into the Arch install usb media. At this point I have a custom windows installation with an already shrinked C drive. If not I would have booted into an Ubuntu installation media and used \"\u003Ca href=\"https:\/\/gparted.org\/\"\u003Egparted\u003C\/a\u003E\" to resize the partitions.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EI used \u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Elsblk\u003C\/span\u003E\u003C\/i\u003E command to identify my current partition structure.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u0026nbsp;\u0026nbsp;\u0026nbsp;\u003C\/div\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgKeMhDaHBHaURHw57wjqxhLOwDsSXU037xsbqUS1qrKl1GsACIwFE6aOva-ZBYASgpJfK_2_EhGHVit3qO7pGOx0p18To4DCCiEFvhmLKgHDERHR5OfgwhEWz4sZ4RiKe0lxsYOjLNZkM\/s538\/lsblk1.jpg\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"320\" data-original-width=\"538\" height=\"380\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgKeMhDaHBHaURHw57wjqxhLOwDsSXU037xsbqUS1qrKl1GsACIwFE6aOva-ZBYASgpJfK_2_EhGHVit3qO7pGOx0p18To4DCCiEFvhmLKgHDERHR5OfgwhEWz4sZ4RiKe0lxsYOjLNZkM\/w640-h380\/lsblk1.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003EThe \"nvme0n1p5\" is the windows recovery partition and \"nvme0n1p6\" is my windows data partition. I'm going to delete both these partitions to gain space for the Arch installation. This is done with \u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Efdisk\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Efdisk nvme0n1\u003C\/span\u003E\u003C\/i\u003E - This took me into the fdisk mode for the nvme drive\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Ed\u003C\/span\u003E\u003C\/i\u003E and press \"Enter\" to accept to delete the last partition\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Ed\u003C\/span\u003E\u003C\/i\u003E and press \"Enter\" again to delete one more partition from the bottom\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003En\u003C\/span\u003E\u003C\/i\u003E and press \"Enter\" to create a new partition\u003C\/li\u003E\u003Cli\u003E\"\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E+512M\u003C\/span\u003E\u003C\/i\u003E\" to specify the new partition size. I'm going to use this as my efi boot partition\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Et\u003C\/span\u003E\u003C\/i\u003E to change partition type\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E1\u003C\/span\u003E\u003C\/i\u003E to choose \"EFI\" as the partition type\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003En\u003C\/span\u003E\u003C\/i\u003E again to create the Arch installation partition\u003C\/li\u003E\u003Cli\u003E\"\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E+50G\u003C\/span\u003E\u003C\/i\u003E\" to specify size\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003En\u003C\/span\u003E\u003C\/i\u003E again to create the home partition followed by two \"Enter\" keys to accept the remaining space for the home partition\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Ep\u003C\/span\u003E\u003C\/i\u003E to view what will be created followed by \u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Ew\u003C\/span\u003E\u003C\/i\u003E to write the changes to disk\u003C\/li\u003E\u003C\/ul\u003E\u003Cdiv\u003ENow when I use \u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Elsblk\u003C\/span\u003E\u003C\/i\u003E it shows the newly changed partition structure.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEijnO4D2dhN5wNL-slR7GGaEeq42UQtIZ1Eiqks3oKYWaUzBCSR5dpaFZTURdmI1-sy0sfhFCizynfA4QXb6dRxAeipoxcX3_cHxnxyH9y-P5mbDNt3xj044fO4rxSqzYdWf8xYjPRjzns\/s536\/lsblk2.jpg\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"296\" data-original-width=\"536\" height=\"354\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEijnO4D2dhN5wNL-slR7GGaEeq42UQtIZ1Eiqks3oKYWaUzBCSR5dpaFZTURdmI1-sy0sfhFCizynfA4QXb6dRxAeipoxcX3_cHxnxyH9y-P5mbDNt3xj044fO4rxSqzYdWf8xYjPRjzns\/w640-h354\/lsblk2.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Cbr \/\u003E\u003C\/div\u003ENow that I have the partition structure next step was to format them. The UFI boot partition needs to be fat32 and for the rest I used ext4\u003C\/div\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emkfs.fat -F32 \/dev\/nvme0n1p5\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emkfs.ext4 \/dev\/nvme0n1p6\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emkfs.ext4 \/dev\/nvme0n1p7\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cdiv\u003EThen I continued to mount the partitions. The main Arch installation partition is mounted to \u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E\/mnt\u003C\/span\u003E\u003C\/i\u003E. Boot and home partitions are mounted to \u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E\/mnt\/boot \u003C\/i\u003E\u003C\/span\u003Eand \u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E\/mnt\/home\u003C\/span\u003E\u003C\/i\u003E respectively\u003C\/div\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Emount \/dev\/nvme0n1p6 \/mnt\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Emkdir \/mnt\/home\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Emount \/dev\/nvme0n1p7 \/mnt\/home\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Emkdir \/mnt\/boot\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Emount \/dev\/nvme0n1p5 \/mnt\/boot\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003C\/div\u003E\u003Cdiv\u003EThen I created the fstab file. This is needed to mount these during boot. the \u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003E-U\u003C\/i\u003E\u003C\/span\u003E flag was used to identify the partitions using \u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003EUUID\u003C\/i\u003E\u003C\/span\u003E instead of labels etc.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Emkdir mnt\/etc\/\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Egenfstab -U \/mnt \u0026gt;\u0026gt; \/mnt\/etc\/fstab\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003C\/div\u003E\u003C\/div\u003E\u003Ch2\u003EInstalation\u003C\/h2\u003E\u003Cdiv\u003EI have everything ready to start the installation. First step is to establish an internet connection. Arch installation media\u0026nbsp; comes with the\u0026nbsp;\u003Ca href=\"https:\/\/wiki.archlinux.org\/index.php\/Iwd\"\u003EiNet wireless daemon\u003C\/a\u003E. I used it to establish a wifi connection.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Eiwctl\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Estation wlan0 connect [SSID]\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003C\/div\u003E\u003Cdiv\u003EThen I used \u003Ca href=\"https:\/\/jlk.fjfi.cvut.cz\/arch\/manpages\/man\/pacstrap.8\"\u003Epacstrap\u003C\/a\u003E\u0026nbsp;to install the essentials to the previously created new linux root \u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E\/mnt\u003C\/span\u003E\u003C\/i\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epacstrap \/mnt base linux linux-firmware linux-headers linux-lts linux-lts-headers\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003C\/div\u003E\u003Cdiv\u003EThe latest rolling and the long term kernels were installed using the above command. The header files were installed to support additional module builds in the future. I plan to use the latest rolling kernel for the most part but the LTS kernel may come in handy to recover from kernel panics. Now is the time to switch to the newly installed linux instalation from the usb.\u003C\/div\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Earch-chroot \/mnt\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003C\/div\u003E\u003Cdiv\u003EFirst things first. Install my favorite editors\u003C\/div\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epacman -Sy vim nano\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003C\/div\u003E\u003Cdiv\u003ENext is the boring task of configuration. I followed the \u003Ca href=\"https:\/\/wiki.archlinux.org\/index.php\/installation_guide\"\u003EArch wiki\u003C\/a\u003E for this.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003ESet timezone\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Eln -sf \/usr\/share\/zoneinfo\/America\/Los_Angeles \/etc\/localtime\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Ehwclock --systohc\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cli\u003ELocal config\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Evim \/etc\/locale.gen\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003EUncomment \u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Een_US.UTF-8 UTF-8\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Elocale-gen\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003Evim \u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E\/etc.locale-conf\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003EEnter \u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003ELANG=en_US.UTF-8\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cli\u003ENetwork config\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Evim \/etc\/hostname\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003Cli\u003EEnter name\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Evim \/etc\/hosts\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003EEnter\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E127.0.0.1 localhost\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E::1 localhost\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E127.0.1.1 [name].localdomain [name]\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003C\/ul\u003E\u003C\/ul\u003E\u003Ch3\u003ECreate users and set passwords\u003C\/h3\u003E\u003C\/div\u003E\u003Cdiv\u003EI used passwd command to set the root password then created an everyday user for myself and set a new password to that user\u003C\/div\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Euseradd -g users -G power,storage,wheel -m [name]\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epasswd [name]\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003C\/div\u003E\u003Ch3\u003EBootloader\u003C\/h3\u003E\u003Cdiv\u003ENext I setup grub as the boot-loader. This is the time to get the dual boot with windows setup.\u0026nbsp;\u003C\/div\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003EInstall intel processor microcode\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Cspan style=\"color: #666666;\"\u003E\u003Ci\u003Epacman -S intel-ucode\u003C\/i\u003E\u003C\/span\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cli\u003EInstall grub and util packages\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epacman -S grub efibootmgr mtools\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cli\u003EInstall os-prober and identify Windows\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epacman -S os-prober\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Eos-prober\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cli\u003EInstall grub\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Egrub-install --target=x86_64-efi --efi-directory=\/boot\/ --bootloader-id=GRUB\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cli\u003EMount the windows efi boot partition to a temporary location\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emkdir \/mntwin\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emount \/dev\/nvme0n1p2 \/mntwin\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Egrub-mkconfig -o \/boot\/grub\/grub.cfg\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003C\/ul\u003E\u003Cdiv\u003EThe output confirms that the windows installation was identified.\u0026nbsp;\u003C\/div\u003E\u003C\/div\u003E\u003C\/div\u003E\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhJd2kBPjmWutuUe1sqLLLcuvW9VMpr3MTsavqZVIaedbruxD0v96JooG2svjdv2qqwF1XL0Gy4AHD33qyzgRp1aXitmVHRNE9Op4bc8qLWc8VMSmStLQmwDb0vMJyBCVOgCyTKVo083G8\/s941\/grub.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"591\" data-original-width=\"941\" height=\"402\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhJd2kBPjmWutuUe1sqLLLcuvW9VMpr3MTsavqZVIaedbruxD0v96JooG2svjdv2qqwF1XL0Gy4AHD33qyzgRp1aXitmVHRNE9Op4bc8qLWc8VMSmStLQmwDb0vMJyBCVOgCyTKVo083G8\/w640-h402\/grub.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\u003Cbr \/\u003E\u003Ch3 style=\"text-align: justify;\"\u003ESetup continues...\u003C\/h3\u003E\u003Cdiv style=\"text-align: justify;\"\u003E\u003Cul\u003E\u003Cli\u003EInstall network tools and enable network related \u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Esystemd\u003C\/span\u003E\u003C\/i\u003E services\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epacman -S base-devel networkmanager dialog\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Esystemctl enable NetworkManager\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Esystemctl enable systemd-networkd.service\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Esystemctl enable systemd-resolved.service\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cli\u003ECreate initial ramdisk for the kernels\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emkinitcpio -p linux\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emkinitcpio -p linux-lts\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cli\u003EInstall and configure sudo\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003EInstall sudo and configure so that any user in the wheel group can elevate themselves after confirming the password\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epacman -S sudo\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Evisudo\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003EUncomment and change wheel access line to \u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003E%wheel ALL=(ALL) ALL\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cli\u003ECreate swap file\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Edd if=\/dev\/zero of=\/swapfile bs=1M count=8192 status=progress\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Echmod 600 \/swapfile\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Emkswap \/swapfile\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Eecho '\/swapfile none swap 0 0' | tee -a \/etc\/fstab\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cli\u003EReboot into the new system\u003C\/li\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Eexit\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Eumount -a\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Ereboot\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003C\/ul\u003E\u003Ch2\u003EGnome Install\u003C\/h2\u003E\u003Cdiv\u003EAmazeballs! Now that I have a working arch system I'm gonna install my favorite desktop environment. First I need to connect and setup wifi\u003C\/div\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Enmcli device wifi connect GasGembi password [password]\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cdiv\u003EThen install Gnome\u003C\/div\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Epacman -S xorg-server\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Esudo pacman -S gnome gnome-extra\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Esudo systemctl enable gdm\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cdiv\u003EAfter rebooting I was greeted with the Gnome login screen. :)\u003C\/div\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003EOne last thing. Setting up bluetooth\u003C\/div\u003E\u003Cdiv\u003E\u003Cul\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Elsmod | grep btusb\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Esudo pacman -S bluez bluez-utils\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ci\u003E\u003Cspan style=\"color: #666666;\"\u003Esystemctl enable bluetooth.service\u003C\/span\u003E\u003C\/i\u003E\u003C\/li\u003E\u003C\/ul\u003E\u003Cdiv\u003EThe XPS 13 9300 also comes with a fingerprint sensor and windows hello capabilities. I will address the linux setup for these in a future post.\u0026nbsp;\u003C\/div\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cbr \/\u003E\u003C\/div\u003E\u003C\/div\u003E\u003Cp\u003E\u003Cbr \/\u003E\u003C\/p\u003E\u003Cp\u003E\u003C\/p\u003E"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/1136148174127275583\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2020\/09\/arch-linux-install-on-xp3-13-9300-dual.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/1136148174127275583"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/1136148174127275583"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2020\/09\/arch-linux-install-on-xp3-13-9300-dual.html","title":"Arch Linux install on XP3 13 9300 (Dual boot with Windows 10)"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEioLITtkc5ymzyn1iyoHzD0Tjx4bCQIuPmjMXmHji6F8RoMxs-HqDg5PF8UMjC044q4T9e6muYQe8ZKrq5AECg7pXLP8a90dZs1oRaY3zA0saRCUWfcRz3MbvkRHhck8TT4I9bK0wqh3tc\/s72-c\/archey3.jpg","height":"72","width":"72"},"thr$total":{"$t":"0"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-2906638488682766869"},"published":{"$t":"2020-01-21T21:13:00.001-08:00"},"updated":{"$t":"2020-01-21T21:13:59.852-08:00"},"title":{"type":"text","$t":"Hello SMB, bye bye OMV"},"content":{"type":"html","$t":"\u003Cdiv style=\"text-align: justify;\"\u003E\nIn this post I'm going to talk about why and how I moved my Open Media Vault Network Attached Storage system to my Ubuntu server.\u003C\/div\u003E\n\u003Cbr \/\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nIn my \u003Ca href=\"https:\/\/blog.coding-mayhem.com\/2019\/11\/nas-build-part-iii.html\" target=\"_blank\"\u003Eprevious posts\u003C\/a\u003E I talked about my OMV NAS. In my NAS I have the following things set up.\u003C\/div\u003E\n\u003Cul\u003E\n\u003Cli\u003ESMB shares that can be accessed by both Windows and Linux machines\u003C\/li\u003E\n\u003Cli\u003ECustom user permissions\u003C\/li\u003E\n\u003Cli\u003EAutomated backups\u003C\/li\u003E\n\u003Cli\u003EMetrics and logging\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nIn an attempt to be more frugal I'm trying to reduce the number of servers in my home lab. So lets talk through the process of moving this setup from OMV to Ubuntu.\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nWhat's involved,\u0026nbsp;\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cul\u003E\n\u003Cli\u003EMounting multiple USB hard disks to the same location between reboots\u003C\/li\u003E\n\u003Cli\u003ECreating samba shares in Ubuntu server\u003C\/li\u003E\n\u003Cli\u003ESetting up SMB in windows client machines\u003C\/li\u003E\n\u003Cli\u003EAutomated backups using \u003Ca href=\"https:\/\/linux.die.net\/man\/1\/rsync\" target=\"_blank\"\u003Ersync\u003C\/a\u003E and \u003Ca href=\"http:\/\/manpages.ubuntu.com\/manpages\/trusty\/man8\/cron.8.html\" target=\"_blank\"\u003Ecron\u003C\/a\u003E\u003C\/li\u003E\n\u003Cli\u003EMetrics and logging\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Cdiv\u003E\n\u003Ch2\u003E\n\u003Cu\u003EMounting USB drives permanently\u003C\/u\u003E\u003C\/h2\u003E\nAs mentioned \u003Ca href=\"https:\/\/blog.coding-mayhem.com\/2019\/11\/nas-build-part-ii.html\" target=\"_blank\"\u003Ebefore\u003C\/a\u003E I'm using 3 USB hard drives for storage and backup. These USB drives needs to be mounted to the same location all the time because the SMB shares and the rsync cron job depends on it.\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\nEvery disk partition has a unique identifier which is called an UUID. Firstly you need to find this. This can be found using the \u003Ca href=\"https:\/\/linux.die.net\/man\/8\/blkid\" target=\"_blank\"\u003Eblkid\u003C\/a\u003E command. You may or may not need super user permissions to do this. You can issue \"\u003Cb\u003E\u003Ci\u003Esudo blkid\u003C\/i\u003E\u003C\/b\u003E\" command to find the UUID of all drives connected to your system or you can issue \"\u003Cb\u003E\u003Ci\u003Esudo blkid\u0026nbsp;[device ...]\u003C\/i\u003E\u003C\/b\u003E\" to find the UUID or a specific partition.\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiZKNXvtbGDGV_qCtp36TdQ9YWO57gWcswPJV7_T8qngOvG41BSk-zskfn_xgspQ-juGyyTYEvJpWc_FjsUCmBlJOZqUkd4wapSHsJkpGWrmRsID0OO554sGpBDiHPiTFqfSSinvQDLDKM\/s1600\/Screenshot+from+2020-01-19+16-57-30.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"314\" data-original-width=\"1600\" height=\"125\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiZKNXvtbGDGV_qCtp36TdQ9YWO57gWcswPJV7_T8qngOvG41BSk-zskfn_xgspQ-juGyyTYEvJpWc_FjsUCmBlJOZqUkd4wapSHsJkpGWrmRsID0OO554sGpBDiHPiTFqfSSinvQDLDKM\/s640\/Screenshot+from+2020-01-19+16-57-30.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\nArmed with the UUIDs of my USB disk drives I created mount points for them. I created 3 folders in \"\/media\" as mount points for the disks. Next step is to add entries into the file system tables or\u0026nbsp;\u003Ca href=\"https:\/\/help.ubuntu.com\/community\/Fstab\" target=\"_blank\"\u003Efstab\u003C\/a\u003E. Fstab is generally used to mount internal devices. In my use case though I'm going to use fstab to permanently mount my USB disk drives. The syntax for the \u003Ca href=\"https:\/\/help.ubuntu.com\/community\/Fstab\" target=\"_blank\"\u003Efstab\u003C\/a\u003E is,\u003C\/div\u003E\n\u003Cpre style=\"background-color: #f3f3f3; border: 1px dashed rgb(193, 180, 150); color: #333333; font-family: UbuntuMono, courier, monospace; font-size: 13px; line-height: 16px; margin-bottom: 8px; overflow-wrap: break-word; padding: 4pt; text-align: left; vertical-align: baseline; white-space: pre-wrap;\"\u003E[Device] [Mount Point] [File System Type] [Options] [Dump] [Pass]\u003C\/pre\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\nI added 3 new entries to my \u003Cb\u003E\u003Ci\u003E\/etc\/fstab\u003C\/i\u003E\u003C\/b\u003E file.\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEi7Snr97Chl0WZJ4scvZzuG0XBN3qzu5GCRWCd-i3_jdRUTsyRtK4V_XW_BLQmgm0X17cJvwmYN2gb2dAY96n9uZrJ6MPa_S2XB9_eYe4MMUx_JrbnByOet5qg1704kL3EsHOdi0pWEIY8\/s1600\/Screenshot+from+2020-01-19+18-25-30.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"468\" data-original-width=\"1590\" height=\"188\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEi7Snr97Chl0WZJ4scvZzuG0XBN3qzu5GCRWCd-i3_jdRUTsyRtK4V_XW_BLQmgm0X17cJvwmYN2gb2dAY96n9uZrJ6MPa_S2XB9_eYe4MMUx_JrbnByOet5qg1704kL3EsHOdi0pWEIY8\/s640\/Screenshot+from+2020-01-19+18-25-30.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\nI validated the disk mount locations with a few restarts.\u0026nbsp;\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Ch2 style=\"clear: both; text-align: justify;\"\u003E\n\u003Cu\u003ECreating Samba shares\u003C\/u\u003E\u003C\/h2\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\nI installed samba into my Ubuntu server using the \u003Ca href=\"https:\/\/help.ubuntu.com\/lts\/serverguide\/apt.html\" target=\"_blank\"\u003Eapt\u003C\/a\u003E tool\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\n\u003C\/div\u003E\n\u003Cpre style=\"background-color: #f3f3f3; border: 1px dashed rgb(193, 180, 150); color: #333333; font-family: UbuntuMono, courier, monospace; font-size: 13px; line-height: 16px; margin-bottom: 8px; overflow-wrap: break-word; padding: 4pt; text-align: left; vertical-align: baseline; white-space: pre-wrap;\"\u003Esudo apt install samba\u003C\/pre\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\nNext comes the user management. Firstly I created the users I need in my Ubuntu server using the \"\u003Ca href=\"https:\/\/linux.die.net\/man\/8\/adduser\" target=\"_blank\"\u003Eadduser\u003C\/a\u003E\" command. Samba doesn't use system passwords so I needed to set the samba passwords for the users.\u003C\/div\u003E\n\u003Cpre style=\"background-color: #f3f3f3; border: 1px dashed rgb(193, 180, 150); color: #333333; font-family: UbuntuMono, courier, monospace; font-size: 13px; line-height: 16px; margin-bottom: 8px; overflow-wrap: break-word; padding: 4pt; text-align: left; vertical-align: baseline; white-space: pre-wrap;\"\u003Esudo adduser user1\nsudo smbpasswd -a user1\u003C\/pre\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\nThen I created the samba shares. The configuration has to be added to the \"\u003Cb\u003E\u003Ci\u003E\/etc\/samba\/smb.conf\u003C\/i\u003E\u003C\/b\u003E\".\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEg5rdY5SSrpdxeVPFVn2yndDkYun6lRawX3327s7zut7QSdgl5pVqoztttbd1rnpHs_DX1B42jAdOPC6lH5DYhcwMB0lC-52nMyHx-DiZC9-Yt4lKeX21tr3NG3u-7nXB4XLxveym_2G-I\/s1600\/Screenshot+from+2020-01-20+08-47-21.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"1022\" data-original-width=\"1496\" height=\"436\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEg5rdY5SSrpdxeVPFVn2yndDkYun6lRawX3327s7zut7QSdgl5pVqoztttbd1rnpHs_DX1B42jAdOPC6lH5DYhcwMB0lC-52nMyHx-DiZC9-Yt4lKeX21tr3NG3u-7nXB4XLxveym_2G-I\/s640\/Screenshot+from+2020-01-20+08-47-21.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\nGiven above is the config for one of the shared folders. The configuration follows the samba \u003Ca href=\"https:\/\/www.samba.org\/samba\/docs\/current\/man-html\/smb.conf.5.html\" target=\"_blank\"\u003Esyntax\u003C\/a\u003E. Linux permissions proceed samba permissions so the folders shared has less restrictive permissions to allow \"others\" category read, write and execute permissions as needed.\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Ch2 style=\"clear: both; text-align: justify;\"\u003E\n\u003Cu\u003EEnabling Samba in Windows\u003C\/u\u003E\u003C\/h2\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\nIn order for the windows machines in my network to view the samba shares I had to enable the SMB file sharing support windows feature.\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhELdfFWB6B2ia8HnakeAUTUaYGv-hn8QgLHw-P_NIiRbSn04HyfA-8uCaSdv8_EnKiox2xaqzBPzecBA3KLujnrtW7bReKtdJabMNkYBaSMBESmjR7AUMiOHHsUuHXD7iN_SpmebagYXQ\/s1600\/cfs.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"769\" data-original-width=\"1515\" height=\"324\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhELdfFWB6B2ia8HnakeAUTUaYGv-hn8QgLHw-P_NIiRbSn04HyfA-8uCaSdv8_EnKiox2xaqzBPzecBA3KLujnrtW7bReKtdJabMNkYBaSMBESmjR7AUMiOHHsUuHXD7iN_SpmebagYXQ\/s640\/cfs.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\nI will talk about the backups and logging in a future post. Stay tuned ...\u003C\/div\u003E\n\u003C\/div\u003E\n"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/2906638488682766869\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2020\/01\/hello-smb-bye-bye-omv.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/2906638488682766869"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/2906638488682766869"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2020\/01\/hello-smb-bye-bye-omv.html","title":"Hello SMB, bye bye OMV"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiZKNXvtbGDGV_qCtp36TdQ9YWO57gWcswPJV7_T8qngOvG41BSk-zskfn_xgspQ-juGyyTYEvJpWc_FjsUCmBlJOZqUkd4wapSHsJkpGWrmRsID0OO554sGpBDiHPiTFqfSSinvQDLDKM\/s72-c\/Screenshot+from+2020-01-19+16-57-30.jpg","height":"72","width":"72"},"thr$total":{"$t":"0"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-830349664271273779"},"published":{"$t":"2019-12-26T20:29:00.000-08:00"},"updated":{"$t":"2019-12-29T18:40:04.483-08:00"},"title":{"type":"text","$t":"Intel vs AMD for my server"},"content":{"type":"html","$t":"This is a continuation of my previous post \"\u003Ca href=\"https:\/\/blog.coding-mayhem.com\/2019\/11\/building-server-from-scratch.html\"\u003EBuilding a Server from scratch\u003C\/a\u003E\"\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Ctable align=\"center\" cellpadding=\"0\" cellspacing=\"0\" class=\"tr-caption-container\" style=\"margin-left: auto; margin-right: auto; text-align: center;\"\u003E\u003Ctbody\u003E\n\u003Ctr\u003E\u003Ctd style=\"text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgIJGT5ulr3YbWZHJAXqokoNqjdwoPW4rV_jIpWmLja03I2oehOwAERFb_yTai1Io-RjtPS6LUn8wy6ymBX8pjetAupFN739MXEVX7Vd38uRYxOqgESS6zWwM6bXKgoOFSK-F6DwdIL3v0\/s1600\/IMG_7188.jpg\" imageanchor=\"1\" style=\"margin-left: auto; margin-right: auto;\"\u003E\u003Cimg border=\"0\" data-original-height=\"1600\" data-original-width=\"1521\" height=\"640\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgIJGT5ulr3YbWZHJAXqokoNqjdwoPW4rV_jIpWmLja03I2oehOwAERFb_yTai1Io-RjtPS6LUn8wy6ymBX8pjetAupFN739MXEVX7Vd38uRYxOqgESS6zWwM6bXKgoOFSK-F6DwdIL3v0\/s640\/IMG_7188.jpg\" width=\"608\" \/\u003E\u003C\/a\u003E\u003C\/td\u003E\u003C\/tr\u003E\n\u003Ctr\u003E\u003Ctd class=\"tr-caption\" style=\"text-align: center;\"\u003EMy XPS 12 9q33This Too Shall Pass\u003C\/td\u003E\u003C\/tr\u003E\n\u003C\/tbody\u003E\u003C\/table\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003C\/div\u003E\n\u003Cbr \/\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nLets recap. In my \u003Ca href=\"https:\/\/blog.coding-mayhem.com\/2019\/11\/building-server-from-scratch.html\"\u003Eprevious\u003C\/a\u003E post I narrowed down the processor (\u003Ca href=\"https:\/\/ark.intel.com\/content\/www\/us\/en\/ark\/products\/134870\/intel-core-i3-9100-processor-6m-cache-up-to-4-20-ghz.html\"\u003Ei3-9100\u003C\/a\u003E), chipset (\u003Ca href=\"https:\/\/ark.intel.com\/content\/www\/us\/en\/ark\/products\/133332\/intel-b360-chipset.html\"\u003EB360\u003C\/a\u003E) and the motherboard (\u003Ca href=\"https:\/\/www.asus.com\/us\/Motherboards\/PRIME-B360M-A\/\"\u003EAsus B360M-A\u003C\/a\u003E) I would use if I'm going with an Intel system. This would cost me about $235. In this post I'll be looking at a comparable AMD system. The main areas I'll be covering in this post are,\u003Cbr \/\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"https:\/\/www.blogger.com\/blogger.g?blogID=9001854664565320016#ancProcessor\"\u003EAMD processor discovery\u003C\/a\u003E\u003C\/li\u003E\n\u003Cli\u003E\u003Ca href=\"https:\/\/www.blogger.com\/blogger.g?blogID=9001854664565320016#ancCompProc\"\u003ECompare the chosen AMD processor with the Intel one\u003C\/a\u003E\u003C\/li\u003E\n\u003Cli\u003E\u003Ca href=\"https:\/\/www.blogger.com\/blogger.g?blogID=9001854664565320016#ancChip\"\u003EChipset and Motherboard options for the chosen AMD processor\u003C\/a\u003E\u003C\/li\u003E\n\u003Cli\u003E\u003Ca href=\"https:\/\/www.blogger.com\/blogger.g?blogID=9001854664565320016#ancMem\"\u003EChoosing the right memory for my server\u003C\/a\u003E\u003C\/li\u003E\n\u003Cli\u003E\u003Ca href=\"https:\/\/www.blogger.com\/blogger.g?blogID=9001854664565320016#ancPsu\"\u003EHow to choose a power supply unit\u003C\/a\u003E\u003C\/li\u003E\n\u003Cli\u003E\u003Ca href=\"https:\/\/www.blogger.com\/blogger.g?blogID=9001854664565320016#ancHdd\"\u003EHard drive selection\u003C\/a\u003E\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Ca href=\"https:\/\/www.blogger.com\/null\" name=\"ancProcessor\"\u003E\u003C\/a\u003EGenerally when comparing processors, the main parameters to look at are;\u003Cbr \/\u003E\n\u003Cul\u003E\n\u003Cli\u003EClock speed\u003C\/li\u003E\n\u003Cli\u003ENumber of cores\u003C\/li\u003E\n\u003Cli\u003ENumber of threads\u003C\/li\u003E\n\u003Cli\u003ELocked \/ Unlocked ( in other words is it overclockable )\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Cdiv\u003E\nIn this instance since, my requirement is to run a server on this hardware and the number of cores becomes the major deciding factor. Cause having more cores will improve my virtualization options.\u003C\/div\u003E\n\u003Cbr \/\u003E\nAMD \u003Ca href=\"https:\/\/www.amd.com\/en\/processors\/athlon-and-a-series#ATHLON\"\u003EAthlon\u003C\/a\u003E\u0026nbsp;and\u0026nbsp;\u003Ca href=\"https:\/\/www.amd.com\/en\/ryzen-3\"\u003ERyzen 3\u003C\/a\u003E are comfortably within my price range and some \u003Ca href=\"https:\/\/www.amd.com\/en\/ryzen-5\"\u003ERyzen 5\u003C\/a\u003E processors also fall within my budget.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Ca href=\"https:\/\/www.amd.com\/en\/processors\/athlon-and-a-series#ATHLON\"\u003EAthlon\u003C\/a\u003E\u0026nbsp;\u0026nbsp;processors has 2 cores and 4 threads. The price is very competitive. Compared to the 4 cores and 4 threads of my selected Intel processor they don't look very attractive to me even at their price point.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Ca href=\"https:\/\/www.amd.com\/en\/ryzen-3\"\u003ERyzen 3\u003C\/a\u003E\u0026nbsp;processors has 4 cores and can run 4 threads. There are 2 options. \u003Ca href=\"https:\/\/www.amd.com\/en\/products\/apu\/amd-ryzen-3-2200g\"\u003ERyzen 3 2200g\u003C\/a\u003E and \u003Ca href=\"https:\/\/www.amd.com\/en\/products\/apu\/amd-ryzen-3-3200g\"\u003ERyzen 3 3200g\u003C\/a\u003E.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Ca href=\"https:\/\/www.amd.com\/en\/ryzen-5\"\u003ERyzen 5\u003C\/a\u003E processors has a 6 core and 4 core varieties that can run 12 and 8 threads respectively. All these are better options for my use case rather than the\u0026nbsp;\u003Ca href=\"https:\/\/ark.intel.com\/content\/www\/us\/en\/ark\/products\/134870\/intel-core-i3-9100-processor-6m-cache-up-to-4-20-ghz.html\"\u003Ei3-9100\u003C\/a\u003E. When considering the price, 2 of these processors which has 4 cores and 8 threads with integrated graphics is within the price range. They are the \u003Ca href=\"https:\/\/www.amd.com\/en\/products\/apu\/amd-ryzen-5-2400g\"\u003ERyzen 5 2400g\u003C\/a\u003E and \u003Ca href=\"https:\/\/www.amd.com\/en\/products\/apu\/amd-ryzen-5-3400g\"\u003ERyzen 5 3400g\u003C\/a\u003E.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nWhen looking at the Ryzen 5 models without discrete graphics I need to consider the possible cost of a low end graphics card. The \u003Ca href=\"https:\/\/www.amd.com\/en\/products\/cpu\/amd-ryzen-5-2600\"\u003ERyzen 5 2600\u003C\/a\u003E, and the \u003Ca href=\"https:\/\/www.amd.com\/en\/products\/cpu\/amd-ryzen-5-2600x\"\u003ERyzen5 2600X\u003C\/a\u003E seem like possible candidates in this sector. \n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nLet's have a closer look at these 6 processors.\u003C\/div\u003E\n\u003Cstyle\u003E\n        .compare_table table {\n            border-collapse: collapse;\n            table-layout: fixed;\n            width: 900px;\n        }\n        .compare_table th,\n        .compare_table td {\n            padding: 15px;\n            border: 1px solid green;\n            width: 100px;\n        }\n    \u003C\/style\u003E\n    \u003Cbr \/\u003E\n\u003Ctable align=\"center\" class=\"compare_table\"\u003E\n\u003Cthead\u003E\n\u003Ctr\u003E\n  \u003Cth colspan=\"2\"\u003E\u003C\/th\u003E\n  \u003Cth\u003ERyzen 3 2200g\u003C\/th\u003E\n  \u003Cth\u003ERyzen 3 3200g\u003C\/th\u003E\n  \u003Cth\u003ERyzen 5 2400g\u003C\/th\u003E\n  \u003Cth\u003ERyzen 5 3400g\u003C\/th\u003E\n  \u003Cth\u003ERyzen 5 2600\u003C\/th\u003E\n  \u003Cth\u003ERyzen 5 2600x\u003C\/th\u003E\n \u003C\/tr\u003E\n\u003C\/thead\u003E\n\u003Ctbody\u003E\n\u003Ctr\u003E\n \u003Ctd colspan=\"2\"\u003E\u003Cstrong\u003E# cores\u003C\/strong\u003E\u003C\/td\u003E\n \u003Ctd\u003E4\u003C\/td\u003E\n \u003Ctd\u003E4\u003C\/td\u003E\n \u003Ctd\u003E4\u003C\/td\u003E\n \u003Ctd\u003E4\u003C\/td\u003E\n \u003Ctd\u003E6\u003C\/td\u003E\n \u003Ctd\u003E6\u003C\/td\u003E\n\u003C\/tr\u003E\n\u003Ctr\u003E\n \u003Ctd colspan=\"2\"\u003E\u003Cstrong\u003E# threads\u003C\/strong\u003E\u003C\/td\u003E\n \u003Ctd\u003E4\u003C\/td\u003E\n \u003Ctd\u003E4\u003C\/td\u003E\n \u003Ctd\u003E8\u003C\/td\u003E\n \u003Ctd\u003E8\u003C\/td\u003E\n \u003Ctd\u003E12\u003C\/td\u003E\n \u003Ctd\u003E12\u003C\/td\u003E\n\u003C\/tr\u003E\n\u003Ctr\u003E\n \u003Ctd colspan=\"7\"\u003EClock speed\u003C\/td\u003E\n\u003C\/tr\u003E\n\u003Ctr\u003E\n \u003Ctd\u003E\u003C\/td\u003E\n \u003Ctd\u003E\u003Cstrong\u003EBase\u003C\/strong\u003E\u003C\/td\u003E\n \u003Ctd\u003E3.5GHz\u003C\/td\u003E\n \u003Ctd\u003E3.6GHz\u003C\/td\u003E\n \u003Ctd\u003E3.6GHz\u003C\/td\u003E\n \u003Ctd\u003E3.7GHz\u003C\/td\u003E\n \u003Ctd\u003E3.4GHz\u003C\/td\u003E\n \u003Ctd\u003E3.6GHz\u003C\/td\u003E\n\u003C\/tr\u003E\n\u003Ctr\u003E\n \u003Ctd\u003E\u003C\/td\u003E\n \u003Ctd\u003E\u003Cstrong\u003EBoost\u003C\/strong\u003E\u003C\/td\u003E\n \u003Ctd\u003E3.7GHz\u003C\/td\u003E\n \u003Ctd\u003E4GHz\u003C\/td\u003E\n \u003Ctd\u003E3.9GHz\u003C\/td\u003E\n \u003Ctd\u003E4.2GHz\u003C\/td\u003E\n \u003Ctd\u003E3.9GHz\u003C\/td\u003E\n \u003Ctd\u003E4.2GHz\u003C\/td\u003E\n\u003C\/tr\u003E\n\u003Ctr\u003E\n \u003Ctd colspan=\"7\"\u003ECache\u003C\/td\u003E\n\u003C\/tr\u003E\n\u003Ctr\u003E\n \u003Ctd\u003E\u003C\/td\u003E\n \u003Ctd\u003EL1\u003C\/td\u003E\n \u003Ctd\u003E384KB\u003C\/td\u003E\n \u003Ctd\u003E384KB\u003C\/td\u003E\n \u003Ctd\u003E384KB\u003C\/td\u003E\n \u003Ctd\u003E384KB\u003C\/td\u003E\n \u003Ctd\u003E576KB\u003C\/td\u003E\n \u003Ctd\u003E576KB\u003C\/td\u003E\n\u003C\/tr\u003E\n\u003Ctr\u003E\n \u003Ctd\u003E\u003C\/td\u003E\n \u003Ctd\u003EL2\u003C\/td\u003E\n \u003Ctd\u003E2MB\u003C\/td\u003E\n \u003Ctd\u003E2MB\u003C\/td\u003E\n \u003Ctd\u003E2MB\u003C\/td\u003E\n \u003Ctd\u003E2MB\u003C\/td\u003E\n \u003Ctd\u003E3MB\u003C\/td\u003E\n \u003Ctd\u003E3MB\u003C\/td\u003E\n\u003C\/tr\u003E\n\u003Ctr\u003E\n \u003Ctd\u003E\u003C\/td\u003E\n \u003Ctd\u003EL3\u003C\/td\u003E\n \u003Ctd\u003E4MB\u003C\/td\u003E\n \u003Ctd\u003E4MB\u003C\/td\u003E\n \u003Ctd\u003E4MB\u003C\/td\u003E\n \u003Ctd\u003E4MB\u003C\/td\u003E\n \u003Ctd\u003E16MB\u003C\/td\u003E\n \u003Ctd\u003E16MB\u003C\/td\u003E\n\u003C\/tr\u003E\n\u003Ctr\u003E\n \u003Ctd colspan=\"2\"\u003E\u003Cstrong\u003EIntegrated Graphics\u003C\/strong\u003E\u003C\/td\u003E\n \u003Ctd\u003Eyes\u003C\/td\u003E\n \u003Ctd\u003Eyes\u003C\/td\u003E\n \u003Ctd\u003Eyes\u003C\/td\u003E\n \u003Ctd\u003Eyes\u003C\/td\u003E\n \u003Ctd\u003Eno\u003C\/td\u003E\n \u003Ctd\u003Eno\u003C\/td\u003E\n\u003C\/tr\u003E\n\u003C\/tbody\u003E\n\u003C\/table\u003E\n\u003Cbr \/\u003E\nWe have a clear winner here. The\u0026nbsp;\u003Ca href=\"https:\/\/www.amd.com\/en\/products\/cpu\/amd-ryzen-5-2600\" style=\"text-align: justify;\"\u003ERyzen 5 2600x\u003C\/a\u003E.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Ca href=\"https:\/\/www.blogger.com\/null\" name=\"ancCompProc\"\u003E\u003C\/a\u003ELets compare the\u0026nbsp;\u003Ca href=\"https:\/\/www.amd.com\/en\/products\/cpu\/amd-ryzen-5-2600x\" style=\"text-align: justify;\"\u003ERyzen 5 2600x\u003C\/a\u003E\u0026nbsp;and the\u0026nbsp;\u003Ca href=\"https:\/\/ark.intel.com\/content\/www\/us\/en\/ark\/products\/134870\/intel-core-i3-9100-processor-6m-cache-up-to-4-20-ghz.html\" style=\"text-align: justify;\"\u003Ei3-9100\u003C\/a\u003E\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Ctable align=\"center\" class=\"compare_table\"\u003E\n\u003Cthead\u003E\n\u003Ctr\u003E\n  \u003Cth colspan=\"2\"\u003E\u003C\/th\u003E\n  \u003Cth\u003ERyzen 5 2600x\u003C\/th\u003E\n  \u003Cth\u003ECore i3-9100\u003C\/th\u003E\n \u003C\/tr\u003E\n\u003C\/thead\u003E\n\u003Ctbody\u003E\n\u003Ctr\u003E\n  \u003Ctd colspan=\"2\"\u003E# of cores\u003C\/td\u003E\n  \u003Ctd\u003E6\u003C\/td\u003E\n  \u003Ctd\u003E4\u003C\/td\u003E\n \u003C\/tr\u003E\n\u003Ctr\u003E\n  \u003Ctd colspan=\"2\"\u003E# of threads\u003C\/td\u003E\n  \u003Ctd\u003E12\u003C\/td\u003E\n  \u003Ctd\u003E4\u003C\/td\u003E\n \u003C\/tr\u003E\n\u003Ctr\u003E\n  \u003Ctd colspan=\"4\"\u003EClock speed\u003C\/td\u003E\n \u003C\/tr\u003E\n\u003Ctr\u003E\n  \u003Ctd\u003E\u003C\/td\u003E\n  \u003Ctd\u003EBase\u003C\/td\u003E\n  \u003Ctd\u003E3.6GHz\u003C\/td\u003E\n  \u003Ctd\u003E3.6GHz\u003C\/td\u003E\n \u003C\/tr\u003E\n\u003Ctr\u003E\n  \u003Ctd\u003E\u003C\/td\u003E\n  \u003Ctd\u003EBoost \/ Turbo\u003C\/td\u003E\n  \u003Ctd\u003E4.2GHz\u003C\/td\u003E\n  \u003Ctd\u003E4.2GHz\u003C\/td\u003E\n \u003C\/tr\u003E\n\u003Ctr\u003E\n  \u003Ctd colspan=\"2\"\u003EIntegrated graphics\u003C\/td\u003E\n  \u003Ctd\u003Eno\u003C\/td\u003E\n  \u003Ctd\u003Eyes\u003C\/td\u003E\n \u003C\/tr\u003E\n\u003Ctr\u003E\n  \u003Ctd colspan=\"2\"\u003EMemory\u003C\/td\u003E\n  \u003Ctd\u003EDDR4-2933MHz\u003C\/td\u003E\n  \u003Ctd\u003EDDR4-2400MHz\u003C\/td\u003E\n \u003C\/tr\u003E\n\u003C\/tbody\u003E\n\u003C\/table\u003E\n\u003Cbr \/\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nSo, I'm gonna go with the\u0026nbsp;\u003Ca href=\"https:\/\/www.amd.com\/en\/products\/cpu\/amd-ryzen-5-2600x\" style=\"text-align: justify;\"\u003ERyzen5 2600X\u003C\/a\u003E\u0026nbsp;and get a refurbished basic graphics card. \u003Ca href=\"https:\/\/www.blogger.com\/null\" name=\"ancChip\"\u003E\u003C\/a\u003ENext, lets look at the chipset I should go with for the\u0026nbsp;\u003Ca href=\"https:\/\/www.amd.com\/en\/products\/cpu\/amd-ryzen-5-2600x\" style=\"text-align: justify;\"\u003ERyzen5 2600X\u003C\/a\u003E. The processor needs an AM4 chipset. Looking at the \u003Ca href=\"https:\/\/www.amd.com\/en\/products\/chipsets-am4\"\u003EAM4 chipsets\u003C\/a\u003E, there are 3 main categories of chipsets.\u003C\/div\u003E\n\u003Cbr \/\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nEssential (A320), Mainstream (B350, B450) and Enthusiast (X370, X470, X570). Lets have a closer look at these.\u003C\/div\u003E\n\u003Cbr \/\u003E\n\u003Ctable align=\"center\" class=\"compare_table\"\u003E\n\u003Cthead\u003E\n\u003Ctr\u003E\n  \u003Cth style=\"min-width: 200px;\"\u003E\u003C\/th\u003E\n  \u003Cth\u003EA320\u003C\/th\u003E\n  \u003Cth\u003EB350\u003C\/th\u003E\n  \u003Cth\u003EB450\u003C\/th\u003E\n  \u003Cth\u003EX370\u003C\/th\u003E\n  \u003Cth\u003EX470\u003C\/th\u003E\n  \u003Cth\u003EX570\u003C\/th\u003E\n \u003C\/tr\u003E\n\u003C\/thead\u003E\n\u003Ctbody\u003E\n\u003Ctr\u003E\n  \u003Ctd\u003E\u003Cstrong\u003EOverclocking enabled\u003C\/strong\u003E\u003C\/td\u003E\n  \u003Ctd\u003Eno\u003C\/td\u003E\n  \u003Ctd\u003Eyes\u003C\/td\u003E\n  \u003Ctd\u003Eyes\u003C\/td\u003E\n  \u003Ctd\u003Eyes\u003C\/td\u003E\n  \u003Ctd\u003Eyes\u003C\/td\u003E\n  \u003Ctd\u003Eyes\u003C\/td\u003E\n \u003C\/tr\u003E\n\u003Ctr\u003E\n  \u003Ctd\u003E\u003Cstrong\u003EMemory overclocking\u003C\/strong\u003E\u003C\/td\u003E\n  \u003Ctd\u003Eyes\u003C\/td\u003E\n  \u003Ctd\u003Eyes\u003C\/td\u003E\n  \u003Ctd\u003Eyes\u003C\/td\u003E\n  \u003Ctd\u003Eyes\u003C\/td\u003E\n  \u003Ctd\u003Eyes\u003C\/td\u003E\n  \u003Ctd\u003Eyes\u003C\/td\u003E\n \u003C\/tr\u003E\n\u003Ctr\u003E\n  \u003Ctd\u003E\u003Cstrong\u003EHigh speed platform lanes\u003C\/strong\u003E\u003C\/td\u003E\n  \u003Ctd\u003E24\u003C\/td\u003E\n  \u003Ctd\u003E28\u003C\/td\u003E\n  \u003Ctd\u003E28\u003C\/td\u003E\n  \u003Ctd\u003E38\u003C\/td\u003E\n  \u003Ctd\u003E38\u003C\/td\u003E\n  \u003Ctd\u003E40\u003C\/td\u003E\n \u003C\/tr\u003E\n\u003C\/tbody\u003E\n\u003C\/table\u003E\n\u003Cbr \/\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nI can get the full potential of my processor using a B350, B450 motherboard. \u003Ca href=\"https:\/\/www.asus.com\/us\/Motherboards\/PRIME-B450M-A-CSM\/\"\u003EASUS Prime B450M\u003C\/a\u003E seems like a good option to me.\u0026nbsp; These 2 would cost me around $204. Which is about $30 less than the Intel option but with this configuration I still need a graphics card. The lowest refurbished ones were around $40 to $60 dollars, which seems reasonable.\u003C\/div\u003E\n\u003Cbr \/\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Ca href=\"https:\/\/www.blogger.com\/null\" name=\"ancMem\"\u003E\u003C\/a\u003ENext step is to choose Memory.\u0026nbsp;There are a lot of discussions out there indicating Ryzen processors are much more sensitive to memory speeds. This is because of AMD's Infinity Fabrics dependency on the memory clock rate. What you need to remember is overclocking memory does affect the stability of the memory. When choosing memory there are 2 parameters to look for. The speed and the latency. DDR4 is stable at 2400MHz and the higher the speed the more costly they are. I'm not planning to overclock my memory but I would like to get a module, that at least specifies it can work at the chosen processors memory speed. Also I would go with the lowest latency I can get my hands on without breaking the bank.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nSo I'm looking for memory of specification\u0026nbsp;DDR4-2933 (PC4-23466) with a good latency. The latency is specified as column access strobe latency (CAS) which is the delay between the read command and the data availability. There are modules that specify CAS from 14 onward. I found 14c modules to be way too expensive. I chose 2 DIMMs of 8gb each with a latency of 16c for around $75.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Ca href=\"https:\/\/www.blogger.com\/null\" name=\"ancPsu\"\u003E\u003C\/a\u003ELets look at power supply options now. There are a few parameters to look for when choosing the power supply\u003Cbr \/\u003E\n\u003Cul\u003E\n\u003Cli\u003EMain parameters\u003C\/li\u003E\n\u003Cul\u003E\n\u003Cli\u003EMaximum power (400W, 500W etc...)\u003C\/li\u003E\n\u003Cli\u003EEnergy efficiency (80+, 80+ gold etc...)\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Cli\u003ESecondary parameters\u003C\/li\u003E\n\u003Cul\u003E\n\u003Cli\u003EModulararity\u003C\/li\u003E\n\u003Cli\u003E12v rails\u003C\/li\u003E\n\u003Cli\u003ESATA power connectors, SLI ready, Main connector pins\u003C\/li\u003E\n\u003Cli\u003EForm factor ( ATX, mATX etc...)\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003C\/ul\u003E\n\u003Cdiv\u003E\nFirst off, I need to calculate the maximum wattage for my system. I don't want to get a power supply that can't produce the power output required by my components for obvious reasons. I also don't want to get a power supply with more wattage either, cos more wattage rated PSUs are more expensive. There are many online calculators that allows you to input your devices and get the required wattage for your system. I used a couple of them and it seems I can safely say my power usage is going to be below 350W. So I'm gonna add a margin of error and go with a PSU of 400W.\u0026nbsp;\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\nThen comes the energy efficiency rating. There is a voluntary PSU rating certification program called \u003Ca href=\"https:\/\/en.wikipedia.org\/wiki\/80_Plus\"\u003E80 Plus\u003C\/a\u003E. The basic concept is how efficiently the power supply converts the AC energy to DC. Why is this important? When converting AC to DC current the lost efficiency is generally dissipated as heat. So the more efficient your power supply is the less heat it generates. Also that means you pay less on your electricity bill. Another point I would assume is, in order to create a more efficient PSU the manufacturers would have to use better rated components. The parameters I looked at in the\u0026nbsp;\u003Ca href=\"https:\/\/en.wikipedia.org\/wiki\/80_Plus\"\u003E80 Plus\u003C\/a\u003E\u0026nbsp;program are,\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Ctable align=\"center\" class=\"compare_table\"\u003E\n\u003Cthead\u003E\n\u003Ctr\u003E\n  \u003Cth style=\"min-width: 150px;\"\u003ELoad %\u003C\/th\u003E\n  \u003Cth\u003E20%\u003C\/th\u003E\n  \u003Cth\u003E50%\u003C\/th\u003E\n  \u003Cth\u003E100%\u003C\/th\u003E\n \u003C\/tr\u003E\n\u003C\/thead\u003E\n\u003Ctbody\u003E\n\u003Ctr\u003E\n  \u003Ctd\u003E\u003Cstrong\u003E80 Plus\u003C\/strong\u003E\u003C\/td\u003E\n  \u003Ctd\u003E80%\u003C\/td\u003E\n  \u003Ctd\u003E80%\u003C\/td\u003E\n  \u003Ctd\u003E80%\u003C\/td\u003E\n\u003C\/tr\u003E\n\u003Ctr\u003E\n  \u003Ctd\u003E\u003Cstrong\u003E80 Plus Bronze\u003C\/strong\u003E\u003C\/td\u003E\n  \u003Ctd\u003E82%\u003C\/td\u003E\n  \u003Ctd\u003E85%\u003C\/td\u003E\n  \u003Ctd\u003E82%\u003C\/td\u003E\n\u003C\/tr\u003E\n\u003Ctr\u003E\n  \u003Ctd\u003E\u003Cstrong\u003E80 Plus Silver\u003C\/strong\u003E\u003C\/td\u003E\n  \u003Ctd\u003E85%\u003C\/td\u003E\n  \u003Ctd\u003E88%\u003C\/td\u003E\n  \u003Ctd\u003E85%\u003C\/td\u003E\n\u003C\/tr\u003E\n\u003Ctr\u003E\n  \u003Ctd\u003E\u003Cstrong\u003E80 Plus Gold\u003C\/strong\u003E\u003C\/td\u003E\n  \u003Ctd\u003E87%\u003C\/td\u003E\n  \u003Ctd\u003E90%\u003C\/td\u003E\n  \u003Ctd\u003E87%\u003C\/td\u003E\n\u003C\/tr\u003E\n\u003Ctr\u003E\n  \u003Ctd\u003E\u003Cstrong\u003E80 Plus Platinum\u003C\/strong\u003E\u003C\/td\u003E\n  \u003Ctd\u003E90%\u003C\/td\u003E\n  \u003Ctd\u003E92%\u003C\/td\u003E\n  \u003Ctd\u003E89%\u003C\/td\u003E\n\u003C\/tr\u003E\n\u003Ctr\u003E\n  \u003Ctd\u003E\u003Cstrong\u003E80 Plus Titanium\u003C\/strong\u003E\u003C\/td\u003E\n  \u003Ctd\u003E92%\u003C\/td\u003E\n  \u003Ctd\u003E94%\u003C\/td\u003E\n  \u003Ctd\u003E90%\u003C\/td\u003E\n\u003C\/tr\u003E\n\u003C\/tbody\u003E\n\u003C\/table\u003E\n\u003Cbr \/\u003E\n\u003Cdiv\u003E\nThere are power supplies that are modular which means you can remove the unwanted power cables. There are various levels of modular like full, semi etc. This is purely an aesthetic aspect which will help in your builds cable management. Then I have to make sure the PSU can be fixed into the casing I choose, have enough SATA power cables to support the devices I'm going to add etc etc...\u003Cbr \/\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\nConsidering all the above and the price, I chose a \u003Ca href=\"https:\/\/www.evga.com\/products\/product.aspx?pn=100-BR-0450-K1\"\u003E450W Bronze\u003C\/a\u003E power supply.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Ca href=\"https:\/\/www.blogger.com\/null\" name=\"ancHdd\"\u003E\u003C\/a\u003EThen comes the hard drive selection. Or should I say storage mediums. The speed of the storage medium would significantly affect application load speeds and OS load speeds. The board I chose supports M.2 SSDs. Which is the fastest option at the moment. When choosing a M.2 SSD it's very important to look closer at the motherboard specification. Whether it supports M.2 SATA or PCIE etc etc. In my motherboard specification it says I can use\u0026nbsp;type 2242\/2260\/2280\/22110 with PCIE 3.0 support. For the time being I'm not going to go with a M.2 purely due to my allocated budget for this project. I have an existing SATA SSD which I'm going to use to install my server OS. Over time I would watch my server performance and may consider upgrading.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nNow all that's remaining is to choose a casing that supports my motherboard (mATX) and start building the server. Stay tuned...\u003C\/div\u003E\n\u003Cbr \/\u003E"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/830349664271273779\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2019\/12\/intel-vs-amd-for-my-server.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/830349664271273779"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/830349664271273779"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2019\/12\/intel-vs-amd-for-my-server.html","title":"Intel vs AMD for my server"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgIJGT5ulr3YbWZHJAXqokoNqjdwoPW4rV_jIpWmLja03I2oehOwAERFb_yTai1Io-RjtPS6LUn8wy6ymBX8pjetAupFN739MXEVX7Vd38uRYxOqgESS6zWwM6bXKgoOFSK-F6DwdIL3v0\/s72-c\/IMG_7188.jpg","height":"72","width":"72"},"thr$total":{"$t":"0"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-1600754415877889680"},"published":{"$t":"2019-11-26T21:47:00.000-08:00"},"updated":{"$t":"2019-12-01T15:26:29.320-08:00"},"title":{"type":"text","$t":"Building a Server from scratch (Part 1)"},"content":{"type":"html","$t":"\u003Cbr \/\u003E\n\u003Ctable align=\"center\" cellpadding=\"0\" cellspacing=\"0\" class=\"tr-caption-container\" style=\"margin-left: auto; margin-right: auto; text-align: center;\"\u003E\u003Ctbody\u003E\n\u003Ctr\u003E\u003Ctd style=\"text-align: center;\"\u003E\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhlVXncKyDhSyJUfW5Z5G0hRSS9Ubb-GZVykZ7zJ2Jqlzvs3uYi_8fdgH9B5P7XNo2DIpnZS2Z84aShDtLURe1xBGy1PBIr56ZCRQiU770udhSbu39cF-hEg9AoPlfRaWoljKgFsWXztFk\/s1600\/DellMB.jpg\" imageanchor=\"1\" style=\"margin-left: auto; margin-right: auto;\"\u003E\u003Cimg border=\"0\" data-original-height=\"1200\" data-original-width=\"1600\" height=\"480\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhlVXncKyDhSyJUfW5Z5G0hRSS9Ubb-GZVykZ7zJ2Jqlzvs3uYi_8fdgH9B5P7XNo2DIpnZS2Z84aShDtLURe1xBGy1PBIr56ZCRQiU770udhSbu39cF-hEg9AoPlfRaWoljKgFsWXztFk\/s640\/DellMB.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/td\u003E\u003C\/tr\u003E\n\u003Ctr\u003E\u003Ctd class=\"tr-caption\" style=\"text-align: center;\"\u003EMy Dell Laptop MB from 2011\u003C\/td\u003E\u003C\/tr\u003E\n\u003C\/tbody\u003E\u003C\/table\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nThere was a time back in the day where everyone used PCs. Laptops were not as powerful and were rare and expensive. I would say I have build roughly about 20 PCs from scratch for friends and family during those good old times. Nowadays building a PC seems like something only gamers do.\u0026nbsp;\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nI'm in the process of building a home server. I will talk about the whys in a future post. In the process I had to refresh my knowledge about building a PC. In this post I will outline the thought process I went through while building my Server from scratch.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nFirst step is to decide on the processor. Everything else evolves around the processor. For example,\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cul\u003E\n\u003Cli\u003EMotherboard chip-set\u0026nbsp;\u003C\/li\u003E\n\u003Cli\u003EMemory speeds\u003C\/li\u003E\n\u003Cli\u003EMemory types ( M.2, Ultra M.2 )\u003C\/li\u003E\n\u003Cli\u003EI\/O capabilities ( SATA 6Gb\/s, 3Gb\/s )\u003C\/li\u003E\n\u003Cli\u003EOn-board graphics\u003C\/li\u003E\n\u003Cli\u003EOverclocking\u003C\/li\u003E\n\u003Cli\u003EBudget\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Cdiv\u003E\nFirst I checked Intel processors. I assumed that Intel is going to be more expensive compared to AMD so the idea is to find the best Intel Processor \/ MB combo for my project and then find a comparable AMD alternative to see the price difference.\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\nOn the time of the writing latest Intel's were the Core 10th Gen. I'm on a budget so I was looking at the older generations to grab a bargain. 7th gen processors weren't seen much in retailers. 8th gen processors were plenty available. Intel released the 300 series chipsets for the 8th and 9th gen Core processors. These chipsets are not backward compatible with the 7th gen processors. That means in order to use a 7th gen processor I need to find a motherboard with a 200 series chipset. Even though it was possible the options were limited. So I started looking at the 8th Gen Intel Core processors.\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\nIntel Core i3 8th gen has a F series. They are very competitively priced. One important fact though is they don't have integrated graphics. So if I'm to go with a F series I need a separate graphics card. I was going for integrated graphics as I don't need much graphics performance. It's going to be a server so most of the time I don't need a GUI. The base level Core i3 8th Gen is the \u003Ca href=\"https:\/\/ark.intel.com\/content\/www\/us\/en\/ark\/products\/126688\/intel-core-i3-8100-processor-6m-cache-3-60-ghz.html\"\u003Ei3-8100\u003C\/a\u003E\u0026nbsp;which was retailing for around $134. The base 9th gen \u003Ca href=\"https:\/\/ark.intel.com\/content\/www\/us\/en\/ark\/products\/134870\/intel-core-i3-9100-processor-6m-cache-up-to-4-20-ghz.html\"\u003Ei3-9100\u003C\/a\u003E was retailing for around $153. The specs looked quite \u003Ca href=\"https:\/\/ark.intel.com\/content\/www\/us\/en\/ark\/compare.html?productIds=134870,126688\"\u003Esimilar\u003C\/a\u003E\u0026nbsp;except for \u003Ca href=\"https:\/\/www.intel.com\/content\/www\/us\/en\/support\/articles\/000030893\/processors.html\"\u003ETurbo Boost\u003C\/a\u003E. I decided if I'm going with Intel,\u0026nbsp;\u003Ca href=\"https:\/\/ark.intel.com\/content\/www\/us\/en\/ark\/products\/134870\/intel-core-i3-9100-processor-6m-cache-up-to-4-20-ghz.html\"\u003Ei3-9100\u003C\/a\u003E\u0026nbsp;is the one I would choose because I would get a newer processor for almost the same price.\u0026nbsp;\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\nThen comes the challenge of choosing the right chipset. It's good practice to figure out the chipset you need before deciding on the motherboard. Motherboard capabilities are determined by the chipset. The processor empowers the chipset and the motherboard to do it's job.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\nFor the Core-i3 processor I need a 300 series chipset. As mentioned before Intel 8th gen onwards Carry's a backward incompatible change. Z370 was the first high end chipset which was replaced by Z390 a year later. The other options in superior to inferior order are Q370, H370, B360, H310. Lets look at the features I used to decide on the chipset for my build.\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003C\/div\u003E\n\u003Cstyle\u003E\n        .compare_table table {\n            border-collapse: collapse;\n            table-layout: fixed;\n            width: 900px;\n        }\n        .compare_table th,\n        .compare_table td {\n            padding: 15px;\n            border: 1px solid green;\n            width: 100px;\n        }\n    \u003C\/style\u003E\n    \u003Cbr \/\u003E\n\u003Ctable class=\"compare_table\"\u003E\n        \u003Cthead\u003E\n\u003Ctr\u003E\n                \u003Cth\u003E\u003C\/th\u003E\n                \u003Cth\u003EZ390\u003C\/th\u003E\n                \u003Cth\u003EQ370\u003C\/th\u003E\n                \u003Cth\u003EH370\u003C\/th\u003E\n                \u003Cth\u003EB360\u003C\/th\u003E\n                \u003Cth\u003EH310\u003C\/th\u003E\n            \u003C\/tr\u003E\n\u003C\/thead\u003E\n        \u003Ctbody\u003E\n\u003Ctr\u003E\n                \u003Ctd\u003E\u003Cstrong\u003EBus Speed\u003C\/strong\u003E\u003C\/td\u003E\n                \u003Ctd\u003E8 GT\/s\u003C\/td\u003E\n                \u003Ctd\u003E8 GT\/s\u003C\/td\u003E\n                \u003Ctd\u003E8 GT\/s\u003C\/td\u003E\n                \u003Ctd\u003E8 GT\/s\u003C\/td\u003E\n                \u003Ctd\u003E5 GT\/s\u003C\/td\u003E\n            \u003C\/tr\u003E\n\u003Ctr\u003E\n                \u003Ctd\u003E\u003Cstrong\u003E# of DIMMs per channel\u003C\/strong\u003E\u003C\/td\u003E\n                \u003Ctd\u003E2\u003C\/td\u003E\n                \u003Ctd\u003E2\u003C\/td\u003E\n                \u003Ctd\u003E2\u003C\/td\u003E\n                \u003Ctd\u003E2\u003C\/td\u003E\n                \u003Ctd\u003E1\u003C\/td\u003E\n            \u003C\/tr\u003E\n\u003Ctr\u003E\n                \u003Ctd\u003E\u003Cstrong\u003E# of displays supported\u003C\/strong\u003E\u003C\/td\u003E\n                \u003Ctd\u003E3\u003C\/td\u003E\n                \u003Ctd\u003E3\u003C\/td\u003E\n                \u003Ctd\u003E3\u003C\/td\u003E\n                \u003Ctd\u003E3\u003C\/td\u003E\n                \u003Ctd\u003E2\u003C\/td\u003E\n            \u003C\/tr\u003E\n\u003Ctr\u003E\n                \u003Ctd\u003E\u003Cstrong\u003EPCI Express revision\u003C\/strong\u003E\u003C\/td\u003E\n                \u003Ctd\u003E3.0\u003C\/td\u003E\n                \u003Ctd\u003E3.0\u003C\/td\u003E\n                \u003Ctd\u003E3.0\u003C\/td\u003E\n                \u003Ctd\u003E3.0\u003C\/td\u003E\n                \u003Ctd\u003E2.0\u003C\/td\u003E\n            \u003C\/tr\u003E\n\u003Ctr\u003E\n                \u003Ctd\u003E\u003Cstrong\u003EMax PCI Express lanes\u003C\/strong\u003E\u003C\/td\u003E\n                \u003Ctd\u003E24\u003C\/td\u003E\n                \u003Ctd\u003E24\u003C\/td\u003E\n                \u003Ctd\u003E20\u003C\/td\u003E\n                \u003Ctd\u003E12\u003C\/td\u003E\n                \u003Ctd\u003E6\u003C\/td\u003E\n            \u003C\/tr\u003E\n\u003Ctr\u003E\n                \u003Ctd\u003E\u003Cstrong\u003E# of USB ports\u003C\/strong\u003E\u003C\/td\u003E\n                \u003Ctd\u003E14\u003C\/td\u003E\n                \u003Ctd\u003E14\u003C\/td\u003E\n                \u003Ctd\u003E14\u003C\/td\u003E\n                \u003Ctd\u003E12\u003C\/td\u003E\n                \u003Ctd\u003E10\u003C\/td\u003E\n            \u003C\/tr\u003E\n\u003Ctr\u003E\n                \u003Ctd\u003E\u003Cstrong\u003EMax # SATA 6.0 Gb\/s ports\u003C\/strong\u003E\u003C\/td\u003E\n                \u003Ctd\u003E6\u003C\/td\u003E\n                \u003Ctd\u003E6\u003C\/td\u003E\n                \u003Ctd\u003E6\u003C\/td\u003E\n                \u003Ctd\u003E6\u003C\/td\u003E\n                \u003Ctd\u003E4\u003C\/td\u003E\n            \u003C\/tr\u003E\n\u003Ctr\u003E\n                \u003Ctd\u003E\u003Cstrong\u003EPCI Express configurations\u003C\/strong\u003E\u003C\/td\u003E\n                \u003Ctd\u003E1x16 or 2x8 or 1x8+2x4\u003C\/td\u003E\n                \u003Ctd\u003E1x16 or 2x8 or 1x8+2x4\u003C\/td\u003E\n                \u003Ctd\u003E1x16\u003C\/td\u003E\n                \u003Ctd\u003E1x16\u003C\/td\u003E\n                \u003Ctd\u003E1x16\u003C\/td\u003E\n            \u003C\/tr\u003E\n\u003C\/tbody\u003E\n    \u003C\/table\u003E\n\u003Cbr \/\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nLooking at the i3-9100 \u003Ca href=\"https:\/\/ark.intel.com\/content\/www\/us\/en\/ark\/products\/134870\/intel-core-i3-9100-processor-6m-cache-up-to-4-20-ghz.html\"\u003Especifications\u003C\/a\u003E\u0026nbsp;the bus speed of the processor is 8 GT\/s. So the H310 is out as it only supports bus speeds upto 5 GT\/s. B360 only has 12 PCI express lanes for HSIO (high speed input output) and the i3-9100 has 16 PCIe lanes. This all depends on how the motherboard assigns the lanes. These numbers also determine how many components can connect at the same time. I'm not planning to add a graphics card which has the highest demand for the PCI Express lanes. Chipsets with less lanes has lesser options for components like the number of PCI Express solts, M.2 slots, SATA ports, USB ports etc. The only component I would probably add is a multi port PCIe eathernet card for virtualization. So I can go with a B360 motherboard. Also something to note the B360 chipset doesn't support processor or memory overclocking even with unlocked processors. Only K series processors support overclocking so I can't benefit from overclocking feature anyways. When buying memory paying extra for faster DIMMs than 2400MHz ones would be a waste.\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nIf I go with a motherboard like ASUS \u003Ca href=\"https:\/\/www.asus.com\/us\/Motherboards\/PRIME-B360M-A\/\"\u003EB360M-A\u003C\/a\u003E\u0026nbsp;I can acquire the motherboard and the processor for around $235. Now is the time to look up a comparable AMD MB and Processor combo. Stay tuned...\u0026nbsp;\u0026nbsp;\u003C\/div\u003E\n"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/1600754415877889680\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2019\/11\/building-server-from-scratch.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/1600754415877889680"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/1600754415877889680"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2019\/11\/building-server-from-scratch.html","title":"Building a Server from scratch (Part 1)"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhlVXncKyDhSyJUfW5Z5G0hRSS9Ubb-GZVykZ7zJ2Jqlzvs3uYi_8fdgH9B5P7XNo2DIpnZS2Z84aShDtLURe1xBGy1PBIr56ZCRQiU770udhSbu39cF-hEg9AoPlfRaWoljKgFsWXztFk\/s72-c\/DellMB.jpg","height":"72","width":"72"},"thr$total":{"$t":"0"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-8827827890806376951"},"published":{"$t":"2019-11-17T21:43:00.001-08:00"},"updated":{"$t":"2019-11-17T21:43:46.445-08:00"},"title":{"type":"text","$t":"NAS Build (Part III)"},"content":{"type":"html","$t":"(This is a continuation of my previous \u003Ca href=\"https:\/\/blog.coding-mayhem.com\/2019\/11\/nas-build-part-ii.html\"\u003Epost\u003C\/a\u003E...)\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhc4pfc8pXBSQRJ6zRsN-j-CNl1KVRK-tMmqVpOR7fOVsBDNDJKSnzUL_pE35YuAjZtf285EuJsT4GYrvgrzdp0QHJliwmMOVjxOPgAATJowthG4E9aoTbwP2INBF0JWXrIqvErMcmnY0M\/s1600\/1.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"339\" data-original-width=\"1600\" height=\"132\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhc4pfc8pXBSQRJ6zRsN-j-CNl1KVRK-tMmqVpOR7fOVsBDNDJKSnzUL_pE35YuAjZtf285EuJsT4GYrvgrzdp0QHJliwmMOVjxOPgAATJowthG4E9aoTbwP2INBF0JWXrIqvErMcmnY0M\/s640\/1.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cbr \/\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEh-UNMxi2eksCTFCWVPTYvwq7y2KCs2hUALlU30oUAOpRPtfL-LugZi_YyYwXk3XbnJJdY3UdcfpyAxvItayyUDgJbwEm4rMyuIBnvMHMmc9uRC02zNCeyVQj0jEmGB_sCZrZ_UtBBdXlU\/s1600\/2.jpg\" imageanchor=\"1\" style=\"clear: right; float: right; margin-bottom: 1em; margin-left: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"1600\" data-original-width=\"1084\" height=\"400\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEh-UNMxi2eksCTFCWVPTYvwq7y2KCs2hUALlU30oUAOpRPtfL-LugZi_YyYwXk3XbnJJdY3UdcfpyAxvItayyUDgJbwEm4rMyuIBnvMHMmc9uRC02zNCeyVQj0jEmGB_sCZrZ_UtBBdXlU\/s400\/2.jpg\" width=\"270\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nIn the last post I talked about the RAID failure and needing to find a new solution. In this post I will talk about the solution I went with.\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nIf we are to look back at the failed attempt, the reason I decided to go with a RAID5 setup with my 3 disks is\u0026nbsp;\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003C\/div\u003E\n\u003Cul\u003E\n\u003Cli\u003EHaving a 2TB disk\u003C\/li\u003E\n\u003Cul\u003E\n\u003Cli\u003EBetween vindy and myself having 2TBs seem enough space\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Cli\u003ERedundancy\u0026nbsp;\u003C\/li\u003E\n\u003Cul\u003E\n\u003Cli\u003EThe Raid5 disk can survive a 1 disk failure due to the way parity works.\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003C\/ul\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cbr \/\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nHow do I achieve similar outcomes without the power of RAID. The answer is \"Nightly Backups\"\u003C\/div\u003E\n\u003Cbr \/\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nFirst of all I nuked the RAID5 and partitioned the disks again. This time I created 3 NTFS partitions. Did I hear you ask why NTFS. If for some reason I get the disks out of the NAS I have the flexibility to plug them into any of the devices we use. As mentioned in my first NAS post I use an XPS 15 with Ubuntu and Vindi uses an XPS 12 with Windows. I mounted these so that OMV knows about them. This was done in `Storage` --\u0026gt; `File Systems` option.\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgbj1R3gf1gcPZ26P2sYGmMuxHqRN02cgayQ2RgtpoisV3mt3tfVxBQmYlJOOrVRK6rwFQdRL3Toxy3wAVIxOXmJvHJGgFQajayq54j9c4rOHkVD0TMCWbz_NrSuAsSNbeZ6r9HRKUufa8\/s1600\/Sharesjpg.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"937\" data-original-width=\"1600\" height=\"372\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgbj1R3gf1gcPZ26P2sYGmMuxHqRN02cgayQ2RgtpoisV3mt3tfVxBQmYlJOOrVRK6rwFQdRL3Toxy3wAVIxOXmJvHJGgFQajayq54j9c4rOHkVD0TMCWbz_NrSuAsSNbeZ6r9HRKUufa8\/s640\/Sharesjpg.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cbr \/\u003E\nThen I created 3 shared folders in the 3 HDDs. You can easily do this in `AccessRightsManagement` --\u0026gt; `Shared Folders` section. I'm gonn use one of those shares as my data drive, another as Vindi's data drive and the third as Vindi's backup drive. What about my backup drive you would ask. Well I was able to get redundancy for 2TBs using RAID5 and 3 * 1 TB HDDs but with the new approach this is a compromise I had to make. Theoretically it doesn't make sense to create a shared folder for a backup drive but you will see why soon.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhYAKGHRD2810hSIXgae9j7_qbGuCaqeC7MKqU6lLJfiT5eR0B9AulwaoTv6M1HJgRFjFPGfW-JcOiQbSrFzV-y0j9oA8eqVwH8Vl21rbalGyGiAafC0R9Hnbs4-K-SfaKq8mCF-8h91sE\/s1600\/SMB.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"1042\" data-original-width=\"1600\" height=\"416\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhYAKGHRD2810hSIXgae9j7_qbGuCaqeC7MKqU6lLJfiT5eR0B9AulwaoTv6M1HJgRFjFPGfW-JcOiQbSrFzV-y0j9oA8eqVwH8Vl21rbalGyGiAafC0R9Hnbs4-K-SfaKq8mCF-8h91sE\/s640\/SMB.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nNext step is to create the shares. I'm using SMB shares for this. The reason is I have Windows and Linux machines in my network. I created them using the `Services` -\u0026gt; `SMB` -\u0026gt; `Shares` option. The UI is intuitive and straight forward. As you can see in the above screenshot I have not exposed the backup folder via SMB.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjV-kyInN90w2bnQYYw-fQMdfDexCudzmMRnhcdYQmKah9ueR3fJNOvbxCv6IzAUKHxF1UFiazW8YzCnnzcJvdF8_b8SJVf2YiSoPNx8A2cO4hywFx-uYCCalkqkZWL4b6HgQCythtt85Q\/s1600\/RSyncjpg.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"1283\" data-original-width=\"1600\" height=\"512\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjV-kyInN90w2bnQYYw-fQMdfDexCudzmMRnhcdYQmKah9ueR3fJNOvbxCv6IzAUKHxF1UFiazW8YzCnnzcJvdF8_b8SJVf2YiSoPNx8A2cO4hywFx-uYCCalkqkZWL4b6HgQCythtt85Q\/s640\/RSyncjpg.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cbr \/\u003E\nNext is the daily backup job. OMV comes with the ability to create rsync cron jobs out of the box. This can be achieved via `Services` -\u0026gt; `Rsync` -\u0026gt; `Jobs`.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEg0IUwmGSduC5fS8ysiIJT4TFbR8Lh-Pc3Hu3cKOeuDmZJjpdGB3whyNNtDjhChg_wwIn-055tubP1lHeO9kx4mr3rm37pFLiyv7NsHCtqifsGLTI4FLAFoOS9ze54hlHq_ZlfhkuYcMk0\/s1600\/rsyncdetails.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"721\" data-original-width=\"1600\" height=\"288\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEg0IUwmGSduC5fS8ysiIJT4TFbR8Lh-Pc3Hu3cKOeuDmZJjpdGB3whyNNtDjhChg_wwIn-055tubP1lHeO9kx4mr3rm37pFLiyv7NsHCtqifsGLTI4FLAFoOS9ze54hlHq_ZlfhkuYcMk0\/s640\/rsyncdetails.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cbr \/\u003E\nYou can create a pretty decent rsync chron job using the UI. What more can you ask for. Well there you go. That was it.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nI have had this running for a good 3 weeks without any issues. I'm happy with the setup. Below is the load average of the system. The spikes you see every day are due to the cron job.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEj7KJttzWCCl9UOqvxtid_iOcUioqNTMiOQ7HXhBBFf9GBfeO906T0HFsyN7jHPp-ulrE2zeyqOruKbjD10KoYJJwHtpLHQN0MBhDnx1A8boEJ3Pw00Cd9JpCGrxlzeFPmMiK3Ygzjupf0\/s1600\/cron.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"592\" data-original-width=\"1210\" height=\"312\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEj7KJttzWCCl9UOqvxtid_iOcUioqNTMiOQ7HXhBBFf9GBfeO906T0HFsyN7jHPp-ulrE2zeyqOruKbjD10KoYJJwHtpLHQN0MBhDnx1A8boEJ3Pw00Cd9JpCGrxlzeFPmMiK3Ygzjupf0\/s640\/cron.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cbr \/\u003E"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/8827827890806376951\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2019\/11\/nas-build-part-iii.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/8827827890806376951"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/8827827890806376951"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2019\/11\/nas-build-part-iii.html","title":"NAS Build (Part III)"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhc4pfc8pXBSQRJ6zRsN-j-CNl1KVRK-tMmqVpOR7fOVsBDNDJKSnzUL_pE35YuAjZtf285EuJsT4GYrvgrzdp0QHJliwmMOVjxOPgAATJowthG4E9aoTbwP2INBF0JWXrIqvErMcmnY0M\/s72-c\/1.jpg","height":"72","width":"72"},"thr$total":{"$t":"0"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-3490617347705768577"},"published":{"$t":"2019-11-10T12:23:00.000-08:00"},"updated":{"$t":"2019-11-11T08:24:50.958-08:00"},"category":[{"scheme":"http://www.blogger.com/atom/ns#","term":"NAS"},{"scheme":"http://www.blogger.com/atom/ns#","term":"OMV"},{"scheme":"http://www.blogger.com/atom/ns#","term":"RAID"},{"scheme":"http://www.blogger.com/atom/ns#","term":"Raspberry PI 4"}],"title":{"type":"text","$t":"NAS Build (Part II)"},"content":{"type":"html","$t":"\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEi-S8eUFLW4o0_r6dqF15gGW3JfCSYxNHe3z3VgTZXl-INSqFyIwXF0KH-PHaMoeJejgMLFtUxc9okL9wttyHysLYIcG9bcM5xq_Z_UqJ_jZ2_WLxnDWDue_ddijZtHCISgp91jVcVQVgM\/s1600\/Nas2.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cspan style=\"font-family: inherit;\"\u003E\u003Cimg border=\"0\" data-original-height=\"1196\" data-original-width=\"1600\" height=\"475\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEi-S8eUFLW4o0_r6dqF15gGW3JfCSYxNHe3z3VgTZXl-INSqFyIwXF0KH-PHaMoeJejgMLFtUxc9okL9wttyHysLYIcG9bcM5xq_Z_UqJ_jZ2_WLxnDWDue_ddijZtHCISgp91jVcVQVgM\/s640\/Nas2.jpg\" width=\"640\" \/\u003E\u003C\/span\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003E(This is a continuation from my \u003Ca href=\"https:\/\/blog.coding-mayhem.com\/2019\/11\/nas-build-with-raspberry-pi-4.html\"\u003Eprevious post\u003C\/a\u003E ...)\u003C\/span\u003E\u003Cbr \/\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003EIn this post I'll be covering the following,\u003C\/span\u003E\u003Cbr \/\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Cspan style=\"font-family: inherit;\"\u003ESoftware setup\u0026nbsp;\u003C\/span\u003E\u003C\/li\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Cspan style=\"font-family: inherit;\"\u003EOpen Media Vault\u0026nbsp;\u003C\/span\u003E\u003C\/li\u003E\n\u003Cli\u003E\u003Cspan style=\"font-family: inherit;\"\u003ESoftware Raid using `mdadm`\u003C\/span\u003E\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Cli\u003E\u003Cspan style=\"font-family: inherit;\"\u003EExpectation vs Reality\u003C\/span\u003E\u003C\/li\u003E\n\u003Cli\u003E\u003Cspan style=\"font-family: inherit;\"\u003ERaid setup failure\u003C\/span\u003E\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Cdiv\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003EI received my hardware. Happy days ...\u003C\/span\u003E\u003Cbr \/\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjA-JfwQzH4xsqFLreAVZG09DmV7FbIQIx2UtGi_cgjxB8ClqGzTwF_OcNjFLvdHESryIBZPdD1rmuoeRgyHPKTqFer2OhMm-KqZITpqslCZ5_pnuvg9i2FaraGiWrClZ2qvL1CLTV2cqs\/s1600\/hardware2.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cspan style=\"font-family: inherit;\"\u003E\u003Cimg border=\"0\" data-original-height=\"1200\" data-original-width=\"1600\" height=\"480\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjA-JfwQzH4xsqFLreAVZG09DmV7FbIQIx2UtGi_cgjxB8ClqGzTwF_OcNjFLvdHESryIBZPdD1rmuoeRgyHPKTqFer2OhMm-KqZITpqslCZ5_pnuvg9i2FaraGiWrClZ2qvL1CLTV2cqs\/s640\/hardware2.jpg\" width=\"640\" \/\u003E\u003C\/span\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: justify;\"\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003EBefore narrowing down the hardware I was looking at \u003Ca href=\"https:\/\/www.openmediavault.org\/\"\u003EOMV\u003C\/a\u003E (OpenMediaVault) and \u003Ca href=\"https:\/\/www.freenas.org\/\"\u003EFreeNAS\u003C\/a\u003E. Newer versions of FreeNAS needs a 64 bit processor and at a minimum 8 gigs of memory. No need to say I went with OMV.\u0026nbsp;\u003C\/span\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Ch2\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003E\nSoftware Setup\u003C\/span\u003E\u003C\/h2\u003E\n\u003Ch3\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003E\nOpen Media Vault\u003C\/span\u003E\u003C\/h3\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003EOMV has an images for single board computers (SBC). This made installing OMV in the Pi a peace of cake. There are so many good and even more bad videos on how to do this. I recommend \u003Ca href=\"https:\/\/www.youtube.com\/watch?v=vY5PSAhjD2s\"\u003Ethis\u003C\/a\u003E by TDL.\u003C\/span\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003EThere are a few gotchas to watch out for. First of all get the correct image for your board. Second of all patience is a virtue. OMV images for SBCs go through a setup in the first boot. If the first boot is unable to complete the setup your image is toast. Make sure you have wired network available to your board and also did I mention patience is a virtue. My initial setup took a little over 10 minutes but word on the street is it can take up to 20 minutes. If you have a monitor connected to the board you will see the control panel address when the setup is complete.\u003C\/span\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEidDRmVxt6dzCnKAgkbztlp7br23rPmVrcoybERTSql914tlohfzKBu9dxiNMI4tC_CViMIgjGoVbVgRlMe49YyMmazMZqbT-Ti0kjOibxk4hgSTst6EowB6Lij9V743E-kTO0mFz0wTwo\/s1600\/setupdone.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cspan style=\"font-family: inherit;\"\u003E\u003Cimg border=\"0\" data-original-height=\"908\" data-original-width=\"1600\" height=\"361\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEidDRmVxt6dzCnKAgkbztlp7br23rPmVrcoybERTSql914tlohfzKBu9dxiNMI4tC_CViMIgjGoVbVgRlMe49YyMmazMZqbT-Ti0kjOibxk4hgSTst6EowB6Lij9V743E-kTO0mFz0wTwo\/s640\/setupdone.jpg\" width=\"640\" \/\u003E\u003C\/span\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: left;\"\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003EAfter the setup I did the obvious things like changing the password, setting up ssh, enabling SMB, upgrading all the packages etc. The video I linked does a good job of explaining how to do these.\u0026nbsp;\u003C\/span\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\n\u003Ch3\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003E\nSoftware Raid\u003C\/span\u003E\u003C\/h3\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003EOMV has a UI for creating RAID systems but it doesn't allow creating RAIDs out of USB drives (with good reason)\u003C\/span\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEho-4WE020gQnr3tM9FN_ysQkht_ELCk8-mM2tliWpst_lycktWnGHlGHyuzzKSUwYexq8DGxrpWvk8wCWpVJ4FUYsWtiOnD3J75ogwP610onqrKYKVOCw9HbCl3GuBPSOp_BJwyQyVd_o\/s1600\/OMV1.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cspan style=\"font-family: inherit;\"\u003E\u003Cimg border=\"0\" data-original-height=\"960\" data-original-width=\"1352\" height=\"454\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEho-4WE020gQnr3tM9FN_ysQkht_ELCk8-mM2tliWpst_lycktWnGHlGHyuzzKSUwYexq8DGxrpWvk8wCWpVJ4FUYsWtiOnD3J75ogwP610onqrKYKVOCw9HbCl3GuBPSOp_BJwyQyVd_o\/s640\/OMV1.jpg\" width=\"640\" \/\u003E\u003C\/span\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003ESo I opted to use \u003Ca href=\"https:\/\/linux.die.net\/man\/8\/mdadm\"\u003Emdadm\u003C\/a\u003E to create a software raid using my USB drives. I elected to go with a \u003Ca href=\"https:\/\/en.wikipedia.org\/wiki\/Standard_RAID_levels\"\u003ERAID5\u003C\/a\u003E setup. As mentioned earlier I have 3 USB HDDs of 1TB size. I can create a 2TB raid disk using RAID5 and be good even if one drive fails. Raid 5 uses a distributed parity system where it stores parity data randomly across all 3 drives. That means if one drive fails the data in that drive can be recovered using the parity information stored in the other two drives. Plus I get to have a 2TB disk 😊. So I ordered another 2TB disk which I'm gonna use as a manual geo redundant backup 😁.\u0026nbsp;\u003C\/span\u003E\u003Cbr \/\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003EHere are the steps I used to create the RAID5\u003C\/span\u003E\u003Cbr \/\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003EFirst you need to find your disk information. The following command will help you get that\u003C\/span\u003E\u003Cbr \/\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Cb\u003E\u003Cspan style=\"font-family: \u0026quot;courier new\u0026quot; , \u0026quot;courier\u0026quot; , monospace;\"\u003Elsblk -o NAME,SIZE,FSTYPE,TYPE,MOUNTPOINT\u003C\/span\u003E\u003C\/b\u003E\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Cdiv style=\"text-align: left;\"\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003EThen you need to create the raid. The disk information goes into this command as an input\u003C\/span\u003E\u003C\/div\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Cspan style=\"font-family: \u0026quot;courier new\u0026quot; , \u0026quot;courier\u0026quot; , monospace;\"\u003E\u003Cb\u003Esudo mdadm --create --verbose \/dev\/md0 --level=5 --raid-devices=3 \/dev\/sda \/dev\/sdb \/dev\/sdc \u003C\/b\u003E\u003C\/span\u003E\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Cdiv style=\"text-align: left;\"\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003EThis is going to take some time. For me it took about 6 hours. the progress of this operation can be viewed by looking at the `\/proc\/mdstat` file. You need to print the content of the file in order to view the progress. It's overwritten always so a command like `tail` will not work.\u003C\/span\u003E\u003C\/div\u003E\n\u003C\/div\u003E\n\u003Cdiv style=\"text-align: left;\"\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Cspan style=\"font-family: \u0026quot;courier new\u0026quot; , \u0026quot;courier\u0026quot; , monospace;\"\u003E\u003Cb\u003Ecat \/proc\/mdstat\u003C\/b\u003E\u003C\/span\u003E\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003C\/div\u003E\n\u003C\/div\u003E\n\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cspan style=\"font-family: inherit;\"\u003EOnce the raid is created you will see something like this on your `mdstat` file.\u003C\/span\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhUdxCC-35WmlZRevp6fdr5b6Z0JWrgQ0wempIlBFxoavjt8HV7c2jtYsP9OvxfPC8dObdP1ECaUk5ZS5jbvUgEtypP4Cxf1xpqRqGsDYziiv__CS23ll8gfBChfbyjnZ-vCF7n7FGqbbg\/s1600\/raid_created.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"305\" data-original-width=\"1600\" height=\"122\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhUdxCC-35WmlZRevp6fdr5b6Z0JWrgQ0wempIlBFxoavjt8HV7c2jtYsP9OvxfPC8dObdP1ECaUk5ZS5jbvUgEtypP4Cxf1xpqRqGsDYziiv__CS23ll8gfBChfbyjnZ-vCF7n7FGqbbg\/s640\/raid_created.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nNow is the time to tell linux about your RAID array. You do that by adding the raid information to the `mdadm.conf` file. In the below command I'm using `mdadm` to scan the active array and pipe the output to the `mdadm.conf` file using `tee` command\u003C\/div\u003E\n\u003Cdiv style=\"text-align: left;\"\u003E\n\u003C\/div\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Cspan style=\"font-family: \u0026quot;courier new\u0026quot; , \u0026quot;courier\u0026quot; , monospace;\"\u003E\u003Cb\u003Esudo mdadm --detail --scan | sudo tee -a \/etc\/mdadm\/mdadm.conf\u003C\/b\u003E\u003C\/span\u003E\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Cdiv\u003E\nNext we update the initial RAM file system so that the array is available during boot\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Cb\u003E\u003Cspan style=\"font-family: \u0026quot;courier new\u0026quot; , \u0026quot;courier\u0026quot; , monospace;\"\u003Esudo update-initramfs -u\u003C\/span\u003E\u003C\/b\u003E\u0026nbsp;\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nNow if you go back to the OMV RAID management page you should see the newly created RAID array. Next step is to create the partitions and file systems in the raid array. You can do this in the `File Systems` tab in OMV. The whole process is intuitive so I won't go into details.\u003C\/div\u003E\n\u003C\/div\u003E\n\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgUGsY6JcIrSu7zE_dlsTGVTVMm0CtMIYIUH6Nd2ufKAKU0gxow5iFNfjjUFlSAnvi-9uRJgqJX7rA_MZEqfnvS0pm0KJkJCUQJM0Cnl36RhKNm6N5cZZn1Cv1GhrDC1RQHI8giQ_nh3jY\/s1600\/OMVFileSystem.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"1126\" data-original-width=\"1414\" height=\"508\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgUGsY6JcIrSu7zE_dlsTGVTVMm0CtMIYIUH6Nd2ufKAKU0gxow5iFNfjjUFlSAnvi-9uRJgqJX7rA_MZEqfnvS0pm0KJkJCUQJM0Cnl36RhKNm6N5cZZn1Cv1GhrDC1RQHI8giQ_nh3jY\/s640\/OMVFileSystem.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nNow check your `\/etc\/fstab` file. I found out that OMV added my raid file system information here using labels. I changed it to use name instead. It just comes down to your preference.\u003C\/div\u003E\n\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\nThere are a lot of info about RAID in the wild. I found \u003Ca href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/how-to-create-raid-arrays-with-mdadm-on-ubuntu-16-04\"\u003Ethis\u003C\/a\u003E article to be the most helpful.\u003C\/div\u003E\n\u003Ch2\u003E\nExpectation vs Reality\u003C\/h2\u003E\n\u003Cdiv\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nAt this point I had both the hardware and software set up. I went ahead and created a few SMB shares with custom permissions and went straight into testing the system. I chose the SMB option because I have both Linux and Windows machines in my network. If you need more help in setting up SMB I would recommend \u003Ca href=\"https:\/\/www.youtube.com\/watch?v=QVm92VqCaGA\"\u003Ethis\u003C\/a\u003E video form TDL.\u003C\/div\u003E\n\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhYfPNXxsXKL22As6GJxKrrLBa-1Nz109XqtbtkmQHLAJO6Vfn5a0zTDAWLaBx_KFXy4_DWZ4cIyRLCQQsejgKd0ybJUMz-sDmmYVcp48lmby9TOBP6u3ul70bAo6woeDh_nU8bxtvAedo\/s1600\/NAS.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"551\" data-original-width=\"641\" height=\"550\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhYfPNXxsXKL22As6GJxKrrLBa-1Nz109XqtbtkmQHLAJO6Vfn5a0zTDAWLaBx_KFXy4_DWZ4cIyRLCQQsejgKd0ybJUMz-sDmmYVcp48lmby9TOBP6u3ul70bAo6woeDh_nU8bxtvAedo\/s640\/NAS.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nThe first thing I did was to issue a reboot command. The Pi hanged at boot. After some reading I found out that the Pi 4 has a problem with powered USB hubs. It fails to boot when the hub back powers the Pi. This is a \u003Ca href=\"https:\/\/www.raspberrypi.org\/forums\/viewtopic.php?t=245218\"\u003Eknown\u003C\/a\u003E issue. People have had mixed experiences by disconnecting the back powering from the USB hub. I chose not to go down this path due to a few reasons.\u0026nbsp;\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nIn order to monkey around with the hubs circuit board I need my electronics kit, which I left back at home in Melbourne when I moved to Seattle 🙉. I'm not planning to reboot this setup often so I chose to momentarily unplug the hubs every time I reboot.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nThen comes the biggest shock. Before setting up all this I checked the speeds. I was getting between 8\/12Mbps using a simple SMB setup between the PI and my laptop. So I expected to get the same speeds with the RAID5. Theoretically a RAID5 should give higher write speeds. In my case I knew the HDD speed was not the bottleneck for 12Mbps\u0026nbsp; I was getting. The HDDs I used is capable of operating at around 32Mbps. So I wasn't expecting the 12Mbps to go up with the RAID5 but I was not ready for the result I saw.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nI was only getting about 0.5Mbps. I could not come up with a definitive explanation but it seems the Pi shares the same controller and bus between the USB and Ethernet. I confirmed this by transferring data between my raid and a USB stick directly plugged into the Pi. I was feeling defeated at this point. This is just the tip of the iceberg.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nSo after realizing my mistake I just let the system run for a few days. Truth be told I was looking for a good way to break the news to Vindy (my wife). She is a tecky herself and a witty one. So I knew I'm gonna hear about this 🥴. Did I say this was just the tip of the iceberg.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nI was checking on the system from time to time and I realized the RAID array kept degrading randomly.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgEfn96ZkT8AW0VYUX36AtE2TTfDWZjq6XR95iHepByWGJYQQ-6FVRyLZz8U8-eRoc2Gr3AiGvKcg2p66A8zIjLxYLcf9YQLvrCI1hOpOqH1CV4_AcphpWwzUZRL5CMUXlv6ZPMjQ4koD0\/s1600\/RaidDegraded.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"339\" data-original-width=\"1600\" height=\"134\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgEfn96ZkT8AW0VYUX36AtE2TTfDWZjq6XR95iHepByWGJYQQ-6FVRyLZz8U8-eRoc2Gr3AiGvKcg2p66A8zIjLxYLcf9YQLvrCI1hOpOqH1CV4_AcphpWwzUZRL5CMUXlv6ZPMjQ4koD0\/s640\/RaidDegraded.jpg\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cbr \/\u003E\nOne of the 3 HDDs were getting detached frequently. I tried experimenting with various spin down settings to no avail. The first few times I regenerated the RAID by reattaching the missing disk.\u003Cbr \/\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Cb\u003E\u003Cspan style=\"font-family: \u0026quot;courier new\u0026quot; , \u0026quot;courier\u0026quot; , monospace;\"\u003Esudo mdadm \/dev\/md0 -a \/dev\/sdd\u003C\/span\u003E\u003C\/b\u003E\u0026nbsp;\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Cdiv\u003E\nAfter a few attempts I knew that this is not going to work. Stay tuned to find out more about my solution...\u003C\/div\u003E\n\u003Cbr \/\u003E\n\u0026nbsp;\u0026nbsp; \u0026nbsp;\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/3490617347705768577\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2019\/11\/nas-build-part-ii.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/3490617347705768577"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/3490617347705768577"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2019\/11\/nas-build-part-ii.html","title":"NAS Build (Part II)"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEi-S8eUFLW4o0_r6dqF15gGW3JfCSYxNHe3z3VgTZXl-INSqFyIwXF0KH-PHaMoeJejgMLFtUxc9okL9wttyHysLYIcG9bcM5xq_Z_UqJ_jZ2_WLxnDWDue_ddijZtHCISgp91jVcVQVgM\/s72-c\/Nas2.jpg","height":"72","width":"72"},"thr$total":{"$t":"0"},"georss$featurename":{"$t":"Seattle, WA, USA"},"georss$point":{"$t":"47.6062095 -122.3320708"},"georss$box":{"$t":"47.2636695 -122.9775178 47.9487495 -121.68662379999999"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-4981177093277121795"},"published":{"$t":"2019-11-04T18:24:00.000-08:00"},"updated":{"$t":"2019-11-05T21:40:28.618-08:00"},"title":{"type":"text","$t":"NAS build"},"content":{"type":"html","$t":"\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgeS1JZ2_RLd_9pFg1fYbeBzg3d6y7yKWw83oiSsxixZeXLM5NAkrEg58P4-8qygeM6QwTHVBkTT5-hkXCcLVQ2Fp73mSkRhI9i_s4FeEG_vZN4Mm-tuffY3vkf8k2pofSfO0N4LXF-aeo\/s1600\/IMG_20191019_070706.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"1600\" data-original-width=\"1200\" height=\"320\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgeS1JZ2_RLd_9pFg1fYbeBzg3d6y7yKWw83oiSsxixZeXLM5NAkrEg58P4-8qygeM6QwTHVBkTT5-hkXCcLVQ2Fp73mSkRhI9i_s4FeEG_vZN4Mm-tuffY3vkf8k2pofSfO0N4LXF-aeo\/s320\/IMG_20191019_070706.jpg\" width=\"240\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nSo this is the story about my NAS (\u003Ca href=\"https:\/\/en.wikipedia.org\/wiki\/Network-attached_storage\"\u003ENetwork attached storage\u003C\/a\u003E) build. Spoiler alert, the initial implementation fails but I manage to compromise and go for a plan B.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Ch2\u003E\nWhy ?\u003C\/h2\u003E\nWell why not. :). Actually to tell you a bit of the back story. I use a Dell XPS 15 running \u003Ca href=\"https:\/\/ubuntu.com\/\"\u003EUbuntu\u003C\/a\u003E as my PC and my better half uses a Dell XPS 12 running \u003Ca href=\"https:\/\/www.microsoft.com\/en-us\/windows\/get-windows-10\"\u003EWindows 10\u003C\/a\u003E. Our on-board disk sizes are 500GB and 250GB respectively.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nWe keep our data in external USB drives. Vindi ( my wife ) does food photography as a side gig \/ hobby. So I think it's fair to say that we were having a bit of an inconvenience when it comes to storage.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Ch2\u003E\nHow ?\u003C\/h2\u003E\nSo now to find a solution to my problem. The decision to go with a NAS was quite obvious\u003Cbr \/\u003E\n\u003Cul\u003E\n\u003Cli\u003EAccessible to both of us\u003C\/li\u003E\n\u003Cli\u003EAccessible by all our devices\u003C\/li\u003E\n\u003Cli\u003ELess upkeep after initial setup\u003C\/li\u003E\n\u003Cli\u003ESeems like a fun project 😉\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Ch3\u003E\nHardware\u003C\/h3\u003E\n\u003Cdiv\u003E\nI know there are off the shelf systems but where's the fun in that.\u0026nbsp;\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\nI wanted to keep the cost to a minimum so I decided to use the existing USB hard disks I have. I had 3 USB HDDs. 1TB each.\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\nNext I needed a lightweight machine. After a bit of research I was going back and forth between 2 options.\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cul\u003E\n\u003Cli\u003EAn embedded system like\u003C\/li\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u0026nbsp;\u003Ca href=\"https:\/\/www.asrock.com\/mb\/Intel\/Q1900M\/\"\u003EASRock Q1900M\u003C\/a\u003E\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003C\/ul\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEicYBXFHSF8-Bed2RFdcwG4vtxUvmSL-u46M4LLDhcxapUBk82pJ72AATB94igh6_w1LRZIRSJuvZRnBOwqjnszMTlfMq2AHB-XCBocOiPBJpv3YsbsvOBXlh79hXoNCx-nKTkoL1wDjIQ\/s1600\/Q1900M.jpeg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"205\" data-original-width=\"246\" height=\"166\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEicYBXFHSF8-Bed2RFdcwG4vtxUvmSL-u46M4LLDhcxapUBk82pJ72AATB94igh6_w1LRZIRSJuvZRnBOwqjnszMTlfMq2AHB-XCBocOiPBJpv3YsbsvOBXlh79hXoNCx-nKTkoL1wDjIQ\/s200\/Q1900M.jpeg\" width=\"200\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: left;\"\u003E\nIt was quite tempting to go for an embedded system. The system comes with Processor, VGA, and Mother Board and all I had to source was the memory modules and a casing with a power supply unit. I could have sourced all that for under $200. Unlike the single board computers I can make use of the SATA interface in the embedded system. ( Or can I ? )\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: left;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: left;\"\u003E\nThere are a few reasons why I didn't go down this path. First of all my aim was to open up the USB drives I had and get the SATA drives hidden within them. Luckily for me just before I start butchering the USB HDDs I found out that they don't have SATA HDDs inside of them. At least 2 out of the 3 for \u003Ca href=\"https:\/\/www.youtube.com\/watch?v=DBenRlPzb_s\"\u003Esure didn't\u003C\/a\u003E. So I won't be able to use the SATA interface in the embedded system.\u0026nbsp;\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: left;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: left;\"\u003E\nSecond of all I have never worked on a single board computer like a RaspberryPI. I have fiddled around with \u003Ca href=\"https:\/\/en.wikipedia.org\/wiki\/PIC_microcontrollers\"\u003EPIC\u003C\/a\u003E microchips back in the days but these single board computers seem way ahead of the game compared to those. So I decided to go down that path.\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: left;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cul\u003E\n\u003Cli\u003EA single board computer\u003C\/li\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"https:\/\/www.raspberrypi.org\/products\/raspberry-pi-4-model-b\/\"\u003ERaspberry Pi 4\u003C\/a\u003E\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003C\/ul\u003E\n\u003Cdiv\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjLq4fFWsumw7jcOeefGPzeU21k6YfDJDE6Ya6qRGIXIAD3x5IvF7KxzyPzuMfgU2I3IVLKKyv2J0sTfmMcBPBXB7nsyr70kttye1AtOgfFsnlurVkS27OC_PGsHI56KUenJuQQ_OeZWkE\/s1600\/pi4.jpeg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"172\" data-original-width=\"294\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjLq4fFWsumw7jcOeefGPzeU21k6YfDJDE6Ya6qRGIXIAD3x5IvF7KxzyPzuMfgU2I3IVLKKyv2J0sTfmMcBPBXB7nsyr70kttye1AtOgfFsnlurVkS27OC_PGsHI56KUenJuQQ_OeZWkE\/s1600\/pi4.jpeg\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cul\u003E\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"https:\/\/www.pine64.org\/devices\/single-board-computers\/rock64\/\"\u003ERock64\u003C\/a\u003E\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003C\/ul\u003E\n\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjk6Oe5APl3K_Eks7QNxJ5JluHC3jOEeyplJyoEWsy9FOMTbvHpCzKCNyzag35iRXo-hUIIy4Dq52CKP2LSJDh1leC5B9VovrJdo3P7YuLJ_43y409K0GdpgLwucyi9XF77L8wNswfydRo\/s1600\/ROCK64_sideimg.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" data-original-height=\"354\" data-original-width=\"305\" height=\"200\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjk6Oe5APl3K_Eks7QNxJ5JluHC3jOEeyplJyoEWsy9FOMTbvHpCzKCNyzag35iRXo-hUIIy4Dq52CKP2LSJDh1leC5B9VovrJdo3P7YuLJ_43y409K0GdpgLwucyi9XF77L8wNswfydRo\/s200\/ROCK64_sideimg.jpg\" width=\"171\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\nSo I narrowed down my options to either be the Raspberry PI 4 or the Rock64. I went with the PI due to the 2 USB 3.0 ports and due to its popularity.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nNow it's time to decide on the software. Stay tuned...\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nPS: I did some tests to determine the expected speeds before the build. I'd write about the expectation and reality in a later post. 😁\u003C\/div\u003E\n"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/4981177093277121795\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2019\/11\/nas-build-with-raspberry-pi-4.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/4981177093277121795"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/4981177093277121795"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2019\/11\/nas-build-with-raspberry-pi-4.html","title":"NAS build"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgeS1JZ2_RLd_9pFg1fYbeBzg3d6y7yKWw83oiSsxixZeXLM5NAkrEg58P4-8qygeM6QwTHVBkTT5-hkXCcLVQ2Fp73mSkRhI9i_s4FeEG_vZN4Mm-tuffY3vkf8k2pofSfO0N4LXF-aeo\/s72-c\/IMG_20191019_070706.jpg","height":"72","width":"72"},"thr$total":{"$t":"0"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-7957601785919557219"},"published":{"$t":"2016-07-31T04:59:00.002-07:00"},"updated":{"$t":"2016-08-01T03:10:52.044-07:00"},"title":{"type":"text","$t":"Handling Time Zone across from UI to DB"},"content":{"type":"html","$t":"So I thought about writing a bit about handling date variables across WebAPI to Angular.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Ch3\u003E\nThe Problem\u003C\/h3\u003E\n\u003Cbr \/\u003E\nWhen saving date \/ datetime values sent from the front end how do we keep the timezone information and how do we show them back on the UI.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nFor example let's say you use a simple online note taking application. You wrote a note 8 am in the morning when you were in WA. Now you are looking at your notes from Vic and what time do you want the note to show as the created date\/time ?\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nWell I can't tell you what time you should show as it's a business case but I can tell you how to store the time information so that regardless of what time you need to show, you can achieve that.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Ch3\u003E\nThe Solution\u003C\/h3\u003E\n\u003Cdiv\u003E\nCode on GitHub\u0026nbsp;\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Ca href=\"https:\/\/www.blogger.com\/goog_1787025619\"\u003E\u003Cbr \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Ca href=\"https:\/\/github.com\/kumudug\/DateTime-handling-Front-to-Back\"\u003Ehttps:\/\/github.com\/kumudug\/DateTime-handling-Front-to-Back\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\nWhat the code demos......\u003Cbr \/\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Ch4\u003E\nOn the WebAPI side\u003C\/h4\u003E\nYou can store the date time values in 2 ways\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cul\u003E\n\u003Cli\u003EAs UTC values in a DateTime variable in SQL Server\u003C\/li\u003E\n\u003Cli\u003EIn a DateTimeOffset variable in SQL server with the actual date time. The advantage of this is that you can actually know which time zone the input originated from.\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Cbr \/\u003E\n\u003Ch4\u003E\nOn the Front End\u003C\/h4\u003E\nI have demoed sending of the data from the Angular front end to the WebAPI layer using the following 2 libraries in the code.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"https:\/\/angular-ui.github.io\/bootstrap\/\"\u003EAngular UI Bootstrap\u003C\/a\u003E\u003C\/li\u003E\n\u003Cli\u003E\u003Ca href=\"http:\/\/mgcrea.github.io\/angular-strap\/\"\u003EAngular Strap\u003C\/a\u003E\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/7957601785919557219\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2016\/07\/handling-time-zone-across-from-ui-to-db_60.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/7957601785919557219"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/7957601785919557219"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2016\/07\/handling-time-zone-across-from-ui-to-db_60.html","title":"Handling Time Zone across from UI to DB"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"thr$total":{"$t":"0"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-879995323207599918"},"published":{"$t":"2016-06-10T16:37:00.000-07:00"},"updated":{"$t":"2016-09-18T04:43:13.343-07:00"},"title":{"type":"text","$t":"Setting up KDiff3 to work with TortoiseGIT"},"content":{"type":"html","$t":"\u003Ch2\u003E\nSetting up KDiff3 to work with TortoiseGIT\u003C\/h2\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nWhen I work with git I do most of my work on the command line except for a few tasks. Resolving conflicts is one of them. So when it comes to resolving conflicts I prefer the KDiff3 instead of the TortoiseGIT diff. I was googling around to find the proper way and after grabbing things from difference places here is what I did.\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nObvious steps \u0026nbsp;:)\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Col\u003E\n\u003Cli\u003EInstall git\u003C\/li\u003E\n\u003Cli\u003EInstall KDiff3\u003C\/li\u003E\n\u003Cli\u003EInstall TortoiseGIT\u003C\/li\u003E\n\u003C\/ol\u003E\n\u003C\/div\u003E\n\u003Cdiv\u003E\nThen after that\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Col\u003E\n\u003Cli\u003EOpen tortoise GIT settings\u003C\/li\u003E\n\u003Col\u003E\n\u003Cli\u003EGo to \"Diff Viewer\"\u003C\/li\u003E\n\u003Cli\u003EGo to section \"Configure the program used for comparing different revisio....\"\u003C\/li\u003E\n\u003Cli\u003EChoose \"External\"\u003C\/li\u003E\n\u003Cli\u003EEnter the following \"[ kdiff3 instalation path ]\\kdiff3.exe %base %mine --L1 %bname --L2 %yname\"\u003C\/li\u003E\n\u003Cli\u003EGo to \"Merge Tool\"\u003C\/li\u003E\n\u003Cli\u003EChoose \"External\"\u003C\/li\u003E\n\u003Cli\u003EEnter the following \"[ kdiff3 instalation path ]\\kdiff3.exe %base %mine %theirs -o %merged\"\u003C\/li\u003E\n\u003Cli\u003EClick apply\u003C\/li\u003E\n\u003C\/ol\u003E\n\u003C\/ol\u003E\n\u003Cdiv\u003E\nI will soon write something to show how to actually resolve conflicts using this setup.\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhUAzyQD-VDw58PXlHCGR36pxeVb4SlRF0Zq8txYoQquEWZ0Akz55x10Dxg_I-u5sSlpKKgwfUbmAXjeuEzqVnvgP5NyBLnTMV8236L__01piXqa6p2gioEmxJilQrGbQLfNtkb4rEL90A\/s1600\/GitDiff.png\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" height=\"504\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhUAzyQD-VDw58PXlHCGR36pxeVb4SlRF0Zq8txYoQquEWZ0Akz55x10Dxg_I-u5sSlpKKgwfUbmAXjeuEzqVnvgP5NyBLnTMV8236L__01piXqa6p2gioEmxJilQrGbQLfNtkb4rEL90A\/s640\/GitDiff.png\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/879995323207599918\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2016\/06\/setting-up-kdiff3-to-work-with.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/879995323207599918"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/879995323207599918"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2016\/06\/setting-up-kdiff3-to-work-with.html","title":"Setting up KDiff3 to work with TortoiseGIT"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhUAzyQD-VDw58PXlHCGR36pxeVb4SlRF0Zq8txYoQquEWZ0Akz55x10Dxg_I-u5sSlpKKgwfUbmAXjeuEzqVnvgP5NyBLnTMV8236L__01piXqa6p2gioEmxJilQrGbQLfNtkb4rEL90A\/s72-c\/GitDiff.png","height":"72","width":"72"},"thr$total":{"$t":"0"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-6731558766730002491"},"published":{"$t":"2016-04-19T05:50:00.000-07:00"},"updated":{"$t":"2016-04-19T05:58:24.551-07:00"},"title":{"type":"text","$t":"Angular directive to validate a decimal input field with min\/max "},"content":{"type":"html","$t":"I came across a requirement to validate a simple numeric input field with a minimum and a maximum value. So I tried using the html5 validations first like so\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cspan style=\"background-color: white; font-family: \u0026quot;consolas\u0026quot; , \u0026quot;courier new\u0026quot;; font-size: 16px; line-height: 22.4px;\"\u003E\u0026nbsp;\u0026nbsp;\u003C\/span\u003E\u003Cspan class=\"highLT\" style=\"box-sizing: border-box; color: blue; font-family: \u0026quot;consolas\u0026quot; , \u0026quot;courier new\u0026quot;; font-size: 16px; line-height: 22.4px;\"\u003E\u0026lt;\u003C\/span\u003E\u003Cspan class=\"highELE\" style=\"box-sizing: border-box; color: brown; font-family: \u0026quot;consolas\u0026quot; , \u0026quot;courier new\u0026quot;; font-size: 16px; line-height: 22.4px;\"\u003Einput\u003C\/span\u003E\u003Cspan style=\"background-color: white; font-family: \u0026quot;consolas\u0026quot; , \u0026quot;courier new\u0026quot;; font-size: 16px; line-height: 22.4px;\"\u003E\u0026nbsp;\u003C\/span\u003E\u003Cspan class=\"highATT\" style=\"box-sizing: border-box; color: red; font-family: \u0026quot;consolas\u0026quot; , \u0026quot;courier new\u0026quot;; font-size: 16px; line-height: 22.4px;\"\u003Etype=\u003C\/span\u003E\u003Cspan class=\"highVAL\" style=\"box-sizing: border-box; color: mediumblue; font-family: \u0026quot;consolas\u0026quot; , \u0026quot;courier new\u0026quot;; font-size: 16px; line-height: 22.4px;\"\u003E\"number\"\u003C\/span\u003E\u003Cspan style=\"background-color: white; font-family: \u0026quot;consolas\u0026quot; , \u0026quot;courier new\u0026quot;; font-size: 16px; line-height: 22.4px;\"\u003E\u0026nbsp;\u003C\/span\u003E\u003Cspan class=\"highATT\" style=\"box-sizing: border-box; color: red; font-family: \u0026quot;consolas\u0026quot; , \u0026quot;courier new\u0026quot;; font-size: 16px; line-height: 22.4px;\"\u003Ename=\u003C\/span\u003E\u003Cspan class=\"highVAL\" style=\"box-sizing: border-box; color: mediumblue; font-family: \u0026quot;consolas\u0026quot; , \u0026quot;courier new\u0026quot;; font-size: 16px; line-height: 22.4px;\"\u003E\"quantity\"\u003C\/span\u003E\u003Cspan style=\"background-color: white; font-family: \u0026quot;consolas\u0026quot; , \u0026quot;courier new\u0026quot;; font-size: 16px; line-height: 22.4px;\"\u003E\u0026nbsp;\u003C\/span\u003E\u003Cspan class=\"highATT\" style=\"box-sizing: border-box; color: red; font-family: \u0026quot;consolas\u0026quot; , \u0026quot;courier new\u0026quot;; font-size: 16px; line-height: 22.4px;\"\u003Emin=\u003C\/span\u003E\u003Cspan class=\"highVAL\" style=\"box-sizing: border-box; color: mediumblue; font-family: \u0026quot;consolas\u0026quot; , \u0026quot;courier new\u0026quot;; font-size: 16px; line-height: 22.4px;\"\u003E\"1\"\u003C\/span\u003E\u003Cspan style=\"background-color: white; font-family: \u0026quot;consolas\u0026quot; , \u0026quot;courier new\u0026quot;; font-size: 16px; line-height: 22.4px;\"\u003E\u0026nbsp;\u003C\/span\u003E\u003Cspan class=\"highATT\" style=\"box-sizing: border-box; color: red; font-family: \u0026quot;consolas\u0026quot; , \u0026quot;courier new\u0026quot;; font-size: 16px; line-height: 22.4px;\"\u003Emax=\u003C\/span\u003E\u003Cspan class=\"highVAL\" style=\"box-sizing: border-box; color: mediumblue; font-family: \u0026quot;consolas\u0026quot; , \u0026quot;courier new\u0026quot;; font-size: 16px; line-height: 22.4px;\"\u003E\"5\"\u003C\/span\u003E\u003Cspan class=\"highGT\" style=\"box-sizing: border-box; color: blue; font-family: \u0026quot;consolas\u0026quot; , \u0026quot;courier new\u0026quot;; font-size: 16px; line-height: 22.4px;\"\u003E\u0026gt;\u003C\/span\u003E\u003Cbr \/\u003E\n\u003Cspan class=\"highGT\" style=\"box-sizing: border-box; color: blue; font-family: \u0026quot;consolas\u0026quot; , \u0026quot;courier new\u0026quot;; font-size: 16px; line-height: 22.4px;\"\u003E\u003Cbr \/\u003E\u003C\/span\u003E\n\nThe above works perfectly until you need to have decimal minimum and maximum values. So I thought why not write a directive to support this.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nThe code can be found in the following GitHub repo\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Ca href=\"https:\/\/github.com\/kumudug\/angular_min_max_validate\"\u003Ehttps:\/\/github.com\/kumudug\/angular_min_max_validate\u003C\/a\u003E\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u0026nbsp;The directive supports the following\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cul\u003E\n\u003Cli\u003EDecimal min and max validation\u003C\/li\u003E\n\u003Cli\u003EDecimal min value only validation\u003C\/li\u003E\n\u003Cli\u003EDecimal max value only validation\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\n\u003Cu\u003EUsage\u003C\/u\u003E\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003C!-- HTML generated using hilite.me --\u003E\u003Cbr \/\u003E\n\u003Cdiv style=\"background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;\"\u003E\n\u003Cpre style=\"line-height: 125%; margin: 0;\"\u003E\u003Cspan style=\"color: #007700;\"\u003E\u0026lt;input\u003C\/span\u003E \u003Cspan style=\"color: #0000cc;\"\u003Etype=\u003C\/span\u003E\u003Cspan style=\"background-color: #fff0f0;\"\u003E\"number\"\u003C\/span\u003E \u003Cspan style=\"color: #0000cc;\"\u003Eclass=\u003C\/span\u003E\u003Cspan style=\"background-color: #fff0f0;\"\u003E\"form-control\"\u003C\/span\u003E \u003Cspan style=\"color: #0000cc;\"\u003Eid=\u003C\/span\u003E\u003Cspan style=\"background-color: #fff0f0;\"\u003E\"decimal1\"\u003C\/span\u003E \u003Cspan style=\"color: #0000cc;\"\u003Ename=\u003C\/span\u003E\u003Cspan style=\"background-color: #fff0f0;\"\u003E\"decimal1\"\u003C\/span\u003E \u003Cspan style=\"color: #0000cc;\"\u003Eng-model=\u003C\/span\u003E\u003Cspan style=\"background-color: #fff0f0;\"\u003E\"vm.dec1\"\u003C\/span\u003E \u003Cspan style=\"color: #0000cc;\"\u003Erequired\u003C\/span\u003E \u003Cspan style=\"color: #0000cc;\"\u003Ech-validate-min-max\u003C\/span\u003E \u003Cspan style=\"color: #0000cc;\"\u003Emin-val=\u003C\/span\u003E\u003Cspan style=\"background-color: #fff0f0;\"\u003E\"0.2\"\u003C\/span\u003E \u003Cspan style=\"color: #0000cc;\"\u003Emax-val=\u003C\/span\u003E\u003Cspan style=\"background-color: #fff0f0;\"\u003E\"1.7\"\u003C\/span\u003E\u003Cspan style=\"color: #007700;\"\u003E\u0026gt;\u003C\/span\u003E\n\u003C\/pre\u003E\n\u003C\/div\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cu\u003EInitial View\u003C\/u\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEipK0MlqRKBkW0uDION7H52QtXjCM8lj3FBTgJe2m0jMiGxr4vNIDNlU_g86zYavDjYXlGxIB4XByOhj9YhH3_ft8jgWG6edR-CusTDm8NgpHrdRZrE7_yEKVa1gUBLScMZcg6HTySqyno\/s1600\/2016-04-19+22_45_00-Angular+min-max+validate+-+Internet+Explorer.png\" imageanchor=\"1\" style=\"clear: left; float: left; margin-bottom: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEipK0MlqRKBkW0uDION7H52QtXjCM8lj3FBTgJe2m0jMiGxr4vNIDNlU_g86zYavDjYXlGxIB4XByOhj9YhH3_ft8jgWG6edR-CusTDm8NgpHrdRZrE7_yEKVa1gUBLScMZcg6HTySqyno\/s1600\/2016-04-19+22_45_00-Angular+min-max+validate+-+Internet+Explorer.png\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cbr \/\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cu\u003EAfter validation is triggered\u003C\/u\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhyJndKyHDx82U_LZ_Hujqb6hRhBrpaSNcK3JoKLxolsT4muujly3LJ4nr3tgwCGuYXHlMRFpYZEZeqPXr9JRZB_ekIJPamASo6xtuNqDPH-qsGbQbYofQi0d-R5Sduid7ThI5J_ljc9Js\/s1600\/2016-04-19+22_46_54-Angular+min-max+validate+-+Internet+Explorer.png\" imageanchor=\"1\" style=\"clear: left; float: left; margin-bottom: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhyJndKyHDx82U_LZ_Hujqb6hRhBrpaSNcK3JoKLxolsT4muujly3LJ4nr3tgwCGuYXHlMRFpYZEZeqPXr9JRZB_ekIJPamASo6xtuNqDPH-qsGbQbYofQi0d-R5Sduid7ThI5J_ljc9Js\/s1600\/2016-04-19+22_46_54-Angular+min-max+validate+-+Internet+Explorer.png\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/6731558766730002491\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2016\/04\/angular-directive-to-validate-decimal.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/6731558766730002491"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/6731558766730002491"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2016\/04\/angular-directive-to-validate-decimal.html","title":"Angular directive to validate a decimal input field with min\/max "}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEipK0MlqRKBkW0uDION7H52QtXjCM8lj3FBTgJe2m0jMiGxr4vNIDNlU_g86zYavDjYXlGxIB4XByOhj9YhH3_ft8jgWG6edR-CusTDm8NgpHrdRZrE7_yEKVa1gUBLScMZcg6HTySqyno\/s72-c\/2016-04-19+22_45_00-Angular+min-max+validate+-+Internet+Explorer.png","height":"72","width":"72"},"thr$total":{"$t":"0"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-1298435697794916023"},"published":{"$t":"2016-04-10T15:48:00.003-07:00"},"updated":{"$t":"2016-04-10T15:48:51.219-07:00"},"title":{"type":"text","$t":"Inline editing using ng-table"},"content":{"type":"html","$t":"I was working on an enterprise application that needed table in-line editing. I thought why engineer something from scratch when we can use something that's already out there.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nAfter doing some looking around \u003Ca href=\"https:\/\/github.com\/esvit\/ng-table\" target=\"_blank\"\u003Eng-table\u003C\/a\u003E was the preferred option. It supported sorting, filtering etc which were required functionalities but it didn't mention anything about in-line editing. So I started looking at the API on my own.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nI noticed that the API supports loading data using the \"NgTableParams\" and I used this service to control the view.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nInstead of blabbering on I will let the code do the talking. The sample code is hosted in the following GitHub url\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Ca href=\"https:\/\/github.com\/kumudug\/ng-table-inline-editing\"\u003Ehttps:\/\/github.com\/kumudug\/ng-table-inline-editing\u003C\/a\u003E\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nThe code supports the following\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cul\u003E\n\u003Cli\u003EAdding new items with validation\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgx6V8ssM8sghboZLBYKTkgN7XYiUeLDNUvHrCEpR52jRIy3Ic5enFSPnKyl3UHBo2eiJpfjacvchxAP2f3zqK09gcNyP1ibWp-18lgGEJVOqOfKHkic98z_smxcJiKrefcOk3UkISTij4\/s1600\/new.png\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" height=\"179\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgx6V8ssM8sghboZLBYKTkgN7XYiUeLDNUvHrCEpR52jRIy3Ic5enFSPnKyl3UHBo2eiJpfjacvchxAP2f3zqK09gcNyP1ibWp-18lgGEJVOqOfKHkic98z_smxcJiKrefcOk3UkISTij4\/s640\/new.png\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cul\u003E\n\u003Cli\u003EEditing existing items with validation\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiow33MWS15lAcmHYh488ILTXr_lJMIjsCw4Hmm4FLaG0tnyZB9-t8bEWtes-8EpKFyraBGIPQQhJqXDJLHtiRBqAb7N0UIvD3g-sL8ZKK2dSRCI6eiSatKAPe-tB2B9R0ovzqVW2MnP3Q\/s1600\/Edit.png\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" height=\"148\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiow33MWS15lAcmHYh488ILTXr_lJMIjsCw4Hmm4FLaG0tnyZB9-t8bEWtes-8EpKFyraBGIPQQhJqXDJLHtiRBqAb7N0UIvD3g-sL8ZKK2dSRCI6eiSatKAPe-tB2B9R0ovzqVW2MnP3Q\/s640\/Edit.png\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cul\u003E\n\u003Cli\u003EDeleting items with confirmation\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiSV2MHdr4FvJeIqHeGcpSP6KPh0gr4V2KNZdSUQXT7i2BAhbDP6GG3bB0W7_9DsJf-T3UsitaiauDaj5MNRhpRQGtBHHBsstH0f2NU2ByfyKY3_hl_-88Fby39l530fSwa_cfirCwD_bE\/s1600\/Delete.png\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" height=\"152\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiSV2MHdr4FvJeIqHeGcpSP6KPh0gr4V2KNZdSUQXT7i2BAhbDP6GG3bB0W7_9DsJf-T3UsitaiauDaj5MNRhpRQGtBHHBsstH0f2NU2ByfyKY3_hl_-88Fby39l530fSwa_cfirCwD_bE\/s640\/Delete.png\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cul\u003E\n\u003Cli\u003EUndo add, edit and delete\u003C\/li\u003E\n\u003C\/ul\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEh7yUjyEWTsLT3DhPzvwUqdj9H22dXUsPIey5G6XWH3A68aROCPTYVBD7ktOANC_xymVrTgc62nCQuoLTKHRhWxEzbNLmzzUFXBQSS7xnF1eqbHDx3r9O-vo6In64Lvd0XjzmdXDrKdrQc\/s1600\/Undo.png\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" height=\"178\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEh7yUjyEWTsLT3DhPzvwUqdj9H22dXUsPIey5G6XWH3A68aROCPTYVBD7ktOANC_xymVrTgc62nCQuoLTKHRhWxEzbNLmzzUFXBQSS7xnF1eqbHDx3r9O-vo6In64Lvd0XjzmdXDrKdrQc\/s640\/Undo.png\" width=\"640\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/1298435697794916023\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2016\/04\/inline-editing-using-ng-table.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/1298435697794916023"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/1298435697794916023"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2016\/04\/inline-editing-using-ng-table.html","title":"Inline editing using ng-table"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgx6V8ssM8sghboZLBYKTkgN7XYiUeLDNUvHrCEpR52jRIy3Ic5enFSPnKyl3UHBo2eiJpfjacvchxAP2f3zqK09gcNyP1ibWp-18lgGEJVOqOfKHkic98z_smxcJiKrefcOk3UkISTij4\/s72-c\/new.png","height":"72","width":"72"},"thr$total":{"$t":"0"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-4515110116817205114"},"published":{"$t":"2016-03-13T21:36:00.002-07:00"},"updated":{"$t":"2016-03-13T21:36:59.916-07:00"},"title":{"type":"text","$t":"ngTable with custom sort [empty values first]"},"content":{"type":"html","$t":"Let me start by saying the background story\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nI was building a simple grid layout for an enterprise project and the requirement was to show the details in a grid view and the grid view needed sorting. So I just spent a couple of hours to set up the required bower packages for \u003Ca href=\"http:\/\/ng-table.com\/\"\u003Eng-table\u003C\/a\u003E\u0026nbsp;and write a simple html template and the angular code to support it and I thought I was done.\u0026nbsp;\u0026nbsp;\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nNot so fast.......\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nThe test came back failed with reasoning \"Sorting is not working as expected.\". Apparently they wanted the empty values to be displayed on top in an \"Ascending\" order which is not the default feature of\u0026nbsp;AngularJS\u0026nbsp;\u003Ca href=\"https:\/\/docs.angularjs.org\/api\/ng\/filter\/orderBy\"\u003Eorderby filter\u003C\/a\u003E. So this is how I fixed it.\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: left;\"\u003E\nGitHub repo for the proof of concept:\u0026nbsp;\u003Ca href=\"https:\/\/github.com\/kumudug\/ng-table-customBinding-sorting-inlineEditing\"\u003Ehttps:\/\/github.com\/kumudug\/ng-table-customBinding-sorting-inlineEditing\u003C\/a\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Ci\u003E\u003Cb\u003EProblem\u003C\/b\u003E\u003C\/i\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nWhen implementing sorting, I used the default AngularJS \u003Ca href=\"https:\/\/docs.angularjs.org\/api\/ng\/filter\/orderBy\"\u003Eorderby filter\u003C\/a\u003E service. Which puts empty values at the bottom. According to the requirement specification this was not desirable.\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cb\u003E\u003Ci\u003E\u003Cbr \/\u003E\u003C\/i\u003E\u003C\/b\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cb\u003E\u003Ci\u003ESolution\u003C\/i\u003E\u003C\/b\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cb\u003E\u003Ci\u003E\u003Cbr \/\u003E\u003C\/i\u003E\u003C\/b\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nAngular orderby filter has several options. One of these is the ability to give a getter function that enables you to override the value compared, to determine the sorting. This is the path I took.\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nSo when applying the orderby filter I have given the comparator function as below\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhZCaSScR3xTLWHPu33o3OejQ4S_X1YKKMaYJNW0MIdXiWx5DPwdwRv9XayEpDOzPB_d-1g7ekhz_38xijcdxKEhoD9h4KFqqjvK3zVqgyz5hyphenhyphenGVpBS0s1b5Fqr1BwpHsA8plCfttYDZ7E\/s1600\/blogger1.png\" imageanchor=\"1\" style=\"clear: left; float: left; margin-bottom: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhZCaSScR3xTLWHPu33o3OejQ4S_X1YKKMaYJNW0MIdXiWx5DPwdwRv9XayEpDOzPB_d-1g7ekhz_38xijcdxKEhoD9h4KFqqjvK3zVqgyz5hyphenhyphenGVpBS0s1b5Fqr1BwpHsA8plCfttYDZ7E\/s1600\/blogger1.png\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cbr \/\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nThen in the \"comparatorFunc\" I would return 0 for all the null values. This would result them being sorted on top in ascending order.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003E\n\u003Ca href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgYOGPZ6u6DeTPYTBf4Ycug1j6FvugOqfSxbJcWOPOOy9JUNl4_sj5sGLGtC2OvdBa3ikuc908j5yM68f1vkK-rTIi6STQY8-8A7U8xqbtv8Gh7n1q2_-SkFf_AwaVo_6XFt_uAzwpXVqY\/s1600\/blogger2.png\" imageanchor=\"1\" style=\"clear: left; float: left; margin-bottom: 1em; margin-right: 1em;\"\u003E\u003Cimg border=\"0\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgYOGPZ6u6DeTPYTBf4Ycug1j6FvugOqfSxbJcWOPOOy9JUNl4_sj5sGLGtC2OvdBa3ikuc908j5yM68f1vkK-rTIi6STQY8-8A7U8xqbtv8Gh7n1q2_-SkFf_AwaVo_6XFt_uAzwpXVqY\/s1600\/blogger2.png\" \/\u003E\u003C\/a\u003E\u003C\/div\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cb\u003E\u003Ci\u003E\u003Cbr \/\u003E\u003C\/i\u003E\u003C\/b\u003E\u003C\/div\u003E\n"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/4515110116817205114\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2016\/03\/ngtable-with-custom-sort-empty-values.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/4515110116817205114"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/4515110116817205114"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2016\/03\/ngtable-with-custom-sort-empty-values.html","title":"ngTable with custom sort [empty values first]"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"media$thumbnail":{"xmlns$media":"http://search.yahoo.com/mrss/","url":"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhZCaSScR3xTLWHPu33o3OejQ4S_X1YKKMaYJNW0MIdXiWx5DPwdwRv9XayEpDOzPB_d-1g7ekhz_38xijcdxKEhoD9h4KFqqjvK3zVqgyz5hyphenhyphenGVpBS0s1b5Fqr1BwpHsA8plCfttYDZ7E\/s72-c\/blogger1.png","height":"72","width":"72"},"thr$total":{"$t":"0"}},{"id":{"$t":"tag:blogger.com,1999:blog-9001854664565320016.post-6968363815942308858"},"published":{"$t":"2015-12-27T21:20:00.001-08:00"},"updated":{"$t":"2015-12-27T21:20:51.494-08:00"},"title":{"type":"text","$t":"How AngularJS let me down !!!"},"content":{"type":"html","$t":"\u003Cbr \/\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nThis all started when I was asked to build a simple website for a startup food blog. When I initially thought down on the architecture there was nothing much to decide on. The requirement was to have a simple page with some images, recipes that can be maintained easily and edited frequently. If this requirement was given to a consultancy organization I'm pretty sure they would start it with a CMS without a second thought. Well then again they didn't ask a consultancy organization. They asked me. So me being not very fond of CMS systems I decided to go down on the AngularJS path which I am already accustomed to.\u0026nbsp;\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nI was able to get the site hosted within days. I had a nice json data repository set up for the client to work with. Everything was going smoothly until I was asked this question. Why aren't my links working in social media sites as they should be?? !!!!!!!\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nSo here goes the OMG moment. None of the social media crawlers liked the javascript in my pages. So obviously what all those crawlers were seeing was a div tag inside the DOM. It didn't come to my mind at all that this would happen when I started designing the project. So as I was battling the feeling of a few sleepless weekends that I might have to suck up in the near future, I was thinking of alternatives.\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nDo I finally give in and design a WordPress blog? No way am I gonna do that!. I have more pride than that. So I decided to do a URL rewrite and present a compiled html using PhantomJS to social media crawlers. So how did I do it?\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nIf I see a user agent string of a crawler, I compile the site using PhantomJS and present the html to the crawler. Sounds simple but wait for it. The site was hosted in IIS and even though running PhantomJS and doing the rewrite would have been much easier in Node, due to some constraints that was not an option. So I started walking down the dark ally of setting up IIS url rewrite rules for the crawlers.\u0026nbsp;\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\nIf you haven't already guessed by now this is just the first part of the solution. Then, I started doing a proof of concept for the IIS url rewrite in github.\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cbr \/\u003E\u003C\/div\u003E\n\u003Cdiv style=\"text-align: justify;\"\u003E\n\u003Cspan style=\"color: #263238; font-family: arial, sans-serif; font-size: 13px; line-height: 16px; text-align: left; text-decoration: underline;\"\u003E\u003Ca href=\"https:\/\/github.com\/kumudug\/IIS-URL-Rewrite-Useragent\"\u003Ehttps:\/\/github.com\/kumudug\/IIS-URL-Rewrite-Useragent\u003C\/a\u003E\u003C\/span\u003E\u003C\/div\u003E\n\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nSo to summarize...\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cb\u003E\u003Ci\u003EThe problem\u003C\/i\u003E\u003C\/b\u003E\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nI was creating an AngularJS application for a client when I hit a roadblock. The project needed the ability to support facebook Open Graph properties, pinterest rich pins, stumble upon links, google plus links. All the above were failing.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cb\u003E\u003Ci\u003EThe reason\u003C\/i\u003E\u003C\/b\u003E\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nAll the above mentioned crawlers do not execute javascript. So I was stuck between a rock and a hard place. :(. So the soution I designed was to do a url rewrite for all the requests coming from the above said crawlers to a page generated using PhantomJS. Simple right? not quite. Since I already had html5 type url rewrites set up etc it was pretty cumbersome to write all the URL rewrite logic for IIS. At one point I was not sure how the user agent strings actually looked like. So born was this project.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cb\u003E\u003Ci\u003EPurpose\u003C\/i\u003E\u003C\/b\u003E\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nThis project is going to help me understand the user agent string that is used by the above mentioned crawlers and how to do url the rewrites for them.\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Cb\u003E\u003Ci\u003ESolution\u003C\/i\u003E\u003C\/b\u003E\u003Cbr \/\u003E\n\u003Cbr \/\u003E\nI have done a URL rewrite for the above mentioned crawlers and have supported and tested the following rich object and schema handling platforms\u003Cbr \/\u003E\n\u003Cbr \/\u003E\n\u003Ca href=\"http:\/\/schema.org\/\"\u003Ehttp:\/\/schema.org\/\u003C\/a\u003E\u003Cbr \/\u003E\n\u003Ca href=\"http:\/\/ogp.me\/\"\u003Ehttp:\/\/ogp.me\/\u003C\/a\u003E [facebook]\u003Cbr \/\u003E\n\u003Ca href=\"https:\/\/developers.pinterest.com\/docs\/rich-pins\/overview\/\"\u003Ehttps:\/\/developers.pinterest.com\/docs\/rich-pins\/overview\/\u003C\/a\u003E [pinterest]"},"link":[{"rel":"replies","type":"application/atom+xml","href":"https:\/\/blog.coding-mayhem.com\/feeds\/6968363815942308858\/comments\/default","title":"Post Comments"},{"rel":"replies","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2015\/12\/how-angularjs-let-me-down.html#comment-form","title":"0 Comments"},{"rel":"edit","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/6968363815942308858"},{"rel":"self","type":"application/atom+xml","href":"https:\/\/www.blogger.com\/feeds\/9001854664565320016\/posts\/default\/6968363815942308858"},{"rel":"alternate","type":"text/html","href":"https:\/\/blog.coding-mayhem.com\/2015\/12\/how-angularjs-let-me-down.html","title":"How AngularJS let me down !!!"}],"author":[{"name":{"$t":"Kumudu"},"uri":{"$t":"http:\/\/www.blogger.com\/profile\/09631376530178263243"},"email":{"$t":"noreply@blogger.com"},"gd$image":{"rel":"http://schemas.google.com/g/2005#thumbnail","width":"32","height":"26","src":"\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEheIXkdSfQ4sSU9aHt6G6U_FEwkJ_a_jBR5viyuYuJZQYWNRx5uqmA8oTm0lD_Z2F0E2DECZ0glaex2H0eKqIVuszBkQ4ha6M9DKpSh8rPWy6qJ7OQINJ8zFOvrMEqoJA\/s113\/IMG_0077_1.jpg"}}],"thr$total":{"$t":"0"},"georss$featurename":{"$t":"Melbourne VIC, Australia"},"georss$point":{"$t":"-37.814107 144.96327999999994"},"georss$box":{"$t":"-38.6164245 143.67238649999993 -37.0117895 146.25417349999995"}}]}}