[{"data":1,"prerenderedAt":11300},["ShallowReactive",2],{"content-page:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs":3,"content-page-quiz:none":996,"book-module-total-pages":997,"content-section-pages:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F":998,"content-directory-pages:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs":11299},{"id":4,"title":5,"audience":6,"body":7,"contentType":971,"course":972,"description":973,"estimateBasis":974,"estimatedDiscussionMinutes":975,"estimatedLiveMinutes":976,"estimatedTotalMinutes":977,"extension":893,"meta":978,"module":979,"navigation":980,"order":981,"path":982,"promptAssist":983,"seo":984,"status":985,"stem":986,"tags":987,"videoDuration":991,"videoId":992,"videoLink":993,"videoTitle":994,"week":979,"__hash__":995},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs.md","Git Commands And Pull Requests","student",{"type":8,"value":9,"toc":934},"minimark",[10,45,66,84,118,154,207,223,244,277,311,354,385,420,444,496,523,553,571,583,619,652,688,723,749,777,810,885,931],[11,12,15,19,23],"slide",{"id":13,"level":14},"objectives","2",[16,17,18],"h2",{"id":13},"Objectives",[20,21,22],"p",{},"By the end, you should be able to:",[24,25,26,30,33,36,39,42],"ul",{},[27,28,29],"li",{},"Explain what the common Git commands do",[27,31,32],{},"Connect commands to the working folder, staging area, local commits, and GitHub remote",[27,34,35],{},"Create a branch for practice work",[27,37,38],{},"Stage, commit, and push a small change",[27,40,41],{},"Open a pull request on GitHub",[27,43,44],{},"Investigate a failed push and a merge conflict",[11,46,48,52,55,58],{"id":47,"level":14},"git-vs-github",[16,49,51],{"id":50},"git-versus-github","Git Versus GitHub",[20,53,54],{},"Git is the tool that tracks file history",[20,56,57],{},"GitHub is a website that hosts a remote copy of a Git repository",[24,59,60,63],{},[27,61,62],{},"Git: local terminal workflow",[27,64,65],{},"GitHub: remote branches, pull requests, issues, and project evidence",[11,67,69,73,78,81],{"id":68,"level":14},"git-stages",[16,70,72],{"id":71},"the-git-stages","The Git Stages",[74,75],"code-snippet",{"language":76,"src":77},"text","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fthe-git-stages-01.txt",[20,79,80],{},"Common commands:",[74,82],{"language":76,"src":83},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fthe-git-stages-02.txt",[11,85,87,91,94,98,101,104],{"id":86,"level":14},"status-first",[16,88,90],{"id":89},"command-1-git-status","Command 1: git status",[20,92,93],{},"Run:",[74,95],{"language":96,"src":97},"bash","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-1-git-status-03.sh",[20,99,100],{},"Use this before and after every important Git action",[20,102,103],{},"It tells you:",[24,105,106,109,112,115],{},[27,107,108],{},"Current branch",[27,110,111],{},"Changed files",[27,113,114],{},"Staged files",[27,116,117],{},"Whether your working tree is clean",[11,119,121,125,127,130],{"id":120,"level":14},"branch-command",[16,122,124],{"id":123},"command-2-git-branch","Command 2: git branch",[20,126,93],{},[74,128],{"language":96,"src":129},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-2-git-branch-04.sh",[24,131,132,135,138],{},[27,133,134],{},"Active branch has an asterisk",[27,136,137],{},"Branches are separate timelines for work",[27,139,140,141],{},"Branch names are case-sensitive\n",[24,142,143],{},[27,144,145,149,150,153],{},[146,147,148],"code",{},"Practice"," and ",[146,151,152],{},"practice"," are different names",[11,155,157,161,168,171],{"id":156,"level":14},"create-branch",[16,158,160],{"id":159},"practice-step-1-create-a-branch","Practice Step 1: Create A Branch",[20,162,163,164,167],{},"Start from ",[146,165,166],{},"main",":",[74,169],{"language":96,"src":170},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpractice-step-1-create-a-05.sh",[24,172,173,184],{},[27,174,175,176,178,179],{},"First two commands: make sure ",[146,177,166],{}," is current\n",[24,180,181],{},[27,182,183],{},"Explained more later",[27,185,186,187],{},"Branch control commands\n",[24,188,189,195,201],{},[27,190,191,194],{},[146,192,193],{},"git checkout -b practice",": create and switch",[27,196,197,200],{},[146,198,199],{},"git branch practice",": create only",[27,202,203,206],{},[146,204,205],{},"git checkout practice",": switch to existing",[11,208,210,214,217,220],{"id":209,"level":14},"make-file",[16,211,213],{"id":212},"practice-step-2-make-a-small-file","Practice Step 2: Make A Small File",[20,215,216],{},"Create a small practice file:",[74,218],{"language":96,"src":219},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpractice-step-2-make-a-s-06.sh",[20,221,222],{},"Expected result: Git shows the new file as untracked",[11,224,226,230,233,236,239],{"id":225,"level":14},"add-command",[16,227,229],{"id":228},"command-3-git-add","Command 3: git add",[20,231,232],{},"Stage the new file:",[74,234],{"language":96,"src":235},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-3-git-add-07.sh",[20,237,238],{},"Staging means: include this change in the next commit",[24,240,241],{},[27,242,243],{},"See below for add patterns and verification checks",[11,245,248,253,256,259],{"id":246,"level":247},"add-variants","3",[249,250,252],"h3",{"id":251},"common-git-add-patterns","Common git add Patterns",[20,254,255],{},"Use the smallest clear target when possible",[74,257],{"language":96,"src":258},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommon-git-add-patterns-08.sh",[24,260,261,264,267],{},[27,262,263],{},"Single file: safest when you changed one file",[27,265,266],{},"Folder: useful when one feature is grouped in one folder",[27,268,269,272,273,276],{},[146,270,271],{},"git add .",": convenient, but review ",[146,274,275],{},"git status"," first",[11,278,280,284,287,290],{"id":279,"level":14},"diff-command",[16,281,283],{"id":282},"command-4-git-diff","Command 4: git diff",[20,285,286],{},"Before committing, inspect what changed:",[74,288],{"language":96,"src":289},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-4-git-diff-09.sh",[24,291,292,299,302,308],{},[27,293,294,295,298],{},"New untracked file: ",[146,296,297],{},"git diff"," may show nothing",[27,300,301],{},"That does not mean the file is missing",[27,303,304,305,307],{},"Use ",[146,306,275],{}," to confirm untracked files",[27,309,310],{},"See the slide below for supporting examples and follow-up details",[11,312,314,318,321,324,327,330],{"id":313,"level":247},"cached-rm",[249,315,317],{"id":316},"if-you-staged-the-wrong-file","If You Staged The Wrong File",[20,319,320],{},"If a file was staged by mistake, remove it from staging:",[74,322],{"language":96,"src":323},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fif-you-staged-the-wrong--10.sh",[20,325,326],{},"For a folder:",[74,328],{"language":96,"src":329},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fif-you-staged-the-wrong--11.sh",[24,331,332,343],{},[27,333,334,337,338],{},[146,335,336],{},"--cached",": remove from staging only\n",[24,339,340],{},[27,341,342],{},"Keeps the file in your working folder",[27,344,345,348,349],{},[146,346,347],{},"-r",": folder mode\n",[24,350,351],{},[27,352,353],{},"Recursive: include files inside the folder",[11,355,357,361,364,367,370],{"id":356,"level":14},"commit-command",[16,358,360],{"id":359},"command-5-git-commit","Command 5: git commit",[20,362,363],{},"Commit the staged file:",[74,365],{"language":96,"src":366},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-5-git-commit-12.sh",[20,368,369],{},"A commit is a saved checkpoint in your local repository",[24,371,372,383],{},[27,373,374,377,378],{},[146,375,376],{},"-m",": commit message",[24,379,380],{},[27,381,382],{},"Required, even if the message is an empty string",[27,384,310],{},[11,386,388,392,394,397,417],{"id":387,"level":247},"log-command",[249,389,391],{"id":390},"check-the-local-history","Check The Local History",[20,393,93],{},[74,395],{"language":96,"src":396},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcheck-the-local-history-13.sh",[24,398,399,405,411],{},[27,400,401,404],{},[146,402,403],{},"log",": show commit history",[27,406,407,410],{},[146,408,409],{},"--oneline",": one commit per line",[27,412,413,416],{},[146,414,415],{},"-5",": show the latest five commits",[20,418,419],{},"You should see your latest commit near the top",[11,421,423,427,430,433],{"id":422,"level":14},"push-command",[16,424,426],{"id":425},"command-6-git-push","Command 6: git push",[20,428,429],{},"Send the branch to GitHub:",[74,431],{"language":96,"src":432},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-6-git-push-14.sh",[24,434,435,441],{},[27,436,437,440],{},[146,438,439],{},"origin",": common remote name for GitHub",[27,442,443],{},"Final part: branch you are pushing",[11,445,447,451],{"id":446,"level":14},"open-pr",[16,448,450],{"id":449},"pull-request","Pull Request",[452,453,456,486],"two-col",{"gap":454,"left-width":455,"right-width":455},"lg","1fr",[457,458,460,463,466,469,472,475],"template",{"v-slot:left":459},"",[20,461,462],{},"On GitHub, open a pull request",[20,464,465],{},"Use this direction:",[74,467],{"language":76,"src":468},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-request-15.txt",[20,470,471],{},"Use a clear description:",[74,473],{"language":76,"src":474},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-request-description-16.txt",[24,476,477,480,483],{},[27,478,479],{},"Review page before merge",[27,481,482],{},"Shows what will change",[27,484,485],{},"Captures branch evidence",[457,487,488],{"v-slot:right":459},[20,489,490],{},[491,492],"img",{"alt":493,"src":494,"variant":495},"GitHub pull request creation page showing base main and compare practice","\u002Fimages\u002Fshared\u002Fgit-workflow\u002Fgithub-create-pull-request.png","sidecar-screenshot",[11,497,499,503,506,514,517,520],{"id":498,"level":14},"merge-pr",[16,500,502],{"id":501},"merge-and-sync","Merge And Sync",[20,504,505],{},"After GitHub merge:",[24,507,508],{},[27,509,510,511,513],{},"Local ",[146,512,166],{}," is not updated automatically",[20,515,516],{},"Sync it:",[74,518],{"language":96,"src":519},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fmerge-and-sync-15.sh",[20,521,522],{},"Remote changes must be pulled down intentionally",[11,524,526,530,533,550],{"id":525,"level":14},"why-prs",[16,527,529],{"id":528},"why-pull-requests-matter","Why Pull Requests Matter",[20,531,532],{},"Pull requests create evidence:",[24,534,535,538,541,544,547],{},[27,536,537],{},"Which branch changed",[27,539,540],{},"Which files changed",[27,542,543],{},"What discussion or explanation was provided",[27,545,546],{},"Chance to review risky changes before merging",[27,548,549],{},"When the change was merged",[20,551,552],{},"For this course, pull requests are part of the workflow evidence, not just a GitHub feature",[11,554,556,560,563],{"id":555,"level":14},"exploration-intro",[16,557,559],{"id":558},"troubleshooting-explorations","Troubleshooting Explorations",[20,561,562],{},"The next slides use controlled problems to practice recovery",[24,564,565,568],{},[27,566,567],{},"The goal is not avoiding every error",[27,569,570],{},"The goal is reading output, identifying state, and recovering without guessing",[11,572,574,577,580],{"id":573,"level":14},"exploration-setup",[16,575,576],{"id":573},"Exploration Setup",[20,578,579],{},"Create a conflict practice branch:",[74,581],{"language":96,"src":582},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-setup-16.sh",[11,584,586,590,596,603,608,611,614],{"id":585,"level":14},"exploration-issue-1",[16,587,589],{"id":588},"exploration-issue-1-push-rejected","Exploration Issue 1: Push Rejected",[20,591,592,593],{},"On GitHub, switch to ",[146,594,595],{},"practice-conflict",[20,597,598,599,602],{},"Edit one line in ",[146,600,601],{},"myFile.txt"," directly on GitHub and commit the change",[24,604,605],{},[27,606,607],{},"Use the same line you will change locally",[20,609,610],{},"Back locally, edit that same line and commit:",[74,612],{"language":96,"src":613},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-issue-1-push-17.sh",[24,615,616],{},[27,617,618],{},"See the slides below for the rejected push and the pull that creates the conflict",[11,620,622,626,629],{"id":621,"level":247},"issue-1-push-without-pulling",[249,623,625],{"id":624},"try-push-without-pulling","Try Push Without Pulling",[20,627,628],{},"Push the local commit before pulling the GitHub commit:",[452,630,631,644],{"gap":454,"left-width":455,"right-width":455},[457,632,633,636],{"v-slot:left":459},[74,634],{"language":96,"src":635},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Ftry-push-without-pulling-20.sh",[24,637,638,641],{},[27,639,640],{},"Expected result: push rejected",[27,642,643],{},"Reason: GitHub has a commit your local branch does not have",[457,645,646],{"v-slot:right":459},[20,647,648],{},[491,649],{"alt":650,"src":651,"variant":495},"Git push rejected because the remote branch has commits that are not local yet","\u002Fimages\u002Fshared\u002Fgit-workflow\u002Fgit-push-rejected-before-pull.png",[11,653,655,659],{"id":654,"level":247},"issue-1-read-output",[249,656,658],{"id":657},"pull-the-remote-change","Pull The Remote Change",[452,660,661,680],{"gap":454,"left-width":455,"right-width":455},[457,662,663,666,669,672,677],{"v-slot:left":459},[20,664,665],{},"The usual next command is:",[74,667],{"language":96,"src":668},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-the-remote-change-20.sh",[20,670,671],{},"If Git asks how to reconcile divergent branches:",[24,673,674],{},[27,675,676],{},"Use merge behavior for this course practice",[74,678],{"language":96,"src":679},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-the-remote-change-21.sh",[457,681,682],{"v-slot:right":459},[20,683,684],{},[491,685],{"alt":686,"src":687,"variant":495},"Git pull output asking how to reconcile divergent branches","\u002Fimages\u002Fshared\u002Fgit-workflow\u002Fgit-pull-divergent-branches.png",[11,689,691,695,698,703,706,709,712],{"id":690,"level":14},"exploration-issue-2",[16,692,694],{"id":693},"exploration-issue-2-merge-conflict","Exploration Issue 2: Merge Conflict",[20,696,697],{},"After pulling, Git should report a conflict",[20,699,700,701],{},"Open ",[146,702,601],{},[20,704,705],{},"You may see markers like:",[74,707],{"language":76,"src":708},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-issue-2-merg-18.txt",[20,710,711],{},"Conflict markers show:",[24,713,714,717,720],{},[27,715,716],{},"Your local version",[27,718,719],{},"The GitHub version",[27,721,722],{},"The part Git could not combine automatically",[11,724,726,730,736,739,742,745],{"id":725,"level":247},"resolve-conflict",[249,727,729],{"id":728},"resolve-the-conflict","Resolve The Conflict",[20,731,732,733,735],{},"Edit ",[146,734,601],{}," so it contains the final text you want",[20,737,738],{},"Remove all conflict markers",[20,740,741],{},"Then run:",[74,743],{"language":96,"src":744},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fresolve-the-conflict-19.sh",[24,746,747],{},[27,748,310],{},[11,750,752,756,759],{"id":751,"level":247},"verify-conflict-resolution",[249,753,755],{"id":754},"verify-the-recovery","Verify The Recovery",[20,757,758],{},"Check:",[24,760,761,766,769,774],{},[27,762,763,765],{},[146,764,275],{}," is clean",[27,767,768],{},"GitHub shows the updated branch",[27,770,771,773],{},[146,772,601],{}," contains the final text",[27,775,776],{},"No conflict markers remain",[11,778,780,783],{"id":779,"level":14},"common-mistakes",[16,781,782],{"id":779},"Common Mistakes",[24,784,785,788,791,794,797,807],{},[27,786,787],{},"Committing on the wrong branch",[27,789,790],{},"Forgetting to push after committing",[27,792,793],{},"Forgetting to pull after merging on GitHub",[27,795,796],{},"Leaving conflict markers in a file",[27,798,799,800,803,804],{},"Using vague branch names like ",[146,801,802],{},"stuff"," or ",[146,805,806],{},"final",[27,808,809],{},"Making several unrelated changes in one commit",[11,811,813,817],{"id":812,"level":14},"further-learning",[16,814,816],{"id":815},"key-terms-and-further-learning","Key Terms And Further Learning",[452,818,819,845],{"gap":454,"left-width":455,"right-width":455},[457,820,821,825],{"v-slot:left":459},[249,822,824],{"id":823},"key-terms","Key Terms",[24,826,827,830,833,836,839,842],{},[27,828,829],{},"Working folder: files you can edit",[27,831,832],{},"Staging area: changes selected for the next commit",[27,834,835],{},"Commit: local saved checkpoint",[27,837,838],{},"Remote: GitHub copy of the repository",[27,840,841],{},"Pull request: GitHub page for reviewing and merging branch work",[27,843,844],{},"Conflict: a change Git cannot merge automatically",[457,846,847,850],{"v-slot:right":459},[249,848,849],{"id":812},"Further Learning",[24,851,852,862,869,877],{},[27,853,854,855],{},"Pro Git Book: ",[856,857,861],"a",{"href":858,"rel":859},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Basics-Getting-a-Git-Repository",[860],"nofollow","Git Basics",[27,863,854,864],{},[856,865,868],{"href":866,"rel":867},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Branching-Basic-Branching-and-Merging",[860],"Basic Branching and Merging",[27,870,871,872],{},"GitHub Docs: ",[856,873,876],{"href":874,"rel":875},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fpull-requests\u002Fcollaborating-with-pull-requests\u002Fproposing-changes-to-your-work-with-pull-requests\u002Fcreating-a-pull-request",[860],"Creating a pull request",[27,878,879,880],{},"Oh Shit, Git!?!: ",[856,881,884],{"href":882,"rel":883},"https:\u002F\u002Fohshitgit.com\u002F",[860],"Common Git recovery situations",[11,886,888,891],{"id":887,"level":14},"summary",[16,889,890],{"id":887},"Summary",[452,892,896,921],{"gap":893,"left-width":894,"right-width":895},"md","0.72fr","1.38fr",[457,897,898,901],{"v-slot:left":459},[20,899,900],{},"Before leaving this presentation, confirm you can:",[24,902,903,909,912,915,918],{},[27,904,905,906,908],{},"Read ",[146,907,275],{}," before choosing the next command",[27,910,911],{},"Move a change from working folder to staging area to commit",[27,913,914],{},"Push a branch to GitHub and open a pull request",[27,916,917],{},"Recognize when a failed push or conflict needs recovery",[27,919,920],{},"Next: open the cloned repository in VS Code",[457,922,923,926],{"v-slot:right":459},[20,924,925],{},"Git\u002FGitHub flow:",[927,928],"figure-image",{"alt":929,"src":930},"Lane diagram showing local Git commands moving from the base branch to a feature or homework branch, then pushing to GitHub for pull request review and merge, then pulling the base branch back locally","\u002Fimages\u002Fshared\u002Fgit-github-lane-flow.svg",[20,932,933],{},"::",{"title":459,"searchDepth":935,"depth":935,"links":936},2,[937,938,939,940,941,942,943,944,948,951,954,955,956,957,958,959,960,964,968,969,970],{"id":13,"depth":935,"text":18},{"id":50,"depth":935,"text":51},{"id":71,"depth":935,"text":72},{"id":89,"depth":935,"text":90},{"id":123,"depth":935,"text":124},{"id":159,"depth":935,"text":160},{"id":212,"depth":935,"text":213},{"id":228,"depth":935,"text":229,"children":945},[946],{"id":251,"depth":947,"text":252},3,{"id":282,"depth":935,"text":283,"children":949},[950],{"id":316,"depth":947,"text":317},{"id":359,"depth":935,"text":360,"children":952},[953],{"id":390,"depth":947,"text":391},{"id":425,"depth":935,"text":426},{"id":449,"depth":935,"text":450},{"id":501,"depth":935,"text":502},{"id":528,"depth":935,"text":529},{"id":558,"depth":935,"text":559},{"id":573,"depth":935,"text":576},{"id":588,"depth":935,"text":589,"children":961},[962,963],{"id":624,"depth":947,"text":625},{"id":657,"depth":947,"text":658},{"id":693,"depth":935,"text":694,"children":965},[966,967],{"id":728,"depth":947,"text":729},{"id":754,"depth":947,"text":755},{"id":779,"depth":935,"text":782},{"id":815,"depth":935,"text":816},{"id":887,"depth":935,"text":890},"presentation","Internet Applications","Practice the core Git workflow with small changes, branches, pull requests, and two guided troubleshooting scenarios.","Face-to-face class of about 40 students; includes command explanation, branch practice, pull request walkthrough, conflict exploration, and recovery discussion.","20","70","90",{},"1",true,"40","\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs",false,{"title":5,"description":973},"published","internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs",[988,989,990],"git","branches","pull-requests","48:54","MOa9zIUOqaI","https:\u002F\u002Fyoutu.be\u002FMOa9zIUOqaI","Git Commands and PRs","GTIGHU5IyAE7RcRy68evvCM5YPZVDAWUbiTdBfC9nCI",null,[],[999,1496,2559,3445,4539,5194,5985,7052,7778,8603],{"id":1000,"title":1001,"audience":6,"body":1002,"contentType":971,"course":972,"description":1477,"estimateBasis":1478,"estimatedDiscussionMinutes":1479,"estimatedLiveMinutes":975,"estimatedTotalMinutes":1480,"extension":893,"meta":1481,"module":979,"navigation":980,"order":1482,"path":1483,"promptAssist":983,"seo":1484,"status":985,"stem":1485,"tags":1486,"videoDuration":1491,"videoId":1492,"videoLink":1493,"videoTitle":1494,"week":979,"__hash__":1495},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord.md","Learn Courses Platform And Discord",{"type":8,"value":1003,"toc":1462},[1004,1038,1078,1123,1173,1221,1254,1316,1357,1407,1436],[11,1005,1007,1011,1025],{"id":1006,"level":14},"learn-courses-flow",[16,1008,1010],{"id":1009},"what-is-the-learn-courses-platform","What is the Learn Courses Platform",[24,1012,1013,1016,1019,1022],{},[27,1014,1015],{},"This is a platform I've built over the years to aid assignment submissions and course utilities",[27,1017,1018],{},"It provides objective-based worksheets to fill in images, urls, and open responses to document assignment evidence",[27,1020,1021],{},"The goal is to keep tasks clear and objective for students and grading",[27,1023,1024],{},"Also includes a few other utilities for courses (such as joining the Discord server)",[20,1026,1027,1028,1032,1033,1037],{},"NOTE: Summer 2026 the previous Learn Platform (",[856,1029,1030],{"href":1030,"rel":1031},"https:\u002F\u002Flearn.ethereallab.app",[860],") has been replaced by Learn Courses Platform (",[856,1034,1035],{"href":1035,"rel":1036},"https:\u002F\u002Fcourses.ethereallab.app",[860],"). The deprecated site is still available as a backup but all activities\u002Fcontent is being migrated to the new version",[11,1039,1041,1044,1047,1075],{"id":1040,"level":14},"learn-courses-title",[16,1042,1001],{"id":1043},"learn-courses-platform-and-discord",[20,1045,1046],{},"How to join:",[24,1048,1049,1055,1063,1066,1069,1072],{},[27,1050,1051,1052],{},"Visit the platform ",[856,1053,1035],{"href":1035,"rel":1054},[860],[27,1056,1057,1058],{},"Sign in with your NJIT email\n",[24,1059,1060],{},[27,1061,1062],{},"If you're in the Canvas course, you should automatically get synced to this platform",[27,1064,1065],{},"Visit your Profile page",[27,1067,1068],{},"Associate your Discord account",[27,1070,1071],{},"Join the course Discord server",[27,1073,1074],{},"Verify that your course channels appear on Discord",[20,1076,1077],{},"You can follow the steps on the below slides for guidance",[11,1079,1081,1084],{"id":1080,"level":247},"visit-learn-courses",[16,1082,1083],{"id":1080},"Visit Learn Courses",[452,1085,1086,1115],{"gap":454,"left-width":455,"right-width":455},[457,1087,1088,1091,1096],{"v-slot:left":459},[20,1089,1090],{},"Go to:",[20,1092,1093],{},[856,1094,1035],{"href":1035,"rel":1095},[860],[24,1097,1098,1106,1109,1112],{},[27,1099,1100,1101,1105],{},"Click the ",[1102,1103,1104],"strong",{},"Login"," button",[27,1107,1108],{},"Use your NJIT email",[27,1110,1111],{},"Only NJIT accounts are allowed",[27,1113,1114],{},"If the browser tries a personal Chrome profile, log out of that account or switch profiles",[457,1116,1117],{"v-slot:right":459},[20,1118,1119],{},[491,1120],{"alt":1121,"src":1122,"variant":495},"Learn Courses logged-out home page with the Login button visible","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fhome-loggedout-login-button.png",[11,1124,1126,1129],{"id":1125,"level":247},"associate-discord-name",[16,1127,1128],{"id":1125},"Associate Discord Name",[452,1130,1131,1157],{"gap":454,"left-width":455,"right-width":455},[457,1132,1133,1136,1154],{"v-slot:left":459},[20,1134,1135],{},"On Learn Courses:",[1137,1138,1139,1142,1148,1151],"ol",{},[27,1140,1141],{},"Open your Profile",[27,1143,1144,1145],{},"Click ",[1102,1146,1147],{},"Refresh Discord Username",[27,1149,1150],{},"Authorize the Discord prompt",[27,1152,1153],{},"After the success message appears, save your profile",[20,1155,1156],{},"If you are not sure where you are, use the Home icon in the top left to return to the dashboard.",[457,1158,1159,1166],{"v-slot:right":459},[20,1160,1161],{},[491,1162],{"alt":1163,"src":1164,"variant":495,"max-height":1165},"Learn Courses dashboard sidebar with Profile and course links visible","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdashboard-sidebar-profile-links.png","13rem",[20,1167,1168],{},[491,1169],{"alt":1170,"src":1171,"variant":495,"max-height":1172},"Learn Courses profile page with Discord connection controls visible","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fprofile-page.png","16rem",[11,1174,1176,1179],{"id":1175,"level":247},"authorize-discord",[16,1177,1178],{"id":1175},"Authorize Discord",[452,1180,1181,1205],{"gap":454,"left-width":455,"right-width":455},[457,1182,1183,1186],{"v-slot:left":459},[20,1184,1185],{},"Discord will ask whether Learn Courses can access your Discord account.",[24,1187,1188,1191,1196,1199,1202],{},[27,1189,1190],{},"Confirm you are signed in to the correct Discord account",[27,1192,1144,1193],{},[1102,1194,1195],{},"Authorize",[27,1197,1198],{},"Return to Learn Courses",[27,1200,1201],{},"Look for the success message",[27,1203,1204],{},"Save the profile change",[457,1206,1207,1214],{"v-slot:right":459},[20,1208,1209],{},[491,1210],{"alt":1211,"src":1212,"variant":495,"max-height":1213},"Discord authorization prompt for Learn Courses","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdiscord-auth.png","25rem",[20,1215,1216],{},[491,1217],{"alt":1218,"src":1219,"variant":495,"max-height":1220},"Learn Courses success message after connecting Discord","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdiscord-connected-success.png","7rem",[11,1222,1224,1227,1230,1236,1243],{"id":1223,"level":247},"join-the-channel",[16,1225,1226],{"id":1223},"Join The Channel",[20,1228,1229],{},"Use the Discord link provided on Canvas, or use:",[20,1231,1232],{},[856,1233,1234],{"href":1234,"rel":1235},"https:\u002F\u002Fdiscord.com\u002Finvite\u002FYEHcm44wzg",[860],[20,1237,1238,1239,1242],{},"This should send you to the ",[146,1240,1241],{},"access-channel"," channel.",[24,1244,1245,1248,1251],{},[27,1246,1247],{},"Other channels are protected by a bot",[27,1249,1250],{},"Messages may be blocked until your name and role are set",[27,1252,1253],{},"You'll have temporary access until a role is applied so if you leave before completing the steps you'll have to revisit the invite link",[11,1255,1257,1260],{"id":1256,"level":14},"verify-with-quackbot",[16,1258,1259],{"id":1256},"Verify With QuackBot",[452,1261,1262,1307],{"gap":454,"left-width":455,"right-width":455},[457,1263,1264,1276,1282,1287,1290,1304],{"v-slot:left":459},[24,1265,1266,1269],{},[27,1267,1268],{},"A summer 2026 change was to have the bot attempt to auto-detect new members and apply roles automatically",[27,1270,1271,1272,1275],{},"If you don't see the proper semester category (i.e., ",[146,1273,1274],{},"summer-2026",") or the expected channels you can do the below action",[20,1277,1278,1279,1281],{},"In ",[146,1280,1241],{},", enter:",[20,1283,1284],{},[146,1285,1286],{},"@QuackBot",[20,1288,1289],{},"QuackBot will:",[24,1291,1292,1295,1298,1301],{},[27,1293,1294],{},"Verify your account",[27,1296,1297],{},"Pull in your name and section",[27,1299,1300],{},"Apply your class role",[27,1302,1303],{},"Update your server nickname",[20,1305,1306],{},"This does not change your real Discord username.",[457,1308,1309],{"v-slot:right":459},[20,1310,1311],{},[491,1312],{"alt":1313,"src":1314,"variant":495,"max-height":1315},"QuackBot response showing the student already has a course role","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fquackbot-role-response.png","8rem",[11,1317,1319,1323,1326,1337,1341],{"id":1318,"level":14},"welcome-and-potential-issues",[16,1320,1322],{"id":1321},"welcome","Welcome",[20,1324,1325],{},"If the previous steps worked, you should see a new semester category in the Discord sidebar.",[24,1327,1328,1331,1334],{},[27,1329,1330],{},"It should appear after the general channels",[27,1332,1333],{},"It should include one or more channels for your active courses",[27,1335,1336],{},"Use the correct course channel for class questions and discussion",[249,1338,1340],{"id":1339},"potential-issues","Potential Issues",[24,1342,1343,1346],{},[27,1344,1345],{},"If you recently joined the class, your UCID may still need to be added to Learn Courses",[27,1347,1348,1349,1352],{},"If there is an issue, email the instructor or DM ",[146,1350,1351],{},"MattToegel",[24,1353,1354],{},[27,1355,1356],{},"Some Discord privacy settings may require a friend request before DMs work",[11,1358,1360,1363],{"id":1359,"level":14},"general-conduct",[16,1361,1362],{"id":1359},"General Conduct",[24,1364,1365,1368,1371,1382,1385,1393,1401,1404],{},[27,1366,1367],{},"Use class-related channels for questions and discussion",[27,1369,1370],{},"Ask general course questions in the channel instead of DM when possible",[27,1372,1373,1374],{},"Do not post screenshots of in-progress assignment solutions\n",[24,1375,1376,1379],{},[27,1377,1378],{},"This would be more ideal for a DM",[27,1380,1381],{},"If you see posted solution-like items don't assume they're correct",[27,1383,1384],{},"General unrelated code is okay when it supports a discussion (like content from a presentation or reading)",[27,1386,1387,1388],{},"If the instructor needs to see assignment code, they may ask you to DM the screenshot\n",[24,1389,1390],{},[27,1391,1392],{},"Since repositories should be set to private; repo links are fine to post in the class channel since other students should not have access to them",[27,1394,1395,1396],{},"Keep off-topic items out of class channels\n",[24,1397,1398],{},[27,1399,1400],{},"There are plenty of categorized channels to use and I can always make more",[27,1402,1403],{},"Helping classmates understand topics is encouraged just be mindful not to spoon-feed",[27,1405,1406],{},"Sharing direct solutions goes against the Academic Integrity Policy",[11,1408,1410,1413,1416],{"id":1409,"level":14},"quick-check",[16,1411,1412],{"id":1409},"Quick Check",[20,1414,1415],{},"Before continuing, confirm:",[24,1417,1418,1421,1424,1427,1430,1433],{},[27,1419,1420],{},"You can sign in to Learn Courses with your NJIT email",[27,1422,1423],{},"Your profile is saved",[27,1425,1426],{},"Discord is associated with your Learn Courses profile",[27,1428,1429],{},"You joined the Discord server",[27,1431,1432],{},"QuackBot applied your course role",[27,1434,1435],{},"You can see the correct course channel",[11,1437,1438,1440],{"id":887,"level":14},[16,1439,890],{"id":887},[24,1441,1442,1445,1453,1456,1459],{},[27,1443,1444],{},"Learn Courses supports course tools and course-specific setup",[27,1446,1447,1448],{},"Canvas remains the official assignment, grade, and course hub\n",[24,1449,1450],{},[27,1451,1452],{},"All necessary items will be linked on Canvas",[27,1454,1455],{},"Discord is the preferred quick communication channel",[27,1457,1458],{},"QuackBot connects your Discord account to the correct course role",[27,1460,1461],{},"Good course communication keeps help requests specific and protects private information",{"title":459,"searchDepth":935,"depth":935,"links":1463},[1464,1465,1466,1467,1468,1469,1470,1471,1474,1475,1476],{"id":1009,"depth":935,"text":1010},{"id":1043,"depth":935,"text":1001},{"id":1080,"depth":935,"text":1083},{"id":1125,"depth":935,"text":1128},{"id":1175,"depth":935,"text":1178},{"id":1223,"depth":935,"text":1226},{"id":1256,"depth":935,"text":1259},{"id":1321,"depth":935,"text":1322,"children":1472},[1473],{"id":1339,"depth":947,"text":1340},{"id":1359,"depth":935,"text":1362},{"id":1409,"depth":935,"text":1412},{"id":887,"depth":935,"text":890},"Set up Learn Courses Platform and Discord before starting terminal, Git, and local server work.","Face-to-face class of about 40 students; includes account sign-in, Discord association, QuackBot role setup, and communication expectations.","10","30",{},"0","\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord",{"title":1001,"description":1477},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord",[1487,1488,1489,1490],"course-tools","learn-courses","discord","setup","11:16","ScmHyEF1sA0","https:\u002F\u002Fyoutu.be\u002FScmHyEF1sA0","Joining Learn Platform and Discord Server","tEFV7lUabcy7whz7FSHEjPXSirrd3ginqQq4O4AkW9o",{"id":1497,"title":1498,"audience":6,"body":1499,"contentType":971,"course":972,"description":2543,"estimateBasis":2544,"estimatedDiscussionMinutes":1479,"estimatedLiveMinutes":2545,"estimatedTotalMinutes":2546,"extension":893,"meta":2547,"module":979,"navigation":980,"order":1479,"path":2548,"promptAssist":983,"seo":2549,"status":985,"stem":2550,"tags":2551,"videoDuration":2555,"videoId":2556,"videoLink":2557,"videoTitle":1498,"week":979,"__hash__":2558},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands.md","Basic CLI Commands",{"type":8,"value":1500,"toc":2509},[1501,1559,1595,1627,1689,1756,1807,1833,1850,1888,1916,1937,1972,1994,2066,2089,2133,2195,2246,2273,2293,2322,2360,2390,2400,2463],[11,1502,1504,1508],{"id":1503,"level":14},"why-cli-first",[16,1505,1507],{"id":1506},"why-cli-comes-first","Why CLI Comes First",[24,1509,1510,1518,1526,1540,1548],{},[27,1511,1512,1513],{},"Common language for setup and developer tools\n",[24,1514,1515],{},[27,1516,1517],{},"Git, servers, package installs, deployment logs",[27,1519,1520,1521],{},"Works when there is no full desktop\n",[24,1522,1523],{},[27,1524,1525],{},"SSH, Ubuntu Server, minimal system access",[27,1527,1528,1529],{},"Direct check of what the computer sees\n",[24,1530,1531,1534,1537],{},[27,1532,1533],{},"Current folder",[27,1535,1536],{},"Files and permissions",[27,1538,1539],{},"Command output",[27,1541,1542,1543],{},"Repeatable steps beat guessing through menus\n",[24,1544,1545],{},[27,1546,1547],{},"Run a command, read output, adjust",[27,1549,1550,1551],{},"Location still matters\n",[24,1552,1553,1556],{},[27,1554,1555],{},"Wrong folder can make correct commands fail",[27,1557,1558],{},"Or create files in the wrong place",[11,1560,1562,1565,1568],{"id":1561,"level":14},"goal",[16,1563,1564],{"id":1561},"Goal",[20,1566,1567],{},"Build the command-line habits that make setup work predictable:",[24,1569,1570,1573,1576,1589,1592],{},[27,1571,1572],{},"Know what folder the terminal is using",[27,1574,1575],{},"Read file and folder lists before moving",[27,1577,1578,1579,1582,1583,1585,1586],{},"Recognize common flags like ",[146,1580,1581],{},"-a",", ",[146,1584,347],{},", and ",[146,1587,1588],{},"-l",[27,1590,1591],{},"Make small file changes and verify them",[27,1593,1594],{},"Stop safely when output does not match the lesson",[11,1596,1598,1601,1604,1624],{"id":1597,"level":14},"before-you-start",[16,1599,1600],{"id":1597},"Before You Start",[20,1602,1603],{},"Run these commands on your host computer",[24,1605,1606,1618,1621],{},[27,1607,1608,1609],{},"Windows: Git Bash",[24,1610,1611],{},[27,1612,1613,1614],{},"Need Git Bash now? Use the Windows install slide in the next presentation:\n",[856,1615,1617],{"href":1616},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fview\u002Fslides#step-1-install-git-on-windows","Install Git On Windows",[27,1619,1620],{},"Apple macOS: Terminal",[27,1622,1623],{},"Linux: Terminal",[20,1625,1626],{},"Use one terminal window for the whole practice so your location is easy to track",[11,1628,1630,1634],{"id":1629,"level":14},"working-directory",[16,1631,1633],{"id":1632},"the-main-idea","The Main Idea",[24,1635,1636,1647,1658,1681],{},[27,1637,1638,1639],{},"Terminal commands run from one folder at a time\n",[24,1640,1641],{},[27,1642,1643,1644],{},"That folder is the ",[1102,1645,1646],{},"working directory",[27,1648,1649,1652,1653],{},[146,1650,1651],{},"pwd",": print working directory\n",[24,1654,1655],{},[27,1656,1657],{},"Shows the full path to the folder your terminal is using",[27,1659,1660,1661],{},"Fresh terminal usually starts in your home folder\n",[24,1662,1663,1669,1675],{},[27,1664,1665,1666],{},"Windows Git Bash: ",[146,1667,1668],{},"\u002Fc\u002FUsers\u002Fyour-username",[27,1670,1671,1672],{},"Apple macOS: ",[146,1673,1674],{},"\u002FUsers\u002Fyour-username",[27,1676,1677,1678],{},"Linux: ",[146,1679,1680],{},"\u002Fhome\u002Fyour-username",[27,1682,1683,1684],{},"Commands from this lesson start from the working directory\n",[24,1685,1686],{},[27,1687,1688],{},"Unless you give a different path",[11,1690,1692,1695,1698,1750],{"id":1691,"level":14},"paths-relative-and-absolute",[16,1693,1694],{"id":1691},"Paths: Relative And Absolute",[20,1696,1697],{},"Paths build on the working directory. They tell the terminal which file or folder you mean",[24,1699,1700,1706,1712,1718,1744],{},[27,1701,1702,1703],{},"Relative path: starts from the working directory, like ",[146,1704,1705],{},"public\u002Findex.php",[27,1707,1708,1709],{},"Absolute path: starts from the system root, like ",[146,1710,1711],{},"\u002Fhome\u002Fstudent\u002Fproject",[27,1713,1714,1717],{},[146,1715,1716],{},"."," means the current folder",[27,1719,1720,1723,1724],{},[146,1721,1722],{},".."," means the parent folder\n",[24,1725,1726,1732,1738],{},[27,1727,1728,1731],{},[146,1729,1730],{},"..\u002F.."," goes up two folders",[27,1733,1734,1735],{},"Example: ",[146,1736,1737],{},"cd ..\u002F..",[27,1739,1740,1743],{},[146,1741,1742],{},"..."," is not a shortcut",[27,1745,1746,1749],{},[146,1747,1748],{},"~"," means your home folder",[20,1751,1752,1753,1755],{},"If a command affects the wrong place, check ",[146,1754,1651],{}," first, then check the path you typed",[11,1757,1759,1762,1765,1784,1787],{"id":1758,"level":14},"flags-options-and-arguments",[16,1760,1761],{"id":1758},"Flags, Options, And Arguments",[20,1763,1764],{},"Commands usually follow this shape:",[24,1766,1767,1773,1778],{},[27,1768,1769,1770],{},"Command: what to do, like ",[146,1771,1772],{},"ls",[27,1774,1775,1776],{},"Flag or option: how to do it, like ",[146,1777,1581],{},[27,1779,1780,1781],{},"Argument: what to do it to, like ",[146,1782,1783],{},"public_html",[20,1785,1786],{},"Examples:",[24,1788,1789,1795,1801],{},[27,1790,1791,1794],{},[146,1792,1793],{},"ls -a"," shows hidden files",[27,1796,1797,1800],{},[146,1798,1799],{},"cp -r folder backup-folder"," copies a folder",[27,1802,1803,1806],{},[146,1804,1805],{},"nano -l file.txt"," opens with line numbers",[11,1808,1810,1814,1817,1828],{"id":1809,"level":14},"practice-loop",[16,1811,1813],{"id":1812},"practice-1-location-and-paths","Practice 1: Location And Paths",[20,1815,1816],{},"For each command, use the same pattern:",[1137,1818,1819,1822,1825],{},[27,1820,1821],{},"Run one command",[27,1823,1824],{},"Read the output",[27,1826,1827],{},"Confirm the folder or file changed the way you expected",[24,1829,1830],{},[27,1831,1832],{},"See the slides below for workflow steps, checkpoints, and expected results",[11,1834,1836,1839,1841,1844,1847],{"id":1835,"level":247},"step-1-confirm-where-you-are",[16,1837,1838],{"id":1835},"Step 1: Confirm Where You Are",[20,1840,93],{},[74,1842],{"language":96,"src":1843},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-1-confirm-where-you-01.sh",[20,1845,1846],{},"Expected result: a folder path",[20,1848,1849],{},"If you see a path, the terminal is working and you know your current location",[11,1851,1853,1856,1858,1861,1864,1867,1870],{"id":1852,"level":247},"step-2-list-files",[16,1854,1855],{"id":1852},"Step 2: List Files",[20,1857,93],{},[74,1859],{"language":96,"src":1860},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-list-files-02.sh",[20,1862,1863],{},"Expected result: file and folder names from your current location",[20,1865,1866],{},"For hidden files and details too, run:",[74,1868],{"language":96,"src":1869},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-list-files-03.sh",[24,1871,1872,1877,1882],{},[27,1873,1874,1876],{},[146,1875,1581],{}," includes hidden files",[27,1878,1879,1881],{},[146,1880,1588],{}," uses a long listing",[27,1883,1884,1887],{},[146,1885,1886],{},"-la"," combines both",[11,1889,1891,1894,1897,1900,1907,1913],{"id":1890,"level":247},"step-3-change-folders",[16,1892,1893],{"id":1890},"Step 3: Change Folders",[20,1895,1896],{},"Start from your home folder, then move up and back",[74,1898],{"language":96,"src":1899},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-3-change-folders-04.sh",[20,1901,1902,1903,1906],{},"This avoids assuming your computer has a specific folder like ",[146,1904,1905],{},"Documents"," in the current location",[20,1908,1909,1910,1912],{},"When you move into a named folder later, run ",[146,1911,1772],{}," first and pick a folder that actually appears in the list",[20,1914,1915],{},"If a path has spaces, wrap it in quotes",[11,1917,1919,1923,1925,1928],{"id":1918,"level":247},"step-4-create-practice-folder",[16,1920,1922],{"id":1921},"step-4-create-a-practice-folder","Step 4: Create A Practice Folder",[20,1924,93],{},[74,1926],{"language":96,"src":1927},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-4-create-a-practice-05.sh",[20,1929,1930,1931,1933,1934],{},"Expected result: ",[146,1932,1651],{}," ends with ",[146,1935,1936],{},"cli-practice",[11,1938,1940,1944,1946,1949,1952],{"id":1939,"level":247},"step-5-create-and-read-file",[16,1941,1943],{"id":1942},"step-5-write-text-to-a-file","Step 5: Write Text To A File",[20,1945,93],{},[74,1947],{"language":96,"src":1948},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-5-write-text-to-a-f-06.sh",[20,1950,1951],{},"What this command does:",[24,1953,1954,1960,1966],{},[27,1955,1956,1959],{},[146,1957,1958],{},"echo"," prepares text for the terminal",[27,1961,1962,1965],{},[146,1963,1964],{},">"," redirects that text into a file instead of printing it on screen",[27,1967,1968,1971],{},[146,1969,1970],{},"cli-proof.txt"," is created in the current folder, or replaced if it already exists",[11,1973,1975,1979,1982,1985,1991],{"id":1974,"level":247},"step-5-read-file-back",[249,1976,1978],{"id":1977},"step-5-continued-read-the-file-back","Step 5 Continued: Read The File Back",[20,1980,1981],{},"Then read it back:",[74,1983],{"language":96,"src":1984},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-5-continued-read-th-07.sh",[20,1986,1987,1990],{},[146,1988,1989],{},"cat"," prints file contents in the terminal",[20,1992,1993],{},"Expected result: the terminal prints the text you wrote",[11,1995,1997,2001,2003,2012,2015,2041,2044],{"id":1996,"level":14},"file-management-loop",[16,1998,2000],{"id":1999},"practice-2-file-management","Practice 2: File Management",[20,2002,1816],{},[1137,2004,2005,2007,2009],{},[27,2006,1821],{},[27,2008,1824],{},[27,2010,2011],{},"Confirm the file changed the way you expected",[20,2013,2014],{},"Commands in this practice:",[24,2016,2017,2023,2029,2035],{},[27,2018,2019,2022],{},[146,2020,2021],{},"touch"," creates an empty file",[27,2024,2025,2028],{},[146,2026,2027],{},"cp"," copies a file or folder",[27,2030,2031,2034],{},[146,2032,2033],{},"mv"," moves or renames",[27,2036,2037,2040],{},[146,2038,2039],{},"rm"," deletes",[20,2042,2043],{},"Important flags:",[24,2045,2046,2052,2058,2064],{},[27,2047,2048,2051],{},[146,2049,2050],{},"cp -r"," copies folders",[27,2053,2054,2057],{},[146,2055,2056],{},"rm -r"," deletes folders",[27,2059,2060,2063],{},[146,2061,2062],{},"rm -f"," forces deletion",[27,2065,1832],{},[11,2067,2069,2073,2075,2078,2083],{"id":2068,"level":247},"practice-2-step-1-create-empty-file",[16,2070,2072],{"id":2071},"step-1-create-an-empty-file","Step 1: Create An Empty File",[20,2074,93],{},[74,2076],{"language":96,"src":2077},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-1-create-an-empty-f-08.sh",[20,2079,2080,2082],{},[146,2081,2021],{}," creates an empty file, or updates the timestamp if the file already exists",[20,2084,1930,2085,2088],{},[146,2086,2087],{},"practice-empty.txt"," appears in the folder list",[11,2090,2092,2096,2098,2101,2104,2109,2122],{"id":2091,"level":247},"practice-2-step-2-copy-rename-and-delete",[16,2093,2095],{"id":2094},"step-2-copy-rename-and-delete","Step 2: Copy, Rename, And Delete",[20,2097,93],{},[74,2099],{"language":96,"src":2100},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-copy-rename-and-d-09.sh",[20,2102,2103],{},"Expected result: the backup is copied, renamed, then removed",[20,2105,304,2106,2108],{},[146,2107,2039],{}," carefully. Deleting from the terminal usually skips the recycle bin",[24,2110,2111,2116],{},[27,2112,2113,2115],{},[146,2114,347],{},": recursive, includes folders and everything inside them",[27,2117,2118,2121],{},[146,2119,2120],{},"-f",": force, skips many confirmation prompts",[2123,2124,2126],"alert",{"color":2125},"red",[20,2127,2128,2129,2132],{},"Never run ",[146,2130,2131],{},"rm -rf \u002F",". It can try to delete the whole system from the root folder.",[11,2134,2136,2140,2143,2160,2165,2170,2190],{"id":2135,"level":14},"terminal-editors",[16,2137,2139],{"id":2138},"practice-3-terminal-editors","Practice 3: Terminal Editors",[20,2141,2142],{},"Sometimes you need to edit a file from a terminal",[24,2144,2145,2151],{},[27,2146,2147,2150],{},[146,2148,2149],{},"nano"," is beginner-friendly",[27,2152,2153,803,2156,2159],{},[146,2154,2155],{},"vi",[146,2157,2158],{},"vim"," is common on servers but has a learning curve",[20,2161,304,2162,2164],{},[146,2163,2149],{}," for this course unless a lesson says otherwise",[20,2166,304,2167,2169],{},[146,2168,1805],{}," when line numbers would help",[20,2171,2172,2173,803,2175,2177,2178,2181,2182,2185,2186,2189],{},"If you accidentally open ",[146,2174,2155],{},[146,2176,2158],{},", press ",[146,2179,2180],{},"Esc",", type ",[146,2183,2184],{},":q",", and press ",[146,2187,2188],{},"Enter"," to exit without saving",[24,2191,2192],{},[27,2193,2194],{},"See the slide below for workflow steps, checkpoints, and expected results",[11,2196,2198,2203,2205,2208,2212,2234],{"id":2197,"level":247},"edit-with-nano",[16,2199,2200,2201],{"id":2197},"Edit With ",[146,2202,2149],{},[20,2204,93],{},[74,2206],{"language":96,"src":2207},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fedit-with-nano-10.sh",[20,2209,1278,2210,167],{},[146,2211,2149],{},[24,2213,2214,2217,2224,2228],{},[27,2215,2216],{},"Type a short note",[27,2218,2219,2220,2223],{},"Press ",[146,2221,2222],{},"Ctrl+O"," to save",[27,2225,2219,2226],{},[146,2227,2188],{},[27,2229,2219,2230,2233],{},[146,2231,2232],{},"Ctrl+X"," to exit",[20,2235,2236,2237,2239,2240,2181,2242,2185,2244],{},"If you open ",[146,2238,2155],{}," by mistake, press ",[146,2241,2180],{},[146,2243,2184],{},[146,2245,2188],{},[11,2247,2249,2255,2260,2263,2266,2269],{"id":2248,"level":14},"sudo-and-permission-boundaries",[16,2250,2251,2254],{"id":2248},[146,2252,2253],{},"sudo"," And Permission Boundaries",[20,2256,2257,2259],{},[146,2258,2253],{}," runs a command with elevated permissions",[20,2261,2262],{},"Use it only when a setup lesson explicitly says to use it",[20,2264,2265],{},"Example:",[74,2267],{"language":96,"src":2268},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fsudo-and-permission-boun-11.sh",[24,2270,2271],{},[27,2272,310],{},[11,2274,2276,2281,2287],{"id":2275,"level":247},"sudo-by-operating-system",[249,2277,2278,2280],{"id":2275},[146,2279,2253],{}," By Operating System",[20,2282,2283,2284,2286],{},"On Linux and macOS, ",[146,2285,2253],{}," is common for package installation and service management",[20,2288,2289,2290,2292],{},"Modern Windows also has a native ",[146,2291,2253],{}," option, but Windows Git Bash usually does not need it for this course. If elevated access is needed on Windows, open Git Bash as administrator",[11,2294,2296,2299,2302,2313],{"id":2295,"level":14},"quick-safety-routine",[16,2297,2298],{"id":2295},"Quick Safety Routine",[20,2300,2301],{},"Before a command changes files, ask:",[24,2303,2304,2307,2310],{},[27,2305,2306],{},"What folder am I in?",[27,2308,2309],{},"Do I see the files I expect?",[27,2311,2312],{},"Am I about to change the right folder?",[20,2314,2315,2316,2318,2319],{},"If one answer is unclear, stop and run ",[146,2317,1651],{}," plus ",[146,2320,2321],{},"ls -la",[11,2323,2324,2326],{"id":779,"level":14},[16,2325,782],{"id":779},[24,2327,2328,2344,2350,2358],{},[27,2329,2330,2333,2334,2336,2337,2339,2340,2343],{},[146,2331,2332],{},"No such file or directory",": run ",[146,2335,1651],{},", then ",[146,2338,1772],{},", then try ",[146,2341,2342],{},"cd"," again",[27,2345,2346,2347,2349],{},"Command affected the wrong folder: check ",[146,2348,1651],{}," before continuing",[27,2351,2352,2354,2355,2357],{},[146,2353,1989],{}," cannot find the file: run ",[146,2356,2321],{}," and check the exact filename",[27,2359,310],{},[11,2361,2363,2367],{"id":2362,"level":247},"common-mistakes-recovery",[249,2364,2366],{"id":2365},"recovery-checks","Recovery Checks",[24,2368,2369,2372,2378,2384],{},[27,2370,2371],{},"Spaces in a path: wrap the path in quotes",[27,2373,2374,2375],{},"Command keeps running: press ",[146,2376,2377],{},"Ctrl+C",[27,2379,2380,2381],{},"Permission denied: move back home with ",[146,2382,2383],{},"cd ~",[27,2385,2386,2387,2389],{},"Wrong ",[146,2388,2039],{},": stop and ask before doing more work",[11,2391,2392,2394,2397],{"id":1409,"level":14},[16,2393,1412],{"id":1409},[20,2395,2396],{},"You are ready for the next setup lesson when these commands make sense:",[74,2398],{"language":96,"src":2399},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fquick-check-12.sh",[11,2401,2402,2404],{"id":812,"level":14},[16,2403,816],{"id":815},[452,2405,2406,2436],{"gap":454,"left-width":455,"right-width":455},[457,2407,2408,2410,2416,2425],{"v-slot:left":459},[249,2409,824],{"id":823},[20,2411,2412,2415],{},[1102,2413,2414],{},"Working directory"," - The folder where the next terminal command runs",[20,2417,2418,2421,2422],{},[1102,2419,2420],{},"Path"," - A file or folder location, such as ",[146,2423,2424],{},"public_html\u002Findex.php",[20,2426,2427,2430,2431,2433,2434],{},[1102,2428,2429],{},"Flag"," - An extra command option, such as ",[146,2432,1886],{}," in ",[146,2435,2321],{},[457,2437,2438,2440],{"v-slot:right":459},[249,2439,849],{"id":812},[24,2441,2442,2449,2456],{},[27,2443,2444],{},[856,2445,2448],{"href":2446,"rel":2447},"https:\u002F\u002Fdocumentation.ubuntu.com\u002Fdesktop\u002Fen\u002Flatest\u002Ftutorial\u002Fthe-linux-command-line-for-beginners\u002F",[860],"Ubuntu Tutorial: The Linux Command Line For Beginners",[27,2450,2451],{},[856,2452,2455],{"href":2453,"rel":2454},"https:\u002F\u002Fwww.gnu.org\u002Fsoftware\u002Fcoreutils\u002Fmanual\u002Fcoreutils.html",[860],"GNU Coreutils Manual",[27,2457,2458],{},[856,2459,2462],{"href":2460,"rel":2461},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FLearn_web_development\u002FGetting_started\u002FEnvironment_setup\u002FCommand_line",[860],"MDN: Command Line Crash Course",[11,2464,2465,2467,2469],{"id":887,"level":14},[16,2466,890],{"id":887},[20,2468,900],{},[24,2470,2471,2476,2481,2492,2506],{},[27,2472,304,2473,2475],{},[146,2474,1651],{}," to check where commands will run",[27,2477,304,2478,2480],{},[146,2479,2321],{}," to inspect the current folder",[27,2482,304,2483,1582,2485,1582,2487,1585,2489,2491],{},[146,2484,2342],{},[146,2486,1716],{},[146,2488,1722],{},[146,2490,1748],{}," to move intentionally",[27,2493,2494,2495,1582,2497,1582,2499,1582,2501,1585,2503,2505],{},"Use file commands such as ",[146,2496,2021],{},[146,2498,2027],{},[146,2500,2033],{},[146,2502,2039],{},[146,2504,2149],{}," carefully",[27,2507,2508],{},"Stop and check location when output does not match the lesson",{"title":459,"searchDepth":935,"depth":935,"links":2510},[2511,2512,2513,2514,2515,2516,2517,2518,2519,2520,2521,2522,2525,2526,2527,2528,2529,2531,2536,2537,2540,2541,2542],{"id":1506,"depth":935,"text":1507},{"id":1561,"depth":935,"text":1564},{"id":1597,"depth":935,"text":1600},{"id":1632,"depth":935,"text":1633},{"id":1691,"depth":935,"text":1694},{"id":1758,"depth":935,"text":1761},{"id":1812,"depth":935,"text":1813},{"id":1835,"depth":935,"text":1838},{"id":1852,"depth":935,"text":1855},{"id":1890,"depth":935,"text":1893},{"id":1921,"depth":935,"text":1922},{"id":1942,"depth":935,"text":1943,"children":2523},[2524],{"id":1977,"depth":947,"text":1978},{"id":1999,"depth":935,"text":2000},{"id":2071,"depth":935,"text":2072},{"id":2094,"depth":935,"text":2095},{"id":2138,"depth":935,"text":2139},{"id":2197,"depth":935,"text":2530},"Edit With nano",{"id":2248,"depth":935,"text":2532,"children":2533},"sudo And Permission Boundaries",[2534],{"id":2275,"depth":947,"text":2535},"sudo By Operating System",{"id":2295,"depth":935,"text":2298},{"id":779,"depth":935,"text":782,"children":2538},[2539],{"id":2365,"depth":947,"text":2366},{"id":1409,"depth":935,"text":1412},{"id":815,"depth":935,"text":816},{"id":887,"depth":935,"text":890},"Practice the terminal commands you need so you can move through folders, inspect files, and verify your location before running course commands.","Face-to-face class of about 40 students; includes short CLI demo, student command practice, path\u002Fflag checks, and common beginner recovery questions.","45","55",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands",{"title":1498,"description":2543},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands",[2552,2553,2554],"cli","terminal","filesystem","46:05","NsSRKv_uBWM","https:\u002F\u002Fyoutu.be\u002FNsSRKv_uBWM","q_NRWUOCcsk5lm6u6kKPFGl9E9VqeQhaC0qb86nD7aY",{"id":2560,"title":2561,"audience":6,"body":2562,"contentType":971,"course":972,"description":3433,"estimateBasis":3434,"estimatedDiscussionMinutes":1479,"estimatedLiveMinutes":3435,"estimatedTotalMinutes":2545,"extension":893,"meta":3436,"module":979,"navigation":980,"order":975,"path":3437,"promptAssist":983,"seo":3438,"status":985,"stem":3439,"tags":3440,"videoDuration":3441,"videoId":3442,"videoLink":3443,"videoTitle":2561,"week":979,"__hash__":3444},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools.md","Git Tools",{"type":8,"value":2563,"toc":3403},[2564,2587,2616,2644,2682,2713,2744,2778,2807,2837,2874,2877,2907,2938,2967,3017,3035,3052,3072,3097,3128,3146,3187,3232,3314,3374],[11,2565,2566,2568],{"id":1561,"level":14},[16,2567,1564],{"id":1561},[24,2569,2570,2573,2576],{},[27,2571,2572],{},"Install Git",[27,2574,2575],{},"Choose one terminal for your operating system",[27,2577,2578,2579,1582,2582,1585,2584,2586],{},"Confirm ",[146,2580,2581],{},"git --version",[146,2583,1651],{},[146,2585,2321],{}," work before GitHub setup",[11,2588,2590,2594],{"id":2589,"level":14},"terminal-choice-by-os",[16,2591,2593],{"id":2592},"terminal-choices","Terminal Choices",[24,2595,2596,2599,2602,2605,2607,2610,2613],{},[27,2597,2598],{},"Pick the terminal for your operating system",[27,2600,2601],{},"Use that same terminal for this lesson path",[27,2603,2604],{},"Run commands on your own computer unless a later lesson explicitly says \"inside the VM\"",[27,2606,1608],{},[27,2608,2609],{},"Apple macOS: Terminal, with iTerm2 optional",[27,2611,2612],{},"Linux: Terminal, with Tilix optional",[27,2614,2615],{},"These operating system notes are alternatives, not a sequence",[11,2617,2619,2623,2641],{"id":2618,"level":14},"step-1-install-git-on-windows",[16,2620,2622],{"id":2621},"windows-path-git-bash","Windows Path: Git Bash",[1137,2624,2625,2632,2635,2638],{},[27,2626,2627,2628],{},"Go to ",[856,2629,2630],{"href":2630,"rel":2631},"https:\u002F\u002Fgit-scm.com\u002Finstall\u002Fwindows",[860],[27,2633,2634],{},"Download and run the Git for Windows installer",[27,2636,2637],{},"Open Git Bash from the Start menu",[27,2639,2640],{},"Use Git Bash whenever this course says to use the terminal",[20,2642,2643],{},"See the slides below for the install settings, launch check, and Windows terminal habit",[11,2645,2647,2650],{"id":2646,"level":247},"windows-installer-components",[249,2648,2649],{"id":2646},"Windows Installer: Components",[452,2651,2655,2663],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},"1.4fr","0.9fr","never",[457,2656,2657],{"v-slot:left":459},[20,2658,2659],{},[491,2660],{"alt":2661,"src":2662,"variant":495},"Git for Windows installer component selection screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep01_components.png",[457,2664,2665],{"v-slot:right":459},[24,2666,2667,2670,2676],{},[27,2668,2669],{},"Recommended to have these components selected",[27,2671,2672,2673],{},"Keep ",[146,2674,2675],{},"Git Bash Here",[27,2677,2678,2679],{},"Continue with ",[146,2680,2681],{},"Next",[11,2683,2685,2688],{"id":2684,"level":247},"windows-installer-default-editor",[249,2686,2687],{"id":2684},"Windows Installer: Default Editor",[452,2689,2690,2698],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,2691,2692],{"v-slot:left":459},[20,2693,2694],{},[491,2695],{"alt":2696,"src":2697,"variant":495},"Git for Windows installer default editor selection screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep02_default_editor.png",[457,2699,2700],{"v-slot:right":459},[24,2701,2702,2705,2710],{},[27,2703,2704],{},"Choose the editor you are comfortable with",[27,2706,2707,2709],{},[146,2708,2149],{}," or VS Code is friendlier than Vim for most beginners",[27,2711,2712],{},"This setting affects Git messages if Git opens an editor",[11,2714,2716,2719],{"id":2715,"level":247},"windows-installer-branch-name",[249,2717,2718],{"id":2715},"Windows Installer: Branch Name",[452,2720,2721,2729],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,2722,2723],{"v-slot:left":459},[20,2724,2725],{},[491,2726],{"alt":2727,"src":2728,"variant":495},"Git for Windows installer default branch name screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep03_branch_naming.png",[457,2730,2731],{"v-slot:right":459},[24,2732,2733,2738,2741],{},[27,2734,2735,2736],{},"Select the option that uses ",[146,2737,166],{},[27,2739,2740],{},"Course repositories will tell you which branch to use later",[27,2742,2743],{},"Do not create custom branch names here",[11,2745,2747,2750],{"id":2746,"level":247},"windows-installer-path",[249,2748,2749],{"id":2746},"Windows Installer: PATH",[452,2751,2752,2760],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,2753,2754],{"v-slot:left":459},[20,2755,2756],{},[491,2757],{"alt":2758,"src":2759,"variant":495},"Git for Windows installer PATH environment screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep04_path.png",[457,2761,2762],{"v-slot:right":459},[24,2763,2764,2767,2772,2775],{},[27,2765,2766],{},"Select the recommended PATH option",[27,2768,2769,2770],{},"This lets Git Bash and common tools find ",[146,2771,988],{},[27,2773,2774],{},"Avoid options that say Git Bash only",[27,2776,2777],{},"The third option can be used if you understand the consequences",[11,2779,2781,2784],{"id":2780,"level":247},"windows-installer-ssh",[249,2782,2783],{"id":2780},"Windows Installer: SSH",[452,2785,2786,2794],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,2787,2788],{"v-slot:left":459},[20,2789,2790],{},[491,2791],{"alt":2792,"src":2793,"variant":495},"Git for Windows installer SSH executable screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep05_ssh_bundled.png",[457,2795,2796],{"v-slot:right":459},[24,2797,2798,2801,2804],{},[27,2799,2800],{},"Use the bundled OpenSSH option",[27,2802,2803],{},"This keeps Git Bash SSH behavior predictable",[27,2805,2806],{},"SSH setup happens in the next lesson",[11,2808,2810,2814],{"id":2809,"level":247},"windows-installer-openssl",[249,2811,2813],{"id":2812},"windows-installer-https","Windows Installer: HTTPS",[452,2815,2816,2824],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,2817,2818],{"v-slot:left":459},[20,2819,2820],{},[491,2821],{"alt":2822,"src":2823,"variant":495},"Git for Windows installer HTTPS transport backend screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep06_openssl.png",[457,2825,2826],{"v-slot:right":459},[24,2827,2828,2831,2834],{},[27,2829,2830],{},"Keep the OpenSSL option",[27,2832,2833],{},"This is the normal Git for Windows choice",[27,2835,2836],{},"It supports secure GitHub connections",[11,2838,2840,2844],{"id":2839,"level":247},"windows-installer-checkout-style",[249,2841,2843],{"id":2842},"windows-installer-line-endings","Windows Installer: Line Endings",[452,2845,2846,2854],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,2847,2848],{"v-slot:left":459},[20,2849,2850],{},[491,2851],{"alt":2852,"src":2853,"variant":495},"Git for Windows installer line ending conversion screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep07_checkout_style.png",[457,2855,2856,2867],{"v-slot:right":459},[24,2857,2858,2861,2864],{},[27,2859,2860],{},"Keep the default line-ending option",[27,2862,2863],{},"Git handles Windows and Linux line endings for you",[27,2865,2866],{},"Do not change this unless a lesson says to",[2868,2869,2871],"admonition",{"type":2870},"note",[20,2872,2873],{},"Line-ending warnings may appear later. They are usually informational, not a sign that there's an issue.",[20,2875,2876],{},"::\n::",[11,2878,2880,2884],{"id":2879,"level":247},"windows-installer-mintty",[249,2881,2883],{"id":2882},"windows-installer-terminal-emulator","Windows Installer: Terminal Emulator",[452,2885,2886,2894],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,2887,2888],{"v-slot:left":459},[20,2889,2890],{},[491,2891],{"alt":2892,"src":2893,"variant":495},"Git for Windows installer terminal emulator screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep08_mintty.png",[457,2895,2896],{"v-slot:right":459},[24,2897,2898,2901,2904],{},[27,2899,2900],{},"Keep MinTTY selected",[27,2902,2903],{},"This is the normal Git Bash window",[27,2905,2906],{},"Course screenshots will assume this terminal style",[11,2908,2910,2914],{"id":2909,"level":247},"windows-installer-fast-forward",[249,2911,2913],{"id":2912},"windows-installer-pull-behavior","Windows Installer: Pull Behavior",[452,2915,2916,2924],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,2917,2918],{"v-slot:left":459},[20,2919,2920],{},[491,2921],{"alt":2922,"src":2923,"variant":495},"Git for Windows installer git pull behavior screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep09_ff_merge.png",[457,2925,2926],{"v-slot:right":459},[24,2927,2928,2935],{},[27,2929,2930,2931,2934],{},"Keep the default ",[146,2932,2933],{},"git pull"," behavior",[27,2936,2937],{},"Later lessons explain pull, merge, and conflicts",[11,2939,2941,2944],{"id":2940,"level":247},"windows-installer-credential-manager",[249,2942,2943],{"id":2940},"Windows Installer: Credential Manager",[452,2945,2946,2954],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,2947,2948],{"v-slot:left":459},[20,2949,2950],{},[491,2951],{"alt":2952,"src":2953,"variant":495},"Git for Windows installer credential manager screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep10_credential_manager.png",[457,2955,2956],{"v-slot:right":459},[24,2957,2958,2961,2964],{},[27,2959,2960],{},"Keep Git Credential Manager enabled",[27,2962,2963],{},"It helps with browser-based GitHub sign-in",[27,2965,2966],{},"This course still uses SSH for repo pushes",[11,2968,2970,2973],{"id":2969,"level":247},"windows-installer-extra-options",[249,2971,2972],{"id":2969},"Windows Installer: Extra Options",[452,2974,2975,2983],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,2976,2977],{"v-slot:left":459},[20,2978,2979],{},[491,2980],{"alt":2981,"src":2982,"variant":495},"Git for Windows installer extra options screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep11_extra_options_optional.png",[457,2984,2985],{"v-slot:right":459},[24,2986,2987,2995,3006,3014],{},[27,2988,2989,2990],{},"Enable file system caching\n",[24,2991,2992],{},[27,2993,2994],{},"Improves Git performance on Windows",[27,2996,2997,2998],{},"Enable symbolic links if available\n",[24,2999,3000,3003],{},[27,3001,3002],{},"Helps Git handle link-like files correctly",[27,3004,3005],{},"May require Windows Developer Mode or admin rights",[27,3007,3008,3009],{},"Skip experimental options\n",[24,3010,3011],{},[27,3012,3013],{},"They can change behavior between Git versions",[27,3015,3016],{},"Finish the installer",[11,3018,3020,3024],{"id":3019,"level":247},"step-1-open-git-bash-on-windows",[249,3021,3023],{"id":3022},"open-git-bash","Open Git Bash",[24,3025,3026,3029,3032],{},[27,3027,3028],{},"Start menu -> Git Bash",[27,3030,3031],{},"Pin it if that helps you find the same terminal later",[27,3033,3034],{},"Run the checks in the next slides from Git Bash",[11,3036,3038,3041],{"id":3037,"level":247},"windows-terminal-habit",[249,3039,3040],{"id":3037},"Windows Terminal Habit",[24,3042,3043,3046,3049],{},[27,3044,3045],{},"Use Git Bash for course commands on Windows",[27,3047,3048],{},"If another terminal opens by accident, close it and open Git Bash",[27,3050,3051],{},"Staying in one terminal makes setup problems easier to diagnose",[11,3053,3055,3058],{"id":3054,"level":14},"macos-path-terminal",[16,3056,3057],{"id":3054},"macOS Path: Terminal",[24,3059,3060,3063,3066,3069],{},[27,3061,3062],{},"Built-in Terminal is fully supported",[27,3064,3065],{},"Optional iTerm2 gives you tabs, split panes, and profiles",[27,3067,3068],{},"Beginner default: start with Terminal unless you already prefer iTerm2",[27,3070,3071],{},"See the slide below for the optional modern terminal install path",[11,3073,3075,3079],{"id":3074,"level":247},"macos-optional-iterm2-install",[249,3076,3078],{"id":3077},"optional-iterm2-install","Optional iTerm2 Install",[24,3080,3081,3088,3091,3094],{},[27,3082,3083,3084],{},"Download the stable release from ",[856,3085,3086],{"href":3086,"rel":3087},"https:\u002F\u002Fiterm2.com\u002Fdownloads.html",[860],[27,3089,3090],{},"Move iTerm2 to Applications",[27,3092,3093],{},"Open iTerm2 and run the same checks as Terminal",[27,3095,3096],{},"Use Terminal or iTerm2 consistently for course commands",[11,3098,3100,3103,3117,3120,3123],{"id":3099,"level":14},"linux-path-terminal",[16,3101,3102],{"id":3099},"Linux Path: Terminal",[24,3104,3105,3108,3111],{},[27,3106,3107],{},"Open the built-in Terminal app",[27,3109,3110],{},"Git is often installed already",[27,3112,3113,3114,3116],{},"If ",[146,3115,2581],{}," fails, use your distribution package manager",[20,3118,3119],{},"For Ubuntu:",[74,3121],{"language":96,"src":3122},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Flinux-path-terminal-01.sh",[24,3124,3125],{},[27,3126,3127],{},"See the slide below for the optional split-pane terminal setup",[11,3129,3131,3135,3138,3140,3143],{"id":3130,"level":247},"linux-optional-tilix-install",[249,3132,3134],{"id":3133},"optional-tilix-install","Optional Tilix Install",[20,3136,3137],{},"Tilix is a Linux terminal with split panes and profiles",[20,3139,3119],{},[74,3141],{"language":96,"src":3142},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Foptional-tilix-install-02.sh",[20,3144,3145],{},"Use the built-in Terminal if optional installs add friction",[11,3147,3149,3153],{"id":3148,"level":14},"step-3-confirm-git-and-shell",[16,3150,3152],{"id":3151},"confirm-git-and-shell","Confirm Git And Shell",[452,3154,3157,3171],{"gap":454,"left-width":3155,"right-width":3156},"1.15fr","0.85fr",[457,3158,3159,3161,3164,3167],{"v-slot:left":459},[20,3160,93],{},[74,3162],{"language":96,"src":3163},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fconfirm-git-and-shell-03.sh",[20,3165,3166],{},"Expected output:",[74,3168],{"language":3169,"src":3170},"plaintext","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fexample-output-04.txt",[457,3172,3173,3176],{"v-slot:right":459},[20,3174,3175],{},"This confirms:",[24,3177,3178,3181,3184],{},[27,3179,3180],{},"Git is installed",[27,3182,3183],{},"The terminal can find Git",[27,3185,3186],{},"Your shell matches later course commands",[11,3188,3190,3194],{"id":3189,"level":14},"step-4-cli-safety-check-before-every-git-command",[16,3191,3193],{"id":3192},"check-location-before-git-commands","Check Location Before Git Commands",[452,3195,3197,3209],{"gap":454,"left-width":3196,"right-width":2653},"1.1fr",[457,3198,3199,3201,3204,3206],{"v-slot:left":459},[20,3200,93],{},[74,3202],{"language":96,"src":3203},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fcheck-location-before-git-commands-05.sh",[20,3205,3166],{},[74,3207],{"language":3169,"src":3208},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fexample-output-06.txt",[457,3210,3211,3214],{"v-slot:right":459},[20,3212,3213],{},"Use this before Git commands:",[24,3215,3216,3221,3226,3229],{},[27,3217,3218,3220],{},[146,3219,1651],{}," shows the current folder",[27,3222,3223,3225],{},[146,3224,2321],{}," shows what is inside it",[27,3227,3228],{},"If the folder is wrong, fix location first",[27,3230,3231],{},"Do not run Git commands while guessing",[11,3233,3234,3236],{"id":779,"level":14},[16,3235,782],{"id":779},[452,3237,3238,3280],{"gap":454,"left-width":455,"right-width":455},[457,3239,3240],{"v-slot:left":459},[24,3241,3242,3255,3272],{},[27,3243,3244,3247],{},[146,3245,3246],{},"git: command not found",[24,3248,3249,3252],{},[27,3250,3251],{},"Git is missing, or this terminal cannot find it",[27,3253,3254],{},"Close the terminal and reopen the correct one",[27,3256,3257,3260],{},[146,3258,3259],{},"not a git repository",[24,3261,3262,3265],{},[27,3263,3264],{},"The command ran outside a cloned repository",[27,3266,304,3267,149,3269,3271],{},[146,3268,1651],{},[146,3270,2321],{},", then move to the repo folder",[27,3273,3274,3275],{},"Wrong terminal",[24,3276,3277],{},[27,3278,3279],{},"Windows users should switch back to Git Bash",[457,3281,3282,3285],{"v-slot:right":459},[27,3283,3284],{},"Too many terminals open",[1137,3286,3287,3290,3300,3305,3311],{},[27,3288,3289],{},"Close extra terminal windows",[27,3291,3292,3293],{},"Open the correct terminal\n",[24,3294,3295,3297],{},[27,3296,1608],{},[27,3298,3299],{},"Apple macOS\u002FLinux: Terminal",[27,3301,3302,3303],{},"Run ",[146,3304,2581],{},[27,3306,3302,3307,149,3309],{},[146,3308,1651],{},[146,3310,2321],{},[27,3312,3313],{},"Continue only after the folder looks right",[11,3315,3316,3318],{"id":812,"level":14},[16,3317,816],{"id":815},[452,3319,3320,3342],{"gap":454,"left-width":455,"right-width":455},[457,3321,3322,3324,3330,3336],{"v-slot:left":459},[249,3323,824],{"id":823},[20,3325,3326,3329],{},[1102,3327,3328],{},"Terminal"," - A text-based interface where you type commands to control your computer",[20,3331,3332,3335],{},[1102,3333,3334],{},"CLI (Command Line Interface)"," - The text-based interface where you type commands",[20,3337,3338,3341],{},[1102,3339,3340],{},"Git"," - A tool for tracking changes in code files over time",[457,3343,3344,3346],{"v-slot:right":459},[249,3345,849],{"id":812},[24,3347,3348,3355,3361,3367],{},[27,3349,3350],{},[856,3351,3354],{"href":3352,"rel":3353},"https:\u002F\u002Fgit-scm.com\u002Fdownloads",[860],"Git Downloads",[27,3356,3357],{},[856,3358,3360],{"href":2630,"rel":3359},[860],"Git For Windows Install Page",[27,3362,3363],{},[856,3364,3366],{"href":3086,"rel":3365},[860],"iTerm2 Downloads",[27,3368,3369],{},[856,3370,3373],{"href":3371,"rel":3372},"https:\u002F\u002Fgnunn1.github.io\u002Ftilix-web\u002F",[860],"Tilix",[11,3375,3376,3378,3381],{"id":887,"level":14},[16,3377,890],{"id":887},[20,3379,3380],{},"Before moving on, confirm you can:",[24,3382,3383,3386,3390,3397,3400],{},[27,3384,3385],{},"Open the correct terminal for your operating system",[27,3387,3302,3388],{},[146,3389,2581],{},[27,3391,304,3392,149,3394,3396],{},[146,3393,1651],{},[146,3395,2321],{}," to check your location",[27,3398,3399],{},"Understand what terminal\u002FCLI refers to",[27,3401,3402],{},"Keep track of terminal instances",{"title":459,"searchDepth":935,"depth":935,"links":3404},[3405,3406,3407,3422,3425,3428,3429,3430,3431,3432],{"id":1561,"depth":935,"text":1564},{"id":2592,"depth":935,"text":2593},{"id":2621,"depth":935,"text":2622,"children":3408},[3409,3410,3411,3412,3413,3414,3415,3416,3417,3418,3419,3420,3421],{"id":2646,"depth":947,"text":2649},{"id":2684,"depth":947,"text":2687},{"id":2715,"depth":947,"text":2718},{"id":2746,"depth":947,"text":2749},{"id":2780,"depth":947,"text":2783},{"id":2812,"depth":947,"text":2813},{"id":2842,"depth":947,"text":2843},{"id":2882,"depth":947,"text":2883},{"id":2912,"depth":947,"text":2913},{"id":2940,"depth":947,"text":2943},{"id":2969,"depth":947,"text":2972},{"id":3022,"depth":947,"text":3023},{"id":3037,"depth":947,"text":3040},{"id":3054,"depth":935,"text":3057,"children":3423},[3424],{"id":3077,"depth":947,"text":3078},{"id":3099,"depth":935,"text":3102,"children":3426},[3427],{"id":3133,"depth":947,"text":3134},{"id":3151,"depth":935,"text":3152},{"id":3192,"depth":935,"text":3193},{"id":779,"depth":935,"text":782},{"id":815,"depth":935,"text":816},{"id":887,"depth":935,"text":890},"Install Git and choose the correct terminal for course commands.","Face-to-face class of about 40 students; includes OS-specific terminal choices, Git installation, short checks, and setup friction.","35",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools",{"title":2561,"description":3433},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools",[988,2553,1490],"21:30","u1x5bq-JmCg","https:\u002F\u002Fyoutu.be\u002Fu1x5bq-JmCg","71DrP8YI_ks4jUswWJXy9rmZOVVoeaJAEPancHNHsV4",{"id":3446,"title":3447,"audience":6,"body":3448,"contentType":971,"course":972,"description":4522,"estimateBasis":4523,"estimatedDiscussionMinutes":4524,"estimatedLiveMinutes":976,"estimatedTotalMinutes":4525,"extension":893,"meta":4526,"module":979,"navigation":980,"order":1480,"path":4527,"promptAssist":983,"seo":4528,"status":985,"stem":4529,"tags":4530,"videoDuration":4534,"videoId":4535,"videoLink":4536,"videoTitle":4537,"week":979,"__hash__":4538},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh.md","Set Up GitHub SSH",{"type":8,"value":3449,"toc":4494},[3450,3476,3494,3519,3532,3559,3596,3673,3721,3788,3864,3906,3932,3964,4001,4046,4080,4149,4151,4154,4165,4237,4266,4300,4348,4394,4462],[11,3451,3453,3456],{"id":3452,"level":14},"goals",[16,3454,3455],{"id":3452},"Goals",[24,3457,3458,3461,3464,3467,3470,3473],{},[27,3459,3460],{},"Confirm Git works in the correct terminal",[27,3462,3463],{},"Sign in to GitHub with a school or personal account",[27,3465,3466],{},"Create or reuse an SSH key for GitHub",[27,3468,3469],{},"Add the public key to GitHub",[27,3471,3472],{},"Create and clone your course repository",[27,3474,3475],{},"Set Git identity inside the cloned repository",[11,3477,3479,3482,3491],{"id":3478,"level":14},"terminal-by-os",[16,3480,3481],{"id":3478},"Terminal By OS",[24,3483,3484,3486,3489],{},[27,3485,1608],{},[27,3487,3488],{},"Apple macOS: Terminal or iTerm2",[27,3490,1623],{},[20,3492,3493],{},"Run these commands on your own computer",[11,3495,3497,3500],{"id":3496,"level":14},"git-and-ssh-terms",[16,3498,3499],{"id":3496},"Git And SSH Terms",[24,3501,3502,3505,3513,3516],{},[27,3503,3504],{},"Git identity: name and email attached to commits in a repository",[27,3506,3507,3508],{},"SSH key pair: private key stays on your computer, public key goes to GitHub\n",[24,3509,3510],{},[27,3511,3512],{},"This is how we'll authenticate to GitHub",[27,3514,3515],{},"SSH agent: helper that keeps your private key available to Git commands",[27,3517,3518],{},"Clone: local folder connected to a GitHub repository",[11,3520,3522,3525,3529],{"id":3521,"level":14},"ssh-key-flow",[16,3523,3524],{"id":3521},"SSH Key Flow",[3526,3527],"mermaid",{"code":3528},"sequenceDiagram\n  participant Terminal\n  participant PrivateKey as Private key on your computer\n  participant GitHub as Public key in GitHub\n  Terminal->>PrivateKey: Load key with ssh-add\n  Terminal->>GitHub: Ask to authenticate\n  GitHub-->>Terminal: Confirm matching public key\n",[20,3530,3531],{},"GitHub receives only the public key. The private key stays on your computer",[11,3533,3535,3538],{"id":3534,"level":14},"step-1-check-git",[16,3536,3537],{"id":3534},"Step 1: Check Git",[452,3539,3540,3548],{"gap":454,"left-width":455,"right-width":455},[457,3541,3542,3544],{"v-slot:left":459},[20,3543,93],{},[74,3545],{"label":3546,"language":96,"src":3547},"check-git.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-1-check-git-01.sh",[457,3549,3550,3552,3556],{"v-slot:right":459},[20,3551,3166],{},[74,3553],{"label":3554,"language":3169,"src":3555},"example-output.txt","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-02.txt",[20,3557,3558],{},"A valid version means Git is installed and available in this terminal",[11,3560,3562,3566],{"id":3561,"level":14},"step-2-github-account",[16,3563,3565],{"id":3564},"step-2-sign-in-to-github","Step 2: Sign In To GitHub",[452,3567,3569,3588],{"gap":454,"left-width":455,"right-width":3568},"0.8fr",[457,3570,3571],{"v-slot:left":459},[24,3572,3573,3576,3579,3582,3585],{},[27,3574,3575],{},"Use an existing GitHub account or create one",[27,3577,3578],{},"School email recommended for course identity",[27,3580,3581],{},"Personal email is fine if you prefer it",[27,3583,3584],{},"Avoid work email so course access does not depend on an employer account",[27,3586,3587],{},"Confirm you can open GitHub Settings before continuing",[457,3589,3590],{"v-slot:right":459},[20,3591,3592],{},[491,3593],{"alt":3594,"src":3595,"variant":495},"GitHub account menu open with Settings visible","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fgithub-logged-in.png",[11,3597,3599,3603],{"id":3598,"level":14},"step-2-create-repo",[16,3600,3602],{"id":3601},"step-3-create-course-repository","Step 3: Create Course Repository",[452,3604,3606,3665],{"gap":454,"left-width":3605,"right-width":3155},"0.95fr",[457,3607,3608,3611],{"v-slot:left":459},[20,3609,3610],{},"In GitHub:",[24,3612,3613,3618,3624,3630,3645,3651,3654,3662],{},[27,3614,1144,3615],{},[146,3616,3617],{},"+",[27,3619,3620,3621],{},"Choose ",[146,3622,3623],{},"New repository",[27,3625,3626,3627],{},"Name it ",[146,3628,3629],{},"\u003Cucid>-IT202-\u003Csection>-\u003CsemYear>",[27,3631,3632,3633,3636,3637,3640,3641,3644],{},"Semester code examples: ",[146,3634,3635],{},"S2026"," spring, ",[146,3638,3639],{},"M2026"," summer, ",[146,3642,3643],{},"F2026"," fall",[27,3646,3647,3648],{},"Set visibility to ",[146,3649,3650],{},"Private",[27,3652,3653],{},"Toggle \"Add README\"",[27,3655,3656,3657],{},"Do not toggle \"Add .gitignore\"",[24,3658,3659],{},[27,3660,3661],{},"A future lesson will discuss and add this important file",[27,3663,3664],{},"Do not add starter files unless instructed",[457,3666,3667],{"v-slot:right":459},[20,3668,3669],{},[491,3670],{"alt":3671,"src":3672,"variant":495},"GitHub new repository form with course naming pattern, private visibility, and README enabled","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fnew-repo.png",[11,3674,3676,3680,3707],{"id":3675,"level":14},"step-3-check-existing-key",[16,3677,3679],{"id":3678},"step-4-check-for-existing-ssh-key","Step 4: Check For Existing SSH Key",[452,3681,3682,3690],{"gap":454,"left-width":455,"right-width":455},[457,3683,3684,3686],{"v-slot:left":459},[20,3685,93],{},[74,3687],{"label":3688,"language":96,"src":3689},"check-ssh-folder.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-3-check-for-existing-ssh-key-03.sh",[457,3691,3692,3695,3698],{"v-slot:right":459},[20,3693,3694],{},"Example output:",[74,3696],{"label":3554,"language":3169,"src":3697},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-04.txt",[20,3699,3700,3701,149,3704],{},"Look for a matching GitHub-specific pair such as ",[146,3702,3703],{},"github_key",[146,3705,3706],{},"github_key.pub",[20,3708,3709,3710,3713,3714,803,3717,3720],{},"You can reuse an existing matching pair only if it is ",[1102,3711,3712],{},"NOT"," a default key such as ",[146,3715,3716],{},"id_ed25519",[146,3718,3719],{},"id_rsa",". Otherwise, create a GitHub-specific key in the next step",[11,3722,3724,3728,3730,3734,3736,3739],{"id":3723,"level":14},"step-4-create-key-if-needed",[16,3725,3727],{"id":3726},"step-5-create-ssh-key-if-needed","Step 5: Create SSH Key If Needed",[20,3729,93],{},[74,3731],{"label":3732,"language":96,"src":3733},"create-github-key.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-4-create-ssh-key-if-needed-05.sh",[20,3735,3694],{},[74,3737],{"label":3554,"language":3169,"src":3738},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-06.txt",[24,3740,3741,3767,3772,3777],{},[27,3742,3743,3744],{},"Command flags:\n",[24,3745,3746,3752,3758],{},[27,3747,3748,3751],{},[146,3749,3750],{},"-t"," chooses the key type",[27,3753,3754,3757],{},[146,3755,3756],{},"-C"," adds a comment label, usually your GitHub email",[27,3759,3760,3762,3763,3766],{},[146,3761,2120],{}," chooses the output file path (must include ",[146,3764,3765],{},"~\u002F.ssh\u002F"," followed by the file name)",[27,3768,3769,3771],{},[146,3770,3703],{}," is the private key file",[27,3773,3774,3776],{},[146,3775,3706],{}," is the public key file for GitHub",[27,3778,3779,3780],{},"Passphrase is optional unless your instructor requires one\n",[24,3781,3782,3785],{},[27,3783,3784],{},"Pro: protects the key if someone gets the file",[27,3786,3787],{},"Con: adds an unlock prompt when the key is used",[11,3789,3791,3795,3812,3844],{"id":3790,"level":14},"step-5-start-agent-and-add-key",[16,3792,3794],{"id":3793},"step-6-start-ssh-agent-and-verify-key","Step 6: Start SSH Agent And Verify Key",[452,3796,3797,3805],{"gap":454,"left-width":3196,"right-width":455},[457,3798,3799,3801],{"v-slot:left":459},[20,3800,93],{},[74,3802],{"label":3803,"language":96,"src":3804},"start-agent-add-key.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-5-start-ssh-agent-and-add-key-07.sh",[457,3806,3807,3809],{"v-slot:right":459},[20,3808,3694],{},[74,3810],{"label":3554,"language":3169,"src":3811},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-08.txt",[24,3813,3814,3820,3841],{},[27,3815,3816,3819],{},[146,3817,3818],{},"eval \"$(ssh-agent -s)\""," starts the SSH helper GitHub docs usually show",[27,3821,3822,3823,3826,3827,3830],{},"If that fails, run ",[146,3824,3825],{},"exec ssh-agent bash",", then run ",[146,3828,3829],{},"ssh-add ~\u002F.ssh\u002Fgithub_key",[24,3831,3832],{},[27,3833,304,3834,3837,3838,3840],{},[146,3835,3836],{},"~\u002F.ssh\u002Fgithub_key"," because ",[146,3839,1748],{}," avoids issues with spaces in home directory paths",[27,3842,3843],{},"Then verify the key is loaded",[452,3845,3846,3854],{"gap":454,"left-width":455,"right-width":455},[457,3847,3848,3850],{"v-slot:left":459},[20,3849,93],{},[74,3851],{"label":3852,"language":96,"src":3853},"verify-loaded-key.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fverify-loaded-key-09.sh",[457,3855,3856,3858,3861],{"v-slot:right":459},[20,3857,3166],{},[74,3859],{"label":3554,"language":3169,"src":3860},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-10.txt",[20,3862,3863],{},"One loaded key is enough for this lesson",[11,3865,3867,3871,3888],{"id":3866,"level":14},"step-6-copy-public-key",[16,3868,3870],{"id":3869},"step-7-copy-public-key","Step 7: Copy Public Key",[452,3872,3873,3881],{"gap":454,"left-width":455,"right-width":455},[457,3874,3875,3877],{"v-slot:left":459},[20,3876,93],{},[74,3878],{"label":3879,"language":96,"src":3880},"show-public-key.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-6-copy-public-key-11.sh",[457,3882,3883,3885],{"v-slot:right":459},[20,3884,3694],{},[74,3886],{"label":3554,"language":3169,"src":3887},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-12.txt",[24,3889,3890,3900],{},[27,3891,3892,3893,3896,3897,3899],{},"Copy the full line starting with ",[146,3894,3895],{},"ssh-ed25519"," and ending with the value you set with ",[146,3898,3756],{}," earlier",[27,3901,3902,3903,3905],{},"Do not copy ",[146,3904,3703],{},", which is the private key (never share the private key)",[11,3907,3909,3913],{"id":3908,"level":14},"step-7-add-key-to-github",[16,3910,3912],{"id":3911},"step-8-add-key-to-github","Step 8: Add Key To GitHub",[24,3914,3915,3918,3923,3926,3929],{},[27,3916,3917],{},"In GitHub, open account settings",[27,3919,2627,3920],{},[146,3921,3922],{},"SSH and GPG keys",[27,3924,3925],{},"Add a new authentication key",[27,3927,3928],{},"Paste the public key from the previous step",[27,3930,3931],{},"See the slides below for the GitHub screens",[11,3933,3935,3939],{"id":3934,"level":247},"step-8-open-github-settings",[249,3936,3938],{"id":3937},"open-github-settings","Open GitHub Settings",[452,3940,3941,3949],{"gap":454,"left-width":3196,"right-width":2653,"stack":2654},[457,3942,3943],{"v-slot:left":459},[20,3944,3945],{},[491,3946],{"alt":3947,"src":3948,"variant":495},"GitHub profile menu with Settings highlighted","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fssh-key-01-gh-menu.png",[457,3950,3951],{"v-slot:right":459},[24,3952,3953,3956,3961],{},[27,3954,3955],{},"Click your GitHub profile photo",[27,3957,3620,3958],{},[146,3959,3960],{},"Settings",[27,3962,3963],{},"Use the account menu, not the repository settings",[11,3965,3967,3971],{"id":3966,"level":247},"step-8-open-ssh-keys-page",[249,3968,3970],{"id":3969},"open-ssh-and-gpg-keys","Open SSH And GPG Keys",[452,3972,3973,3981],{"gap":454,"left-width":3196,"right-width":2653,"stack":2654},[457,3974,3975],{"v-slot:left":459},[20,3976,3977],{},[491,3978],{"alt":3979,"src":3980,"variant":495},"GitHub settings sidebar with SSH and GPG keys selected","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fssh-key-02-gh-ssh-link.png",[457,3982,3983],{"v-slot:right":459},[24,3984,3985,3992,3996],{},[27,3986,3987,3988,3991],{},"Find the ",[146,3989,3990],{},"Access"," section",[27,3993,700,3994],{},[146,3995,3922],{},[27,3997,3620,3998],{},[146,3999,4000],{},"New SSH key",[11,4002,4004,4008],{"id":4003,"level":247},"step-8-add-new-ssh-key",[249,4005,4007],{"id":4006},"add-new-ssh-key","Add New SSH Key",[452,4009,4011,4019],{"gap":454,"left-width":4010,"right-width":3156,"stack":2654},"1.35fr",[457,4012,4013],{"v-slot:left":459},[20,4014,4015],{},[491,4016],{"alt":4017,"src":4018,"variant":495},"GitHub Add new SSH Key form with title, authentication key type, and public key field","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fssh-key-03-add-new-key.png",[457,4020,4021],{"v-slot:right":459},[24,4022,4023,4029,4035,4038,4043],{},[27,4024,4025,4026],{},"Title it clearly, such as ",[146,4027,4028],{},"\u003Ccourse> Laptop",[27,4030,4031,4032],{},"Keep key type as ",[146,4033,4034],{},"Authentication Key",[27,4036,4037],{},"Paste the full public key line",[27,4039,1144,4040],{},[146,4041,4042],{},"Add SSH key",[27,4044,4045],{},"Never paste the private key",[11,4047,4049,4053],{"id":4048,"level":14},"step-8-test-auth",[16,4050,4052],{"id":4051},"step-9-test-github-ssh-access","Step 9: Test GitHub SSH Access",[452,4054,4055,4070],{"gap":454,"left-width":455,"right-width":3196},[457,4056,4057,4059,4063],{"v-slot:left":459},[20,4058,93],{},[74,4060],{"label":4061,"language":96,"src":4062},"test-github-ssh.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-8-test-github-ssh-access-13.sh",[20,4064,4065,4066,4069],{},"If prompted the first time, type ",[146,4067,4068],{},"yes"," to trust GitHub's host key",[457,4071,4072,4074,4077],{"v-slot:right":459},[20,4073,3166],{},[74,4075],{"label":3554,"language":3169,"src":4076},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-14.txt",[20,4078,4079],{},"This confirms authentication, then GitHub closes the connection",[11,4081,4083,4087],{"id":4082,"level":14},"step-9-clone-repo",[16,4084,4086],{"id":4085},"step-10-clone-course-repository","Step 10: Clone Course Repository",[452,4088,4089,4130],{"gap":454,"left-width":2653,"right-width":3196},[457,4090,4091,4095,4124],{"v-slot:left":459},[249,4092,4094],{"id":4093},"get-the-ssh-clone-url","Get The SSH Clone URL",[24,4096,4097,4103,4110,4117],{},[27,4098,4099,4100],{},"In your GitHub repository, click ",[146,4101,4102],{},"Code",[27,4104,4105,4106,4109],{},"Choose the ",[146,4107,4108],{},"SSH"," tab",[27,4111,4112,4113,4116],{},"Copy the ",[146,4114,4115],{},"git@github.com:..."," link",[27,4118,4119,4120,4123],{},"Use that link in the ",[146,4121,4122],{},"git clone"," command",[20,4125,4126],{},[491,4127],{"alt":4128,"src":4129,"variant":495},"GitHub repository Code menu with SSH clone URL selected","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fgithub-clone-url.png",[457,4131,4132,4135,4139],{"v-slot:right":459},[20,4133,4134],{},"Run from the folder that should contain your course repo:",[74,4136],{"label":4137,"language":96,"src":4138},"clone-course-repository.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-9-clone-course-repository-15.sh",[2868,4140,4142],{"type":4141},"tip",[20,4143,4144,4145,4148],{},"Before cloning, run ",[146,4146,4147],{},"git rev-parse --show-toplevel",". If it prints a path, move somewhere else first. Clone this repo only once.",[20,4150,3694],{},[74,4152],{"label":3554,"language":3169,"src":4153},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-16.txt",[20,4155,4156,4157,4160,4161,4164],{},"If you see an empty repository warning, you probably forgot to add ",[146,4158,4159],{},"README.md"," when creating the repo. Create it with ",[146,4162,4163],{},"touch README.md",", then use the add\u002Fcommit\u002Fpush commands from the next lesson\n::\n::",[11,4166,4168,4172,4191,4210,4230],{"id":4167,"level":14},"step-10-set-repo-identity",[16,4169,4171],{"id":4170},"step-11-set-repo-git-identity","Step 11: Set Repo Git Identity",[452,4173,4174,4183],{"gap":454,"left-width":455,"right-width":455},[457,4175,4176,4179],{"v-slot:left":459},[20,4177,4178],{},"Run inside the cloned repository:",[74,4180],{"label":4181,"language":96,"src":4182},"set-repo-identity.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-10-set-repo-git-identity-17.sh",[457,4184,4185,4187],{"v-slot:right":459},[20,4186,3166],{},[74,4188],{"label":4189,"language":3169,"src":4190},"config-output.txt","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-19.txt",[452,4192,4193,4202],{"gap":454,"left-width":455,"right-width":455},[457,4194,4195,4198],{"v-slot:left":459},[20,4196,4197],{},"Then verify:",[74,4199],{"label":4200,"language":96,"src":4201},"verify-repo-identity.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-10-set-repo-git-identity-18.sh",[457,4203,4204,4206],{"v-slot:right":459},[20,4205,3166],{},[74,4207],{"label":4208,"language":3169,"src":4209},"identity-output.txt","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-20.txt",[24,4211,4212,4218,4224],{},[27,4213,4214,4217],{},[146,4215,4216],{},"user.name"," can be your real or display name, though commonly it's your GitHub username",[27,4219,4220,4223],{},[146,4221,4222],{},"user.email"," should match a GitHub email or GitHub no-reply address for commit linking to work (this is important)",[27,4225,4226,4229],{},[146,4227,4228],{},"core.sshCommand"," tells this repository to use your course GitHub key",[20,4231,4232,4233,4236],{},"These commands set identity for this repository. The ",[146,4234,4235],{},"--global"," flag is an option only if you intentionally want the same identity for all repositories",[11,4238,4240,4244,4247,4263],{"id":4239,"level":14},"step-11-invite-collaborators",[16,4241,4243],{"id":4242},"step-12-invite-course-collaborators","Step 12: Invite Course Collaborators",[20,4245,4246],{},"In GitHub, open your course repository:",[24,4248,4249,4252,4257,4260],{},[27,4250,4251],{},"Settings -> Collaborators and teams",[27,4253,4254,4255],{},"Invite ",[146,4256,1351],{},[27,4258,4259],{},"Invite your TA if your section has one",[27,4261,4262],{},"Wait until the invitation shows as sent or accepted",[20,4264,4265],{},"This is so it can be accessed for grading and assistance",[11,4267,4269,4272],{"id":4268,"level":14},"troubleshooting-auth",[16,4270,4271],{"id":4268},"Troubleshooting Auth",[24,4273,4274,4280,4287,4294,4297],{},[27,4275,4276,4279],{},[146,4277,4278],{},"Permission denied (publickey)",": GitHub did not accept a loaded key",[27,4281,4282,4283,4286],{},"No loaded key in ",[146,4284,4285],{},"ssh-add -l",": start the agent and add the key again",[27,4288,4289,4290,4293],{},"Wrong key in GitHub: delete it and paste the ",[146,4291,4292],{},".pub"," key again",[27,4295,4296],{},"Wrong account: make sure the success message names your GitHub account",[27,4298,4299],{},"See the slide below for a quick reset sequence",[11,4301,4303,4307,4309,4336],{"id":4302,"level":247},"troubleshooting-auth-recovery",[249,4304,4306],{"id":4305},"quick-reset-sequence","Quick Reset Sequence",[20,4308,93],{},[1137,4310,4311,4315,4319,4323,4328,4331],{},[27,4312,4313],{},[146,4314,3818],{},[27,4316,4317],{},[146,4318,3829],{},[27,4320,4321],{},[146,4322,4285],{},[27,4324,4325],{},[146,4326,4327],{},"cat ~\u002F.ssh\u002Fgithub_key.pub",[27,4329,4330],{},"Re-paste the public key in GitHub if needed",[27,4332,4333],{},[146,4334,4335],{},"ssh -T git@github.com",[20,4337,3113,4338,4340,4341,4343,4344,4347],{},[146,4339,3818],{}," fails in Git Bash, use ",[146,4342,3825],{},", then repeat the ",[146,4345,4346],{},"ssh-add"," steps",[11,4349,4350,4352,4355],{"id":1409,"level":14},[16,4351,1412],{"id":1409},[20,4353,4354],{},"You are done when all are true:",[24,4356,4357,4362,4369,4374,4377,4382,4385],{},[27,4358,4359,4361],{},[146,4360,2581],{}," works",[27,4363,4364,4366,4367],{},[146,4365,4285],{}," shows ",[146,4368,3703],{},[27,4370,4371,4373],{},[146,4372,4335],{}," names your GitHub account",[27,4375,4376],{},"Your private course repository exists on GitHub",[27,4378,4379,4381],{},[146,4380,1351],{}," and your TA, if applicable, are invited as collaborators",[27,4383,4384],{},"Your local terminal is open to the cloned repository",[27,4386,4387,149,4390,4393],{},[146,4388,4389],{},"git config user.name",[146,4391,4392],{},"git config user.email"," return your repo identity",[11,4395,4396,4398],{"id":812,"level":14},[16,4397,816],{"id":815},[452,4399,4400,4428],{"gap":454,"left-width":455,"right-width":455},[457,4401,4402,4404,4410,4416,4422],{"v-slot:left":459},[249,4403,824],{"id":823},[20,4405,4406,4409],{},[1102,4407,4408],{},"Git identity"," - commit name and email saved in repo config",[20,4411,4412,4415],{},[1102,4413,4414],{},"SSH key pair"," - private key on your computer, public key in GitHub",[20,4417,4418,4421],{},[1102,4419,4420],{},"SSH agent"," - background helper that makes your private key available",[20,4423,4424,4427],{},[1102,4425,4426],{},"Clone"," - local copy of a GitHub repository",[457,4429,4430,4432],{"v-slot:right":459},[249,4431,849],{"id":812},[24,4433,4434,4441,4448,4455],{},[27,4435,4436],{},[856,4437,4440],{"href":4438,"rel":4439},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fauthentication\u002Fconnecting-to-github-with-ssh\u002Fgenerating-a-new-ssh-key-and-adding-it-to-the-ssh-agent",[860],"GitHub Docs: Generate a new SSH key and add it to the ssh-agent",[27,4442,4443],{},[856,4444,4447],{"href":4445,"rel":4446},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fauthentication\u002Fconnecting-to-github-with-ssh\u002Ftesting-your-ssh-connection",[860],"GitHub Docs: Testing your SSH connection",[27,4449,4450],{},[856,4451,4454],{"href":4452,"rel":4453},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Frepositories\u002Fcreating-and-managing-repositories\u002Fcreating-a-new-repository",[860],"GitHub Docs: Create a repository",[27,4456,4457],{},[856,4458,4461],{"href":4459,"rel":4460},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Frepositories\u002Fcreating-and-managing-repositories\u002Fcloning-a-repository",[860],"GitHub Docs: Cloning a repository",[11,4463,4464,4466,4468],{"id":887,"level":14},[16,4465,890],{"id":887},[20,4467,900],{},[24,4469,4470,4473,4476,4479,4482,4485,4491],{},[27,4471,4472],{},"Use the correct terminal for your operating system",[27,4474,4475],{},"Authenticate to GitHub with SSH",[27,4477,4478],{},"Find your private course repository on GitHub",[27,4480,4481],{},"Invite course collaborators",[27,4483,4484],{},"Open the local clone in the terminal",[27,4486,4487,4488],{},"Show repo-local Git identity with ",[146,4489,4490],{},"git config",[27,4492,4493],{},"Next: practice the Git commands used for course work",{"title":459,"searchDepth":935,"depth":935,"links":4495},[4496,4497,4498,4499,4500,4501,4502,4503,4504,4505,4506,4507,4512,4513,4514,4515,4516,4519,4520,4521],{"id":3452,"depth":935,"text":3455},{"id":3478,"depth":935,"text":3481},{"id":3496,"depth":935,"text":3499},{"id":3521,"depth":935,"text":3524},{"id":3534,"depth":935,"text":3537},{"id":3564,"depth":935,"text":3565},{"id":3601,"depth":935,"text":3602},{"id":3678,"depth":935,"text":3679},{"id":3726,"depth":935,"text":3727},{"id":3793,"depth":935,"text":3794},{"id":3869,"depth":935,"text":3870},{"id":3911,"depth":935,"text":3912,"children":4508},[4509,4510,4511],{"id":3937,"depth":947,"text":3938},{"id":3969,"depth":947,"text":3970},{"id":4006,"depth":947,"text":4007},{"id":4051,"depth":935,"text":4052},{"id":4085,"depth":935,"text":4086},{"id":4170,"depth":935,"text":4171},{"id":4242,"depth":935,"text":4243},{"id":4268,"depth":935,"text":4271,"children":4517},[4518],{"id":4305,"depth":947,"text":4306},{"id":1409,"depth":935,"text":1412},{"id":815,"depth":935,"text":816},{"id":887,"depth":935,"text":890},"Connect your computer to GitHub with SSH, create the course repository, clone it, and set repo-local Git identity.","Face-to-face class of about 40 students; includes GitHub account check, SSH key generation, GitHub UI steps, repo creation, clone troubleshooting, repo-local Git identity, and authentication checks.","15","85",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh",{"title":3447,"description":4522},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh",[988,4531,4532,4533],"github","ssh","repository","48:26","HZG3_HfczOk","https:\u002F\u002Fyoutu.be\u002FHZG3_HfczOk","Setup Git SSH and GitHub","rJ2RP6nrPEoOj98kzeevFpO0YOXaJl-M5ajP_tsjwvA",{"id":4,"title":5,"audience":6,"body":4540,"contentType":971,"course":972,"description":973,"estimateBasis":974,"estimatedDiscussionMinutes":975,"estimatedLiveMinutes":976,"estimatedTotalMinutes":977,"extension":893,"meta":5191,"module":979,"navigation":980,"order":981,"path":982,"promptAssist":983,"seo":5192,"status":985,"stem":986,"tags":5193,"videoDuration":991,"videoId":992,"videoLink":993,"videoTitle":994,"week":979,"__hash__":995},{"type":8,"value":4541,"toc":5156},[4542,4562,4576,4586,4608,4632,4668,4678,4692,4712,4734,4764,4786,4810,4826,4858,4876,4896,4908,4916,4940,4964,4990,5014,5032,5052,5074,5124,5154],[11,4543,4544,4546,4548],{"id":13,"level":14},[16,4545,18],{"id":13},[20,4547,22],{},[24,4549,4550,4552,4554,4556,4558,4560],{},[27,4551,29],{},[27,4553,32],{},[27,4555,35],{},[27,4557,38],{},[27,4559,41],{},[27,4561,44],{},[11,4563,4564,4566,4568,4570],{"id":47,"level":14},[16,4565,51],{"id":50},[20,4567,54],{},[20,4569,57],{},[24,4571,4572,4574],{},[27,4573,62],{},[27,4575,65],{},[11,4577,4578,4580,4582,4584],{"id":68,"level":14},[16,4579,72],{"id":71},[74,4581],{"language":76,"src":77},[20,4583,80],{},[74,4585],{"language":76,"src":83},[11,4587,4588,4590,4592,4594,4596,4598],{"id":86,"level":14},[16,4589,90],{"id":89},[20,4591,93],{},[74,4593],{"language":96,"src":97},[20,4595,100],{},[20,4597,103],{},[24,4599,4600,4602,4604,4606],{},[27,4601,108],{},[27,4603,111],{},[27,4605,114],{},[27,4607,117],{},[11,4609,4610,4612,4614,4616],{"id":120,"level":14},[16,4611,124],{"id":123},[20,4613,93],{},[74,4615],{"language":96,"src":129},[24,4617,4618,4620,4622],{},[27,4619,134],{},[27,4621,137],{},[27,4623,140,4624],{},[24,4625,4626],{},[27,4627,4628,149,4630,153],{},[146,4629,148],{},[146,4631,152],{},[11,4633,4634,4636,4640,4642],{"id":156,"level":14},[16,4635,160],{"id":159},[20,4637,163,4638,167],{},[146,4639,166],{},[74,4641],{"language":96,"src":170},[24,4643,4644,4652],{},[27,4645,175,4646,178,4648],{},[146,4647,166],{},[24,4649,4650],{},[27,4651,183],{},[27,4653,186,4654],{},[24,4655,4656,4660,4664],{},[27,4657,4658,194],{},[146,4659,193],{},[27,4661,4662,200],{},[146,4663,199],{},[27,4665,4666,206],{},[146,4667,205],{},[11,4669,4670,4672,4674,4676],{"id":209,"level":14},[16,4671,213],{"id":212},[20,4673,216],{},[74,4675],{"language":96,"src":219},[20,4677,222],{},[11,4679,4680,4682,4684,4686,4688],{"id":225,"level":14},[16,4681,229],{"id":228},[20,4683,232],{},[74,4685],{"language":96,"src":235},[20,4687,238],{},[24,4689,4690],{},[27,4691,243],{},[11,4693,4694,4696,4698,4700],{"id":246,"level":247},[249,4695,252],{"id":251},[20,4697,255],{},[74,4699],{"language":96,"src":258},[24,4701,4702,4704,4706],{},[27,4703,263],{},[27,4705,266],{},[27,4707,4708,272,4710,276],{},[146,4709,271],{},[146,4711,275],{},[11,4713,4714,4716,4718,4720],{"id":279,"level":14},[16,4715,283],{"id":282},[20,4717,286],{},[74,4719],{"language":96,"src":289},[24,4721,4722,4726,4728,4732],{},[27,4723,294,4724,298],{},[146,4725,297],{},[27,4727,301],{},[27,4729,304,4730,307],{},[146,4731,275],{},[27,4733,310],{},[11,4735,4736,4738,4740,4742,4744,4746],{"id":313,"level":247},[249,4737,317],{"id":316},[20,4739,320],{},[74,4741],{"language":96,"src":323},[20,4743,326],{},[74,4745],{"language":96,"src":329},[24,4747,4748,4756],{},[27,4749,4750,337,4752],{},[146,4751,336],{},[24,4753,4754],{},[27,4755,342],{},[27,4757,4758,348,4760],{},[146,4759,347],{},[24,4761,4762],{},[27,4763,353],{},[11,4765,4766,4768,4770,4772,4774],{"id":356,"level":14},[16,4767,360],{"id":359},[20,4769,363],{},[74,4771],{"language":96,"src":366},[20,4773,369],{},[24,4775,4776,4784],{},[27,4777,4778,377,4780],{},[146,4779,376],{},[24,4781,4782],{},[27,4783,382],{},[27,4785,310],{},[11,4787,4788,4790,4792,4794,4808],{"id":387,"level":247},[249,4789,391],{"id":390},[20,4791,93],{},[74,4793],{"language":96,"src":396},[24,4795,4796,4800,4804],{},[27,4797,4798,404],{},[146,4799,403],{},[27,4801,4802,410],{},[146,4803,409],{},[27,4805,4806,416],{},[146,4807,415],{},[20,4809,419],{},[11,4811,4812,4814,4816,4818],{"id":422,"level":14},[16,4813,426],{"id":425},[20,4815,429],{},[74,4817],{"language":96,"src":432},[24,4819,4820,4824],{},[27,4821,4822,440],{},[146,4823,439],{},[27,4825,443],{},[11,4827,4828,4830],{"id":446,"level":14},[16,4829,450],{"id":449},[452,4831,4832,4852],{"gap":454,"left-width":455,"right-width":455},[457,4833,4834,4836,4838,4840,4842,4844],{"v-slot:left":459},[20,4835,462],{},[20,4837,465],{},[74,4839],{"language":76,"src":468},[20,4841,471],{},[74,4843],{"language":76,"src":474},[24,4845,4846,4848,4850],{},[27,4847,479],{},[27,4849,482],{},[27,4851,485],{},[457,4853,4854],{"v-slot:right":459},[20,4855,4856],{},[491,4857],{"alt":493,"src":494,"variant":495},[11,4859,4860,4862,4864,4870,4872,4874],{"id":498,"level":14},[16,4861,502],{"id":501},[20,4863,505],{},[24,4865,4866],{},[27,4867,510,4868,513],{},[146,4869,166],{},[20,4871,516],{},[74,4873],{"language":96,"src":519},[20,4875,522],{},[11,4877,4878,4880,4882,4894],{"id":525,"level":14},[16,4879,529],{"id":528},[20,4881,532],{},[24,4883,4884,4886,4888,4890,4892],{},[27,4885,537],{},[27,4887,540],{},[27,4889,543],{},[27,4891,546],{},[27,4893,549],{},[20,4895,552],{},[11,4897,4898,4900,4902],{"id":555,"level":14},[16,4899,559],{"id":558},[20,4901,562],{},[24,4903,4904,4906],{},[27,4905,567],{},[27,4907,570],{},[11,4909,4910,4912,4914],{"id":573,"level":14},[16,4911,576],{"id":573},[20,4913,579],{},[74,4915],{"language":96,"src":582},[11,4917,4918,4920,4924,4928,4932,4934,4936],{"id":585,"level":14},[16,4919,589],{"id":588},[20,4921,592,4922],{},[146,4923,595],{},[20,4925,598,4926,602],{},[146,4927,601],{},[24,4929,4930],{},[27,4931,607],{},[20,4933,610],{},[74,4935],{"language":96,"src":613},[24,4937,4938],{},[27,4939,618],{},[11,4941,4942,4944,4946],{"id":621,"level":247},[249,4943,625],{"id":624},[20,4945,628],{},[452,4947,4948,4958],{"gap":454,"left-width":455,"right-width":455},[457,4949,4950,4952],{"v-slot:left":459},[74,4951],{"language":96,"src":635},[24,4953,4954,4956],{},[27,4955,640],{},[27,4957,643],{},[457,4959,4960],{"v-slot:right":459},[20,4961,4962],{},[491,4963],{"alt":650,"src":651,"variant":495},[11,4965,4966,4968],{"id":654,"level":247},[249,4967,658],{"id":657},[452,4969,4970,4984],{"gap":454,"left-width":455,"right-width":455},[457,4971,4972,4974,4976,4978,4982],{"v-slot:left":459},[20,4973,665],{},[74,4975],{"language":96,"src":668},[20,4977,671],{},[24,4979,4980],{},[27,4981,676],{},[74,4983],{"language":96,"src":679},[457,4985,4986],{"v-slot:right":459},[20,4987,4988],{},[491,4989],{"alt":686,"src":687,"variant":495},[11,4991,4992,4994,4996,5000,5002,5004,5006],{"id":690,"level":14},[16,4993,694],{"id":693},[20,4995,697],{},[20,4997,700,4998],{},[146,4999,601],{},[20,5001,705],{},[74,5003],{"language":76,"src":708},[20,5005,711],{},[24,5007,5008,5010,5012],{},[27,5009,716],{},[27,5011,719],{},[27,5013,722],{},[11,5015,5016,5018,5022,5024,5026,5028],{"id":725,"level":247},[249,5017,729],{"id":728},[20,5019,732,5020,735],{},[146,5021,601],{},[20,5023,738],{},[20,5025,741],{},[74,5027],{"language":96,"src":744},[24,5029,5030],{},[27,5031,310],{},[11,5033,5034,5036,5038],{"id":751,"level":247},[249,5035,755],{"id":754},[20,5037,758],{},[24,5039,5040,5044,5046,5050],{},[27,5041,5042,765],{},[146,5043,275],{},[27,5045,768],{},[27,5047,5048,773],{},[146,5049,601],{},[27,5051,776],{},[11,5053,5054,5056],{"id":779,"level":14},[16,5055,782],{"id":779},[24,5057,5058,5060,5062,5064,5066,5072],{},[27,5059,787],{},[27,5061,790],{},[27,5063,793],{},[27,5065,796],{},[27,5067,799,5068,803,5070],{},[146,5069,802],{},[146,5071,806],{},[27,5073,809],{},[11,5075,5076,5078],{"id":812,"level":14},[16,5077,816],{"id":815},[452,5079,5080,5098],{"gap":454,"left-width":455,"right-width":455},[457,5081,5082,5084],{"v-slot:left":459},[249,5083,824],{"id":823},[24,5085,5086,5088,5090,5092,5094,5096],{},[27,5087,829],{},[27,5089,832],{},[27,5091,835],{},[27,5093,838],{},[27,5095,841],{},[27,5097,844],{},[457,5099,5100,5102],{"v-slot:right":459},[249,5101,849],{"id":812},[24,5103,5104,5109,5114,5119],{},[27,5105,854,5106],{},[856,5107,861],{"href":858,"rel":5108},[860],[27,5110,854,5111],{},[856,5112,868],{"href":866,"rel":5113},[860],[27,5115,871,5116],{},[856,5117,876],{"href":874,"rel":5118},[860],[27,5120,879,5121],{},[856,5122,884],{"href":882,"rel":5123},[860],[11,5125,5126,5128],{"id":887,"level":14},[16,5127,890],{"id":887},[452,5129,5130,5148],{"gap":893,"left-width":894,"right-width":895},[457,5131,5132,5134],{"v-slot:left":459},[20,5133,900],{},[24,5135,5136,5140,5142,5144,5146],{},[27,5137,905,5138,908],{},[146,5139,275],{},[27,5141,911],{},[27,5143,914],{},[27,5145,917],{},[27,5147,920],{},[457,5149,5150,5152],{"v-slot:right":459},[20,5151,925],{},[927,5153],{"alt":929,"src":930},[20,5155,933],{},{"title":459,"searchDepth":935,"depth":935,"links":5157},[5158,5159,5160,5161,5162,5163,5164,5165,5168,5171,5174,5175,5176,5177,5178,5179,5180,5184,5188,5189,5190],{"id":13,"depth":935,"text":18},{"id":50,"depth":935,"text":51},{"id":71,"depth":935,"text":72},{"id":89,"depth":935,"text":90},{"id":123,"depth":935,"text":124},{"id":159,"depth":935,"text":160},{"id":212,"depth":935,"text":213},{"id":228,"depth":935,"text":229,"children":5166},[5167],{"id":251,"depth":947,"text":252},{"id":282,"depth":935,"text":283,"children":5169},[5170],{"id":316,"depth":947,"text":317},{"id":359,"depth":935,"text":360,"children":5172},[5173],{"id":390,"depth":947,"text":391},{"id":425,"depth":935,"text":426},{"id":449,"depth":935,"text":450},{"id":501,"depth":935,"text":502},{"id":528,"depth":935,"text":529},{"id":558,"depth":935,"text":559},{"id":573,"depth":935,"text":576},{"id":588,"depth":935,"text":589,"children":5181},[5182,5183],{"id":624,"depth":947,"text":625},{"id":657,"depth":947,"text":658},{"id":693,"depth":935,"text":694,"children":5185},[5186,5187],{"id":728,"depth":947,"text":729},{"id":754,"depth":947,"text":755},{"id":779,"depth":935,"text":782},{"id":815,"depth":935,"text":816},{"id":887,"depth":935,"text":890},{},{"title":5,"description":973},[988,989,990],{"id":5195,"title":5196,"audience":6,"body":5197,"contentType":971,"course":972,"description":5969,"estimateBasis":5970,"estimatedDiscussionMinutes":1479,"estimatedLiveMinutes":1480,"estimatedTotalMinutes":981,"extension":893,"meta":5971,"module":979,"navigation":980,"order":5972,"path":5973,"promptAssist":983,"seo":5974,"status":985,"stem":5975,"tags":5976,"videoDuration":5980,"videoId":5981,"videoLink":5982,"videoTitle":5983,"week":979,"__hash__":5984},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment.md","Local Development Environment Setup",{"type":8,"value":5198,"toc":5947},[5199,5216,5234,5255,5280,5315,5347,5425,5502,5604,5632,5697,5774,5798,5825,5843,5867,5918],[11,5200,5202,5205],{"id":5201,"level":14},"local-development-environment-title",[16,5203,5196],{"id":5204},"local-development-environment-setup",[24,5206,5207,5210,5213],{},[27,5208,5209],{},"VS Code for editing course files",[27,5211,5212],{},"Course profile for Internet Applications extensions",[27,5214,5215],{},"Optional local PHP check on your own computer",[11,5217,5218,5220],{"id":1561,"level":14},[16,5219,1564],{"id":1561},[24,5221,5222,5225,5228,5231],{},[27,5223,5224],{},"Install VS Code",[27,5226,5227],{},"Open the course repository root",[27,5229,5230],{},"Install the required extensions for the course",[27,5232,5233],{},"Have a local php install as a light weight dev server (as a backup for the VM lessons)",[11,5235,5237,5240],{"id":5236,"level":14},"what-this-setup-does",[16,5238,5239],{"id":5236},"What This Setup Does",[24,5241,5242,5245,5248],{},[27,5243,5244],{},"VS Code: editor for course files",[27,5246,5247],{},"Extensions: syntax help, Git visibility, database viewing, time tracking",[27,5249,5250,5251,5254],{},"Optional host PHP: quick ",[146,5252,5253],{},"php -v"," check and editor support",[11,5256,5258,5261],{"id":5257,"level":14},"step-1-install-vs-code",[16,5259,5260],{"id":5257},"Step 1: Install VS Code",[24,5262,5263,5271,5274,5277],{},[27,5264,5265,5266],{},"Download: ",[856,5267,5270],{"href":5268,"rel":5269},"https:\u002F\u002Fcode.visualstudio.com\u002FDownload",[860],"Visual Studio Code",[27,5272,5273],{},"Install like a normal desktop app",[27,5275,5276],{},"Do not install VS Code inside your repository folder",[27,5278,5279],{},"VS Code is the editor; the repo is the workspace folder",[11,5281,5283,5286,5289,5312],{"id":5282,"level":14},"step-2-open-the-repository",[16,5284,5285],{"id":5282},"Step 2: Open The Repository",[20,5287,5288],{},"After the course repo is cloned:",[24,5290,5291,5301,5304,5309],{},[27,5292,5293,5294,5297,5298],{},"VS Code -> ",[146,5295,5296],{},"File"," -> ",[146,5299,5300],{},"Open Folder",[27,5302,5303],{},"Choose the repository root",[27,5305,5306,5307],{},"Folder name should match ",[146,5308,3629],{},[27,5310,5311],{},"Trust the workspace only if it is your cloned GitHub repo",[20,5313,5314],{},"Do not open a ZIP copy or clone the same repo again",[11,5316,5318,5322,5344],{"id":5317,"level":14},"step-3-create-course-profile",[16,5319,5321],{"id":5320},"step-3-create-a-course-profile","Step 3: Create A Course Profile",[24,5323,5324,5330,5338,5341],{},[27,5325,5326,5327],{},"Gear icon -> ",[146,5328,5329],{},"Profiles",[27,5331,5332,5333,803,5335],{},"Create ",[146,5334,972],{},[146,5336,5337],{},"PHP",[27,5339,5340],{},"Switch into that profile",[27,5342,5343],{},"Install course extensions there",[20,5345,5346],{},"Profiles keep this course setup separate from other projects",[11,5348,5350,5353,5357],{"id":5349,"level":14},"step-4-install-extensions",[16,5351,5352],{"id":5349},"Step 4: Install Extensions",[249,5354,5356],{"id":5355},"start-with-these","Start With These",[24,5358,5359,5367,5375,5383,5391,5399,5414,5422],{},[27,5360,5361,5362],{},"Auto Rename Tag (Jun Han)\n",[24,5363,5364],{},[27,5365,5366],{},"Auto-completes matching HTML tags while you edit",[27,5368,5369,5370],{},"Bracket Lens (wraith13)\n",[24,5371,5372],{},[27,5373,5374],{},"Adds readability cues for closing brackets",[27,5376,5377,5378],{},"GitLens (GitKraken)\n",[24,5379,5380],{},[27,5381,5382],{},"Required: Git history, blame, and branch visibility in-editor",[27,5384,5385,5386],{},"MySQL (cweijan)\n",[24,5387,5388],{},[27,5389,5390],{},"Required later: connect to and inspect course database tables",[27,5392,5393,5394],{},"PHP Intelephense (Ben Mewburn)\n",[24,5395,5396],{},[27,5397,5398],{},"PHP language support, syntax checks, and warnings",[27,5400,5401,5402],{},"Todo Tree (Gruntfuggly)\n",[24,5403,5404],{},[27,5405,5406,5407,1582,5410,5413],{},"Finds and lists ",[146,5408,5409],{},"TODO",[146,5411,5412],{},"FIXME",", and similar comments",[27,5415,5416,5417],{},"WakaTime\n",[24,5418,5419],{},[27,5420,5421],{},"Required in sections that use time tracking; needs your API key",[27,5423,5424],{},"See the slides below for MySQL and WakaTime setup",[11,5426,5428,5432],{"id":5427,"level":247},"step-4a-setup-mysql-extension",[16,5429,5431],{"id":5430},"step-4a-configure-mysql-extension","Step 4A: Configure MySQL Extension",[452,5433,5435,5494],{"gap":454,"left-width":2653,"right-width":3196,"align":5434},"center",[457,5436,5437,5441],{"v-slot:left":459},[249,5438,5440],{"id":5439},"connection-settings","Connection Settings",[24,5442,5443,5446,5491],{},[27,5444,5445],{},"Open the MySQL panel from the VS Code sidebar",[27,5447,5448,5449],{},"Create a new connection with your course database details",[24,5450,5451,5457,5463,5466,5469],{},[27,5452,5453,5454],{},"Host: ",[146,5455,5456],{},"db.ethereallab.app",[27,5458,5459,5460],{},"Port: ",[146,5461,5462],{},"3306",[27,5464,5465],{},"Username: your UCID",[27,5467,5468],{},"Database: your UCID",[27,5470,5471,5472],{},"Password: from your generated connection string\n",[24,5473,5474,5482],{},[27,5475,5476,5477],{},"Get it from the ",[856,5478,5481],{"href":5479,"rel":5480},"https:\u002F\u002Fcourses.ethereallab.app\u002Fdatabase",[860],"course database page",[27,5483,5484,5485,149,5488],{},"Use the 12 characters between ",[146,5486,5487],{},"ucid:",[146,5489,5490],{},"@",[27,5492,5493],{},"Save this connection; you will reuse it in later database lessons",[457,5495,5496],{"v-slot:right":459},[20,5497,5498],{},[491,5499],{"alt":5500,"src":5501,"variant":495},"MySQL extension connection setup for the course database","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fmysql-setup.png",[11,5503,5505,5509],{"id":5504,"level":247},"step-4b-setup-wakatime",[16,5506,5508],{"id":5507},"step-4b-configure-wakatime","Step 4B: Configure WakaTime",[452,5510,5512,5567],{"gap":454,"left-width":3605,"right-width":5511,"align":5434},"1.05fr",[457,5513,5514,5518],{"v-slot:left":459},[249,5515,5517],{"id":5516},"setup-order","Setup Order",[24,5519,5520,5527,5530,5533,5536,5539,5556,5561,5564],{},[27,5521,2627,5522],{},[856,5523,5526],{"href":5524,"rel":5525},"https:\u002F\u002Fwakatime.com\u002Fsignup",[860],"WakaTime",[27,5528,5529],{},"Create or open your account",[27,5531,5532],{},"Copy your API key from account settings",[27,5534,5535],{},"In VS Code, search Extensions for WakaTime",[27,5537,5538],{},"Install the WakaTime extension",[27,5540,5541,5542],{},"Open Command Palette:",[24,5543,5544,5550],{},[27,5545,5546,5547],{},"Windows\u002FLinux: ",[146,5548,5549],{},"Ctrl+Shift+P",[27,5551,5552,5553],{},"macOS: ",[146,5554,5555],{},"Cmd+Shift+P",[27,5557,3302,5558],{},[146,5559,5560],{},"WakaTime: API Key",[27,5562,5563],{},"Paste your API key",[27,5565,5566],{},"Restart VS Code if tracking does not appear right away",[457,5568,5569,5574,5581,5586,5593,5598],{"v-slot:right":459},[1137,5570,5571],{},[27,5572,5573],{},"WakaTime account settings:",[20,5575,5576],{},[491,5577],{"alt":5578,"src":5579,"variant":495,"max-height":5580},"WakaTime account settings API key detail","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fsettings-api-key-detail.png","14rem",[1137,5582,5583],{"start":935},[27,5584,5585],{},"VS Code extension search:",[20,5587,5588],{},[491,5589],{"alt":5590,"src":5591,"variant":495,"max-height":5592},"VS Code Extensions search results showing WakaTime","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fvs-code-search.png","9rem",[1137,5594,5595],{"start":947},[27,5596,5597],{},"VS Code API key command:",[20,5599,5600],{},[491,5601],{"alt":5602,"src":5603,"variant":495,"max-height":5592},"Command Palette with WakaTime API key command","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fvs-code-prompt.png",[11,5605,5607,5610],{"id":5606,"level":14},"step-5-optional-local-php",[16,5608,5609],{"id":5606},"Step 5: Optional Local PHP",[24,5611,5612,5615,5618,5626,5629],{},[27,5613,5614],{},"Useful for editor support",[27,5616,5617],{},"Useful for quick terminal checks",[27,5619,5620,5621],{},"Not the main course runtime\n",[24,5622,5623],{},[27,5624,5625],{},"Viable backup solution if VM lesson has issues",[27,5627,5628],{},"VM and Render still run the real app path",[27,5630,5631],{},"See the slides below for OS-specific install notes",[11,5633,5635,5638],{"id":5634,"level":247},"step-5a-windows-php-zip",[16,5636,5637],{"id":5634},"Step 5A: Windows PHP ZIP",[452,5639,5640,5671],{"gap":454,"left-width":455,"right-width":455},[457,5641,5642,5646],{"v-slot:left":459},[249,5643,5645],{"id":5644},"download-and-extract","Download And Extract",[24,5647,5648,5651,5661,5666],{},[27,5649,5650],{},"Download PHP for Windows as a ZIP",[27,5652,5653,5654],{},"Extract it outside your repository",[24,5655,5656],{},[27,5657,1734,5658],{},[146,5659,5660],{},"C:\\tools\\php",[27,5662,5663,5664],{},"Add that extracted PHP folder to the user ",[146,5665,2420],{},[27,5667,5668,5669],{},"Restart Git Bash, PowerShell, and VS Code after editing ",[146,5670,2420],{},[457,5672,5673,5677,5693],{"v-slot:right":459},[249,5674,5676],{"id":5675},"visual-checks","Visual Checks",[24,5678,5679,5685,5690],{},[27,5680,5681,5682],{},"The extracted folder contains ",[146,5683,5684],{},"php.exe",[27,5686,5687,5688],{},"The Path entry points to the folder, not to ",[146,5689,5684],{},[27,5691,5692],{},"A new terminal can run:",[74,5694],{"language":96,"src":5695,"label":5696},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Fwindows-php-path-check-03.sh","windows-php-check.sh",[11,5698,5700,5703],{"id":5699,"level":247},"step-5b-macos-homebrew-php",[16,5701,5702],{"id":5699},"Step 5B: macOS Homebrew PHP",[452,5704,5705,5736],{"gap":454,"left-width":455,"right-width":455},[457,5706,5707,5711],{"v-slot:left":459},[249,5708,5710],{"id":5709},"install-homebrew","Install Homebrew",[24,5712,5713,5716,5724,5727,5730,5733],{},[27,5714,5715],{},"Open Terminal",[27,5717,5718,5719],{},"Copy the install command from ",[856,5720,5723],{"href":5721,"rel":5722},"https:\u002F\u002Fbrew.sh\u002F",[860],"brew.sh",[27,5725,5726],{},"Expect Terminal to ask for your Mac password",[27,5728,5729],{},"Expect Homebrew to mention Command Line Tools if needed",[27,5731,5732],{},"At the end, Homebrew may print \"Next steps\"",[27,5734,5735],{},"Run those \"Next steps\" commands if shown",[457,5737,5738,5742,5746,5749],{"v-slot:right":459},[249,5739,5741],{"id":5740},"then-install-php","Then Install PHP",[74,5743],{"language":96,"src":5744,"label":5745},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Fmacos-install-php-homebrew-04.sh","macos-php.sh",[20,5747,5748],{},"Look for:",[24,5750,5751,5757,5762,5768],{},[27,5752,5753,5756],{},[146,5754,5755],{},"brew --version"," prints a version",[27,5758,5759,5761],{},[146,5760,5253],{}," prints PHP 8 output",[27,5763,5764,5765],{},"Apple Silicon Macs commonly use ",[146,5766,5767],{},"\u002Fopt\u002Fhomebrew",[27,5769,5770,5771],{},"Intel Macs commonly use ",[146,5772,5773],{},"\u002Fusr\u002Flocal",[11,5775,5777,5781,5783,5787],{"id":5776,"level":247},"step-5c-linux-php-cli",[16,5778,5780],{"id":5779},"step-5c-ubuntulinux-php-cli","Step 5C: Ubuntu\u002FLinux PHP CLI",[20,5782,93],{},[74,5784],{"language":96,"src":5785,"label":5786},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Flinux-install-php-cli-05.sh","linux-php.sh",[24,5788,5789,5792,5795],{},[27,5790,5791],{},"This installs command-line PHP",[27,5793,5794],{},"This is only for local terminal checks",[27,5796,5797],{},"The later VM lesson installs Apache, PHP, and MySQL together",[11,5799,5801,5804,5806,5809,5811,5814],{"id":5800,"level":14},"step-6-verify-optional-php",[16,5802,5803],{"id":5800},"Step 6: Verify Optional PHP",[20,5805,93],{},[74,5807],{"language":96,"src":5808},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Fstep-6-verify-optional-p-01.sh",[20,5810,3694],{},[74,5812],{"language":76,"src":5813},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Fexample-output-02.txt",[24,5815,5816,5819,5822],{},[27,5817,5818],{},"Exact version can differ",[27,5820,5821],{},"PHP 8 output means the terminal can find PHP",[27,5823,5824],{},"Windows may need a terminal or VS Code restart after PATH changes",[11,5826,5827,5829],{"id":779,"level":14},[16,5828,782],{"id":779},[24,5830,5831,5834,5837,5840],{},[27,5832,5833],{},"Installing tools inside the repository folder",[27,5835,5836],{},"Opening the parent folder instead of the repo root",[27,5838,5839],{},"Editing a ZIP copy instead of the cloned repo",[27,5841,5842],{},"Installing extensions in the wrong VS Code profile",[11,5844,5845,5847],{"id":1409,"level":14},[16,5846,1412],{"id":1409},[24,5848,5849,5852,5855,5858,5861],{},[27,5850,5851],{},"VS Code opens your course repository root",[27,5853,5854],{},"Course profile is active",[27,5856,5857],{},"PHP Intelephense is installed",[27,5859,5860],{},"GitLens is installed",[27,5862,5863,5864,5866],{},"Optional: ",[146,5865,5253],{}," prints a PHP 8 version",[11,5868,5869,5871],{"id":815,"level":14},[16,5870,816],{"id":815},[452,5872,5873,5891],{"gap":454,"left-width":455,"right-width":455},[457,5874,5875,5877],{"v-slot:left":459},[249,5876,824],{"id":823},[24,5878,5879,5882,5885,5888],{},[27,5880,5881],{},"IDE: editor with development tools",[27,5883,5884],{},"Extension: add-on that changes VS Code behavior",[27,5886,5887],{},"Profile: saved VS Code setup",[27,5889,5890],{},"PATH: system setting used to find commands",[457,5892,5893,5895],{"v-slot:right":459},[249,5894,849],{"id":812},[24,5896,5897,5904,5911],{},[27,5898,5899],{},[856,5900,5903],{"href":5901,"rel":5902},"https:\u002F\u002Fcode.visualstudio.com\u002Fdocs\u002Fintrovideos\u002Fbasics",[860],"VS Code Getting Started",[27,5905,5906],{},[856,5907,5910],{"href":5908,"rel":5909},"https:\u002F\u002Fcode.visualstudio.com\u002Fdocs\u002Fconfigure\u002Fprofiles",[860],"VS Code Profiles",[27,5912,5913],{},[856,5914,5917],{"href":5915,"rel":5916},"https:\u002F\u002Fwww.php.net\u002Fmanual\u002Fen\u002Finstall.php",[860],"PHP Installation",[11,5919,5920,5922],{"id":887,"level":14},[16,5921,890],{"id":887},[24,5923,5924,5927,5930,5933,5944],{},[27,5925,5926],{},"VS Code installed as the course editor",[27,5928,5929],{},"Repository opens from its root folder",[27,5931,5932],{},"Course extensions live in a course profile",[27,5934,5935,5936],{},"Local PHP is optional for this Internet Applications path\n",[24,5937,5938,5941],{},[27,5939,5940],{},"Summer 2026 added information about VM setup in a future lesson to teach clearer Apache\u002FMySQL topics",[27,5942,5943],{},"VM, Apache, Render QA, and Render production remain the real runtime checks",[27,5945,5946],{},"Next: copy the instructor template into the repository",{"title":459,"searchDepth":935,"depth":935,"links":5948},[5949,5950,5951,5952,5953,5954,5955,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968],{"id":5204,"depth":935,"text":5196},{"id":1561,"depth":935,"text":1564},{"id":5236,"depth":935,"text":5239},{"id":5257,"depth":935,"text":5260},{"id":5282,"depth":935,"text":5285},{"id":5320,"depth":935,"text":5321},{"id":5349,"depth":935,"text":5352,"children":5956},[5957],{"id":5355,"depth":947,"text":5356},{"id":5430,"depth":935,"text":5431},{"id":5507,"depth":935,"text":5508},{"id":5606,"depth":935,"text":5609},{"id":5634,"depth":935,"text":5637},{"id":5699,"depth":935,"text":5702},{"id":5779,"depth":935,"text":5780},{"id":5800,"depth":935,"text":5803},{"id":779,"depth":935,"text":782},{"id":1409,"depth":935,"text":1412},{"id":815,"depth":935,"text":816},{"id":887,"depth":935,"text":890},"Set up VS Code, course extensions, and optional local PHP checks.","First-pass timing estimate for VS Code installation, extension profile setup, optional PHP verification, and beginner folder checks.",{},"50","\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment",{"title":5196,"description":5969},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment",[5977,5978,5979],"vscode","local-development","php","44:26","0s1N-m3LABc","https:\u002F\u002Fyoutu.be\u002F0s1N-m3LABc","Local Development Environment setup","X5U0DDKjg7X7HrYtDDcsE4QqlBLimZ9weKgnZlc8H2s",{"id":5986,"title":5987,"audience":6,"body":5988,"contentType":971,"course":972,"description":7039,"estimateBasis":7040,"estimatedDiscussionMinutes":4524,"estimatedLiveMinutes":2545,"estimatedTotalMinutes":7041,"extension":893,"meta":7042,"module":979,"navigation":980,"order":7041,"path":7043,"promptAssist":983,"seo":7044,"status":985,"stem":7045,"tags":7046,"videoDuration":7047,"videoId":7048,"videoLink":7049,"videoTitle":7050,"week":979,"__hash__":7051},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository.md","Add Instructor Template To Your Repository",{"type":8,"value":5989,"toc":7011},[5990,6019,6061,6089,6122,6153,6199,6292,6336,6381,6426,6471,6543,6602,6675,6729,6805,6874,6906,6958,6982],[11,5991,5992,5994,5997],{"id":13,"level":14},[16,5993,18],{"id":13},[20,5995,5996],{},"By the end, you should have:",[24,5998,5999,6002,6005,6011,6016],{},[27,6000,6001],{},"Cloned course repository open in the terminal",[27,6003,6004],{},"Starter template copied into the repository root",[27,6006,6007,6008],{},"Baseline commit on ",[146,6009,6010],{},"Module01-Course-Template",[27,6012,6013,6014],{},"Pull request merged into ",[146,6015,166],{},[27,6017,6018],{},"Clean working tree before moving on",[11,6020,6022,6026],{"id":6021,"level":14},"step-1-open-clone",[16,6023,6025],{"id":6024},"step-1-open-the-cloned-repository","Step 1: Open The Cloned Repository",[452,6027,6028,6036],{"gap":454,"left-width":455,"right-width":455},[457,6029,6030,6032],{"v-slot:left":459},[20,6031,93],{},[74,6033],{"language":96,"src":6034,"label":6035},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-1-open-the-cloned-repository-01.sh","open-cloned-repository.sh",[457,6037,6038,6040,6043],{"v-slot:right":459},[20,6039,3694],{},[74,6041],{"language":3169,"src":6042,"label":3554},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fopen-cloned-repository-output.txt",[24,6044,6045,6050,6055],{},[27,6046,6047,6049],{},[146,6048,1651],{},": current working directory",[27,6051,6052,6054],{},[146,6053,275],{},": current branch and file state",[27,6056,6057,6058,6060],{},"Important check: ",[146,6059,1651],{}," ends with your repository folder",[11,6062,6064,6068,6071,6074],{"id":6063,"level":14},"step-2-open-vscode",[16,6065,6067],{"id":6066},"step-2-open-the-repository-root","Step 2: Open The Repository Root",[20,6069,6070],{},"Run from inside the cloned repository folder:",[74,6072],{"language":96,"src":6073},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-2-open-the-reposito-01.sh",[24,6075,6076,6081,6086],{},[27,6077,6078,6080],{},[146,6079,146],{},": opens VS Code from the terminal",[27,6082,6083,6085],{},[146,6084,1716],{}," means \"this current folder\"",[27,6087,6088],{},"VS Code should show your repository folder, not the parent folder",[11,6090,6092,6096],{"id":6091,"level":14},"step-3-download-template",[16,6093,6095],{"id":6094},"step-3-download-the-instructor-template","Step 3: Download The Instructor Template",[24,6097,6098,6110,6113,6116,6119],{},[27,6099,6100,6101],{},"Open the instructor template repository",[24,6102,6103],{},[27,6104,6105],{},[856,6106,6109],{"href":6107,"rel":6108},"https:\u002F\u002Fgithub.com\u002FMattToegel\u002FIT202-2026",[860],"IT202-2026",[27,6111,6112],{},"Download the ZIP",[27,6114,6115],{},"Extract the ZIP",[27,6117,6118],{},"Copy scaffold contents into your repository root",[27,6120,6121],{},"See the slide below for the copy rule",[11,6123,6125,6129,6132,6135,6150],{"id":6124,"level":247},"template-copy-rule",[249,6126,6128],{"id":6127},"copy-rule","Copy Rule",[20,6130,6131],{},"Copy the contents of the extracted template folder",[20,6133,6134],{},"Do not copy:",[24,6136,6137,6140,6147],{},[27,6138,6139],{},"The extracted wrapper folder as one extra nested folder",[27,6141,6142,6143,6146],{},"The template repository's hidden ",[146,6144,6145],{},".git"," folder",[27,6148,6149],{},"Old files from a different semester",[20,6151,6152],{},"Repository root should contain the starter folders directly",[11,6154,6156,6160,6163,6166],{"id":6155,"level":14},"step-4-check-structure",[16,6157,6159],{"id":6158},"step-4-check-the-starter-structure","Step 4: Check The Starter Structure",[20,6161,6162],{},"After copying, repository root should look similar to:",[74,6164],{"language":76,"src":6165},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-4-check-the-starter-02.txt",[24,6167,6168,6173,6182,6196],{},[27,6169,6170,6172],{},[146,6171,1783],{}," should be directly inside your repository root",[27,6174,6175,6176,6179,6180],{},"Module folders and ",[146,6177,6178],{},"project"," live inside ",[146,6181,1783],{},[27,6183,6184,1582,6187,1585,6190,6193,6194],{},[146,6185,6186],{},"lib",[146,6188,6189],{},"partials",[146,6191,6192],{},"sql"," stay outside ",[146,6195,1783],{},[27,6197,6198],{},"See the slide below for the public\u002Fprivate folder boundary",[11,6200,6202,6206,6289],{"id":6201,"level":247},"public-html-boundary",[249,6203,6205],{"id":6204},"public-and-private-boundary","Public And Private Boundary",[24,6207,6208,6242,6264,6269,6274,6280,6286],{},[27,6209,6210,6212,6213],{},[146,6211,1783],{},": web root Apache can serve\n",[24,6214,6215,6225,6230,6236],{},[27,6216,6217,6220,6221,6224],{},[146,6218,6219],{},"m01"," through ",[146,6222,6223],{},"m10",": module practice folders",[27,6226,6227,6229],{},[146,6228,6178],{},": course project folder",[27,6231,6232,6235],{},[146,6233,6234],{},"index.php",": first browser entry point",[27,6237,6238,6241],{},[146,6239,6240],{},"test_db.php",": database connection check",[27,6243,6244,6246,6247],{},[146,6245,6186],{},": reusable PHP helpers\n",[24,6248,6249,6255],{},[27,6250,6251,6254],{},[146,6252,6253],{},".env.sample",": example local config file",[27,6256,6257,149,6260,6263],{},[146,6258,6259],{},"config.php",[146,6261,6262],{},"db.php",": config and database helpers",[27,6265,6266,6268],{},[146,6267,6189],{},": shared page pieces",[27,6270,6271,6273],{},[146,6272,6192],{},": database setup scripts",[27,6275,6276,6279],{},[146,6277,6278],{},"Dockerfile",": consistent runtime setup",[27,6281,6282,6285],{},[146,6283,6284],{},"structure.md",": starter layout notes",[27,6287,6288],{},"Private folders should not be opened directly in the browser",[20,6290,6291],{},"Later server setup expects this folder boundary",[11,6293,6295,6299],{"id":6294,"level":14},"step-5-check-status",[16,6296,6298],{"id":6297},"step-5-create-the-template-branch","Step 5: Create The Template Branch",[452,6300,6301,6309],{"gap":454,"left-width":455,"right-width":455},[457,6302,6303,6305],{"v-slot:left":459},[20,6304,93],{},[74,6306],{"language":96,"src":6307,"label":6308},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-5-create-template-branch-05.sh","create-template-branch.sh",[457,6310,6311,6314,6317],{"v-slot:right":459},[20,6312,6313],{},"Expected idea:",[74,6315],{"language":76,"src":6316,"label":3554},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstatus-after-template-copy.txt",[24,6318,6319,6325,6330,6333],{},[27,6320,6321,6324],{},[146,6322,6323],{},"git checkout -b",": create and move to a new branch",[27,6326,6327,6328],{},"Branch name: ",[146,6329,6010],{},[27,6331,6332],{},"New files listed as untracked",[27,6334,6335],{},"No changes means likely wrong folder or copy missed",[11,6337,6339,6343],{"id":6338,"level":14},"step-6-stage",[16,6340,6342],{"id":6341},"step-6-stage-the-baseline-files","Step 6: Stage The Baseline Files",[452,6344,6345,6353],{"gap":454,"left-width":455,"right-width":455},[457,6346,6347,6349],{"v-slot:left":459},[20,6348,93],{},[74,6350],{"language":96,"src":6351,"label":6352},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-6-stage-the-baseline-files-06.sh","stage-baseline.sh",[457,6354,6355,6358,6376,6378],{"v-slot:right":459},[20,6356,6357],{},"What this means:",[24,6359,6360,6366,6371],{},[27,6361,6362,6365],{},[146,6363,6364],{},"git add",": choose files for the next commit",[27,6367,6368,6370],{},[146,6369,1716],{}," means current folder and contents",[27,6372,6373,6375],{},[146,6374,275],{},": verify what is staged before committing",[20,6377,6313],{},[74,6379],{"language":76,"src":6380,"label":3554},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstatus-after-stage.txt",[11,6382,6384,6388],{"id":6383,"level":14},"step-7-commit",[16,6385,6387],{"id":6386},"step-7-commit-the-baseline","Step 7: Commit The Baseline",[452,6389,6390,6398],{"gap":454,"left-width":455,"right-width":455},[457,6391,6392,6394],{"v-slot:left":459},[20,6393,93],{},[74,6395],{"language":96,"src":6396,"label":6397},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-7-commit-the-baseline-07.sh","commit-baseline.sh",[457,6399,6400,6402,6405],{"v-slot:right":459},[20,6401,6313],{},[74,6403],{"language":76,"src":6404,"label":3554},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fcommit-baseline-output.txt",[24,6406,6407,6413,6423],{},[27,6408,6409,6412],{},[146,6410,6411],{},"git commit",": save staged changes in local history",[27,6414,6415,6417,6418],{},[146,6416,376],{},": commit message\n",[24,6419,6420],{},[27,6421,6422],{},"Message is required, even if empty",[27,6424,6425],{},"Baseline commit: starter state before custom work",[11,6427,6429,6433],{"id":6428,"level":14},"step-8-push",[16,6430,6432],{"id":6431},"step-8-push-the-template-branch","Step 8: Push The Template Branch",[452,6434,6435,6443],{"gap":454,"left-width":455,"right-width":455},[457,6436,6437,6439],{"v-slot:left":459},[20,6438,93],{},[74,6440],{"language":96,"src":6441,"label":6442},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-8-push-to-github-08.sh","push-baseline.sh",[457,6444,6445,6447,6450],{"v-slot:right":459},[20,6446,6313],{},[74,6448],{"language":76,"src":6449,"label":3554},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fpush-baseline-output.txt",[24,6451,6452,6457,6463,6468],{},[27,6453,6454,6456],{},[146,6455,439],{},": GitHub remote",[27,6458,6459,6462],{},[146,6460,6461],{},"-u",": remembers this branch's GitHub tracking branch",[27,6464,6465,6467],{},[146,6466,6010],{},": branch being sent",[27,6469,6470],{},"Refresh GitHub after the push",[11,6472,6474,6478],{"id":6473,"level":14},"step-9-open-pull-request",[16,6475,6477],{"id":6476},"step-9-open-the-pull-request","Step 9: Open The Pull Request",[452,6479,6480,6523],{"gap":454,"left-width":455,"right-width":455},[457,6481,6482,6484],{"v-slot:left":459},[20,6483,3610],{},[24,6485,6486,6489,6505,6510,6515,6518],{},[27,6487,6488],{},"Open your course repository",[27,6490,1144,6491,6494],{},[1102,6492,6493],{},"Compare & pull request",[24,6495,6496],{},[27,6497,6498,6499,5297,6502],{},"Or use ",[1102,6500,6501],{},"Pull requests",[1102,6503,6504],{},"New pull request",[27,6506,6507,6508],{},"Set base branch to ",[146,6509,166],{},[27,6511,6512,6513],{},"Set compare branch to ",[146,6514,6010],{},[27,6516,6517],{},"Confirm the changed files are the starter template files",[27,6519,1144,6520],{},[1102,6521,6522],{},"Create pull request",[457,6524,6525,6528,6532],{"v-slot:right":459},[20,6526,6527],{},"Use a short title and description:",[74,6529],{"language":76,"src":6530,"label":6531},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fpull-request-description.txt","pull-request-description.txt",[24,6533,6534,6537,6540],{},[27,6535,6536],{},"Base receives the changes",[27,6538,6539],{},"Compare contains your branch work",[27,6541,6542],{},"If base and compare are reversed, do not create the pull request",[11,6544,6546,6552],{"id":6545,"level":14},"step-10-merge-sync-main",[16,6547,6549,6550],{"id":6548},"step-10-merge-and-sync-main","Step 10: Merge And Sync ",[146,6551,166],{},[452,6553,6554,6576],{"gap":454,"left-width":455,"right-width":455},[457,6555,6556,6558,6570,6572],{"v-slot:left":459},[20,6557,3610],{},[24,6559,6560,6565],{},[27,6561,1144,6562],{},[1102,6563,6564],{},"Merge pull request",[27,6566,1144,6567],{},[1102,6568,6569],{},"Confirm merge",[20,6571,741],{},[74,6573],{"language":96,"src":6574,"label":6575},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-10-sync-main-after-pr-10.sh","sync-main-after-pr.sh",[457,6577,6578,6580,6583],{"v-slot:right":459},[20,6579,6313],{},[74,6581],{"language":76,"src":6582,"label":3554},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fsync-main-after-pr-output.txt",[24,6584,6585,6591,6597],{},[27,6586,6587,6590],{},[146,6588,6589],{},"git checkout main",": return to the main branch",[27,6592,6593,6596],{},[146,6594,6595],{},"git pull origin main",": download the merged template files",[27,6598,6599,6600,765],{},"Continue only when local ",[146,6601,166],{},[11,6603,6605,6611],{"id":6604,"level":14},"step-11-create-local-env",[16,6606,6607,6608],{"id":6604},"Step 11: Create Local ",[146,6609,6610],{},".env",[452,6612,6613,6635],{"gap":454,"left-width":455,"right-width":455},[457,6614,6615,6618,6622],{"v-slot:left":459},[20,6616,6617],{},"Run from the repository root:",[74,6619],{"language":96,"src":6620,"label":6621},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-11-create-local-env-11.sh","create-local-env.sh",[24,6623,6624],{},[27,6625,6626,6627,6630,6631],{},"Get ",[146,6628,6629],{},"DB_URL"," from ",[856,6632,6634],{"href":5479,"rel":6633},[860],"courses.ethereallab.app\u002Fdatabase",[457,6636,6637,6640,6645],{"v-slot:right":459},[20,6638,6639],{},"Fill in values similar to:",[74,6641],{"language":6642,"src":6643,"label":6644},"dotenv","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Flocal-env-example.txt","lib\u002F.env",[24,6646,6647,6652,6657,6660,6665,6670],{},[27,6648,6649,6651],{},[146,6650,6610],{}," stores local secrets",[27,6653,2672,6654,6656],{},[146,6655,6610],{}," on your computer only",[27,6658,6659],{},"Do not commit your real connection string",[27,6661,6662,6663],{},"Paste the generated database connection string as ",[146,6664,6629],{},[27,6666,6667,6669],{},[146,6668,6259],{}," loads local or hosted environment variables",[27,6671,6672,6673],{},"Do not paste secrets directly into ",[146,6674,6259],{},[11,6676,6678,6682],{"id":6677,"level":14},"step-12-test-local-db",[16,6679,6681],{"id":6680},"step-12-test-local-database-connection","Step 12: Test Local Database Connection",[452,6683,6684,6692],{"gap":454,"left-width":455,"right-width":455},[457,6685,6686,6688],{"v-slot:left":459},[20,6687,6617],{},[74,6689],{"language":96,"src":6690,"label":6691},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-12-test-local-db-12.sh","run-local-php.sh",[457,6693,6694,6697,6701],{"v-slot:right":459},[20,6695,6696],{},"Then open:",[74,6698],{"language":76,"src":6699,"label":6700},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Ftest-db-url.txt","browser-url.txt",[24,6702,6703,6709,6715,6723],{},[27,6704,6705,6708],{},[146,6706,6707],{},"php -S",": starts PHP's built-in local server",[27,6710,6711,6714],{},[146,6712,6713],{},"-t public_html",": serves the course web root",[27,6716,6717,6719,6720,6722],{},[146,6718,6240],{},": confirms PHP can read ",[146,6721,6610],{}," and connect to MySQL",[27,6724,6725,6726,6728],{},"Stop the server with ",[146,6727,2377],{}," when finished",[11,6730,6732,6740,6746],{"id":6731,"level":14},"step-13-enable-pdo-mysql",[16,6733,6735,6736,6739],{"id":6734},"step-13-enable-pdo_mysql-if-needed","Step 13: Enable ",[146,6737,6738],{},"pdo_mysql"," If Needed",[20,6741,6742,6743,1716],{},"This is usually a Windows PHP ZIP setup issue. macOS and Linux usually install MySQL support through Homebrew or ",[146,6744,6745],{},"apt",[452,6747,6748,6779],{"gap":454,"left-width":455,"right-width":455},[457,6749,6750,6753,6757,6760],{"v-slot:left":459},[20,6751,6752],{},"Find the PHP folder:",[74,6754],{"language":96,"src":6755,"label":6756},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-13-find-php-folder-13.sh","find-php-folder.sh",[20,6758,6759],{},"In that folder:",[24,6761,6762,6768,6774],{},[27,6763,6764,6765],{},"Find ",[146,6766,6767],{},"php.ini-development",[27,6769,6770,6771],{},"Copy it as ",[146,6772,6773],{},"php.ini",[27,6775,700,6776,6778],{},[146,6777,6773],{}," in your editor",[457,6780,6781,6784,6788,6791,6795],{"v-slot:right":459},[20,6782,6783],{},"Uncomment these lines:",[74,6785],{"language":6786,"src":6787,"label":6773},"ini","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fphp-ini-pdo-mysql-settings.txt",[20,6789,6790],{},"Mac\u002FLinux usually use:",[74,6792],{"language":96,"src":6793,"label":6794},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fmacos-linux-pdo-mysql-commands-14.sh","macos-linux-php-mysql.sh",[24,6796,6797,6802],{},[27,6798,6799,6800],{},"Restart the php dev server after changing ",[146,6801,6773],{},[27,6803,6804],{},"Run Step 12 again after enabling the extension",[11,6806,6808,6810,6813],{"id":6807,"level":14},"quick-check-final",[16,6809,1412],{"id":1409},[20,6811,6812],{},"Confirm all of these:",[24,6814,6815,6818,6826,6829,6834,6843,6849,6854,6859,6865],{},[27,6816,6817],{},"GitHub shows the starter files",[27,6819,6820,6821,6823,6824],{},"GitHub shows a pull request from ",[146,6822,6010],{}," into ",[146,6825,166],{},[27,6827,6828],{},"The pull request is merged",[27,6830,510,6831,6833],{},[146,6832,166],{}," says the working tree is clean",[27,6835,6836,6220,6839,6842],{},[146,6837,6838],{},"public_html\u002Fm01",[146,6840,6841],{},"public_html\u002Fm10"," exist",[27,6844,6845,6848],{},[146,6846,6847],{},"public_html\u002Fproject"," exists",[27,6850,6851,6853],{},[146,6852,1783],{}," is not nested inside another accidental folder",[27,6855,6856,6858],{},[146,6857,6644],{}," exists locally and is not committed with real secrets",[27,6860,6861,6864],{},[146,6862,6863],{},"http:\u002F\u002Flocalhost:3000\u002Ftest_db.php"," confirms the database connection",[27,6866,6867,6868,6870,6871,6873],{},"Windows PHP has ",[146,6869,6738],{}," enabled if ",[146,6872,6240],{}," reports a missing driver",[11,6875,6877,6881,6883,6886,6895],{"id":6876,"level":14},"reset-check",[16,6878,6880],{"id":6879},"if-something-looks-wrong","If Something Looks Wrong",[20,6882,93],{},[74,6884],{"language":96,"src":6885},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fif-something-looks-wrong-03.sh",[6887,6888,6889],"blockquote",{},[20,6890,6891,6892,6894],{},"Tip: ",[146,6893,4147],{}," prints the repository root when your current folder is inside a Git repository",[24,6896,6897,6900,6903],{},[27,6898,6899],{},"Output should point to your course repository",[27,6901,6902],{},"If it points somewhere else, move folders before continuing",[27,6904,6905],{},"Avoid cloning inside another cloned repository",[11,6907,6908,6910],{"id":779,"level":14},[16,6909,782],{"id":779},[24,6911,6912,6915,6918,6923,6926,6929,6934,6944,6949,6952],{},[27,6913,6914],{},"Opening the parent folder instead of the repository root",[27,6916,6917],{},"Copying the instructor template folder as a nested folder",[27,6919,6920,6921,6146],{},"Copying the template ",[146,6922,6145],{},[27,6924,6925],{},"Keeping the downloaded ZIP inside the repository",[27,6927,6928],{},"Re-cloning the repository instead of opening the existing clone",[27,6930,6931,6932],{},"Putting module folders outside ",[146,6933,1783],{},[27,6935,6936,6937,6939,6940,6943],{},"Renaming ",[146,6938,6219],{}," to ",[146,6941,6942],{},"M1"," or mixing folder casing",[27,6945,6946,6947],{},"Doing template work directly on ",[146,6948,166],{},[27,6950,6951],{},"Reversing base and compare branches in the pull request",[27,6953,6954,6955,6957],{},"Forgetting to sync local ",[146,6956,166],{}," after the pull request is merged",[11,6959,6960,6962],{"id":823,"level":14},[16,6961,824],{"id":823},[24,6963,6964,6967,6970,6973,6976,6979],{},[27,6965,6966],{},"Repository root: top folder of the cloned project",[27,6968,6969],{},"Baseline: starter state before custom work begins",[27,6971,6972],{},"Pull request: GitHub review page used to merge branch work",[27,6974,6975],{},"Web root: folder served to the browser",[27,6977,6978],{},"Scaffold: starter folders that organize future work",[27,6980,6981],{},"Staging: choosing files for the next commit",[11,6983,6984,6986,6989],{"id":887,"level":14},[16,6985,890],{"id":887},[20,6987,6988],{},"Before leaving this presentation, confirm the following:",[24,6990,6991,6994,6997,7000,7006],{},[27,6992,6993],{},"You still have one clone for your repository",[27,6995,6996],{},"Your VS Code is able to open directly to your repository",[27,6998,6999],{},"Your repository has the full starter baseline correctly structured",[27,7001,7002,7003,7005],{},"GitHub remote ",[146,7004,166],{}," has the baseline content",[27,7007,510,7008,7010],{},[146,7009,166],{}," was synchronized",{"title":459,"searchDepth":935,"depth":935,"links":7012},[7013,7014,7015,7016,7019,7022,7023,7024,7025,7026,7027,7029,7031,7032,7034,7035,7036,7037,7038],{"id":13,"depth":935,"text":18},{"id":6024,"depth":935,"text":6025},{"id":6066,"depth":935,"text":6067},{"id":6094,"depth":935,"text":6095,"children":7017},[7018],{"id":6127,"depth":947,"text":6128},{"id":6158,"depth":935,"text":6159,"children":7020},[7021],{"id":6204,"depth":947,"text":6205},{"id":6297,"depth":935,"text":6298},{"id":6341,"depth":935,"text":6342},{"id":6386,"depth":935,"text":6387},{"id":6431,"depth":935,"text":6432},{"id":6476,"depth":935,"text":6477},{"id":6548,"depth":935,"text":7028},"Step 10: Merge And Sync main",{"id":6604,"depth":935,"text":7030},"Step 11: Create Local .env",{"id":6680,"depth":935,"text":6681},{"id":6734,"depth":935,"text":7033},"Step 13: Enable pdo_mysql If Needed",{"id":1409,"depth":935,"text":1412},{"id":6879,"depth":935,"text":6880},{"id":779,"depth":935,"text":782},{"id":823,"depth":935,"text":824},{"id":887,"depth":935,"text":890},"Continue from your cloned course repository, copy in the instructor template, and merge the baseline files through a pull request.","Face-to-face class of about 40 students; starts from an existing clone and includes template copy checks, ZIP extraction, first commit verification, and common folder mistakes.","60",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository",{"title":5987,"description":7039},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository",[4533,457,988],"47:11","4n0-QuXO_Aw","https:\u002F\u002Fyoutu.be\u002F4n0-QuXO_Aw","Adding Instructor\u002FCourse Template","iYq9WdND1ODBRrXLU2gX9dNCXvDc-Kvqufsokl_jg3E",{"id":7053,"title":7054,"audience":6,"body":7055,"contentType":971,"course":972,"description":7765,"estimateBasis":7766,"estimatedDiscussionMinutes":4524,"estimatedLiveMinutes":981,"estimatedTotalMinutes":2546,"extension":893,"meta":7767,"module":979,"navigation":980,"order":976,"path":7768,"promptAssist":983,"seo":7769,"status":985,"stem":7770,"tags":7771,"videoDuration":7773,"videoId":7774,"videoLink":7775,"videoTitle":7776,"week":979,"__hash__":7777},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches.md","QA And Prod Branches",{"type":8,"value":7056,"toc":7744},[7057,7091,7139,7161,7215,7280,7338,7388,7453,7494,7586,7626,7653,7711],[11,7058,7059,7061,7063],{"id":13,"level":14},[16,7060,18],{"id":13},[20,7062,22],{},[24,7064,7065,7074,7079,7083,7088],{},[27,7066,7067,7068,149,7071],{},"Understand the purpose and usage of ",[146,7069,7070],{},"qa",[146,7072,7073],{},"prod",[27,7075,7076,7077],{},"Create and push ",[146,7078,7070],{},[27,7080,7076,7081],{},[146,7082,7073],{},[27,7084,7085,7086],{},"Keep local work pointed at ",[146,7087,7070],{},[27,7089,7090],{},"Confirm GitHub has the expected branches",[11,7092,7094,7097,7132],{"id":7093,"level":14},"branch-roles",[16,7095,7096],{"id":7093},"Branch Roles",[24,7098,7099,7109,7119,7129],{},[27,7100,7101,7103,7104],{},[146,7102,166],{},": starter baseline and shared source branch\n",[24,7105,7106],{},[27,7107,7108],{},"Most projects stick with this; we'll split ours into development lanes",[27,7110,7111,7113,7114],{},[146,7112,7070],{},": public testing and evidence branch\n",[24,7115,7116],{},[27,7117,7118],{},"Normal branch to return to before new course work",[27,7120,7121,7123,7124],{},[146,7122,7073],{},": stable grading and evaluation branch\n",[24,7125,7126],{},[27,7127,7128],{},"Protected from everyday local edits",[27,7130,7131],{},"Later deployment setup connects Render to these branches",[20,7133,7134,7135,5297,7137],{},"Course flow: feature or homework branch -> ",[146,7136,7070],{},[146,7138,7073],{},[11,7140,7141,7143,7146,7150],{"id":1597,"level":14},[16,7142,1600],{"id":1597},[20,7144,7145],{},"Run inside the course repository:",[74,7147],{"label":7148,"language":96,"src":7149},"before-you-start.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fbefore-you-start.sh",[24,7151,7152,7155,7158],{},[27,7153,7154],{},"Working tree should be clean",[27,7156,7157],{},"Starter baseline already pushed to GitHub",[27,7159,7160],{},"Stop if Git says files are modified or untracked",[11,7162,7164,7170],{"id":7163,"level":14},"step-1-sync-main",[16,7165,7167,7168],{"id":7166},"step-1-start-from-main","Step 1: Start From ",[146,7169,166],{},[452,7171,7172,7180],{"gap":454,"left-width":455,"right-width":455},[457,7173,7174,7176],{"v-slot:left":459},[20,7175,93],{},[74,7177],{"label":7178,"language":96,"src":7179},"sync-main.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fsync-main.sh",[457,7181,7182,7184,7187],{"v-slot:right":459},[20,7183,3694],{},[74,7185],{"label":3554,"language":76,"src":7186},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fsync-main-output.txt",[24,7188,7189,7196],{},[27,7190,7191,7193,7194],{},[146,7192,6589],{},": switch to ",[146,7195,166],{},[27,7197,7198,7200,7201,7203,7204],{},[146,7199,6595],{},": get the latest ",[146,7202,166],{}," from GitHub\n",[24,7205,7206,7210],{},[27,7207,7208,6456],{},[146,7209,439],{},[27,7211,7212,7214],{},[146,7213,166],{},": remote branch being pulled",[11,7216,7218,7224],{"id":7217,"level":14},"step-2-create-qa",[16,7219,7221,7222],{"id":7220},"step-2-create-and-push-qa","Step 2: Create And Push ",[146,7223,7070],{},[452,7225,7226,7234],{"gap":454,"left-width":455,"right-width":455},[457,7227,7228,7230],{"v-slot:left":459},[20,7229,93],{},[74,7231],{"label":7232,"language":96,"src":7233},"create-qa.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-qa.sh",[457,7235,7236,7238,7241],{"v-slot:right":459},[20,7237,3694],{},[74,7239],{"label":3554,"language":76,"src":7240},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-qa-output.txt",[24,7242,7243,7260],{},[27,7244,7245,7248,7249,7251,7252],{},[146,7246,7247],{},"git checkout -b qa",": create ",[146,7250,7070],{}," and switch to it\n",[24,7253,7254],{},[27,7255,7256,7259],{},[146,7257,7258],{},"-b",": creates a new branch of the following name",[27,7261,7262,7265,7266,7268,7269],{},[146,7263,7264],{},"git push -u origin qa",": send ",[146,7267,7070],{}," to GitHub\n",[24,7270,7271],{},[27,7272,7273,7275,7276,7279],{},[146,7274,6461],{},": remember ",[146,7277,7278],{},"origin\u002Fqa"," as the upstream branch",[11,7281,7283,7289],{"id":7282,"level":14},"step-3-create-prod",[16,7284,7286,7287],{"id":7285},"step-3-create-and-push-prod","Step 3: Create And Push ",[146,7288,7073],{},[452,7290,7291,7299],{"gap":454,"left-width":455,"right-width":455},[457,7292,7293,7295],{"v-slot:left":459},[20,7294,93],{},[74,7296],{"label":7297,"language":96,"src":7298},"create-prod.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-prod.sh",[457,7300,7301,7303,7306],{"v-slot:right":459},[20,7302,3694],{},[74,7304],{"label":3554,"language":76,"src":7305},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-prod-output.txt",[24,7307,7308,7316,7321,7333],{},[27,7309,5332,7310,7312,7313,7315],{},[146,7311,7073],{}," from the current ",[146,7314,7070],{}," branch",[27,7317,7318],{},[146,7319,7320],{},"git checkout -b prod",[27,7322,7323,7324,7268,7326],{},"Push ",[146,7325,7073],{},[24,7327,7328],{},[27,7329,7330],{},[146,7331,7332],{},"git push origin prod",[27,7334,7335,7337],{},[146,7336,7073],{}," starts from the same clean baseline",[11,7339,7341,7346],{"id":7340,"level":14},"step-4-return-to-qa",[16,7342,7343,7344],{"id":7340},"Step 4: Return To ",[146,7345,7070],{},[452,7347,7348,7356],{"gap":454,"left-width":455,"right-width":455},[457,7349,7350,7352],{"v-slot:left":459},[20,7351,93],{},[74,7353],{"label":7354,"language":96,"src":7355},"return-to-qa.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Freturn-to-qa.sh",[457,7357,7358,7360,7363],{"v-slot:right":459},[20,7359,3694],{},[74,7361],{"label":3554,"language":76,"src":7362},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Freturn-to-qa-output.txt",[24,7364,7365,7370,7375],{},[27,7366,7367,7369],{},[146,7368,7070],{}," should have the asterisk",[27,7371,7372,7374],{},[146,7373,7073],{}," should still exist on GitHub",[27,7376,7377,7378,7380],{},"Do not start normal course work from ",[146,7379,7073],{},[24,7381,7382],{},[27,7383,7384,7385,7387],{},"We'll remove local ",[146,7386,7073],{}," to avoid this issue",[11,7389,7391,7397],{"id":7390,"level":14},"step-5-delete-local-prod",[16,7392,7394,7395],{"id":7393},"step-5-remove-local-prod","Step 5: Remove Local ",[146,7396,7073],{},[452,7398,7399,7407],{"gap":454,"left-width":455,"right-width":455},[457,7400,7401,7403],{"v-slot:left":459},[20,7402,93],{},[74,7404],{"label":7405,"language":96,"src":7406},"delete-local-prod.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fdelete-local-prod.sh",[457,7408,7409,7411,7414],{"v-slot:right":459},[20,7410,3694],{},[74,7412],{"label":3554,"language":76,"src":7413},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fdelete-local-prod-output.txt",[24,7415,7416,7438],{},[27,7417,7418,7421,7422,7424],{},[146,7419,7420],{},"git branch -d prod",": delete local ",[146,7423,7073],{},[24,7425,7426,7432],{},[27,7427,7428,7431],{},[146,7429,7430],{},"-d",": delete only if Git considers it safe",[27,7433,7434,7437],{},[146,7435,7436],{},"-D",": can be used as a forced delete",[27,7439,7440,7443,7444],{},[146,7441,7442],{},"git branch -r",": list remote branches\n",[24,7445,7446],{},[27,7447,7448,7449,7452],{},"Confirms ",[146,7450,7451],{},"origin\u002Fprod"," still exists",[11,7454,7456,7459,7462,7465,7479,7482],{"id":7455,"level":14},"github-check",[16,7457,7458],{"id":7455},"GitHub Check",[20,7460,7461],{},"Open the branch dropdown on GitHub",[20,7463,7464],{},"You should see:",[24,7466,7467,7471,7475],{},[27,7468,7469],{},[146,7470,166],{},[27,7472,7473],{},[146,7474,7070],{},[27,7476,7477],{},[146,7478,7073],{},[20,7480,7481],{},"Branch roles:",[24,7483,7484,7489],{},[27,7485,7486,7488],{},[146,7487,7070],{},": testing and evidence",[27,7490,7491,7493],{},[146,7492,7073],{},": stable grading target",[11,7495,7497,7501],{"id":7496,"level":14},"normal-workflow",[16,7498,7500],{"id":7499},"normal-workflow-after-setup","Normal Workflow After Setup",[1137,7502,7503,7520,7528,7539,7544,7558,7561,7568,7580],{},[27,7504,7505,7506,7508],{},"Return to ",[146,7507,7070],{},[24,7509,7510,7515],{},[27,7511,7512],{},[146,7513,7514],{},"git checkout qa",[27,7516,7517],{},[146,7518,7519],{},"git pull origin qa",[27,7521,7522,7523],{},"Create a feature or homework branch\n",[24,7524,7525],{},[27,7526,7527],{},"Branch name matches the task",[27,7529,7530,7531],{},"Commit the work on that branch\n",[24,7532,7533],{},[27,7534,7535,7536,7538],{},"Check ",[146,7537,275],{}," before each Git command",[27,7540,7541,7542],{},"Push the branch and open a pull request into ",[146,7543,7070],{},[27,7545,7546,7547,7549,7550],{},"Merge into ",[146,7548,7070],{}," after review\n",[24,7551,7552],{},[27,7553,7554,7555,7557],{},"QA deployment will update from ",[146,7556,7070],{}," after Render setup",[27,7559,7560],{},"Test the QA version",[27,7562,7563,7564,6823,7566],{},"Open a pull request from ",[146,7565,7070],{},[146,7567,7073],{},[27,7569,7546,7570,7572,7573],{},[146,7571,7073],{}," when stable\n",[24,7574,7575],{},[27,7576,7577,7578,7557],{},"Production deployment will use ",[146,7579,7073],{},[27,7581,7582,7583,7585],{},"Return locally to ",[146,7584,7070],{}," and pull before the next task",[11,7587,7588,7590],{"id":779,"level":14},[16,7589,782],{"id":779},[24,7591,7592,7597,7602,7610,7618,7621],{},[27,7593,7594,7595],{},"Working directly on ",[146,7596,7073],{},[27,7598,7599,7600],{},"Forgetting to return to ",[146,7601,7070],{},[27,7603,7604,7605,7607,7608],{},"Pushing ",[146,7606,7070],{}," but not ",[146,7609,7073],{},[27,7611,7612,7613,7615,7616],{},"Deleting remote ",[146,7614,7073],{}," instead of local ",[146,7617,7073],{},[27,7619,7620],{},"Assuming GitHub has the branch without checking",[27,7622,7623,7624,765],{},"Starting new work before ",[146,7625,275],{},[11,7627,7628,7630,7633],{"id":1409,"level":14},[16,7629,1412],{"id":1409},[20,7631,7632],{},"Answer before moving on:",[24,7634,7635,7638,7641,7644,7650],{},[27,7636,7637],{},"Which branch should QA deployment watch?",[27,7639,7640],{},"Which branch should production grading use?",[27,7642,7643],{},"Which branch should you return to before new work?",[27,7645,7646,7647,7649],{},"Why remove local ",[146,7648,7073],{}," after pushing it?",[27,7651,7652],{},"What future setup connects Render to these branches?",[11,7654,7655,7657],{"id":812,"level":14},[16,7656,816],{"id":815},[452,7658,7659,7684],{"gap":454,"left-width":455,"right-width":455},[457,7660,7661,7663],{"v-slot:left":459},[249,7662,824],{"id":823},[24,7664,7665,7668,7671,7676,7681],{},[27,7666,7667],{},"Branch: named line of Git history",[27,7669,7670],{},"Upstream: remote branch Git remembers for push\u002Fpull",[27,7672,7673,7675],{},[146,7674,7070],{},": public testing branch",[27,7677,7678,7680],{},[146,7679,7073],{},": stable grading branch",[27,7682,7683],{},"Remote-only branch: exists on GitHub, not locally",[457,7685,7686,7688],{"v-slot:right":459},[249,7687,849],{"id":812},[24,7689,7690,7697,7704],{},[27,7691,871,7692],{},[856,7693,7696],{"href":7694,"rel":7695},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fget-started\u002Fusing-git\u002Fabout-git#about-branches",[860],"About branches",[27,7698,871,7699],{},[856,7700,7703],{"href":7701,"rel":7702},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fpull-requests\u002Fcollaborating-with-pull-requests\u002Fproposing-changes-to-your-work-with-pull-requests\u002Fabout-pull-requests",[860],"About pull requests",[27,7705,854,7706],{},[856,7707,7710],{"href":7708,"rel":7709},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Branching-Branches-in-a-Nutshell",[860],"Git Branching",[11,7712,7713,7715,7717],{"id":887,"level":14},[16,7714,890],{"id":887},[20,7716,900],{},[24,7718,7719,7728,7732,7736,7741],{},[27,7720,7721,7722,1582,7724,1585,7726],{},"Explain ",[146,7723,166],{},[146,7725,7070],{},[146,7727,7073],{},[27,7729,7076,7730],{},[146,7731,7070],{},[27,7733,7076,7734],{},[146,7735,7073],{},[27,7737,7738,7739],{},"Keep local work branched from ",[146,7740,7070],{},[27,7742,7743],{},"Verify remote branches on GitHub",{"title":459,"searchDepth":935,"depth":935,"links":7745},[7746,7747,7748,7749,7751,7753,7755,7757,7759,7760,7761,7762,7763,7764],{"id":13,"depth":935,"text":18},{"id":7093,"depth":935,"text":7096},{"id":1597,"depth":935,"text":1600},{"id":7166,"depth":935,"text":7750},"Step 1: Start From main",{"id":7220,"depth":935,"text":7752},"Step 2: Create And Push qa",{"id":7285,"depth":935,"text":7754},"Step 3: Create And Push prod",{"id":7340,"depth":935,"text":7756},"Step 4: Return To qa",{"id":7393,"depth":935,"text":7758},"Step 5: Remove Local prod",{"id":7455,"depth":935,"text":7458},{"id":7499,"depth":935,"text":7500},{"id":779,"depth":935,"text":782},{"id":1409,"depth":935,"text":1412},{"id":815,"depth":935,"text":816},{"id":887,"depth":935,"text":890},"Create the Internet Applications QA and production branches, then connect each branch to its role in the course workflow.","Face-to-face class of about 40 students; includes branch roles, command practice, GitHub branch checks, and QA\u002Fprod workflow questions.",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches",{"title":7054,"description":7765},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches",[988,989,7070,7772],"production","10:35","32XilHQwRiY","https:\u002F\u002Fyoutu.be\u002F32XilHQwRiY","Create QA and Prod Branches","GZx1sXtI0BMbyb6Gbpj7aoBvczhhR-FV7YpFE4j4UCs",{"id":7779,"title":7780,"audience":6,"body":7781,"contentType":971,"course":972,"description":8588,"estimateBasis":8589,"estimatedDiscussionMinutes":4524,"estimatedLiveMinutes":2546,"estimatedTotalMinutes":976,"extension":893,"meta":8590,"module":979,"navigation":980,"order":8591,"path":8592,"promptAssist":983,"seo":8593,"status":985,"stem":8594,"tags":8595,"videoDuration":8598,"videoId":8599,"videoLink":8600,"videoTitle":8601,"week":979,"__hash__":8602},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F08-render-setup.md","Render Setup",{"type":8,"value":7782,"toc":8567},[7783,7810,7833,7862,7930,7991,8026,8062,8099,8149,8195,8230,8276,8313,8341,8373,8420,8453,8521],[11,7784,7786,7789],{"id":7785,"level":14},"render-setup-title",[16,7787,7780],{"id":7788},"render-setup",[24,7790,7791,7794,7799,7804,7807],{},[27,7792,7793],{},"Connect GitHub repo to Render",[27,7795,7796,7797],{},"Create a QA service from ",[146,7798,7070],{},[27,7800,7801,7802],{},"Create a production service from ",[146,7803,7073],{},[27,7805,7806],{},"Add the course database connection string",[27,7808,7809],{},"Verify live URLs and deploy logs",[11,7811,7812,7814,7816],{"id":3452,"level":14},[16,7813,3455],{"id":3452},[20,7815,22],{},[24,7817,7818,7821,7824,7827,7830],{},[27,7819,7820],{},"Explain what Render does in the course workflow",[27,7822,7823],{},"Create separate QA and production services",[27,7825,7826],{},"Connect each service to the correct branch",[27,7828,7829],{},"Read Render logs when a deploy fails",[27,7831,7832],{},"Identify which deployed URL to submit or test",[11,7834,7836,7839,7856],{"id":7835,"level":14},"what-render-does",[16,7837,7838],{"id":7835},"What Render Does",[24,7840,7841,7844,7847,7850,7853],{},[27,7842,7843],{},"Hosts your PHP app from GitHub",[27,7845,7846],{},"Watches a selected branch",[27,7848,7849],{},"Rebuilds when that branch changes",[27,7851,7852],{},"Stores secrets as environment variables",[27,7854,7855],{},"Gives each service a public URL",[20,7857,7858,7859],{},"Course loop: ",[146,7860,7861],{},"local work -> GitHub branch -> Render URL",[11,7863,7865,7867],{"id":7864,"level":14},"free-tier-and-before-start",[16,7866,1600],{"id":1597},[452,7868,7869,7898],{"gap":454,"left-width":455,"right-width":455},[457,7870,7871,7875],{"v-slot:left":459},[249,7872,7874],{"id":7873},"free-tier","Free Tier",[24,7876,7877,7887,7895],{},[27,7878,3620,7879,7882],{},[146,7880,7881],{},"Free",[24,7883,7884],{},[27,7885,7886],{},"Render may default to a paid plan",[27,7888,7889,7890],{},"Free services can sleep",[24,7891,7892],{},[27,7893,7894],{},"First visit after sleep may be slow",[27,7896,7897],{},"Avoid extra services unless instructed",[457,7899,7900,7904],{"v-slot:right":459},[249,7901,7903],{"id":7902},"repo-ready","Repo Ready",[24,7905,7906,7909,7914,7923],{},[27,7907,7908],{},"Starter files committed and pushed",[27,7910,7911,7913],{},[146,7912,6278],{}," in repo root",[27,7915,7916,1582,7918,1585,7920,7922],{},[146,7917,1783],{},[146,7919,6186],{},[146,7921,6189],{}," present",[27,7924,7925,149,7927,7929],{},[146,7926,7070],{},[146,7928,7073],{}," branches exist on GitHub",[11,7931,7933,7936],{"id":7932,"level":14},"target-architecture",[16,7934,7935],{"id":7932},"Target Architecture",[452,7937,7938,7966],{"gap":454,"left-width":455,"right-width":455},[457,7939,7940,7944],{"v-slot:left":459},[249,7941,7943],{"id":7942},"qa-service","QA Service",[24,7945,7946,7952,7957,7960],{},[27,7947,7948,7949],{},"Name: ",[146,7950,7951],{},"\u003Cucid>-it202-\u003Csection>-qa",[27,7953,7954,7955],{},"Watches ",[146,7956,7070],{},[27,7958,7959],{},"Used for testing and evidence",[27,7961,7962,7963],{},"URL ends with ",[146,7964,7965],{},"-qa.onrender.com",[457,7967,7968,7972],{"v-slot:right":459},[249,7969,7971],{"id":7970},"production-service","Production Service",[24,7973,7974,7979,7983,7986],{},[27,7975,7948,7976],{},[146,7977,7978],{},"\u003Cucid>-it202-\u003Csection>-prod",[27,7980,7954,7981],{},[146,7982,7073],{},[27,7984,7985],{},"Stable version after QA checks",[27,7987,7962,7988],{},[146,7989,7990],{},"-prod.onrender.com",[11,7992,7994,7998],{"id":7993,"level":14},"step-1-sign-up",[16,7995,7997],{"id":7996},"step-1-sign-up-with-github","Step 1: Sign Up With GitHub",[452,7999,8000,8018],{"gap":454,"left-width":3156,"right-width":3155},[457,8001,8002],{"v-slot:left":459},[24,8003,8004,8009,8012,8015],{},[27,8005,2627,8006],{},[146,8007,8008],{},"render.com",[27,8010,8011],{},"Choose GitHub sign-in",[27,8013,8014],{},"Authorize Render when prompted",[27,8016,8017],{},"Land on the Render dashboard",[457,8019,8020],{"v-slot:right":459},[20,8021,8022],{},[491,8023],{"alt":8024,"src":8025,"variant":495},"Render GitHub sign-in screen","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-01-github-signin.png",[11,8027,8029,8032],{"id":8028,"level":14},"step-2-new-web-service",[16,8030,8031],{"id":8028},"Step 2: New Web Service",[452,8033,8034,8054],{"gap":454,"left-width":3156,"right-width":3155},[457,8035,8036],{"v-slot:left":459},[24,8037,8038,8043,8048,8051],{},[27,8039,1144,8040],{},[146,8041,8042],{},"New +",[27,8044,3620,8045],{},[146,8046,8047],{},"Web Service",[27,8049,8050],{},"Do not choose a database service here",[27,8052,8053],{},"This creates the hosted PHP app",[457,8055,8056],{"v-slot:right":459},[20,8057,8058],{},[491,8059],{"alt":8060,"src":8061,"variant":495},"Render New menu with Web Service option","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-04-new-menu.png",[11,8063,8065,8069],{"id":8064,"level":14},"step-3-connect-repo",[16,8066,8068],{"id":8067},"step-3-connect-repository","Step 3: Connect Repository",[452,8070,8071,8091],{"gap":454,"left-width":2653,"right-width":3196},[457,8072,8073],{"v-slot:left":459},[24,8074,8075,8078,8081,8088],{},[27,8076,8077],{},"Select your student course repository",[27,8079,8080],{},"Authorize repository access if Render asks",[27,8082,8083,8084,8087],{},"Ensure it's the proper repository (format: ",[146,8085,8086],{},"ucid-course-section-semYear",")",[27,8089,8090],{},"Continue to service settings",[457,8092,8093],{"v-slot:right":459},[20,8094,8095],{},[491,8096],{"alt":8097,"src":8098,"variant":495},"Render repository selection screen","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-07-select-repo.png",[11,8100,8102,8106],{"id":8101,"level":14},"step-4-configure-qa",[16,8103,8105],{"id":8104},"step-4-configure-qa-service","Step 4: Configure QA Service",[452,8107,8108,8141],{"gap":454,"left-width":3156,"right-width":3155},[457,8109,8110,8113],{"v-slot:left":459},[20,8111,8112],{},"Use these settings:",[24,8114,8115,8119,8124,8130,8135,8138],{},[27,8116,7948,8117],{},[146,8118,7951],{},[27,8120,8121,8122],{},"Branch: ",[146,8123,7070],{},[27,8125,8126,8127],{},"Runtime: ",[146,8128,8129],{},"Docker",[27,8131,8132,8133],{},"Instance type: ",[146,8134,7881],{},[27,8136,8137],{},"Root directory: blank",[27,8139,8140],{},"Build\u002Fstart commands: blank",[457,8142,8143],{"v-slot:right":459},[20,8144,8145],{},[491,8146],{"alt":8147,"src":8148,"variant":495},"Render QA service configuration","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-08-qa-config-basic.png",[11,8150,8152,8156],{"id":8151,"level":14},"step-5-env-vars",[16,8153,8155],{"id":8154},"step-5-add-environment-variables","Step 5: Add Environment Variables",[452,8157,8158,8187],{"gap":454,"left-width":3605,"right-width":5511},[457,8159,8160],{"v-slot:left":459},[24,8161,8162,8175,8181,8184],{},[27,8163,8164,8165,8167],{},"Add ",[146,8166,6629],{},[24,8168,8169],{},[27,8170,8171,8172],{},"Get it from ",[856,8173,6634],{"href":5479,"rel":8174},[860],[27,8176,8177,8178,8180],{},"Do not use \"add from ",[146,8179,6610],{},"\"",[27,8182,8183],{},"Add later API keys only when a later lesson requires them",[27,8185,8186],{},"Repeat required env vars on both QA and production",[457,8188,8189],{"v-slot:right":459},[20,8190,8191],{},[491,8192],{"alt":8193,"src":8194,"variant":495},"Render environment variables section","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-09-env-vars.png",[11,8196,8198,8201],{"id":8197,"level":14},"step-6-deploy-qa",[16,8199,8200],{"id":8197},"Step 6: Deploy QA",[452,8202,8203,8222],{"gap":454,"left-width":2653,"right-width":3196},[457,8204,8205],{"v-slot:left":459},[24,8206,8207,8210,8213,8216,8219],{},[27,8208,8209],{},"Create the QA service",[27,8211,8212],{},"Watch the first deploy log",[27,8214,8215],{},"Wait for a success state",[27,8217,8218],{},"Open the QA URL",[27,8220,8221],{},"Confirm the starter page loads",[457,8223,8224],{"v-slot:right":459},[20,8225,8226],{},[491,8227],{"alt":8228,"src":8229,"variant":495},"Successful Render QA deployment","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-10-qa-deployed.png",[11,8231,8233,8237],{"id":8232,"level":14},"step-7-create-prod",[16,8234,8236],{"id":8235},"step-7-create-production-service","Step 7: Create Production Service",[452,8238,8239,8268],{"gap":454,"left-width":3156,"right-width":3155},[457,8240,8241,8244],{"v-slot:left":459},[20,8242,8243],{},"Create a second web service:",[24,8245,8246,8249,8253,8257,8261,8265],{},[27,8247,8248],{},"Same repository",[27,8250,7948,8251],{},[146,8252,7978],{},[27,8254,8121,8255],{},[146,8256,7073],{},[27,8258,8126,8259],{},[146,8260,8129],{},[27,8262,8132,8263],{},[146,8264,7881],{},[27,8266,8267],{},"Same required env vars",[457,8269,8270],{"v-slot:right":459},[20,8271,8272],{},[491,8273],{"alt":8274,"src":8275,"variant":495},"Render production service configuration","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-11-prod-config.png",[11,8277,8278,8281],{"id":7496,"level":14},[16,8279,8280],{"id":7496},"Normal Workflow",[1137,8282,8283,8286,8289,8294,8297,8300,8303,8310],{},[27,8284,8285],{},"Work locally on a feature or homework branch",[27,8287,8288],{},"Commit and push that branch to GitHub",[27,8290,8291,8292],{},"Open a pull request into ",[146,8293,7070],{},[27,8295,8296],{},"Merge after review",[27,8298,8299],{},"Render updates the QA URL",[27,8301,8302],{},"Test the QA URL",[27,8304,7563,8305,6823,8307,8309],{},[146,8306,7070],{},[146,8308,7073],{}," after evidence gathering",[27,8311,8312],{},"Render updates the production URL",[11,8314,8316,8319],{"id":8315,"level":14},"urls-and-cold-starts",[16,8317,8318],{"id":8315},"URLs And Cold Starts",[24,8320,8321,8324,8327,8330,8338],{},[27,8322,8323],{},"QA URL shows the test deployment",[27,8325,8326],{},"Production URL shows the stable deployment",[27,8328,8329],{},"Homework evidence usually starts with QA",[27,8331,8332,8333],{},"Free services may sleep after inactivity\n",[24,8334,8335],{},[27,8336,8337],{},"First visit after sleep may take extra time (2 - 5 minutes)",[27,8339,8340],{},"Do not submit before Render finishes deploying",[11,8342,8344,8347],{"id":8343,"level":14},"logs-and-status",[16,8345,8346],{"id":8343},"Logs And Status",[452,8348,8349,8365],{"gap":454,"left-width":2653,"right-width":3196},[457,8350,8351],{"v-slot:left":459},[24,8352,8353,8356,8359,8362],{},[27,8354,8355],{},"Logs show build and startup output",[27,8357,8358],{},"Dashboard status shows deploy progress",[27,8360,8361],{},"Failed deploys usually show the first useful clue",[27,8363,8364],{},"Read the first clear error before changing settings",[457,8366,8367],{"v-slot:right":459},[20,8368,8369],{},[491,8370],{"alt":8371,"src":8372,"variant":495},"Render deploy logs","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-12-logs.png",[11,8374,8376,8379],{"id":8375,"level":14},"troubleshooting",[16,8377,8378],{"id":8375},"Troubleshooting",[24,8380,8381,8391,8399,8409],{},[27,8382,8383,8384],{},"Build fails\n",[24,8385,8386],{},[27,8387,7535,8388,8390],{},[146,8389,6278],{},", root directory, runtime, and instance type",[27,8392,8393,8394],{},"App deploys but page fails\n",[24,8395,8396],{},[27,8397,8398],{},"Check logs for PHP errors",[27,8400,8401,8402],{},"Database connection fails\n",[24,8403,8404],{},[27,8405,7535,8406,8408],{},[146,8407,6629],{}," spelling and copied value",[27,8410,8411,8412],{},"Wrong version appears\n",[24,8413,8414,8417],{},[27,8415,8416],{},"Confirm the service watches the expected branch",[27,8418,8419],{},"Clear browser cache or test in a private window",[11,8421,8422,8424],{"id":779,"level":14},[16,8423,782],{"id":779},[24,8425,8426,8436,8439,8444,8447,8450],{},[27,8427,8428,8429,8431,8432,803,8434],{},"Choosing ",[146,8430,166],{}," instead of ",[146,8433,7070],{},[146,8435,7073],{},[27,8437,8438],{},"Creating one service for both environments",[27,8440,8441,8442],{},"Forgetting ",[146,8443,6629],{},[27,8445,8446],{},"Using a paid instance type by accident",[27,8448,8449],{},"Checking GitHub but not the Render URL",[27,8451,8452],{},"Changing code locally but forgetting to push and merge",[11,8454,8455,8457],{"id":815,"level":14},[16,8456,816],{"id":815},[452,8458,8459,8487],{"gap":454,"left-width":455,"right-width":455},[457,8460,8461,8463,8469,8475,8481],{"v-slot:left":459},[249,8462,824],{"id":823},[20,8464,8465,8468],{},[1102,8466,8467],{},"Service"," - one deployed app on Render",[20,8470,8471,8474],{},[1102,8472,8473],{},"Watched branch"," - Git branch Render deploys from",[20,8476,8477,8480],{},[1102,8478,8479],{},"Environment variable"," - setting stored outside code",[20,8482,8483,8486],{},[1102,8484,8485],{},"Deploy log"," - output from Render's build\u002Fstart process",[457,8488,8489,8491],{"v-slot:right":459},[249,8490,849],{"id":812},[24,8492,8493,8500,8507,8514],{},[27,8494,8495],{},[856,8496,8499],{"href":8497,"rel":8498},"https:\u002F\u002Frender.com\u002Fdocs\u002Fweb-services",[860],"Render Docs: Web Services",[27,8501,8502],{},[856,8503,8506],{"href":8504,"rel":8505},"https:\u002F\u002Frender.com\u002Fdocs\u002Fdeploys",[860],"Render Docs: Deploys",[27,8508,8509],{},[856,8510,8513],{"href":8511,"rel":8512},"https:\u002F\u002Frender.com\u002Fdocs\u002Fconfigure-environment-variables",[860],"Render Docs: Environment Variables",[27,8515,8516],{},[856,8517,8520],{"href":8518,"rel":8519},"https:\u002F\u002Frender.com\u002Fdocs\u002Ffree",[860],"Render Docs: Free Instance Types",[11,8522,8523,8525,8528],{"id":887,"level":14},[16,8524,890],{"id":887},[20,8526,8527],{},"Before leaving this presentation, confirm you:",[24,8529,8530,8533,8536,8543,8546,8549],{},[27,8531,8532],{},"Created QA and production Render services",[27,8534,8535],{},"Matched each service to the correct branch",[27,8537,8538,8539,6630,8541],{},"Added ",[146,8540,6629],{},[146,8542,6634],{},[27,8544,8545],{},"Opened each deployed URL",[27,8547,8548],{},"Read logs instead of assuming it worked",[27,8550,8551,8552],{},"Understand the local -> GitHub -> Render loop\n",[24,8553,8554,8557,8562],{},[27,8555,8556],{},"Majority of your work will be done locally and tested locally",[27,8558,8559,8561],{},[146,8560,7070],{}," is just for gathering evidence for submissions",[27,8563,8564,8566],{},[146,8565,7073],{}," is what will be verified during grading",{"title":459,"searchDepth":935,"depth":935,"links":8568},[8569,8570,8571,8572,8573,8574,8575,8576,8577,8578,8579,8580,8581,8582,8583,8584,8585,8586,8587],{"id":7788,"depth":935,"text":7780},{"id":3452,"depth":935,"text":3455},{"id":7835,"depth":935,"text":7838},{"id":1597,"depth":935,"text":1600},{"id":7932,"depth":935,"text":7935},{"id":7996,"depth":935,"text":7997},{"id":8028,"depth":935,"text":8031},{"id":8067,"depth":935,"text":8068},{"id":8104,"depth":935,"text":8105},{"id":8154,"depth":935,"text":8155},{"id":8197,"depth":935,"text":8200},{"id":8235,"depth":935,"text":8236},{"id":7496,"depth":935,"text":8280},{"id":8315,"depth":935,"text":8318},{"id":8343,"depth":935,"text":8346},{"id":8375,"depth":935,"text":8378},{"id":779,"depth":935,"text":782},{"id":815,"depth":935,"text":816},{"id":887,"depth":935,"text":890},"Connect the course repository to Render, create QA and production services, and verify the deploy loop from GitHub to a live URL.","Face-to-face class of about 40 students; includes Render account setup, QA\u002Fprod service creation, environment variables, deploy verification, and first troubleshooting pass.",{},"80","\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F08-render-setup",{"title":7780,"description":8588},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F08-render-setup",[8596,8597,7070,7772],"render","deployment","21:42","esZd5RIpqCQ","https:\u002F\u002Fyoutu.be\u002FesZd5RIpqCQ","Render.com Setup (QA and Prod)","_1jV7vdhppggQ8TAOecx_1jFvjG90__8eGGlaXbnc28",{"id":8604,"title":8605,"audience":6,"body":8606,"contentType":971,"course":972,"description":11280,"estimateBasis":11281,"estimatedDiscussionMinutes":11282,"estimatedLiveMinutes":11283,"estimatedTotalMinutes":11284,"extension":893,"meta":11285,"module":979,"navigation":980,"order":977,"path":11286,"promptAssist":983,"seo":11287,"status":985,"stem":11288,"tags":11289,"videoDuration":11294,"videoId":11295,"videoLink":11296,"videoTitle":11297,"week":979,"__hash__":11298},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox.md","Local Ubuntu Web Server With VirtualBox",{"type":8,"value":8607,"toc":11212},[8608,8637,8682,8718,8787,8819,8846,8878,8904,8933,8962,8989,9020,9048,9084,9149,9184,9230,9273,9317,9364,9427,9463,9498,9535,9568,9605,9638,9668,9698,9728,9758,9788,9822,9854,9886,9918,9967,9969,10012,10038,10079,10131,10210,10261,10292,10322,10352,10402,10427,10477,10525,10583,10641,10682,10712,10746,10780,10814,10865,10917,10936,10964,11012,11084,11184],[11,8609,8611,8614],{"id":8610,"level":14},"virtualbox-title",[16,8612,8605],{"id":8613},"local-ubuntu-web-server-with-virtualbox",[24,8615,8616,8619,8622,8625,8628,8634],{},[27,8617,8618],{},"Primary course path for the local Ubuntu VM",[27,8620,8621],{},"Create an Ubuntu Server VM in VirtualBox",[27,8623,8624],{},"Connect from your host terminal with SSH",[27,8626,8627],{},"Share the course repo into Ubuntu",[27,8629,8630,8631,8633],{},"Serve ",[146,8632,1783],{}," through Apache and PHP",[27,8635,8636],{},"Create a local MySQL database for testing",[11,8638,8640,8643,8646,8657,8660],{"id":8639,"level":14},"main-goal",[16,8641,8642],{"id":8639},"Main Goal",[20,8644,8645],{},"Your host computer and Ubuntu VM have different jobs:",[24,8647,8648,8651,8654],{},[27,8649,8650],{},"Host computer: edit files with VS Code and open the browser",[27,8652,8653],{},"Ubuntu VM: run Apache, PHP, MySQL, and server commands",[27,8655,8656],{},"Shared folder: lets both use the same course repo files",[20,8658,8659],{},"Target result:",[24,8661,8662,8668,8673,8676,8679],{},[27,8663,8664,8665],{},"Host browser opens ",[146,8666,8667],{},"http:\u002F\u002Flocalhost:3000",[27,8669,8670,8671],{},"Apache serves the repo's ",[146,8672,1783],{},[27,8674,8675],{},"PHP executes inside Ubuntu",[27,8677,8678],{},"Local MySQL has a database and user named after your UCID",[27,8680,8681],{},"Edits made on the host appear after browser refresh",[11,8683,8685,8688,8691,8710,8713],{"id":8684,"level":14},"virtualbox-caveat",[16,8686,8687],{"id":8684},"VirtualBox Caveat",[20,8689,8690],{},"VirtualBox is the primary local VM path for this course:",[24,8692,8693,8696,8699,8707],{},[27,8694,8695],{},"Works well on modern Windows, Linux, and Intel Mac hosts",[27,8697,8698],{},"Apple Silicon Mac requires an ARM64 Ubuntu Server ISO",[27,8700,8701,8702],{},"Windows on Arm support is experimental in VirtualBox\n",[24,8703,8704],{},[27,8705,8706],{},"Avoid unless your instructor confirms it for your machine",[27,8708,8709],{},"Arm hosts cannot run x86\u002FAMD64 guest images",[20,8711,8712],{},"VMware is the fallback path if VirtualBox is not a good fit for your machine",[2868,8714,8715],{"type":4141},[20,8716,8717],{},"Most students do not need BIOS changes. If VirtualBox cannot start the VM or does not offer a 64-bit Ubuntu option, check that Intel VT-x, AMD-V, or SVM is enabled in BIOS\u002FUEFI. On Windows, Hyper-V-related features can also interfere on some systems.",[11,8719,8720,8722],{"id":1597,"level":14},[16,8721,1600],{"id":1597},[24,8723,8724,8742,8760,8763,8766,8769,8784],{},[27,8725,8726,8727],{},"VirtualBox downloaded\n",[24,8728,8729,8736,8739],{},[27,8730,8731],{},[856,8732,8735],{"href":8733,"rel":8734},"https:\u002F\u002Fwww.virtualbox.org\u002Fwiki\u002FDownloads",[860],"VirtualBox downloads",[27,8737,8738],{},"Windows\u002FLinux\u002FIntel Mac: use the standard host installer",[27,8740,8741],{},"Apple Silicon Mac: use the macOS Arm64 host installer",[27,8743,8744,8745],{},"Ubuntu Server ISO downloaded\n",[24,8746,8747,8754,8757],{},[27,8748,8749],{},[856,8750,8753],{"href":8751,"rel":8752},"https:\u002F\u002Fubuntu.com\u002Fdownload\u002Fserver#how-to-install-tab-lts",[860],"Ubuntu Server installer",[27,8755,8756],{},"Apple Silicon Mac: use the ARM64 server ISO",[27,8758,8759],{},"Windows, Linux, and Intel Mac: use the AMD64 server ISO",[27,8761,8762],{},"Internet Applications course repo cloned on host computer",[27,8764,8765],{},"Git\u002FGitHub setup already working",[27,8767,8768],{},"Administrator access on your computer",[27,8770,8771,8772,8775,8776],{},"At least ",[146,8773,8774],{},"10 GB"," free disk space for the VM\n",[24,8777,8778],{},[27,8779,8780,8783],{},[146,8781,8782],{},"20-25 GB"," is safer if your computer has room",[27,8785,8786],{},"Stable internet for package installs",[11,8788,8790,8793],{"id":8789,"level":14},"setup-parts",[16,8791,8792],{"id":8789},"Setup Parts",[24,8794,8795,8798,8801,8804,8810,8813,8816],{},[27,8796,8797],{},"VM: Ubuntu Server running inside VirtualBox",[27,8799,8800],{},"NAT adapter: gives the VM internet access",[27,8802,8803],{},"Port forwarding: lets the host reach SSH and Apache",[27,8805,8806,8807],{},"SSH: lets the host terminal control Ubuntu through ",[146,8808,8809],{},"localhost",[27,8811,8812],{},"Shared folder: exposes the host repo inside Ubuntu",[27,8814,8815],{},"Apache\u002FPHP: serves and executes the web app",[27,8817,8818],{},"MySQL: local database server for local testing",[11,8820,8822,8826],{"id":8821,"level":14},"install-virtualbox-windows",[16,8823,8825],{"id":8824},"install-virtualbox-on-windows","Install VirtualBox On Windows",[24,8827,8828,8831,8834,8837,8840,8843],{},[27,8829,8830],{},"Download VirtualBox for Windows hosts",[27,8832,8833],{},"Run the installer as an administrator if prompted",[27,8835,8836],{},"Keep the default install path and features",[27,8838,8839],{},"Accept the network reset warning",[27,8841,8842],{},"Open VirtualBox after installation",[27,8844,8845],{},"See the slides below for the Windows installer screens",[11,8847,8849,8852],{"id":8848,"level":247},"windows-installer-start",[16,8850,8851],{"id":8848},"Windows Installer: Start",[452,8853,8854,8862],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,8855,8856],{"v-slot:left":459},[20,8857,8858],{},[491,8859],{"alt":8860,"src":8861,"variant":495},"VirtualBox Windows installer start screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step1.png",[457,8863,8864],{"v-slot:right":459},[24,8865,8866,8872,8875],{},[27,8867,8868,8869],{},"Launch the downloaded ",[146,8870,8871],{},".exe",[27,8873,8874],{},"Approve the Windows security prompt if shown",[27,8876,8877],{},"Start the setup wizard",[11,8879,8881,8884],{"id":8880,"level":247},"windows-installer-features",[16,8882,8883],{"id":8880},"Windows Installer: Features",[452,8885,8886,8894],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,8887,8888],{"v-slot:left":459},[20,8889,8890],{},[491,8891],{"alt":8892,"src":8893,"variant":495},"VirtualBox Windows installer feature selection screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step2.png",[457,8895,8896],{"v-slot:right":459},[24,8897,8898,8901],{},[27,8899,8900],{},"Keep the default install location",[27,8902,8903],{},"Keep the default features selected",[11,8905,8907,8910],{"id":8906,"level":247},"windows-installer-network-warning",[16,8908,8909],{"id":8906},"Windows Installer: Network Warning",[452,8911,8912,8920],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,8913,8914],{"v-slot:left":459},[20,8915,8916],{},[491,8917],{"alt":8918,"src":8919,"variant":495},"VirtualBox Windows installer network warning","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step3.png",[457,8921,8922],{"v-slot:right":459},[24,8923,8924,8927,8930],{},[27,8925,8926],{},"VirtualBox may reset network adapters briefly",[27,8928,8929],{},"This is expected during install",[27,8931,8932],{},"Save web work before continuing if needed",[11,8934,8936,8939],{"id":8935,"level":247},"windows-installer-ready",[16,8937,8938],{"id":8935},"Windows Installer: Ready",[452,8940,8941,8949],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,8942,8943],{"v-slot:left":459},[20,8944,8945],{},[491,8946],{"alt":8947,"src":8948,"variant":495},"VirtualBox Windows installer ready screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step4.png",[457,8950,8951],{"v-slot:right":459},[24,8952,8953,8956,8959],{},[27,8954,8955],{},"Start the installation",[27,8957,8958],{},"Keep the default choices",[27,8960,8961],{},"Wait for the installer to request permissions if needed",[11,8963,8965,8969],{"id":8964,"level":247},"windows-installer-progress",[16,8966,8968],{"id":8967},"windows-installer-start-options","Windows Installer: Start Options",[452,8970,8971,8979],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,8972,8973],{"v-slot:left":459},[20,8974,8975],{},[491,8976],{"alt":8977,"src":8978,"variant":495},"VirtualBox Windows installer progress screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step5.png",[457,8980,8981],{"v-slot:right":459},[24,8982,8983,8986],{},[27,8984,8985],{},"No need to create a Start Menu item or desktop shortcut unless desired",[27,8987,8988],{},"Third option is likely optional too since we'll be using the VirtualBox Manager",[11,8990,8992,8995],{"id":8991,"level":247},"windows-installer-permission",[16,8993,8994],{"id":8991},"Windows Installer: Permission",[452,8996,8997,9005],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,8998,8999],{"v-slot:left":459},[20,9000,9001],{},[491,9002],{"alt":9003,"src":9004,"variant":495},"VirtualBox Windows installer permission prompt","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step6.png",[457,9006,9007],{"v-slot:right":459},[24,9008,9009,9012],{},[27,9010,9011],{},"Proceed with install",[27,9013,9014,9015],{},"Approve VirtualBox driver prompts\n",[24,9016,9017],{},[27,9018,9019],{},"These let VirtualBox create virtual hardware",[11,9021,9023,9026],{"id":9022,"level":247},"windows-installer-complete",[16,9024,9025],{"id":9022},"Windows Installer: Complete",[452,9027,9028,9036],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,9029,9030],{"v-slot:left":459},[20,9031,9032],{},[491,9033],{"alt":9034,"src":9035,"variant":495},"VirtualBox Windows installer completion screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step7.png",[457,9037,9038],{"v-slot:right":459},[24,9039,9040,9042,9045],{},[27,9041,3016],{},[27,9043,9044],{},"Open VirtualBox",[27,9046,9047],{},"Continue to VM creation",[11,9049,9051,9055],{"id":9050,"level":14},"install-virtualbox-macos",[16,9052,9054],{"id":9053},"install-virtualbox-on-macos","Install VirtualBox On macOS",[452,9056,9057,9076],{"gap":454,"left-width":3605,"right-width":5511,"stack":2654},[457,9058,9059],{"v-slot:left":459},[24,9060,9061,9064,9067,9070,9073],{},[27,9062,9063],{},"Install the VirtualBox host package for your Mac CPU type",[27,9065,9066],{},"Intel Mac: standard macOS host installer",[27,9068,9069],{},"Apple Silicon Mac: Arm64 host installer and Arm64 Ubuntu Server ISO",[27,9071,9072],{},"Approve macOS security prompts if needed",[27,9074,9075],{},"If VirtualBox is not a good fit, use the VMware fallback lesson",[457,9077,9078],{"v-slot:right":459},[20,9079,9080],{},[491,9081],{"alt":9082,"src":9083,"variant":495},"Summary of macOS VirtualBox setup notes","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvm_summary_mac.png",[11,9085,9087,9091,9094],{"id":9086,"level":14},"step-1-create-vm",[16,9088,9090],{"id":9089},"step-1-create-the-vm","Step 1: Create The VM",[20,9092,9093],{},"Create a lightweight Ubuntu Server VM:",[24,9095,9096,9099,9107,9122,9134,9140,9143,9146],{},[27,9097,9098],{},"Type: Linux",[27,9100,9101,9102],{},"Version: Ubuntu 64-bit or Ubuntu Arm64\n",[24,9103,9104],{},[27,9105,9106],{},"Match the version to the ISO you downloaded",[27,9108,9109,9110,9113,9114],{},"Memory: ",[146,9111,9112],{},"1 GB"," course target\n",[24,9115,9116],{},[27,9117,304,9118,9121],{},[146,9119,9120],{},"1.5-2 GB"," if the installer is too slow or refuses to continue (you shouldn't need to do this)",[27,9123,9124,9125,9127,9128],{},"Disk: ",[146,9126,8774],{}," course minimum\n",[24,9129,9130],{},[27,9131,9132,8783],{},[146,9133,8782],{},[27,9135,9136,9137,9139],{},"CPU: ",[146,9138,979],{}," core is enough for this course VM",[27,9141,9142],{},"Enable OpenSSH during install if prompted",[27,9144,9145],{},"Username: use your UCID",[27,9147,9148],{},"See the slides below for VM settings and Ubuntu install screens",[11,9150,9152,9155],{"id":9151,"level":247},"vm-setup-name-and-iso",[16,9153,9154],{"id":9151},"VM Setup: Name And ISO",[452,9156,9157,9165],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,9158,9159],{"v-slot:left":459},[20,9160,9161],{},[491,9162],{"alt":9163,"src":9164,"variant":495},"VirtualBox VM name and ISO setup","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_1.png",[457,9166,9167],{"v-slot:right":459},[24,9168,9169,9172,9178,9181],{},[27,9170,9171],{},"Start a new virtual machine",[27,9173,9174,9175],{},"Name it clearly, such as ",[146,9176,9177],{},"it202-vm",[27,9179,9180],{},"Choose the Ubuntu Server ISO file next",[27,9182,9183],{},"OS fields may look wrong until the ISO is selected",[11,9185,9187,9190],{"id":9186,"level":247},"vm-setup-confirm-ubuntu-iso",[16,9188,9189],{"id":9186},"VM Setup: Confirm Ubuntu ISO",[452,9191,9192,9200],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,9193,9194],{"v-slot:left":459},[20,9195,9196],{},[491,9197],{"alt":9198,"src":9199,"variant":495},"VirtualBox VM name and Ubuntu ISO selected","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_2.png",[457,9201,9202],{"v-slot:right":459},[24,9203,9204,9210,9216,9219],{},[27,9205,9206,9207],{},"Confirm OS is ",[146,9208,9209],{},"Linux",[27,9211,9212,9213],{},"Confirm distribution is ",[146,9214,9215],{},"Ubuntu",[27,9217,9218],{},"Confirm version matches your ISO",[27,9220,2672,9221,9224,9225],{},[146,9222,9223],{},"Unattended Installation"," off\n",[24,9226,9227],{},[27,9228,9229],{},"The Ubuntu installer screens are easier to teach manually",[11,9231,9233,9236],{"id":9232,"level":247},"vm-setup-memory-and-cpu",[16,9234,9235],{"id":9232},"VM Setup: Memory And CPU",[452,9237,9238,9246],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,9239,9240],{"v-slot:left":459},[20,9241,9242],{},[491,9243],{"alt":9244,"src":9245,"variant":495},"VirtualBox VM memory and CPU settings","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_4.png",[457,9247,9248],{"v-slot:right":459},[24,9249,9250,9263,9267,9270],{},[27,9251,9109,9252,9113,9255],{},[146,9253,9254],{},"1024 MB",[24,9256,9257,9260],{},[27,9258,9259],{},"The goal is to match free-tier cloud services",[27,9261,9262],{},"Demonstrates that small apps can run with limited resources",[27,9264,9136,9265],{},[146,9266,979],{},[27,9268,9269],{},"Keep EFI off unless your machine requires it",[27,9271,9272],{},"This VM is for Apache, PHP, MySQL, and local development\u002Ftesting",[11,9274,9276,9279],{"id":9275,"level":247},"vm-setup-virtual-disk",[16,9277,9278],{"id":9275},"VM Setup: Virtual Disk",[452,9280,9281,9289],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,9282,9283],{"v-slot:left":459},[20,9284,9285],{},[491,9286],{"alt":9287,"src":9288,"variant":495},"VirtualBox virtual hard disk settings","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_5.png",[457,9290,9291],{"v-slot:right":459},[24,9292,9293,9299,9302,9314],{},[27,9294,9295,9296],{},"Disk type: ",[146,9297,9298],{},"VDI",[27,9300,9301],{},"Storage: dynamically allocated",[27,9303,9304,9305,9307],{},"Minimum: ",[146,9306,8774],{},[24,9308,9309],{},[27,9310,9311,9313],{},[146,9312,8782],{}," is safer if you have room",[27,9315,9316],{},"Dynamic disk uses space as needed, not all at once",[11,9318,9320,9323],{"id":9319,"level":247},"vm-setup-start-with-gui",[16,9321,9322],{"id":9319},"VM Setup: Start With GUI",[452,9324,9325,9333],{"gap":454,"left-width":2652,"right-width":2653,"stack":2654},[457,9326,9327],{"v-slot:left":459},[20,9328,9329],{},[491,9330],{"alt":9331,"src":9332,"variant":495},"VirtualBox VM selected with the Start button visible","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_6.png",[457,9334,9335],{"v-slot:right":459},[24,9336,9337,9340,9350,9353],{},[27,9338,9339],{},"Select the newly created VM",[27,9341,1144,9342,9345],{},[146,9343,9344],{},"Start",[24,9346,9347],{},[27,9348,9349],{},"Choose the normal GUI start for the first boot",[27,9351,9352],{},"Complete the Ubuntu installer in the VM window",[27,9354,9355,9356],{},"After install and SSH setup, future starts can be headless\n",[24,9357,9358],{},[27,9359,9360,9361,9363],{},"You will connect with ",[146,9362,4532],{}," when you need the VM",[11,9365,9367,9371,9374],{"id":9366,"level":14},"ubuntu-installer",[16,9368,9370],{"id":9369},"step-2-ubuntu-installer","Step 2: Ubuntu Installer",[20,9372,9373],{},"Use the Ubuntu Server installer after the VM starts:",[24,9375,9376,9379,9382,9385,9388,9391,9424],{},[27,9377,9378],{},"Choose the default course options unless noted",[27,9380,9381],{},"Continue without updating the installer if instructed",[27,9383,9384],{},"Use your UCID for the Ubuntu username",[27,9386,9387],{},"Install OpenSSH server during setup",[27,9389,9390],{},"Skip optional server snaps",[27,9392,9393,9394],{},"Keyboard navigation:\n",[24,9395,9396,9403,9413,9419],{},[27,9397,9398,9402],{},[9399,9400,9401],"kbd",{},"Tab"," moves between fields and buttons",[27,9404,9405,9408,9409,9412],{},[9399,9406,9407],{},"Up"," \u002F ",[9399,9410,9411],{},"Down"," moves through lists",[27,9414,9415,9418],{},[9399,9416,9417],{},"Space"," toggles checkboxes",[27,9420,9421,9423],{},[9399,9422,2188],{}," confirms the selected option",[27,9425,9426],{},"See the slides below for the installer screens",[11,9428,9430,9434],{"id":9429,"level":247},"ubuntu-installer-boot-menu",[16,9431,9433],{"id":9432},"step-21-boot-menu","Step 2.1: Boot Menu",[452,9435,9438,9447],{"gap":893,"left-width":9436,"right-width":9437,"stack":2654},"1.75fr","0.65fr",[457,9439,9440],{"v-slot:left":459},[20,9441,9442],{},[491,9443],{"alt":9444,"src":9445,"variant":9446},"Ubuntu Server boot menu in VirtualBox","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_1.png","slide-screenshot",[457,9448,9449],{"v-slot:right":459},[24,9450,9451,9456,9460],{},[27,9452,3620,9453],{},[146,9454,9455],{},"Try or Install Ubuntu Server",[27,9457,2219,9458],{},[9399,9459,2188],{},[27,9461,9462],{},"This starts the Ubuntu Server installer",[11,9464,9466,9470],{"id":9465,"level":247},"ubuntu-installer-language",[16,9467,9469],{"id":9468},"step-22-language","Step 2.2: Language",[452,9471,9472,9480],{"gap":893,"left-width":9436,"right-width":9437,"stack":2654},[457,9473,9474],{"v-slot:left":459},[20,9475,9476],{},[491,9477],{"alt":9478,"src":9479,"variant":9446},"Ubuntu Server installer language screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_2.0.png",[457,9481,9482],{"v-slot:right":459},[24,9483,9484,9487,9493],{},[27,9485,9486],{},"Choose your preferred language",[27,9488,9489,9492],{},[146,9490,9491],{},"English"," is the expected course screenshot path",[27,9494,2219,9495,9497],{},[9399,9496,2188],{}," to continue",[11,9499,9501,9505],{"id":9500,"level":247},"ubuntu-installer-update",[16,9502,9504],{"id":9503},"step-23-update-prompt","Step 2.3: Update Prompt",[452,9506,9507,9515],{"gap":893,"left-width":9436,"right-width":9437,"stack":2654},[457,9508,9509],{"v-slot:left":459},[20,9510,9511],{},[491,9512],{"alt":9513,"src":9514,"variant":9446},"Ubuntu Server installer update prompt","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_2.5.png",[457,9516,9517],{"v-slot:right":459},[24,9518,9519,9529,9532],{},[27,9520,3620,9521,9524],{},[146,9522,9523],{},"Continue without updating",[24,9525,9526],{},[27,9527,9528],{},"If I forget to update the image, it's the second option",[27,9530,9531],{},"Keeps the install path consistent",[27,9533,9534],{},"Package updates happen after Ubuntu is installed",[11,9536,9538,9542],{"id":9537,"level":247},"ubuntu-installer-keyboard",[16,9539,9541],{"id":9540},"step-24-keyboard","Step 2.4: Keyboard",[452,9543,9544,9552],{"gap":893,"left-width":9436,"right-width":9437,"stack":2654},[457,9545,9546],{"v-slot:left":459},[20,9547,9548],{},[491,9549],{"alt":9550,"src":9551,"variant":9446},"Ubuntu Server installer keyboard screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_3.png",[457,9553,9554],{"v-slot:right":459},[24,9555,9556,9559,9565],{},[27,9557,9558],{},"Keep the detected keyboard layout if it matches",[27,9560,9561,9562],{},"Common setting: ",[146,9563,9564],{},"English (US)",[27,9566,9567],{},"Use Identify keyboard only if typing is wrong",[11,9569,9571,9575],{"id":9570,"level":247},"ubuntu-installer-install-type",[16,9572,9574],{"id":9573},"step-25-install-type","Step 2.5: Install Type",[452,9576,9577,9585],{"gap":893,"left-width":9436,"right-width":9437,"stack":2654},[457,9578,9579],{"v-slot:left":459},[20,9580,9581],{},[491,9582],{"alt":9583,"src":9584,"variant":9446},"Ubuntu Server installer installation type screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_4.png",[457,9586,9587],{"v-slot:right":459},[24,9588,9589,9599,9602],{},[27,9590,9591,9592,9595,9596],{},"Select ",[146,9593,9594],{},"Ubuntu Server (minimized)","; don't choose full ",[146,9597,9598],{},"Ubuntu Server",[27,9600,9601],{},"Keep third-party drivers unchecked",[27,9603,9604],{},"Minimized keeps the VM lighter and aids future lessons",[11,9606,9608,9612],{"id":9607,"level":247},"ubuntu-installer-network",[16,9609,9611],{"id":9610},"step-26-network","Step 2.6: Network",[452,9613,9614,9622],{"gap":893,"left-width":9436,"right-width":9437,"stack":2654},[457,9615,9616],{"v-slot:left":459},[20,9617,9618],{},[491,9619],{"alt":9620,"src":9621,"variant":9446},"Ubuntu Server installer network configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_5.png",[457,9623,9624],{"v-slot:right":459},[24,9625,9626,9629,9635],{},[27,9627,9628],{},"DHCP address is expected",[27,9630,9631,9634],{},[146,9632,9633],{},"10.0.2.15"," is normal for VirtualBox NAT",[27,9636,9637],{},"Leave the network settings alone",[11,9639,9641,9645],{"id":9640,"level":247},"ubuntu-installer-proxy",[16,9642,9644],{"id":9643},"step-27-proxy","Step 2.7: Proxy",[452,9646,9647,9655],{"gap":893,"left-width":9436,"right-width":9437,"stack":2654},[457,9648,9649],{"v-slot:left":459},[20,9650,9651],{},[491,9652],{"alt":9653,"src":9654,"variant":9446},"Ubuntu Server installer proxy screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_6.png",[457,9656,9657],{"v-slot:right":459},[24,9658,9659,9662,9665],{},[27,9660,9661],{},"Leave proxy blank",[27,9663,9664],{},"Only fill this in if your network requires a proxy",[27,9666,9667],{},"Most student home networks do not need one",[11,9669,9671,9675],{"id":9670,"level":247},"ubuntu-installer-mirror",[16,9672,9674],{"id":9673},"step-28-mirror","Step 2.8: Mirror",[452,9676,9677,9685],{"gap":893,"left-width":9436,"right-width":9437,"stack":2654},[457,9678,9679],{"v-slot:left":459},[20,9680,9681],{},[491,9682],{"alt":9683,"src":9684,"variant":9446},"Ubuntu Server installer archive mirror screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_7.png",[457,9686,9687],{"v-slot:right":459},[24,9688,9689,9692,9695],{},[27,9690,9691],{},"Keep the default Ubuntu archive mirror",[27,9693,9694],{},"Wait for the mirror check to finish",[27,9696,9697],{},"Continue when the installer allows it",[11,9699,9701,9705],{"id":9700,"level":247},"ubuntu-installer-storage-guided",[16,9702,9704],{"id":9703},"step-29-guided-storage","Step 2.9: Guided Storage",[452,9706,9707,9715],{"gap":893,"left-width":9436,"right-width":9437,"stack":2654},[457,9708,9709],{"v-slot:left":459},[20,9710,9711],{},[491,9712],{"alt":9713,"src":9714,"variant":9446},"Ubuntu Server installer guided storage screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_8.png",[457,9716,9717],{"v-slot:right":459},[24,9718,9719,9722,9725],{},[27,9720,9721],{},"Use the entire virtual disk",[27,9723,9724],{},"LVM is optional, not needed for this course VM",[27,9726,9727],{},"Leave encryption off",[11,9729,9731,9735],{"id":9730,"level":247},"ubuntu-installer-storage-summary",[16,9732,9734],{"id":9733},"step-210-storage-summary","Step 2.10: Storage Summary",[452,9736,9737,9745],{"gap":893,"left-width":9436,"right-width":9437,"stack":2654},[457,9738,9739],{"v-slot:left":459},[20,9740,9741],{},[491,9742],{"alt":9743,"src":9744,"variant":9446},"Ubuntu Server installer storage summary screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_9.png",[457,9746,9747],{"v-slot:right":459},[24,9748,9749,9752,9755],{},[27,9750,9751],{},"Confirm the virtual disk is selected",[27,9753,9754],{},"This only affects the VM disk file",[27,9756,9757],{},"Continue when the layout looks correct",[11,9759,9761,9765],{"id":9760,"level":247},"ubuntu-installer-confirm-storage",[16,9762,9764],{"id":9763},"step-211-confirm-storage","Step 2.11: Confirm Storage",[452,9766,9767,9775],{"gap":893,"left-width":9436,"right-width":9437,"stack":2654},[457,9768,9769],{"v-slot:left":459},[20,9770,9771],{},[491,9772],{"alt":9773,"src":9774,"variant":9446},"Ubuntu Server installer destructive action confirmation","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_10.png",[457,9776,9777],{"v-slot:right":459},[24,9778,9779,9782,9785],{},[27,9780,9781],{},"Confirm the virtual disk format",[27,9783,9784],{},"This does not erase your host computer files",[27,9786,9787],{},"It formats the VM's virtual disk",[11,9789,9791,9795],{"id":9790,"level":247},"ubuntu-installer-profile",[16,9792,9794],{"id":9793},"step-212-profile","Step 2.12: Profile",[452,9796,9797,9805],{"gap":893,"left-width":9436,"right-width":9437,"stack":2654},[457,9798,9799],{"v-slot:left":459},[20,9800,9801],{},[491,9802],{"alt":9803,"src":9804,"variant":9446},"Ubuntu Server installer profile configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_11.png",[457,9806,9807],{"v-slot:right":459},[24,9808,9809,9812,9817,9819],{},[27,9810,9811],{},"Your name: your UCID or name is fine",[27,9813,9814,9815],{},"Server name: ",[146,9816,9177],{},[27,9818,5465],{},[27,9820,9821],{},"Choose a password you can type reliably (it can be simple since it's only for local work)",[11,9823,9825,9829],{"id":9824,"level":247},"ubuntu-installer-pro",[16,9826,9828],{"id":9827},"step-213-ubuntu-pro","Step 2.13: Ubuntu Pro",[452,9830,9831,9839],{"gap":893,"left-width":9436,"right-width":9437,"stack":2654},[457,9832,9833],{"v-slot:left":459},[20,9834,9835],{},[491,9836],{"alt":9837,"src":9838,"variant":9446},"Ubuntu Server installer Ubuntu Pro screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_12.png",[457,9840,9841],{"v-slot:right":459},[24,9842,9843,9848,9851],{},[27,9844,3620,9845],{},[146,9846,9847],{},"Skip for now",[27,9849,9850],{},"Ubuntu Pro is not needed for the course VM",[27,9852,9853],{},"You can continue without an Ubuntu account",[11,9855,9857,9861],{"id":9856,"level":247},"ubuntu-installer-ssh",[16,9858,9860],{"id":9859},"step-214-ssh","Step 2.14: SSH",[452,9862,9863,9871],{"gap":893,"left-width":9436,"right-width":9437,"stack":2654},[457,9864,9865],{"v-slot:left":459},[20,9866,9867],{},[491,9868],{"alt":9869,"src":9870,"variant":9446},"Ubuntu Server installer SSH configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_13.png",[457,9872,9873],{"v-slot:right":459},[24,9874,9875,9880,9883],{},[27,9876,7535,9877],{},[146,9878,9879],{},"Install OpenSSH server",[27,9881,9882],{},"Password authentication is fine for this local VM",[27,9884,9885],{},"No need to import SSH keys for this course setup",[11,9887,9889,9893],{"id":9888,"level":247},"ubuntu-installer-snaps",[16,9890,9892],{"id":9891},"step-215-featured-snaps","Step 2.15: Featured Snaps",[452,9894,9895,9903],{"gap":893,"left-width":9436,"right-width":9437,"stack":2654},[457,9896,9897],{"v-slot:left":459},[20,9898,9899],{},[491,9900],{"alt":9901,"src":9902,"variant":9446},"Ubuntu Server installer featured server snaps screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_14.png",[457,9904,9905],{"v-slot:right":459},[24,9906,9907,9910,9915],{},[27,9908,9909],{},"Leave all featured snaps unchecked",[27,9911,9912,9913],{},"Apache, PHP, and MySQL are installed later with ",[146,9914,6745],{},[27,9916,9917],{},"Continue without selecting extra packages",[11,9919,9921,9925],{"id":9920,"level":247},"ubuntu-installer-installing",[16,9922,9924],{"id":9923},"step-216-installing","Step 2.16: Installing",[452,9926,9927,9935],{"gap":893,"left-width":9436,"right-width":9437,"stack":2654},[457,9928,9929],{"v-slot:left":459},[20,9930,9931],{},[491,9932],{"alt":9933,"src":9934,"variant":9446},"Ubuntu Server installer installing system screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_15.png",[457,9936,9937,9962],{"v-slot:right":459},[24,9938,9939,9942,9945,9953,9959],{},[27,9940,9941],{},"Installation can take a while",[27,9943,9944],{},"High CPU during install is normal",[27,9946,9947,9948,9950,9951],{},"If install struggles at ",[146,9949,9112],{},", recreate the VM with ",[146,9952,9120],{},[27,9954,9955,9956,9958],{},"Keep the course target at ",[146,9957,9112],{}," after setup if possible",[27,9960,9961],{},"Reboot once complete",[2868,9963,9964],{"type":4141},[20,9965,9966],{},"These target resources stay close to common cloud free-tier VMs",[20,9968,2876],{},[11,9970,9972,9976,9979],{"id":9971,"level":14},"step-2-networking",[16,9973,9975],{"id":9974},"virtualbox-configure-networking","VirtualBox: Configure Networking",[20,9977,9978],{},"Use one NAT adapter with port forwarding:",[24,9980,9981,9987,9996,10004,10009],{},[27,9982,9983,9984],{},"VM internet: ",[146,9985,9986],{},"NAT",[27,9988,9989,9990,9993,9994],{},"Host SSH: host ",[146,9991,9992],{},"22"," -> guest ",[146,9995,9992],{},[27,9997,9998,9999,9993,10002],{},"Host browser: host ",[146,10000,10001],{},"3000",[146,10003,8591],{},[27,10005,304,10006,10008],{},[146,10007,8809],{}," from the host computer",[27,10010,10011],{},"See the slides below for adapter and port-forwarding screens",[11,10013,10015,10019,10032],{"id":10014,"level":247},"adapter-settings-screen",[16,10016,10018],{"id":10017},"adapter-settings","Adapter Settings",[24,10020,10021,10024,10029],{},[27,10022,10023],{},"Adapter 1 enabled",[27,10025,10026,10027],{},"Attached to ",[146,10028,9986],{},[27,10030,10031],{},"No second adapter needed for the baseline path",[20,10033,10034],{},[491,10035],{"alt":10036,"src":10037,"variant":9446},"VirtualBox Adapter 1 configured as NAT","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_adapter_1.png",[11,10039,10041,10045,10073],{"id":10040,"level":247},"port-forwarding-screen",[16,10042,10044],{"id":10043},"port-forwarding","Port Forwarding",[24,10046,10047,10055,10062],{},[27,10048,10049,10050,10052,10053],{},"SSH: host ",[146,10051,9992],{}," to guest ",[146,10054,9992],{},[27,10056,10057,10058,10052,10060],{},"Apache HTTP: host ",[146,10059,10001],{},[146,10061,8591],{},[27,10063,10064,10065,10067,10068,10052,10071],{},"If host ",[146,10066,9992],{}," is already busy, use host ",[146,10069,10070],{},"2222",[146,10072,9992],{},[20,10074,10075],{},[491,10076],{"alt":10077,"src":10078,"variant":9446},"VirtualBox NAT port forwarding rules","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_adapter_1_ports.png",[11,10080,10082,10086,10089,10092,10095,10098],{"id":10081,"level":14},"step-3-connect-ssh",[16,10083,10085],{"id":10084},"step-3-connect-with-ssh","Step 3: Connect With SSH",[20,10087,10088],{},"Run from your host terminal:",[74,10090],{"language":96,"src":10091},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-3-connect-with-ssh-01.sh",[20,10093,10094],{},"First connection prompt:",[74,10096],{"language":76,"src":10097},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-3-connect-with-ssh-02.txt",[24,10099,10100,10107,10116,10119,10122],{},[27,10101,10102,10103,10106],{},"Replace ",[146,10104,10105],{},"your_ucid"," with your UCID",[27,10108,10109,10110,10112,10113,10115],{},"Type ",[146,10111,4068],{}," once for this course VM on ",[146,10114,8809],{}," (if prompted like the example above)",[27,10117,10118],{},"Enter your Ubuntu password",[27,10120,10121],{},"After login, commands run inside Ubuntu",[27,10123,10124,803,10127,10130],{},[146,10125,10126],{},"exit",[146,10128,10129],{},"logout"," disconnects from the VM",[11,10132,10134,10138,10141],{"id":10133,"level":14},"step-4-confirm-network",[16,10135,10137],{"id":10136},"step-4-confirm-vm-network","Step 4: Confirm VM Network",[20,10139,10140],{},"Run inside Ubuntu through SSH:",[452,10142,10143,10185],{"gap":454,"left-width":3196,"right-width":455,"stack":2654},[457,10144,10145,10148,10151],{"v-slot:left":459},[20,10146,10147],{},"Network check:",[74,10149],{"language":96,"src":10150},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-4-confirm-vm-networ-03.sh",[24,10152,10153,10159,10165,10171,10177],{},[27,10154,10155,10158],{},[146,10156,10157],{},"ping",": confirms basic network access",[27,10160,10161,10164],{},[146,10162,10163],{},"-c 4",": stop after four replies",[27,10166,10167,10170],{},[146,10168,10169],{},"apt update",": refreshes package indexes",[27,10172,10173,10176],{},[146,10174,10175],{},"apt upgrade",": applies available package updates",[27,10178,3113,10179,10181,10182],{},[146,10180,10157],{}," is not found, run ",[146,10183,10184],{},"sudo apt install iputils-ping",[457,10186,10187,10190,10193],{"v-slot:right":459},[20,10188,10189],{},"Port-forwarding check:",[74,10191],{"language":96,"src":10192},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fslide-id-summary-level-2-04.sh",[24,10194,10195,10200,10203,10207],{},[27,10196,10197,10198],{},"The VM may show ",[146,10199,9633],{},[27,10201,10202],{},"That is normal for VirtualBox NAT",[27,10204,304,10205,10008],{},[146,10206,8809],{},[27,10208,10209],{},"Port forwarding routes host traffic into the VM",[11,10211,10213,10217],{"id":10212,"level":14},"step-5-shared-folder",[16,10214,10216],{"id":10215},"step-5-enable-shared-folder","Step 5: Enable Shared Folder",[452,10218,10219,10253],{"gap":454,"left-width":2653,"right-width":3196,"stack":2654},[457,10220,10221,10224],{"v-slot:left":459},[20,10222,10223],{},"In VirtualBox:",[24,10225,10226,10229,10232,10235,10238,10241,10244,10247,10250],{},[27,10227,10228],{},"Open VM settings",[27,10230,10231],{},"Choose Shared Folders",[27,10233,10234],{},"Folder Path: your cloned course repository folder",[27,10236,10237],{},"Folder Name: a simple repo name with no spaces",[27,10239,10240],{},"Mount Point: leave blank",[27,10242,10243],{},"Read-only: off",[27,10245,10246],{},"Auto-mount: on",[27,10248,10249],{},"Make Machine-permanent: on",[27,10251,10252],{},"Make Global: off",[457,10254,10255],{"v-slot:right":459},[20,10256,10257],{},[491,10258],{"alt":10259,"src":10260,"variant":495},"VirtualBox shared folder settings with the course repo selected","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_shared_folder.png",[11,10262,10264,10268,10271,10274],{"id":10263,"level":14},"step-6-guest-additions",[16,10265,10267],{"id":10266},"step-6-install-shared-folder-support","Step 6: Install Shared Folder Support",[20,10269,10270],{},"Run inside Ubuntu:",[74,10272],{"language":96,"src":10273},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-6-install-shared-fo-05.sh",[24,10275,10276,10283,10289],{},[27,10277,3302,10278,149,10280,10282],{},[146,10279,10169],{},[146,10281,10175],{}," first only if you skipped the Step 4 updates",[27,10284,10285,10288],{},[146,10286,10287],{},"virtualbox-guest-utils",": VirtualBox shared-folder support",[27,10290,10291],{},"Reboot after the group step on the next slide",[11,10293,10295,10299,10302,10305],{"id":10294,"level":247},"step-6b-confirm-vboxsf",[16,10296,10298],{"id":10297},"step-61-check-the-shared-folder","Step 6.1: Check The Shared Folder",[20,10300,10301],{},"Reconnect with SSH, then run inside Ubuntu:",[74,10303],{"language":96,"src":10304},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-6-1-check-the-share-06.sh",[24,10306,10307,10313,10319],{},[27,10308,10309,10312],{},[146,10310,10311],{},"ls \u002Fmedia",": shows available mounted folders",[27,10314,10315,10318],{},[146,10316,10317],{},"ls \u002Fmedia\u002F\u003Cshared-folder>",": checks your course repo share",[27,10320,10321],{},"Permission denied is common the first time",[11,10323,10325,10329,10332,10335],{"id":10324,"level":14},"step-7-locate-share",[16,10326,10328],{"id":10327},"step-7-allow-shared-folder-access","Step 7: Allow Shared Folder Access",[20,10330,10331],{},"If the shared folder exists but says permission denied:",[74,10333],{"language":96,"src":10334},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-7-allow-shared-fold-07.sh",[24,10336,10337,10343,10349],{},[27,10338,10339,10342],{},[146,10340,10341],{},"vboxsf",": group allowed to read VirtualBox shared folders",[27,10344,10345,10348],{},[146,10346,10347],{},"$USER",": your Ubuntu login user for terminal access",[27,10350,10351],{},"Reboot applies the shared-folder support and new group membership",[11,10353,10355,10359,10361,10364,10381,10384],{"id":10354,"level":247},"step-7b-locate-share",[16,10356,10358],{"id":10357},"step-71-locate-the-shared-repo","Step 7.1: Locate The Shared Repo",[20,10360,10301],{},[74,10362],{"language":96,"src":10363},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-7-1-locate-the-shar-08.sh",[24,10365,10366,10372,10378],{},[27,10367,10368,10371],{},[146,10369,10370],{},"\u002Fmedia",": VirtualBox auto-mounted shared folders",[27,10373,10374,10377],{},[146,10375,10376],{},"\u003Cshared-folder>",": your shared course repo folder name",[27,10379,10380],{},"Use the folder that points to your repository",[20,10382,10383],{},"Expected repo folders:",[24,10385,10386,10390,10394,10398],{},[27,10387,10388],{},[146,10389,1783],{},[27,10391,10392],{},[146,10393,6186],{},[27,10395,10396],{},[146,10397,6189],{},[27,10399,10400],{},[146,10401,6192],{},[11,10403,10405,10409,10424],{"id":10404,"level":247},"step-7-2-shared-folder-check",[16,10406,10408],{"id":10407},"step-72-shared-folder-check","Step 7.2: Shared Folder Check",[24,10410,10411,10414,10421],{},[27,10412,10413],{},"Edit a small file from VS Code on host",[27,10415,3302,10416,803,10418,10420],{},[146,10417,1772],{},[146,10419,1989],{}," inside Ubuntu",[27,10422,10423],{},"Confirm Ubuntu sees the same file content",[20,10425,10426],{},"If the file does not match, stop and fix the share before Apache setup",[11,10428,10430,10434,10436,10439],{"id":10429,"level":14},"step-8-install-apache-php-mysql",[16,10431,10433],{"id":10432},"step-8-install-apache-php-and-mysql","Step 8: Install Apache, PHP, And MySQL",[20,10435,10270],{},[74,10437],{"language":96,"src":10438},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-8-install-apache-ph-09.sh",[24,10440,10441,10447,10452,10458,10464,10470],{},[27,10442,10443,10446],{},[146,10444,10445],{},"apache2",": web server",[27,10448,10449,10451],{},[146,10450,5979],{},": PHP runtime",[27,10453,10454,10457],{},[146,10455,10456],{},"libapache2-mod-php",": lets Apache execute PHP files",[27,10459,10460,10463],{},[146,10461,10462],{},"mysql-server",": local MySQL database server",[27,10465,10466,10469],{},[146,10467,10468],{},"php-mysql",": lets PHP connect to MySQL",[27,10471,3302,10472,149,10474,10476],{},[146,10473,10169],{},[146,10475,10175],{}," first only if they have not been run recently",[11,10478,10480,10484,10491],{"id":10479,"level":247},"optional-swap-check",[16,10481,10483],{"id":10482},"optional-add-swap-if-swap-is-off","Optional: Add Swap If Swap Is Off",[20,10485,10486,10487,10490],{},"Ubuntu usually has swap already. Only add this if ",[146,10488,10489],{},"swapon --show"," prints nothing.",[452,10492,10493,10507],{"gap":454,"left-width":455,"right-width":455},[457,10494,10495,10498,10501,10504],{"v-slot:left":459},[20,10496,10497],{},"Check first:",[74,10499],{"language":96,"src":10500},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-add-swap-if-swa-10.sh",[20,10502,10503],{},"Add a small swap file only if swap is off:",[74,10505],{"language":96,"src":10506},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-add-swap-if-swa-11.sh",[457,10508,10509],{"v-slot:right":459},[24,10510,10511,10514,10519,10522],{},[27,10512,10513],{},"Swap gives Ubuntu emergency disk-backed memory",[27,10515,10516,10517],{},"It helps when installs or MySQL briefly need more than ",[146,10518,9112],{},[27,10520,10521],{},"It is slower than RAM, so it is not a performance upgrade",[27,10523,10524],{},"Do not run the setup again if swap already exists",[11,10526,10528,10532,10538],{"id":10527,"level":247},"optional-apache-low-memory",[16,10529,10531],{"id":10530},"optional-limit-apache-memory-use","Optional: Limit Apache Memory Use",[20,10533,10534,10535,10537],{},"Use this if the ",[146,10536,9112],{}," VM feels unstable or Apache starts too many PHP workers.",[452,10539,10540,10553],{"gap":454,"left-width":455,"right-width":455},[457,10541,10542,10545,10550],{"v-slot:left":459},[20,10543,10544],{},"Edit Apache prefork settings in:",[20,10546,10547],{},[146,10548,10549],{},"\u002Fetc\u002Fapache2\u002Fmods-available\u002Fmpm_prefork.conf",[74,10551],{"language":96,"src":10552},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-apache-me-12.sh",[457,10554,10555,10558,10562],{"v-slot:right":459},[20,10556,10557],{},"Change the existing values to:",[74,10559],{"language":10560,"src":10561},"apache","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-apache-me-13.txt",[24,10563,10564,10570,10573,10580],{},[27,10565,10566,10567],{},"Edit the existing lines inside ",[146,10568,10569],{},"\u003CIfModule mpm_prefork_module>",[27,10571,10572],{},"If a line is missing, add it inside that same block",[27,10574,10575,10576,10579],{},"Do not paste a second ",[146,10577,10578],{},"\u003CIfModule>"," block",[27,10581,10582],{},"Restart Apache after config changes",[11,10584,10586,10590,10596],{"id":10585,"level":247},"optional-mysql-low-memory",[16,10587,10589],{"id":10588},"optional-limit-mysql-memory-use","Optional: Limit MySQL Memory Use",[20,10591,10592,10593,10595],{},"Use this only if MySQL struggles on the ",[146,10594,9112],{}," VM.",[452,10597,10598,10611],{"gap":454,"left-width":455,"right-width":455},[457,10599,10600,10603,10608],{"v-slot:left":459},[20,10601,10602],{},"Edit MySQL server settings in:",[20,10604,10605],{},[146,10606,10607],{},"\u002Fetc\u002Fmysql\u002Fmysql.conf.d\u002Fmysqld.cnf",[74,10609],{"language":96,"src":10610},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-mysql-mem-14.sh",[457,10612,10613,10619,10622],{"v-slot:right":459},[20,10614,10615,10616,167],{},"Add or edit these under ",[146,10617,10618],{},"[mysqld]",[74,10620],{"language":6786,"src":10621},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-mysql-mem-15.txt",[24,10623,10624,10630,10635,10638],{},[27,10625,10626,10627,10629],{},"Keep these under the existing ",[146,10628,10618],{}," heading",[27,10631,10632,10633,10629],{},"Do not create a second ",[146,10634,10618],{},[27,10636,10637],{},"If either setting already exists, edit it instead of adding a duplicate",[27,10639,10640],{},"Restart MySQL after config changes",[11,10642,10644,10647,10650,10653],{"id":10643,"level":247},"low-memory-diagnostics",[16,10645,10646],{"id":10643},"Low Memory Diagnostics",[20,10648,10649],{},"Run these after the minor tuning checks:",[74,10651],{"language":96,"src":10652},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Flow-memory-diagnostics-10.sh",[24,10654,10655,10661,10666,10672,10679],{},[27,10656,10657,10660],{},[146,10658,10659],{},"free -h",": shows RAM and swap",[27,10662,10663,10665],{},[146,10664,10489],{},": confirms whether swap is active",[27,10667,10668,10671],{},[146,10669,10670],{},"systemctl status",": checks whether Apache and MySQL are running",[27,10673,10674,10675,10678],{},"No output from the ",[146,10676,10677],{},"grep"," line is usually good",[27,10680,10681],{},"Do not tune randomly; change one setting, restart, then retest",[11,10683,10685,10689,10691,10694,10697,10700],{"id":10684,"level":14},"step-9-create-local-mysql-db",[16,10686,10688],{"id":10687},"step-9-create-a-local-mysql-database","Step 9: Create A Local MySQL Database",[20,10690,10270],{},[74,10692],{"language":96,"src":10693},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-9-create-a-local-my-11.sh",[20,10695,10696],{},"Then run in the MySQL prompt:",[74,10698],{"language":6192,"src":10699},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-9-create-a-local-my-12.sql",[24,10701,10702,10706,10709],{},[27,10703,10102,10704,10106],{},[146,10705,10105],{},[27,10707,10708],{},"Database name and username should match your UCID",[27,10710,10711],{},"Password is local-only unless your instructor says otherwise",[11,10713,10715,10718,10721,10734,10737,10743],{"id":10714,"level":14},"local-vs-remote-database",[16,10716,10717],{"id":10714},"Local Vs Remote Database",[20,10719,10720],{},"This MySQL database is only for local testing:",[24,10722,10723,10727,10729,10731],{},[27,10724,5453,10725],{},[146,10726,8809],{},[27,10728,5468],{},[27,10730,5465],{},[27,10732,10733],{},"Password: your local password",[20,10735,10736],{},"Render uses the instructor-provided remote database connection string",[20,10738,10739,10740],{},"Get that string from ",[856,10741,5479],{"href":5479,"rel":10742},[860],[20,10744,10745],{},"After this lesson, you may optionally point local code at that remote database for extra testing",[11,10747,10749,10753,10755,10758,10760,10763,10766],{"id":10748,"level":14},"step-10-confirm-local-mysql",[16,10750,10752],{"id":10751},"step-10-confirm-local-mysql-login","Step 10: Confirm Local MySQL Login",[20,10754,10270],{},[74,10756],{"language":96,"src":10757},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-10-confirm-local-my-13.sh",[20,10759,741],{},[74,10761],{"language":6192,"src":10762},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-10-confirm-local-my-14.sql",[20,10764,10765],{},"Expected:",[24,10767,10768,10774],{},[27,10769,10770,10773],{},[146,10771,10772],{},"SELECT DATABASE()"," returns your UCID",[27,10775,10776,10779],{},[146,10777,10778],{},"SHOW TABLES"," is empty or shows starter tables later",[11,10781,10783,10789,10792,10795,10798],{"id":10782,"level":14},"step-11-documentroot",[16,10784,10786,10787],{"id":10785},"step-11-point-apache-at-public_html","Step 11: Point Apache At ",[146,10788,1783],{},[20,10790,10791],{},"Apache should serve:",[74,10793],{"language":76,"src":10794},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-11-point-apache-at--15.txt",[20,10796,10797],{},"Do not serve the whole repo",[24,10799,10800,10809],{},[27,10801,10802,1582,10804,1585,10806,10808],{},[146,10803,6186],{},[146,10805,6189],{},[146,10807,6192],{}," stay outside the web root",[27,10810,10811,10813],{},[146,10812,1783],{}," is the browser-facing folder",[11,10815,10817,10821,10824,10829,10831,10836,10839,10842],{"id":10816,"level":247},"apache-site-config",[16,10818,10820],{"id":10819},"step-111-apache-site-config","Step 11.1: Apache Site Config",[20,10822,10823],{},"Create or edit this Apache site config file inside Ubuntu:",[20,10825,10826],{},[146,10827,10828],{},"\u002Fetc\u002Fapache2\u002Fsites-available\u002Fit202.conf",[20,10830,93],{},[20,10832,10833],{},[146,10834,10835],{},"sudo nano \u002Fetc\u002Fapache2\u002Fsites-available\u002Fit202.conf",[20,10837,10838],{},"Add this content to that file:",[74,10840],{"language":10560,"src":10841},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-11-1-apache-site-co-16.txt",[24,10843,10844,10849,10855,10860],{},[27,10845,10102,10846,10848],{},[146,10847,10376],{}," with the actual shared folder name",[27,10850,10851,10852],{},"Save the file as ",[146,10853,10854],{},"it202.conf",[27,10856,10857,10858],{},"Apache listens on guest port ",[146,10859,8591],{},[27,10861,10862,10863],{},"Host browser reaches it through ",[146,10864,8667],{},[11,10866,10868,10872,10874,10877],{"id":10867,"level":247},"enable-site",[16,10869,10871],{"id":10870},"step-112-enable-the-site","Step 11.2: Enable The Site",[20,10873,10270],{},[74,10875],{"language":96,"src":10876},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-11-2-enable-the-sit-17.sh",[24,10878,10879,10885,10891,10897,10905,10911],{},[27,10880,10881,10884],{},[146,10882,10883],{},"a2ensite",": enable a site config",[27,10886,10887,10890],{},[146,10888,10889],{},"a2dissite",": disable a site config",[27,10892,10893,10896],{},[146,10894,10895],{},"www-data",": Apache's user for browser requests",[27,10898,10899,10900,6939,10902,10904],{},"Adding ",[146,10901,10895],{},[146,10903,10341],{}," lets Apache read the shared folder",[27,10906,10907,10910],{},[146,10908,10909],{},"configtest",": check syntax before reload",[27,10912,10913,10916],{},[146,10914,10915],{},"restart",": applies the Apache user group change",[11,10918,10920,10924,10927,10930,10933],{"id":10919,"level":14},"step-12-php-check-page",[16,10921,10923],{"id":10922},"step-12-create-a-php-check-page","Step 12: Create A PHP Check Page",[20,10925,10926],{},"Create this file on the host:",[74,10928],{"language":76,"src":10929},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-12-create-a-php-che-18.txt",[20,10931,10932],{},"Example content:",[74,10934],{"language":5979,"src":10935},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-12-create-a-php-che-19.php",[11,10937,10939,10942,10945,10948,10950],{"id":10938,"level":14},"final-browser-check",[16,10940,10941],{"id":10938},"Final Browser Check",[20,10943,10944],{},"Open from host browser:",[74,10946],{"language":76,"src":10947},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Ffinal-browser-check-20.txt",[20,10949,10765],{},[24,10951,10952,10955,10958,10961],{},[27,10953,10954],{},"Message appears",[27,10956,10957],{},"Time appears",[27,10959,10960],{},"PHP code is not shown as raw text",[27,10962,10963],{},"Editing the file on host changes output after refresh",[11,10965,10967,10970],{"id":10966,"level":14},"common-problems",[16,10968,10969],{"id":10966},"Common Problems",[24,10971,10972,10975,10978,10983,10986,10999,11009],{},[27,10973,10974],{},"Browser timeout: missing or wrong port-forwarding rule",[27,10976,10977],{},"Connection refused: Apache not running",[27,10979,10980,10981],{},"No internet in VM: check Adapter 1 is still ",[146,10982,9986],{},[27,10984,10985],{},"Shared folder missing: check Auto-mount and guest utilities",[27,10987,10988,10989,10992,10993,10995,10996,10998],{},"Browser shows ",[146,10990,10991],{},"403 Forbidden",": confirm ",[146,10994,10895],{}," is in ",[146,10997,10341],{},", then restart Apache or reboot",[27,11000,11001,11002,11005,11006,11008],{},"Permission denied on ",[146,11003,11004],{},"\u002Fmedia\u002Fsf_...",": confirm your Ubuntu user is in ",[146,11007,10341],{}," and reboot",[27,11010,11011],{},"Raw PHP code: PHP module not running through Apache",[11,11013,11015,11018,11021],{"id":11014,"level":14},"recovery-routine",[16,11016,11017],{"id":11014},"Recovery Routine",[20,11019,11020],{},"Check in this order:",[1137,11022,11023,11026,11032,11038,11043,11051,11058,11064,11069,11078],{},[27,11024,11025],{},"VM is running",[27,11027,11028,11031],{},[146,11029,11030],{},"ping github.com"," works inside Ubuntu",[27,11033,11034,11037],{},[146,11035,11036],{},"ssh username@localhost"," works from host",[27,11039,11040,11042],{},[146,11041,10317],{}," shows the shared repo",[27,11044,11045,11048,11049],{},[146,11046,11047],{},"groups"," includes ",[146,11050,10341],{},[27,11052,11053,11048,11056],{},[146,11054,11055],{},"id www-data",[146,11057,10341],{},[27,11059,11060,11063],{},[146,11061,11062],{},"sudo systemctl status apache2"," is active",[27,11065,11066,11063],{},[146,11067,11068],{},"sudo systemctl status mysql",[27,11070,11071,11074,11075],{},[146,11072,11073],{},"sudo apache2ctl configtest"," says ",[146,11076,11077],{},"Syntax OK",[27,11079,11080,11083],{},[146,11081,11082],{},"http:\u002F\u002Flocalhost:3000\u002Fsystem\u002Fvm-check.php"," loads from the host browser",[11,11085,11086,11088],{"id":815,"level":14},[16,11087,816],{"id":815},[452,11089,11090,11131],{"gap":454,"left-width":455,"right-width":455},[457,11091,11092,11094,11100,11109,11114,11120,11126],{"v-slot:left":459},[249,11093,824],{"id":823},[20,11095,11096,11099],{},[1102,11097,11098],{},"VM"," - separate computer running inside your host computer",[20,11101,11102,11105,11106,11108],{},[1102,11103,11104],{},"Port forwarding"," - host ",[146,11107,8809],{}," traffic routed into the VM",[20,11110,11111,11113],{},[1102,11112,10341],{}," - VirtualBox shared-folder permission group",[20,11115,11116,11119],{},[1102,11117,11118],{},"Guest utilities"," - VirtualBox tools that help shared folders work inside Ubuntu",[20,11121,11122,11125],{},[1102,11123,11124],{},"DocumentRoot"," - folder Apache serves to browsers",[20,11127,11128,11130],{},[1102,11129,9986],{}," - VM network mode that gives the VM outbound internet access",[457,11132,11133,11135],{"v-slot:right":459},[249,11134,849],{"id":812},[24,11136,11137,11143,11150,11157,11164,11171,11177],{},[27,11138,11139],{},[856,11140,11142],{"href":8733,"rel":11141},[860],"VirtualBox Downloads",[27,11144,11145],{},[856,11146,11149],{"href":11147,"rel":11148},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002FIntroduction.html",[860],"VirtualBox Manual: Host And Guest Combinations",[27,11151,11152],{},[856,11153,11156],{"href":11154,"rel":11155},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Finstallation.html",[860],"VirtualBox Manual: Installation",[27,11158,11159],{},[856,11160,11163],{"href":11161,"rel":11162},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Fsharedfolders.html",[860],"VirtualBox Manual: Shared Folders",[27,11165,11166],{},[856,11167,11170],{"href":11168,"rel":11169},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Fnetworkingdetails.html#network_nat_service",[860],"VirtualBox Manual: NAT Port Forwarding",[27,11172,11173],{},[856,11174,11176],{"href":8751,"rel":11175},[860],"Ubuntu Server: Installer",[27,11178,11179],{},[856,11180,11183],{"href":11181,"rel":11182},"https:\u002F\u002Fdocumentation.ubuntu.com\u002Fserver\u002Fhow-to\u002Fsecurity\u002Fopenssh-server\u002F",[860],"Ubuntu Server: OpenSSH Server",[11,11185,11186,11188,11190],{"id":887,"level":14},[16,11187,890],{"id":887},[20,11189,900],{},[24,11191,11192,11195,11198,11201,11204,11209],{},[27,11193,11194],{},"Pick the correct Ubuntu ISO for your host CPU",[27,11196,11197],{},"Configure NAT port forwarding",[27,11199,11200],{},"Connect to Ubuntu with SSH",[27,11202,11203],{},"Find the VirtualBox shared repo",[27,11205,11206,11207],{},"Configure Apache to serve ",[146,11208,1783],{},[27,11210,11211],{},"Create a local MySQL database and user named after your UCID",{"title":459,"searchDepth":935,"depth":935,"links":11213},[11214,11215,11216,11217,11218,11219,11220,11221,11222,11223,11224,11225,11226,11227,11228,11229,11230,11231,11232,11233,11234,11235,11236,11237,11238,11239,11240,11241,11242,11243,11244,11245,11246,11247,11248,11249,11250,11251,11252,11253,11254,11255,11256,11257,11258,11259,11260,11261,11262,11263,11264,11265,11266,11267,11268,11269,11270,11272,11273,11274,11275,11276,11277,11278,11279],{"id":8613,"depth":935,"text":8605},{"id":8639,"depth":935,"text":8642},{"id":8684,"depth":935,"text":8687},{"id":1597,"depth":935,"text":1600},{"id":8789,"depth":935,"text":8792},{"id":8824,"depth":935,"text":8825},{"id":8848,"depth":935,"text":8851},{"id":8880,"depth":935,"text":8883},{"id":8906,"depth":935,"text":8909},{"id":8935,"depth":935,"text":8938},{"id":8967,"depth":935,"text":8968},{"id":8991,"depth":935,"text":8994},{"id":9022,"depth":935,"text":9025},{"id":9053,"depth":935,"text":9054},{"id":9089,"depth":935,"text":9090},{"id":9151,"depth":935,"text":9154},{"id":9186,"depth":935,"text":9189},{"id":9232,"depth":935,"text":9235},{"id":9275,"depth":935,"text":9278},{"id":9319,"depth":935,"text":9322},{"id":9369,"depth":935,"text":9370},{"id":9432,"depth":935,"text":9433},{"id":9468,"depth":935,"text":9469},{"id":9503,"depth":935,"text":9504},{"id":9540,"depth":935,"text":9541},{"id":9573,"depth":935,"text":9574},{"id":9610,"depth":935,"text":9611},{"id":9643,"depth":935,"text":9644},{"id":9673,"depth":935,"text":9674},{"id":9703,"depth":935,"text":9704},{"id":9733,"depth":935,"text":9734},{"id":9763,"depth":935,"text":9764},{"id":9793,"depth":935,"text":9794},{"id":9827,"depth":935,"text":9828},{"id":9859,"depth":935,"text":9860},{"id":9891,"depth":935,"text":9892},{"id":9923,"depth":935,"text":9924},{"id":9974,"depth":935,"text":9975},{"id":10017,"depth":935,"text":10018},{"id":10043,"depth":935,"text":10044},{"id":10084,"depth":935,"text":10085},{"id":10136,"depth":935,"text":10137},{"id":10215,"depth":935,"text":10216},{"id":10266,"depth":935,"text":10267},{"id":10297,"depth":935,"text":10298},{"id":10327,"depth":935,"text":10328},{"id":10357,"depth":935,"text":10358},{"id":10407,"depth":935,"text":10408},{"id":10432,"depth":935,"text":10433},{"id":10482,"depth":935,"text":10483},{"id":10530,"depth":935,"text":10531},{"id":10588,"depth":935,"text":10589},{"id":10643,"depth":935,"text":10646},{"id":10687,"depth":935,"text":10688},{"id":10714,"depth":935,"text":10717},{"id":10751,"depth":935,"text":10752},{"id":10785,"depth":935,"text":11271},"Step 11: Point Apache At public_html",{"id":10819,"depth":935,"text":10820},{"id":10870,"depth":935,"text":10871},{"id":10922,"depth":935,"text":10923},{"id":10938,"depth":935,"text":10941},{"id":10966,"depth":935,"text":10969},{"id":11014,"depth":935,"text":11017},{"id":815,"depth":935,"text":816},{"id":887,"depth":935,"text":890},"Build the local Ubuntu VM path with VirtualBox, Apache, PHP, MySQL, SSH, and shared folders.","Face-to-face class of about 40 students; includes VirtualBox install differences, CPU\u002FISO selection, networking, SSH, shared folders, Apache\u002FPHP\u002FMySQL, browser checks, and beginner troubleshooting.","25","95","120",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox",{"title":8605,"description":11280},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox",[11290,11291,10560,11292,11293],"virtualbox","ubuntu","mysql","vm","1:06:16","ArTDIgihfd4","https:\u002F\u002Fyoutu.be\u002FArTDIgihfd4","IT202 VirtualBox and VM Setup","CNlzYvIiYNPSzbQ6tvCdcnJLlvvGSGmurOGWR_mSnms",[],1780581681206]