[{"data":1,"prerenderedAt":11305},["ShallowReactive",2],{"content-page:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools":3,"content-page-quiz:none":950,"book-module-total-pages":951,"content-section-pages:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F":952,"content-directory-pages:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools":11304},{"id":4,"title":5,"audience":6,"body":7,"contentType":926,"course":927,"description":928,"estimateBasis":929,"estimatedDiscussionMinutes":930,"estimatedLiveMinutes":931,"estimatedTotalMinutes":932,"extension":933,"meta":934,"module":935,"navigation":936,"order":937,"path":938,"promptAssist":939,"seo":940,"status":941,"stem":942,"tags":943,"videoDuration":946,"videoId":947,"videoLink":948,"videoTitle":5,"week":935,"__hash__":949},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools.md","Git Tools","student",{"type":8,"value":9,"toc":894},"minimark",[10,45,75,107,153,185,217,252,281,311,348,351,381,412,441,491,509,526,546,571,604,622,664,709,796,863],[11,12,15,19],"slide",{"id":13,"level":14},"goal","2",[16,17,18],"h2",{"id":13},"Goal",[20,21,22,26,29],"ul",{},[23,24,25],"li",{},"Install Git",[23,27,28],{},"Choose one terminal for your operating system",[23,30,31,32,36,37,40,41,44],{},"Confirm ",[33,34,35],"code",{},"git --version",", ",[33,38,39],{},"pwd",", and ",[33,42,43],{},"ls -la"," work before GitHub setup",[11,46,48,52],{"id":47,"level":14},"terminal-choice-by-os",[16,49,51],{"id":50},"terminal-choices","Terminal Choices",[20,53,54,57,60,63,66,69,72],{},[23,55,56],{},"Pick the terminal for your operating system",[23,58,59],{},"Use that same terminal for this lesson path",[23,61,62],{},"Run commands on your own computer unless a later lesson explicitly says \"inside the VM\"",[23,64,65],{},"Windows: Git Bash",[23,67,68],{},"Apple macOS: Terminal, with iTerm2 optional",[23,70,71],{},"Linux: Terminal, with Tilix optional",[23,73,74],{},"These operating system notes are alternatives, not a sequence",[11,76,78,82,103],{"id":77,"level":14},"step-1-install-git-on-windows",[16,79,81],{"id":80},"windows-path-git-bash","Windows Path: Git Bash",[83,84,85,94,97,100],"ol",{},[23,86,87,88],{},"Go to ",[89,90,91],"a",{"href":91,"rel":92},"https:\u002F\u002Fgit-scm.com\u002Finstall\u002Fwindows",[93],"nofollow",[23,95,96],{},"Download and run the Git for Windows installer",[23,98,99],{},"Open Git Bash from the Start menu",[23,101,102],{},"Use Git Bash whenever this course says to use the terminal",[104,105,106],"p",{},"See the slides below for the install settings, launch check, and Windows terminal habit",[11,108,111,115],{"id":109,"level":110},"windows-installer-components","3",[112,113,114],"h3",{"id":109},"Windows Installer: Components",[116,117,122,134],"two-col",{"gap":118,"left-width":119,"right-width":120,"stack":121},"lg","1.4fr","0.9fr","never",[123,124,126],"template",{"v-slot:left":125},"",[104,127,128],{},[129,130],"img",{"alt":131,"src":132,"variant":133},"Git for Windows installer component selection screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep01_components.png","sidecar-screenshot",[123,135,136],{"v-slot:right":125},[20,137,138,141,147],{},[23,139,140],{},"Recommended to have these components selected",[23,142,143,144],{},"Keep ",[33,145,146],{},"Git Bash Here",[23,148,149,150],{},"Continue with ",[33,151,152],{},"Next",[11,154,156,159],{"id":155,"level":110},"windows-installer-default-editor",[112,157,158],{"id":155},"Windows Installer: Default Editor",[116,160,161,169],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,162,163],{"v-slot:left":125},[104,164,165],{},[129,166],{"alt":167,"src":168,"variant":133},"Git for Windows installer default editor selection screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep02_default_editor.png",[123,170,171],{"v-slot:right":125},[20,172,173,176,182],{},[23,174,175],{},"Choose the editor you are comfortable with",[23,177,178,181],{},[33,179,180],{},"nano"," or VS Code is friendlier than Vim for most beginners",[23,183,184],{},"This setting affects Git messages if Git opens an editor",[11,186,188,191],{"id":187,"level":110},"windows-installer-branch-name",[112,189,190],{"id":187},"Windows Installer: Branch Name",[116,192,193,201],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,194,195],{"v-slot:left":125},[104,196,197],{},[129,198],{"alt":199,"src":200,"variant":133},"Git for Windows installer default branch name screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep03_branch_naming.png",[123,202,203],{"v-slot:right":125},[20,204,205,211,214],{},[23,206,207,208],{},"Select the option that uses ",[33,209,210],{},"main",[23,212,213],{},"Course repositories will tell you which branch to use later",[23,215,216],{},"Do not create custom branch names here",[11,218,220,223],{"id":219,"level":110},"windows-installer-path",[112,221,222],{"id":219},"Windows Installer: PATH",[116,224,225,233],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,226,227],{"v-slot:left":125},[104,228,229],{},[129,230],{"alt":231,"src":232,"variant":133},"Git for Windows installer PATH environment screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep04_path.png",[123,234,235],{"v-slot:right":125},[20,236,237,240,246,249],{},[23,238,239],{},"Select the recommended PATH option",[23,241,242,243],{},"This lets Git Bash and common tools find ",[33,244,245],{},"git",[23,247,248],{},"Avoid options that say Git Bash only",[23,250,251],{},"The third option can be used if you understand the consequences",[11,253,255,258],{"id":254,"level":110},"windows-installer-ssh",[112,256,257],{"id":254},"Windows Installer: SSH",[116,259,260,268],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,261,262],{"v-slot:left":125},[104,263,264],{},[129,265],{"alt":266,"src":267,"variant":133},"Git for Windows installer SSH executable screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep05_ssh_bundled.png",[123,269,270],{"v-slot:right":125},[20,271,272,275,278],{},[23,273,274],{},"Use the bundled OpenSSH option",[23,276,277],{},"This keeps Git Bash SSH behavior predictable",[23,279,280],{},"SSH setup happens in the next lesson",[11,282,284,288],{"id":283,"level":110},"windows-installer-openssl",[112,285,287],{"id":286},"windows-installer-https","Windows Installer: HTTPS",[116,289,290,298],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,291,292],{"v-slot:left":125},[104,293,294],{},[129,295],{"alt":296,"src":297,"variant":133},"Git for Windows installer HTTPS transport backend screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep06_openssl.png",[123,299,300],{"v-slot:right":125},[20,301,302,305,308],{},[23,303,304],{},"Keep the OpenSSL option",[23,306,307],{},"This is the normal Git for Windows choice",[23,309,310],{},"It supports secure GitHub connections",[11,312,314,318],{"id":313,"level":110},"windows-installer-checkout-style",[112,315,317],{"id":316},"windows-installer-line-endings","Windows Installer: Line Endings",[116,319,320,328],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,321,322],{"v-slot:left":125},[104,323,324],{},[129,325],{"alt":326,"src":327,"variant":133},"Git for Windows installer line ending conversion screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep07_checkout_style.png",[123,329,330,341],{"v-slot:right":125},[20,331,332,335,338],{},[23,333,334],{},"Keep the default line-ending option",[23,336,337],{},"Git handles Windows and Linux line endings for you",[23,339,340],{},"Do not change this unless a lesson says to",[342,343,345],"admonition",{"type":344},"note",[104,346,347],{},"Line-ending warnings may appear later. They are usually informational, not a sign that there's an issue.",[104,349,350],{},"::\n::",[11,352,354,358],{"id":353,"level":110},"windows-installer-mintty",[112,355,357],{"id":356},"windows-installer-terminal-emulator","Windows Installer: Terminal Emulator",[116,359,360,368],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,361,362],{"v-slot:left":125},[104,363,364],{},[129,365],{"alt":366,"src":367,"variant":133},"Git for Windows installer terminal emulator screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep08_mintty.png",[123,369,370],{"v-slot:right":125},[20,371,372,375,378],{},[23,373,374],{},"Keep MinTTY selected",[23,376,377],{},"This is the normal Git Bash window",[23,379,380],{},"Course screenshots will assume this terminal style",[11,382,384,388],{"id":383,"level":110},"windows-installer-fast-forward",[112,385,387],{"id":386},"windows-installer-pull-behavior","Windows Installer: Pull Behavior",[116,389,390,398],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,391,392],{"v-slot:left":125},[104,393,394],{},[129,395],{"alt":396,"src":397,"variant":133},"Git for Windows installer git pull behavior screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep09_ff_merge.png",[123,399,400],{"v-slot:right":125},[20,401,402,409],{},[23,403,404,405,408],{},"Keep the default ",[33,406,407],{},"git pull"," behavior",[23,410,411],{},"Later lessons explain pull, merge, and conflicts",[11,413,415,418],{"id":414,"level":110},"windows-installer-credential-manager",[112,416,417],{"id":414},"Windows Installer: Credential Manager",[116,419,420,428],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,421,422],{"v-slot:left":125},[104,423,424],{},[129,425],{"alt":426,"src":427,"variant":133},"Git for Windows installer credential manager screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep10_credential_manager.png",[123,429,430],{"v-slot:right":125},[20,431,432,435,438],{},[23,433,434],{},"Keep Git Credential Manager enabled",[23,436,437],{},"It helps with browser-based GitHub sign-in",[23,439,440],{},"This course still uses SSH for repo pushes",[11,442,444,447],{"id":443,"level":110},"windows-installer-extra-options",[112,445,446],{"id":443},"Windows Installer: Extra Options",[116,448,449,457],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,450,451],{"v-slot:left":125},[104,452,453],{},[129,454],{"alt":455,"src":456,"variant":133},"Git for Windows installer extra options screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep11_extra_options_optional.png",[123,458,459],{"v-slot:right":125},[20,460,461,469,480,488],{},[23,462,463,464],{},"Enable file system caching\n",[20,465,466],{},[23,467,468],{},"Improves Git performance on Windows",[23,470,471,472],{},"Enable symbolic links if available\n",[20,473,474,477],{},[23,475,476],{},"Helps Git handle link-like files correctly",[23,478,479],{},"May require Windows Developer Mode or admin rights",[23,481,482,483],{},"Skip experimental options\n",[20,484,485],{},[23,486,487],{},"They can change behavior between Git versions",[23,489,490],{},"Finish the installer",[11,492,494,498],{"id":493,"level":110},"step-1-open-git-bash-on-windows",[112,495,497],{"id":496},"open-git-bash","Open Git Bash",[20,499,500,503,506],{},[23,501,502],{},"Start menu -> Git Bash",[23,504,505],{},"Pin it if that helps you find the same terminal later",[23,507,508],{},"Run the checks in the next slides from Git Bash",[11,510,512,515],{"id":511,"level":110},"windows-terminal-habit",[112,513,514],{"id":511},"Windows Terminal Habit",[20,516,517,520,523],{},[23,518,519],{},"Use Git Bash for course commands on Windows",[23,521,522],{},"If another terminal opens by accident, close it and open Git Bash",[23,524,525],{},"Staying in one terminal makes setup problems easier to diagnose",[11,527,529,532],{"id":528,"level":14},"macos-path-terminal",[16,530,531],{"id":528},"macOS Path: Terminal",[20,533,534,537,540,543],{},[23,535,536],{},"Built-in Terminal is fully supported",[23,538,539],{},"Optional iTerm2 gives you tabs, split panes, and profiles",[23,541,542],{},"Beginner default: start with Terminal unless you already prefer iTerm2",[23,544,545],{},"See the slide below for the optional modern terminal install path",[11,547,549,553],{"id":548,"level":110},"macos-optional-iterm2-install",[112,550,552],{"id":551},"optional-iterm2-install","Optional iTerm2 Install",[20,554,555,562,565,568],{},[23,556,557,558],{},"Download the stable release from ",[89,559,560],{"href":560,"rel":561},"https:\u002F\u002Fiterm2.com\u002Fdownloads.html",[93],[23,563,564],{},"Move iTerm2 to Applications",[23,566,567],{},"Open iTerm2 and run the same checks as Terminal",[23,569,570],{},"Use Terminal or iTerm2 consistently for course commands",[11,572,574,577,591,594,599],{"id":573,"level":14},"linux-path-terminal",[16,575,576],{"id":573},"Linux Path: Terminal",[20,578,579,582,585],{},[23,580,581],{},"Open the built-in Terminal app",[23,583,584],{},"Git is often installed already",[23,586,587,588,590],{},"If ",[33,589,35],{}," fails, use your distribution package manager",[104,592,593],{},"For Ubuntu:",[595,596],"code-snippet",{"language":597,"src":598},"bash","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Flinux-path-terminal-01.sh",[20,600,601],{},[23,602,603],{},"See the slide below for the optional split-pane terminal setup",[11,605,607,611,614,616,619],{"id":606,"level":110},"linux-optional-tilix-install",[112,608,610],{"id":609},"optional-tilix-install","Optional Tilix Install",[104,612,613],{},"Tilix is a Linux terminal with split panes and profiles",[104,615,593],{},[595,617],{"language":597,"src":618},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Foptional-tilix-install-02.sh",[104,620,621],{},"Use the built-in Terminal if optional installs add friction",[11,623,625,629],{"id":624,"level":14},"step-3-confirm-git-and-shell",[16,626,628],{"id":627},"confirm-git-and-shell","Confirm Git And Shell",[116,630,633,648],{"gap":118,"left-width":631,"right-width":632},"1.15fr","0.85fr",[123,634,635,638,641,644],{"v-slot:left":125},[104,636,637],{},"Run:",[595,639],{"language":597,"src":640},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fconfirm-git-and-shell-03.sh",[104,642,643],{},"Expected output:",[595,645],{"language":646,"src":647},"plaintext","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fexample-output-04.txt",[123,649,650,653],{"v-slot:right":125},[104,651,652],{},"This confirms:",[20,654,655,658,661],{},[23,656,657],{},"Git is installed",[23,659,660],{},"The terminal can find Git",[23,662,663],{},"Your shell matches later course commands",[11,665,667,671],{"id":666,"level":14},"step-4-cli-safety-check-before-every-git-command",[16,668,670],{"id":669},"check-location-before-git-commands","Check Location Before Git Commands",[116,672,674,686],{"gap":118,"left-width":673,"right-width":120},"1.1fr",[123,675,676,678,681,683],{"v-slot:left":125},[104,677,637],{},[595,679],{"language":597,"src":680},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fcheck-location-before-git-commands-05.sh",[104,682,643],{},[595,684],{"language":646,"src":685},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fexample-output-06.txt",[123,687,688,691],{"v-slot:right":125},[104,689,690],{},"Use this before Git commands:",[20,692,693,698,703,706],{},[23,694,695,697],{},[33,696,39],{}," shows the current folder",[23,699,700,702],{},[33,701,43],{}," shows what is inside it",[23,704,705],{},"If the folder is wrong, fix location first",[23,707,708],{},"Do not run Git commands while guessing",[11,710,712,715],{"id":711,"level":14},"common-mistakes",[16,713,714],{"id":711},"Common Mistakes",[116,716,718,762],{"gap":118,"left-width":717,"right-width":717},"1fr",[123,719,720],{"v-slot:left":125},[20,721,722,735,754],{},[23,723,724,727],{},[33,725,726],{},"git: command not found",[20,728,729,732],{},[23,730,731],{},"Git is missing, or this terminal cannot find it",[23,733,734],{},"Close the terminal and reopen the correct one",[23,736,737,740],{},[33,738,739],{},"not a git repository",[20,741,742,745],{},[23,743,744],{},"The command ran outside a cloned repository",[23,746,747,748,750,751,753],{},"Use ",[33,749,39],{}," and ",[33,752,43],{},", then move to the repo folder",[23,755,756,757],{},"Wrong terminal",[20,758,759],{},[23,760,761],{},"Windows users should switch back to Git Bash",[123,763,764,767],{"v-slot:right":125},[23,765,766],{},"Too many terminals open",[83,768,769,772,782,787,793],{},[23,770,771],{},"Close extra terminal windows",[23,773,774,775],{},"Open the correct terminal\n",[20,776,777,779],{},[23,778,65],{},[23,780,781],{},"Apple macOS\u002FLinux: Terminal",[23,783,784,785],{},"Run ",[33,786,35],{},[23,788,784,789,750,791],{},[33,790,39],{},[33,792,43],{},[23,794,795],{},"Continue only after the folder looks right",[11,797,799,803],{"id":798,"level":14},"further-learning",[16,800,802],{"id":801},"key-terms-and-further-learning","Key Terms And Further Learning",[116,804,805,830],{"gap":118,"left-width":717,"right-width":717},[123,806,807,811,818,824],{"v-slot:left":125},[112,808,810],{"id":809},"key-terms","Key Terms",[104,812,813,817],{},[814,815,816],"strong",{},"Terminal"," - A text-based interface where you type commands to control your computer",[104,819,820,823],{},[814,821,822],{},"CLI (Command Line Interface)"," - The text-based interface where you type commands",[104,825,826,829],{},[814,827,828],{},"Git"," - A tool for tracking changes in code files over time",[123,831,832,835],{"v-slot:right":125},[112,833,834],{"id":798},"Further Learning",[20,836,837,844,850,856],{},[23,838,839],{},[89,840,843],{"href":841,"rel":842},"https:\u002F\u002Fgit-scm.com\u002Fdownloads",[93],"Git Downloads",[23,845,846],{},[89,847,849],{"href":91,"rel":848},[93],"Git For Windows Install Page",[23,851,852],{},[89,853,855],{"href":560,"rel":854},[93],"iTerm2 Downloads",[23,857,858],{},[89,859,862],{"href":860,"rel":861},"https:\u002F\u002Fgnunn1.github.io\u002Ftilix-web\u002F",[93],"Tilix",[11,864,866,869,872],{"id":865,"level":14},"summary",[16,867,868],{"id":865},"Summary",[104,870,871],{},"Before moving on, confirm you can:",[20,873,874,877,881,888,891],{},[23,875,876],{},"Open the correct terminal for your operating system",[23,878,784,879],{},[33,880,35],{},[23,882,747,883,750,885,887],{},[33,884,39],{},[33,886,43],{}," to check your location",[23,889,890],{},"Understand what terminal\u002FCLI refers to",[23,892,893],{},"Keep track of terminal instances",{"title":125,"searchDepth":895,"depth":895,"links":896},2,[897,898,899,915,918,921,922,923,924,925],{"id":13,"depth":895,"text":18},{"id":50,"depth":895,"text":51},{"id":80,"depth":895,"text":81,"children":900},[901,903,904,905,906,907,908,909,910,911,912,913,914],{"id":109,"depth":902,"text":114},3,{"id":155,"depth":902,"text":158},{"id":187,"depth":902,"text":190},{"id":219,"depth":902,"text":222},{"id":254,"depth":902,"text":257},{"id":286,"depth":902,"text":287},{"id":316,"depth":902,"text":317},{"id":356,"depth":902,"text":357},{"id":386,"depth":902,"text":387},{"id":414,"depth":902,"text":417},{"id":443,"depth":902,"text":446},{"id":496,"depth":902,"text":497},{"id":511,"depth":902,"text":514},{"id":528,"depth":895,"text":531,"children":916},[917],{"id":551,"depth":902,"text":552},{"id":573,"depth":895,"text":576,"children":919},[920],{"id":609,"depth":902,"text":610},{"id":627,"depth":895,"text":628},{"id":669,"depth":895,"text":670},{"id":711,"depth":895,"text":714},{"id":801,"depth":895,"text":802},{"id":865,"depth":895,"text":868},"presentation","Internet Applications","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.","10","35","45","md",{},"1",true,"20","\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools",false,{"title":5,"description":928},"published","internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools",[245,944,945],"terminal","setup","21:30","u1x5bq-JmCg","https:\u002F\u002Fyoutu.be\u002Fu1x5bq-JmCg","71DrP8YI_ks4jUswWJXy9rmZOVVoeaJAEPancHNHsV4",null,[],[953,1446,2504,3164,4260,5199,5990,7057,7783,8608],{"id":954,"title":955,"audience":6,"body":956,"contentType":926,"course":927,"description":1429,"estimateBasis":1430,"estimatedDiscussionMinutes":930,"estimatedLiveMinutes":937,"estimatedTotalMinutes":1431,"extension":933,"meta":1432,"module":935,"navigation":936,"order":1433,"path":1434,"promptAssist":939,"seo":1435,"status":941,"stem":1436,"tags":1437,"videoDuration":1441,"videoId":1442,"videoLink":1443,"videoTitle":1444,"week":935,"__hash__":1445},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord.md","Learn Courses Platform And Discord",{"type":8,"value":957,"toc":1414},[958,992,1032,1076,1125,1173,1206,1268,1309,1359,1388],[11,959,961,965,979],{"id":960,"level":14},"learn-courses-flow",[16,962,964],{"id":963},"what-is-the-learn-courses-platform","What is the Learn Courses Platform",[20,966,967,970,973,976],{},[23,968,969],{},"This is a platform I've built over the years to aid assignment submissions and course utilities",[23,971,972],{},"It provides objective-based worksheets to fill in images, urls, and open responses to document assignment evidence",[23,974,975],{},"The goal is to keep tasks clear and objective for students and grading",[23,977,978],{},"Also includes a few other utilities for courses (such as joining the Discord server)",[104,980,981,982,986,987,991],{},"NOTE: Summer 2026 the previous Learn Platform (",[89,983,984],{"href":984,"rel":985},"https:\u002F\u002Flearn.ethereallab.app",[93],") has been replaced by Learn Courses Platform (",[89,988,989],{"href":989,"rel":990},"https:\u002F\u002Fcourses.ethereallab.app",[93],"). The deprecated site is still available as a backup but all activities\u002Fcontent is being migrated to the new version",[11,993,995,998,1001,1029],{"id":994,"level":14},"learn-courses-title",[16,996,955],{"id":997},"learn-courses-platform-and-discord",[104,999,1000],{},"How to join:",[20,1002,1003,1009,1017,1020,1023,1026],{},[23,1004,1005,1006],{},"Visit the platform ",[89,1007,989],{"href":989,"rel":1008},[93],[23,1010,1011,1012],{},"Sign in with your NJIT email\n",[20,1013,1014],{},[23,1015,1016],{},"If you're in the Canvas course, you should automatically get synced to this platform",[23,1018,1019],{},"Visit your Profile page",[23,1021,1022],{},"Associate your Discord account",[23,1024,1025],{},"Join the course Discord server",[23,1027,1028],{},"Verify that your course channels appear on Discord",[104,1030,1031],{},"You can follow the steps on the below slides for guidance",[11,1033,1035,1038],{"id":1034,"level":110},"visit-learn-courses",[16,1036,1037],{"id":1034},"Visit Learn Courses",[116,1039,1040,1068],{"gap":118,"left-width":717,"right-width":717},[123,1041,1042,1045,1050],{"v-slot:left":125},[104,1043,1044],{},"Go to:",[104,1046,1047],{},[89,1048,989],{"href":989,"rel":1049},[93],[20,1051,1052,1059,1062,1065],{},[23,1053,1054,1055,1058],{},"Click the ",[814,1056,1057],{},"Login"," button",[23,1060,1061],{},"Use your NJIT email",[23,1063,1064],{},"Only NJIT accounts are allowed",[23,1066,1067],{},"If the browser tries a personal Chrome profile, log out of that account or switch profiles",[123,1069,1070],{"v-slot:right":125},[104,1071,1072],{},[129,1073],{"alt":1074,"src":1075,"variant":133},"Learn Courses logged-out home page with the Login button visible","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fhome-loggedout-login-button.png",[11,1077,1079,1082],{"id":1078,"level":110},"associate-discord-name",[16,1080,1081],{"id":1078},"Associate Discord Name",[116,1083,1084,1109],{"gap":118,"left-width":717,"right-width":717},[123,1085,1086,1089,1106],{"v-slot:left":125},[104,1087,1088],{},"On Learn Courses:",[83,1090,1091,1094,1100,1103],{},[23,1092,1093],{},"Open your Profile",[23,1095,1096,1097],{},"Click ",[814,1098,1099],{},"Refresh Discord Username",[23,1101,1102],{},"Authorize the Discord prompt",[23,1104,1105],{},"After the success message appears, save your profile",[104,1107,1108],{},"If you are not sure where you are, use the Home icon in the top left to return to the dashboard.",[123,1110,1111,1118],{"v-slot:right":125},[104,1112,1113],{},[129,1114],{"alt":1115,"src":1116,"variant":133,"max-height":1117},"Learn Courses dashboard sidebar with Profile and course links visible","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdashboard-sidebar-profile-links.png","13rem",[104,1119,1120],{},[129,1121],{"alt":1122,"src":1123,"variant":133,"max-height":1124},"Learn Courses profile page with Discord connection controls visible","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fprofile-page.png","16rem",[11,1126,1128,1131],{"id":1127,"level":110},"authorize-discord",[16,1129,1130],{"id":1127},"Authorize Discord",[116,1132,1133,1157],{"gap":118,"left-width":717,"right-width":717},[123,1134,1135,1138],{"v-slot:left":125},[104,1136,1137],{},"Discord will ask whether Learn Courses can access your Discord account.",[20,1139,1140,1143,1148,1151,1154],{},[23,1141,1142],{},"Confirm you are signed in to the correct Discord account",[23,1144,1096,1145],{},[814,1146,1147],{},"Authorize",[23,1149,1150],{},"Return to Learn Courses",[23,1152,1153],{},"Look for the success message",[23,1155,1156],{},"Save the profile change",[123,1158,1159,1166],{"v-slot:right":125},[104,1160,1161],{},[129,1162],{"alt":1163,"src":1164,"variant":133,"max-height":1165},"Discord authorization prompt for Learn Courses","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdiscord-auth.png","25rem",[104,1167,1168],{},[129,1169],{"alt":1170,"src":1171,"variant":133,"max-height":1172},"Learn Courses success message after connecting Discord","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdiscord-connected-success.png","7rem",[11,1174,1176,1179,1182,1188,1195],{"id":1175,"level":110},"join-the-channel",[16,1177,1178],{"id":1175},"Join The Channel",[104,1180,1181],{},"Use the Discord link provided on Canvas, or use:",[104,1183,1184],{},[89,1185,1186],{"href":1186,"rel":1187},"https:\u002F\u002Fdiscord.com\u002Finvite\u002FYEHcm44wzg",[93],[104,1189,1190,1191,1194],{},"This should send you to the ",[33,1192,1193],{},"access-channel"," channel.",[20,1196,1197,1200,1203],{},[23,1198,1199],{},"Other channels are protected by a bot",[23,1201,1202],{},"Messages may be blocked until your name and role are set",[23,1204,1205],{},"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,1207,1209,1212],{"id":1208,"level":14},"verify-with-quackbot",[16,1210,1211],{"id":1208},"Verify With QuackBot",[116,1213,1214,1259],{"gap":118,"left-width":717,"right-width":717},[123,1215,1216,1228,1234,1239,1242,1256],{"v-slot:left":125},[20,1217,1218,1221],{},[23,1219,1220],{},"A summer 2026 change was to have the bot attempt to auto-detect new members and apply roles automatically",[23,1222,1223,1224,1227],{},"If you don't see the proper semester category (i.e., ",[33,1225,1226],{},"summer-2026",") or the expected channels you can do the below action",[104,1229,1230,1231,1233],{},"In ",[33,1232,1193],{},", enter:",[104,1235,1236],{},[33,1237,1238],{},"@QuackBot",[104,1240,1241],{},"QuackBot will:",[20,1243,1244,1247,1250,1253],{},[23,1245,1246],{},"Verify your account",[23,1248,1249],{},"Pull in your name and section",[23,1251,1252],{},"Apply your class role",[23,1254,1255],{},"Update your server nickname",[104,1257,1258],{},"This does not change your real Discord username.",[123,1260,1261],{"v-slot:right":125},[104,1262,1263],{},[129,1264],{"alt":1265,"src":1266,"variant":133,"max-height":1267},"QuackBot response showing the student already has a course role","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fquackbot-role-response.png","8rem",[11,1269,1271,1275,1278,1289,1293],{"id":1270,"level":14},"welcome-and-potential-issues",[16,1272,1274],{"id":1273},"welcome","Welcome",[104,1276,1277],{},"If the previous steps worked, you should see a new semester category in the Discord sidebar.",[20,1279,1280,1283,1286],{},[23,1281,1282],{},"It should appear after the general channels",[23,1284,1285],{},"It should include one or more channels for your active courses",[23,1287,1288],{},"Use the correct course channel for class questions and discussion",[112,1290,1292],{"id":1291},"potential-issues","Potential Issues",[20,1294,1295,1298],{},[23,1296,1297],{},"If you recently joined the class, your UCID may still need to be added to Learn Courses",[23,1299,1300,1301,1304],{},"If there is an issue, email the instructor or DM ",[33,1302,1303],{},"MattToegel",[20,1305,1306],{},[23,1307,1308],{},"Some Discord privacy settings may require a friend request before DMs work",[11,1310,1312,1315],{"id":1311,"level":14},"general-conduct",[16,1313,1314],{"id":1311},"General Conduct",[20,1316,1317,1320,1323,1334,1337,1345,1353,1356],{},[23,1318,1319],{},"Use class-related channels for questions and discussion",[23,1321,1322],{},"Ask general course questions in the channel instead of DM when possible",[23,1324,1325,1326],{},"Do not post screenshots of in-progress assignment solutions\n",[20,1327,1328,1331],{},[23,1329,1330],{},"This would be more ideal for a DM",[23,1332,1333],{},"If you see posted solution-like items don't assume they're correct",[23,1335,1336],{},"General unrelated code is okay when it supports a discussion (like content from a presentation or reading)",[23,1338,1339,1340],{},"If the instructor needs to see assignment code, they may ask you to DM the screenshot\n",[20,1341,1342],{},[23,1343,1344],{},"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",[23,1346,1347,1348],{},"Keep off-topic items out of class channels\n",[20,1349,1350],{},[23,1351,1352],{},"There are plenty of categorized channels to use and I can always make more",[23,1354,1355],{},"Helping classmates understand topics is encouraged just be mindful not to spoon-feed",[23,1357,1358],{},"Sharing direct solutions goes against the Academic Integrity Policy",[11,1360,1362,1365,1368],{"id":1361,"level":14},"quick-check",[16,1363,1364],{"id":1361},"Quick Check",[104,1366,1367],{},"Before continuing, confirm:",[20,1369,1370,1373,1376,1379,1382,1385],{},[23,1371,1372],{},"You can sign in to Learn Courses with your NJIT email",[23,1374,1375],{},"Your profile is saved",[23,1377,1378],{},"Discord is associated with your Learn Courses profile",[23,1380,1381],{},"You joined the Discord server",[23,1383,1384],{},"QuackBot applied your course role",[23,1386,1387],{},"You can see the correct course channel",[11,1389,1390,1392],{"id":865,"level":14},[16,1391,868],{"id":865},[20,1393,1394,1397,1405,1408,1411],{},[23,1395,1396],{},"Learn Courses supports course tools and course-specific setup",[23,1398,1399,1400],{},"Canvas remains the official assignment, grade, and course hub\n",[20,1401,1402],{},[23,1403,1404],{},"All necessary items will be linked on Canvas",[23,1406,1407],{},"Discord is the preferred quick communication channel",[23,1409,1410],{},"QuackBot connects your Discord account to the correct course role",[23,1412,1413],{},"Good course communication keeps help requests specific and protects private information",{"title":125,"searchDepth":895,"depth":895,"links":1415},[1416,1417,1418,1419,1420,1421,1422,1423,1426,1427,1428],{"id":963,"depth":895,"text":964},{"id":997,"depth":895,"text":955},{"id":1034,"depth":895,"text":1037},{"id":1078,"depth":895,"text":1081},{"id":1127,"depth":895,"text":1130},{"id":1175,"depth":895,"text":1178},{"id":1208,"depth":895,"text":1211},{"id":1273,"depth":895,"text":1274,"children":1424},[1425],{"id":1291,"depth":902,"text":1292},{"id":1311,"depth":895,"text":1314},{"id":1361,"depth":895,"text":1364},{"id":865,"depth":895,"text":868},"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.","30",{},"0","\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord",{"title":955,"description":1429},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord",[1438,1439,1440,945],"course-tools","learn-courses","discord","11:16","ScmHyEF1sA0","https:\u002F\u002Fyoutu.be\u002FScmHyEF1sA0","Joining Learn Platform and Discord Server","tEFV7lUabcy7whz7FSHEjPXSirrd3ginqQq4O4AkW9o",{"id":1447,"title":1448,"audience":6,"body":1449,"contentType":926,"course":927,"description":2490,"estimateBasis":2491,"estimatedDiscussionMinutes":930,"estimatedLiveMinutes":932,"estimatedTotalMinutes":2492,"extension":933,"meta":2493,"module":935,"navigation":936,"order":930,"path":2494,"promptAssist":939,"seo":2495,"status":941,"stem":2496,"tags":2497,"videoDuration":2500,"videoId":2501,"videoLink":2502,"videoTitle":1448,"week":935,"__hash__":2503},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands.md","Basic CLI Commands",{"type":8,"value":1450,"toc":2456},[1451,1509,1542,1573,1634,1701,1752,1778,1795,1833,1861,1882,1917,1939,2011,2034,2078,2140,2192,2220,2240,2268,2306,2336,2346,2409],[11,1452,1454,1458],{"id":1453,"level":14},"why-cli-first",[16,1455,1457],{"id":1456},"why-cli-comes-first","Why CLI Comes First",[20,1459,1460,1468,1476,1490,1498],{},[23,1461,1462,1463],{},"Common language for setup and developer tools\n",[20,1464,1465],{},[23,1466,1467],{},"Git, servers, package installs, deployment logs",[23,1469,1470,1471],{},"Works when there is no full desktop\n",[20,1472,1473],{},[23,1474,1475],{},"SSH, Ubuntu Server, minimal system access",[23,1477,1478,1479],{},"Direct check of what the computer sees\n",[20,1480,1481,1484,1487],{},[23,1482,1483],{},"Current folder",[23,1485,1486],{},"Files and permissions",[23,1488,1489],{},"Command output",[23,1491,1492,1493],{},"Repeatable steps beat guessing through menus\n",[20,1494,1495],{},[23,1496,1497],{},"Run a command, read output, adjust",[23,1499,1500,1501],{},"Location still matters\n",[20,1502,1503,1506],{},[23,1504,1505],{},"Wrong folder can make correct commands fail",[23,1507,1508],{},"Or create files in the wrong place",[11,1510,1511,1513,1516],{"id":13,"level":14},[16,1512,18],{"id":13},[104,1514,1515],{},"Build the command-line habits that make setup work predictable:",[20,1517,1518,1521,1524,1536,1539],{},[23,1519,1520],{},"Know what folder the terminal is using",[23,1522,1523],{},"Read file and folder lists before moving",[23,1525,1526,1527,36,1530,40,1533],{},"Recognize common flags like ",[33,1528,1529],{},"-a",[33,1531,1532],{},"-r",[33,1534,1535],{},"-l",[23,1537,1538],{},"Make small file changes and verify them",[23,1540,1541],{},"Stop safely when output does not match the lesson",[11,1543,1545,1548,1551,1570],{"id":1544,"level":14},"before-you-start",[16,1546,1547],{"id":1544},"Before You Start",[104,1549,1550],{},"Run these commands on your host computer",[20,1552,1553,1564,1567],{},[23,1554,65,1555],{},[20,1556,1557],{},[23,1558,1559,1560],{},"Need Git Bash now? Use the Windows install slide in the next presentation:\n",[89,1561,1563],{"href":1562},"\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",[23,1565,1566],{},"Apple macOS: Terminal",[23,1568,1569],{},"Linux: Terminal",[104,1571,1572],{},"Use one terminal window for the whole practice so your location is easy to track",[11,1574,1576,1580],{"id":1575,"level":14},"working-directory",[16,1577,1579],{"id":1578},"the-main-idea","The Main Idea",[20,1581,1582,1593,1603,1626],{},[23,1583,1584,1585],{},"Terminal commands run from one folder at a time\n",[20,1586,1587],{},[23,1588,1589,1590],{},"That folder is the ",[814,1591,1592],{},"working directory",[23,1594,1595,1597,1598],{},[33,1596,39],{},": print working directory\n",[20,1599,1600],{},[23,1601,1602],{},"Shows the full path to the folder your terminal is using",[23,1604,1605,1606],{},"Fresh terminal usually starts in your home folder\n",[20,1607,1608,1614,1620],{},[23,1609,1610,1611],{},"Windows Git Bash: ",[33,1612,1613],{},"\u002Fc\u002FUsers\u002Fyour-username",[23,1615,1616,1617],{},"Apple macOS: ",[33,1618,1619],{},"\u002FUsers\u002Fyour-username",[23,1621,1622,1623],{},"Linux: ",[33,1624,1625],{},"\u002Fhome\u002Fyour-username",[23,1627,1628,1629],{},"Commands from this lesson start from the working directory\n",[20,1630,1631],{},[23,1632,1633],{},"Unless you give a different path",[11,1635,1637,1640,1643,1695],{"id":1636,"level":14},"paths-relative-and-absolute",[16,1638,1639],{"id":1636},"Paths: Relative And Absolute",[104,1641,1642],{},"Paths build on the working directory. They tell the terminal which file or folder you mean",[20,1644,1645,1651,1657,1663,1689],{},[23,1646,1647,1648],{},"Relative path: starts from the working directory, like ",[33,1649,1650],{},"public\u002Findex.php",[23,1652,1653,1654],{},"Absolute path: starts from the system root, like ",[33,1655,1656],{},"\u002Fhome\u002Fstudent\u002Fproject",[23,1658,1659,1662],{},[33,1660,1661],{},"."," means the current folder",[23,1664,1665,1668,1669],{},[33,1666,1667],{},".."," means the parent folder\n",[20,1670,1671,1677,1683],{},[23,1672,1673,1676],{},[33,1674,1675],{},"..\u002F.."," goes up two folders",[23,1678,1679,1680],{},"Example: ",[33,1681,1682],{},"cd ..\u002F..",[23,1684,1685,1688],{},[33,1686,1687],{},"..."," is not a shortcut",[23,1690,1691,1694],{},[33,1692,1693],{},"~"," means your home folder",[104,1696,1697,1698,1700],{},"If a command affects the wrong place, check ",[33,1699,39],{}," first, then check the path you typed",[11,1702,1704,1707,1710,1729,1732],{"id":1703,"level":14},"flags-options-and-arguments",[16,1705,1706],{"id":1703},"Flags, Options, And Arguments",[104,1708,1709],{},"Commands usually follow this shape:",[20,1711,1712,1718,1723],{},[23,1713,1714,1715],{},"Command: what to do, like ",[33,1716,1717],{},"ls",[23,1719,1720,1721],{},"Flag or option: how to do it, like ",[33,1722,1529],{},[23,1724,1725,1726],{},"Argument: what to do it to, like ",[33,1727,1728],{},"public_html",[104,1730,1731],{},"Examples:",[20,1733,1734,1740,1746],{},[23,1735,1736,1739],{},[33,1737,1738],{},"ls -a"," shows hidden files",[23,1741,1742,1745],{},[33,1743,1744],{},"cp -r folder backup-folder"," copies a folder",[23,1747,1748,1751],{},[33,1749,1750],{},"nano -l file.txt"," opens with line numbers",[11,1753,1755,1759,1762,1773],{"id":1754,"level":14},"practice-loop",[16,1756,1758],{"id":1757},"practice-1-location-and-paths","Practice 1: Location And Paths",[104,1760,1761],{},"For each command, use the same pattern:",[83,1763,1764,1767,1770],{},[23,1765,1766],{},"Run one command",[23,1768,1769],{},"Read the output",[23,1771,1772],{},"Confirm the folder or file changed the way you expected",[20,1774,1775],{},[23,1776,1777],{},"See the slides below for workflow steps, checkpoints, and expected results",[11,1779,1781,1784,1786,1789,1792],{"id":1780,"level":110},"step-1-confirm-where-you-are",[16,1782,1783],{"id":1780},"Step 1: Confirm Where You Are",[104,1785,637],{},[595,1787],{"language":597,"src":1788},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-1-confirm-where-you-01.sh",[104,1790,1791],{},"Expected result: a folder path",[104,1793,1794],{},"If you see a path, the terminal is working and you know your current location",[11,1796,1798,1801,1803,1806,1809,1812,1815],{"id":1797,"level":110},"step-2-list-files",[16,1799,1800],{"id":1797},"Step 2: List Files",[104,1802,637],{},[595,1804],{"language":597,"src":1805},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-list-files-02.sh",[104,1807,1808],{},"Expected result: file and folder names from your current location",[104,1810,1811],{},"For hidden files and details too, run:",[595,1813],{"language":597,"src":1814},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-list-files-03.sh",[20,1816,1817,1822,1827],{},[23,1818,1819,1821],{},[33,1820,1529],{}," includes hidden files",[23,1823,1824,1826],{},[33,1825,1535],{}," uses a long listing",[23,1828,1829,1832],{},[33,1830,1831],{},"-la"," combines both",[11,1834,1836,1839,1842,1845,1852,1858],{"id":1835,"level":110},"step-3-change-folders",[16,1837,1838],{"id":1835},"Step 3: Change Folders",[104,1840,1841],{},"Start from your home folder, then move up and back",[595,1843],{"language":597,"src":1844},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-3-change-folders-04.sh",[104,1846,1847,1848,1851],{},"This avoids assuming your computer has a specific folder like ",[33,1849,1850],{},"Documents"," in the current location",[104,1853,1854,1855,1857],{},"When you move into a named folder later, run ",[33,1856,1717],{}," first and pick a folder that actually appears in the list",[104,1859,1860],{},"If a path has spaces, wrap it in quotes",[11,1862,1864,1868,1870,1873],{"id":1863,"level":110},"step-4-create-practice-folder",[16,1865,1867],{"id":1866},"step-4-create-a-practice-folder","Step 4: Create A Practice Folder",[104,1869,637],{},[595,1871],{"language":597,"src":1872},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-4-create-a-practice-05.sh",[104,1874,1875,1876,1878,1879],{},"Expected result: ",[33,1877,39],{}," ends with ",[33,1880,1881],{},"cli-practice",[11,1883,1885,1889,1891,1894,1897],{"id":1884,"level":110},"step-5-create-and-read-file",[16,1886,1888],{"id":1887},"step-5-write-text-to-a-file","Step 5: Write Text To A File",[104,1890,637],{},[595,1892],{"language":597,"src":1893},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-5-write-text-to-a-f-06.sh",[104,1895,1896],{},"What this command does:",[20,1898,1899,1905,1911],{},[23,1900,1901,1904],{},[33,1902,1903],{},"echo"," prepares text for the terminal",[23,1906,1907,1910],{},[33,1908,1909],{},">"," redirects that text into a file instead of printing it on screen",[23,1912,1913,1916],{},[33,1914,1915],{},"cli-proof.txt"," is created in the current folder, or replaced if it already exists",[11,1918,1920,1924,1927,1930,1936],{"id":1919,"level":110},"step-5-read-file-back",[112,1921,1923],{"id":1922},"step-5-continued-read-the-file-back","Step 5 Continued: Read The File Back",[104,1925,1926],{},"Then read it back:",[595,1928],{"language":597,"src":1929},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-5-continued-read-th-07.sh",[104,1931,1932,1935],{},[33,1933,1934],{},"cat"," prints file contents in the terminal",[104,1937,1938],{},"Expected result: the terminal prints the text you wrote",[11,1940,1942,1946,1948,1957,1960,1986,1989],{"id":1941,"level":14},"file-management-loop",[16,1943,1945],{"id":1944},"practice-2-file-management","Practice 2: File Management",[104,1947,1761],{},[83,1949,1950,1952,1954],{},[23,1951,1766],{},[23,1953,1769],{},[23,1955,1956],{},"Confirm the file changed the way you expected",[104,1958,1959],{},"Commands in this practice:",[20,1961,1962,1968,1974,1980],{},[23,1963,1964,1967],{},[33,1965,1966],{},"touch"," creates an empty file",[23,1969,1970,1973],{},[33,1971,1972],{},"cp"," copies a file or folder",[23,1975,1976,1979],{},[33,1977,1978],{},"mv"," moves or renames",[23,1981,1982,1985],{},[33,1983,1984],{},"rm"," deletes",[104,1987,1988],{},"Important flags:",[20,1990,1991,1997,2003,2009],{},[23,1992,1993,1996],{},[33,1994,1995],{},"cp -r"," copies folders",[23,1998,1999,2002],{},[33,2000,2001],{},"rm -r"," deletes folders",[23,2004,2005,2008],{},[33,2006,2007],{},"rm -f"," forces deletion",[23,2010,1777],{},[11,2012,2014,2018,2020,2023,2028],{"id":2013,"level":110},"practice-2-step-1-create-empty-file",[16,2015,2017],{"id":2016},"step-1-create-an-empty-file","Step 1: Create An Empty File",[104,2019,637],{},[595,2021],{"language":597,"src":2022},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-1-create-an-empty-f-08.sh",[104,2024,2025,2027],{},[33,2026,1966],{}," creates an empty file, or updates the timestamp if the file already exists",[104,2029,1875,2030,2033],{},[33,2031,2032],{},"practice-empty.txt"," appears in the folder list",[11,2035,2037,2041,2043,2046,2049,2054,2067],{"id":2036,"level":110},"practice-2-step-2-copy-rename-and-delete",[16,2038,2040],{"id":2039},"step-2-copy-rename-and-delete","Step 2: Copy, Rename, And Delete",[104,2042,637],{},[595,2044],{"language":597,"src":2045},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-copy-rename-and-d-09.sh",[104,2047,2048],{},"Expected result: the backup is copied, renamed, then removed",[104,2050,747,2051,2053],{},[33,2052,1984],{}," carefully. Deleting from the terminal usually skips the recycle bin",[20,2055,2056,2061],{},[23,2057,2058,2060],{},[33,2059,1532],{},": recursive, includes folders and everything inside them",[23,2062,2063,2066],{},[33,2064,2065],{},"-f",": force, skips many confirmation prompts",[2068,2069,2071],"alert",{"color":2070},"red",[104,2072,2073,2074,2077],{},"Never run ",[33,2075,2076],{},"rm -rf \u002F",". It can try to delete the whole system from the root folder.",[11,2079,2081,2085,2088,2105,2110,2115,2135],{"id":2080,"level":14},"terminal-editors",[16,2082,2084],{"id":2083},"practice-3-terminal-editors","Practice 3: Terminal Editors",[104,2086,2087],{},"Sometimes you need to edit a file from a terminal",[20,2089,2090,2095],{},[23,2091,2092,2094],{},[33,2093,180],{}," is beginner-friendly",[23,2096,2097,2100,2101,2104],{},[33,2098,2099],{},"vi"," or ",[33,2102,2103],{},"vim"," is common on servers but has a learning curve",[104,2106,747,2107,2109],{},[33,2108,180],{}," for this course unless a lesson says otherwise",[104,2111,747,2112,2114],{},[33,2113,1750],{}," when line numbers would help",[104,2116,2117,2118,2100,2120,2122,2123,2126,2127,2130,2131,2134],{},"If you accidentally open ",[33,2119,2099],{},[33,2121,2103],{},", press ",[33,2124,2125],{},"Esc",", type ",[33,2128,2129],{},":q",", and press ",[33,2132,2133],{},"Enter"," to exit without saving",[20,2136,2137],{},[23,2138,2139],{},"See the slide below for workflow steps, checkpoints, and expected results",[11,2141,2143,2148,2150,2153,2158,2180],{"id":2142,"level":110},"edit-with-nano",[16,2144,2145,2146],{"id":2142},"Edit With ",[33,2147,180],{},[104,2149,637],{},[595,2151],{"language":597,"src":2152},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fedit-with-nano-10.sh",[104,2154,1230,2155,2157],{},[33,2156,180],{},":",[20,2159,2160,2163,2170,2174],{},[23,2161,2162],{},"Type a short note",[23,2164,2165,2166,2169],{},"Press ",[33,2167,2168],{},"Ctrl+O"," to save",[23,2171,2165,2172],{},[33,2173,2133],{},[23,2175,2165,2176,2179],{},[33,2177,2178],{},"Ctrl+X"," to exit",[104,2181,2182,2183,2185,2186,2126,2188,2130,2190],{},"If you open ",[33,2184,2099],{}," by mistake, press ",[33,2187,2125],{},[33,2189,2129],{},[33,2191,2133],{},[11,2193,2195,2201,2206,2209,2212,2215],{"id":2194,"level":14},"sudo-and-permission-boundaries",[16,2196,2197,2200],{"id":2194},[33,2198,2199],{},"sudo"," And Permission Boundaries",[104,2202,2203,2205],{},[33,2204,2199],{}," runs a command with elevated permissions",[104,2207,2208],{},"Use it only when a setup lesson explicitly says to use it",[104,2210,2211],{},"Example:",[595,2213],{"language":597,"src":2214},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fsudo-and-permission-boun-11.sh",[20,2216,2217],{},[23,2218,2219],{},"See the slide below for supporting examples and follow-up details",[11,2221,2223,2228,2234],{"id":2222,"level":110},"sudo-by-operating-system",[112,2224,2225,2227],{"id":2222},[33,2226,2199],{}," By Operating System",[104,2229,2230,2231,2233],{},"On Linux and macOS, ",[33,2232,2199],{}," is common for package installation and service management",[104,2235,2236,2237,2239],{},"Modern Windows also has a native ",[33,2238,2199],{}," 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,2241,2243,2246,2249,2260],{"id":2242,"level":14},"quick-safety-routine",[16,2244,2245],{"id":2242},"Quick Safety Routine",[104,2247,2248],{},"Before a command changes files, ask:",[20,2250,2251,2254,2257],{},[23,2252,2253],{},"What folder am I in?",[23,2255,2256],{},"Do I see the files I expect?",[23,2258,2259],{},"Am I about to change the right folder?",[104,2261,2262,2263,2265,2266],{},"If one answer is unclear, stop and run ",[33,2264,39],{}," plus ",[33,2267,43],{},[11,2269,2270,2272],{"id":711,"level":14},[16,2271,714],{"id":711},[20,2273,2274,2290,2296,2304],{},[23,2275,2276,2279,2280,2282,2283,2285,2286,2289],{},[33,2277,2278],{},"No such file or directory",": run ",[33,2281,39],{},", then ",[33,2284,1717],{},", then try ",[33,2287,2288],{},"cd"," again",[23,2291,2292,2293,2295],{},"Command affected the wrong folder: check ",[33,2294,39],{}," before continuing",[23,2297,2298,2300,2301,2303],{},[33,2299,1934],{}," cannot find the file: run ",[33,2302,43],{}," and check the exact filename",[23,2305,2219],{},[11,2307,2309,2313],{"id":2308,"level":110},"common-mistakes-recovery",[112,2310,2312],{"id":2311},"recovery-checks","Recovery Checks",[20,2314,2315,2318,2324,2330],{},[23,2316,2317],{},"Spaces in a path: wrap the path in quotes",[23,2319,2320,2321],{},"Command keeps running: press ",[33,2322,2323],{},"Ctrl+C",[23,2325,2326,2327],{},"Permission denied: move back home with ",[33,2328,2329],{},"cd ~",[23,2331,2332,2333,2335],{},"Wrong ",[33,2334,1984],{},": stop and ask before doing more work",[11,2337,2338,2340,2343],{"id":1361,"level":14},[16,2339,1364],{"id":1361},[104,2341,2342],{},"You are ready for the next setup lesson when these commands make sense:",[595,2344],{"language":597,"src":2345},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fquick-check-12.sh",[11,2347,2348,2350],{"id":798,"level":14},[16,2349,802],{"id":801},[116,2351,2352,2382],{"gap":118,"left-width":717,"right-width":717},[123,2353,2354,2356,2362,2371],{"v-slot:left":125},[112,2355,810],{"id":809},[104,2357,2358,2361],{},[814,2359,2360],{},"Working directory"," - The folder where the next terminal command runs",[104,2363,2364,2367,2368],{},[814,2365,2366],{},"Path"," - A file or folder location, such as ",[33,2369,2370],{},"public_html\u002Findex.php",[104,2372,2373,2376,2377,2379,2380],{},[814,2374,2375],{},"Flag"," - An extra command option, such as ",[33,2378,1831],{}," in ",[33,2381,43],{},[123,2383,2384,2386],{"v-slot:right":125},[112,2385,834],{"id":798},[20,2387,2388,2395,2402],{},[23,2389,2390],{},[89,2391,2394],{"href":2392,"rel":2393},"https:\u002F\u002Fdocumentation.ubuntu.com\u002Fdesktop\u002Fen\u002Flatest\u002Ftutorial\u002Fthe-linux-command-line-for-beginners\u002F",[93],"Ubuntu Tutorial: The Linux Command Line For Beginners",[23,2396,2397],{},[89,2398,2401],{"href":2399,"rel":2400},"https:\u002F\u002Fwww.gnu.org\u002Fsoftware\u002Fcoreutils\u002Fmanual\u002Fcoreutils.html",[93],"GNU Coreutils Manual",[23,2403,2404],{},[89,2405,2408],{"href":2406,"rel":2407},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FLearn_web_development\u002FGetting_started\u002FEnvironment_setup\u002FCommand_line",[93],"MDN: Command Line Crash Course",[11,2410,2411,2413,2416],{"id":865,"level":14},[16,2412,868],{"id":865},[104,2414,2415],{},"Before leaving this presentation, confirm you can:",[20,2417,2418,2423,2428,2439,2453],{},[23,2419,747,2420,2422],{},[33,2421,39],{}," to check where commands will run",[23,2424,747,2425,2427],{},[33,2426,43],{}," to inspect the current folder",[23,2429,747,2430,36,2432,36,2434,40,2436,2438],{},[33,2431,2288],{},[33,2433,1661],{},[33,2435,1667],{},[33,2437,1693],{}," to move intentionally",[23,2440,2441,2442,36,2444,36,2446,36,2448,40,2450,2452],{},"Use file commands such as ",[33,2443,1966],{},[33,2445,1972],{},[33,2447,1978],{},[33,2449,1984],{},[33,2451,180],{}," carefully",[23,2454,2455],{},"Stop and check location when output does not match the lesson",{"title":125,"searchDepth":895,"depth":895,"links":2457},[2458,2459,2460,2461,2462,2463,2464,2465,2466,2467,2468,2469,2472,2473,2474,2475,2476,2478,2483,2484,2487,2488,2489],{"id":1456,"depth":895,"text":1457},{"id":13,"depth":895,"text":18},{"id":1544,"depth":895,"text":1547},{"id":1578,"depth":895,"text":1579},{"id":1636,"depth":895,"text":1639},{"id":1703,"depth":895,"text":1706},{"id":1757,"depth":895,"text":1758},{"id":1780,"depth":895,"text":1783},{"id":1797,"depth":895,"text":1800},{"id":1835,"depth":895,"text":1838},{"id":1866,"depth":895,"text":1867},{"id":1887,"depth":895,"text":1888,"children":2470},[2471],{"id":1922,"depth":902,"text":1923},{"id":1944,"depth":895,"text":1945},{"id":2016,"depth":895,"text":2017},{"id":2039,"depth":895,"text":2040},{"id":2083,"depth":895,"text":2084},{"id":2142,"depth":895,"text":2477},"Edit With nano",{"id":2194,"depth":895,"text":2479,"children":2480},"sudo And Permission Boundaries",[2481],{"id":2222,"depth":902,"text":2482},"sudo By Operating System",{"id":2242,"depth":895,"text":2245},{"id":711,"depth":895,"text":714,"children":2485},[2486],{"id":2311,"depth":902,"text":2312},{"id":1361,"depth":895,"text":1364},{"id":801,"depth":895,"text":802},{"id":865,"depth":895,"text":868},"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.","55",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands",{"title":1448,"description":2490},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands",[2498,944,2499],"cli","filesystem","46:05","NsSRKv_uBWM","https:\u002F\u002Fyoutu.be\u002FNsSRKv_uBWM","q_NRWUOCcsk5lm6u6kKPFGl9E9VqeQhaC0qb86nD7aY",{"id":4,"title":5,"audience":6,"body":2505,"contentType":926,"course":927,"description":928,"estimateBasis":929,"estimatedDiscussionMinutes":930,"estimatedLiveMinutes":931,"estimatedTotalMinutes":932,"extension":933,"meta":3161,"module":935,"navigation":936,"order":937,"path":938,"promptAssist":939,"seo":3162,"status":941,"stem":942,"tags":3163,"videoDuration":946,"videoId":947,"videoLink":948,"videoTitle":5,"week":935,"__hash__":949},{"type":8,"value":2506,"toc":3131},[2507,2525,2545,2564,2590,2614,2638,2664,2686,2708,2734,2736,2758,2780,2802,2840,2852,2864,2878,2895,2917,2929,2957,2991,3059,3107],[11,2508,2509,2511],{"id":13,"level":14},[16,2510,18],{"id":13},[20,2512,2513,2515,2517],{},[23,2514,25],{},[23,2516,28],{},[23,2518,31,2519,36,2521,40,2523,44],{},[33,2520,35],{},[33,2522,39],{},[33,2524,43],{},[11,2526,2527,2529],{"id":47,"level":14},[16,2528,51],{"id":50},[20,2530,2531,2533,2535,2537,2539,2541,2543],{},[23,2532,56],{},[23,2534,59],{},[23,2536,62],{},[23,2538,65],{},[23,2540,68],{},[23,2542,71],{},[23,2544,74],{},[11,2546,2547,2549,2562],{"id":77,"level":14},[16,2548,81],{"id":80},[83,2550,2551,2556,2558,2560],{},[23,2552,87,2553],{},[89,2554,91],{"href":91,"rel":2555},[93],[23,2557,96],{},[23,2559,99],{},[23,2561,102],{},[104,2563,106],{},[11,2565,2566,2568],{"id":109,"level":110},[112,2567,114],{"id":109},[116,2569,2570,2576],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,2571,2572],{"v-slot:left":125},[104,2573,2574],{},[129,2575],{"alt":131,"src":132,"variant":133},[123,2577,2578],{"v-slot:right":125},[20,2579,2580,2582,2586],{},[23,2581,140],{},[23,2583,143,2584],{},[33,2585,146],{},[23,2587,149,2588],{},[33,2589,152],{},[11,2591,2592,2594],{"id":155,"level":110},[112,2593,158],{"id":155},[116,2595,2596,2602],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,2597,2598],{"v-slot:left":125},[104,2599,2600],{},[129,2601],{"alt":167,"src":168,"variant":133},[123,2603,2604],{"v-slot:right":125},[20,2605,2606,2608,2612],{},[23,2607,175],{},[23,2609,2610,181],{},[33,2611,180],{},[23,2613,184],{},[11,2615,2616,2618],{"id":187,"level":110},[112,2617,190],{"id":187},[116,2619,2620,2626],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,2621,2622],{"v-slot:left":125},[104,2623,2624],{},[129,2625],{"alt":199,"src":200,"variant":133},[123,2627,2628],{"v-slot:right":125},[20,2629,2630,2634,2636],{},[23,2631,207,2632],{},[33,2633,210],{},[23,2635,213],{},[23,2637,216],{},[11,2639,2640,2642],{"id":219,"level":110},[112,2641,222],{"id":219},[116,2643,2644,2650],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,2645,2646],{"v-slot:left":125},[104,2647,2648],{},[129,2649],{"alt":231,"src":232,"variant":133},[123,2651,2652],{"v-slot:right":125},[20,2653,2654,2656,2660,2662],{},[23,2655,239],{},[23,2657,242,2658],{},[33,2659,245],{},[23,2661,248],{},[23,2663,251],{},[11,2665,2666,2668],{"id":254,"level":110},[112,2667,257],{"id":254},[116,2669,2670,2676],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,2671,2672],{"v-slot:left":125},[104,2673,2674],{},[129,2675],{"alt":266,"src":267,"variant":133},[123,2677,2678],{"v-slot:right":125},[20,2679,2680,2682,2684],{},[23,2681,274],{},[23,2683,277],{},[23,2685,280],{},[11,2687,2688,2690],{"id":283,"level":110},[112,2689,287],{"id":286},[116,2691,2692,2698],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,2693,2694],{"v-slot:left":125},[104,2695,2696],{},[129,2697],{"alt":296,"src":297,"variant":133},[123,2699,2700],{"v-slot:right":125},[20,2701,2702,2704,2706],{},[23,2703,304],{},[23,2705,307],{},[23,2707,310],{},[11,2709,2710,2712],{"id":313,"level":110},[112,2711,317],{"id":316},[116,2713,2714,2720],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,2715,2716],{"v-slot:left":125},[104,2717,2718],{},[129,2719],{"alt":326,"src":327,"variant":133},[123,2721,2722,2730],{"v-slot:right":125},[20,2723,2724,2726,2728],{},[23,2725,334],{},[23,2727,337],{},[23,2729,340],{},[342,2731,2732],{"type":344},[104,2733,347],{},[104,2735,350],{},[11,2737,2738,2740],{"id":353,"level":110},[112,2739,357],{"id":356},[116,2741,2742,2748],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,2743,2744],{"v-slot:left":125},[104,2745,2746],{},[129,2747],{"alt":366,"src":367,"variant":133},[123,2749,2750],{"v-slot:right":125},[20,2751,2752,2754,2756],{},[23,2753,374],{},[23,2755,377],{},[23,2757,380],{},[11,2759,2760,2762],{"id":383,"level":110},[112,2761,387],{"id":386},[116,2763,2764,2770],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,2765,2766],{"v-slot:left":125},[104,2767,2768],{},[129,2769],{"alt":396,"src":397,"variant":133},[123,2771,2772],{"v-slot:right":125},[20,2773,2774,2778],{},[23,2775,404,2776,408],{},[33,2777,407],{},[23,2779,411],{},[11,2781,2782,2784],{"id":414,"level":110},[112,2783,417],{"id":414},[116,2785,2786,2792],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,2787,2788],{"v-slot:left":125},[104,2789,2790],{},[129,2791],{"alt":426,"src":427,"variant":133},[123,2793,2794],{"v-slot:right":125},[20,2795,2796,2798,2800],{},[23,2797,434],{},[23,2799,437],{},[23,2801,440],{},[11,2803,2804,2806],{"id":443,"level":110},[112,2805,446],{"id":443},[116,2807,2808,2814],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,2809,2810],{"v-slot:left":125},[104,2811,2812],{},[129,2813],{"alt":455,"src":456,"variant":133},[123,2815,2816],{"v-slot:right":125},[20,2817,2818,2824,2832,2838],{},[23,2819,463,2820],{},[20,2821,2822],{},[23,2823,468],{},[23,2825,471,2826],{},[20,2827,2828,2830],{},[23,2829,476],{},[23,2831,479],{},[23,2833,482,2834],{},[20,2835,2836],{},[23,2837,487],{},[23,2839,490],{},[11,2841,2842,2844],{"id":493,"level":110},[112,2843,497],{"id":496},[20,2845,2846,2848,2850],{},[23,2847,502],{},[23,2849,505],{},[23,2851,508],{},[11,2853,2854,2856],{"id":511,"level":110},[112,2855,514],{"id":511},[20,2857,2858,2860,2862],{},[23,2859,519],{},[23,2861,522],{},[23,2863,525],{},[11,2865,2866,2868],{"id":528,"level":14},[16,2867,531],{"id":528},[20,2869,2870,2872,2874,2876],{},[23,2871,536],{},[23,2873,539],{},[23,2875,542],{},[23,2877,545],{},[11,2879,2880,2882],{"id":548,"level":110},[112,2881,552],{"id":551},[20,2883,2884,2889,2891,2893],{},[23,2885,557,2886],{},[89,2887,560],{"href":560,"rel":2888},[93],[23,2890,564],{},[23,2892,567],{},[23,2894,570],{},[11,2896,2897,2899,2909,2911,2913],{"id":573,"level":14},[16,2898,576],{"id":573},[20,2900,2901,2903,2905],{},[23,2902,581],{},[23,2904,584],{},[23,2906,587,2907,590],{},[33,2908,35],{},[104,2910,593],{},[595,2912],{"language":597,"src":598},[20,2914,2915],{},[23,2916,603],{},[11,2918,2919,2921,2923,2925,2927],{"id":606,"level":110},[112,2920,610],{"id":609},[104,2922,613],{},[104,2924,593],{},[595,2926],{"language":597,"src":618},[104,2928,621],{},[11,2930,2931,2933],{"id":624,"level":14},[16,2932,628],{"id":627},[116,2934,2935,2945],{"gap":118,"left-width":631,"right-width":632},[123,2936,2937,2939,2941,2943],{"v-slot:left":125},[104,2938,637],{},[595,2940],{"language":597,"src":640},[104,2942,643],{},[595,2944],{"language":646,"src":647},[123,2946,2947,2949],{"v-slot:right":125},[104,2948,652],{},[20,2950,2951,2953,2955],{},[23,2952,657],{},[23,2954,660],{},[23,2956,663],{},[11,2958,2959,2961],{"id":666,"level":14},[16,2960,670],{"id":669},[116,2962,2963,2973],{"gap":118,"left-width":673,"right-width":120},[123,2964,2965,2967,2969,2971],{"v-slot:left":125},[104,2966,637],{},[595,2968],{"language":597,"src":680},[104,2970,643],{},[595,2972],{"language":646,"src":685},[123,2974,2975,2977],{"v-slot:right":125},[104,2976,690],{},[20,2978,2979,2983,2987,2989],{},[23,2980,2981,697],{},[33,2982,39],{},[23,2984,2985,702],{},[33,2986,43],{},[23,2988,705],{},[23,2990,708],{},[11,2992,2993,2995],{"id":711,"level":14},[16,2994,714],{"id":711},[116,2996,2997,3031],{"gap":118,"left-width":717,"right-width":717},[123,2998,2999],{"v-slot:left":125},[20,3000,3001,3011,3025],{},[23,3002,3003,3005],{},[33,3004,726],{},[20,3006,3007,3009],{},[23,3008,731],{},[23,3010,734],{},[23,3012,3013,3015],{},[33,3014,739],{},[20,3016,3017,3019],{},[23,3018,744],{},[23,3020,747,3021,750,3023,753],{},[33,3022,39],{},[33,3024,43],{},[23,3026,756,3027],{},[20,3028,3029],{},[23,3030,761],{},[123,3032,3033,3035],{"v-slot:right":125},[23,3034,766],{},[83,3036,3037,3039,3047,3051,3057],{},[23,3038,771],{},[23,3040,774,3041],{},[20,3042,3043,3045],{},[23,3044,65],{},[23,3046,781],{},[23,3048,784,3049],{},[33,3050,35],{},[23,3052,784,3053,750,3055],{},[33,3054,39],{},[33,3056,43],{},[23,3058,795],{},[11,3060,3061,3063],{"id":798,"level":14},[16,3062,802],{"id":801},[116,3064,3065,3081],{"gap":118,"left-width":717,"right-width":717},[123,3066,3067,3069,3073,3077],{"v-slot:left":125},[112,3068,810],{"id":809},[104,3070,3071,817],{},[814,3072,816],{},[104,3074,3075,823],{},[814,3076,822],{},[104,3078,3079,829],{},[814,3080,828],{},[123,3082,3083,3085],{"v-slot:right":125},[112,3084,834],{"id":798},[20,3086,3087,3092,3097,3102],{},[23,3088,3089],{},[89,3090,843],{"href":841,"rel":3091},[93],[23,3093,3094],{},[89,3095,849],{"href":91,"rel":3096},[93],[23,3098,3099],{},[89,3100,855],{"href":560,"rel":3101},[93],[23,3103,3104],{},[89,3105,862],{"href":860,"rel":3106},[93],[11,3108,3109,3111,3113],{"id":865,"level":14},[16,3110,868],{"id":865},[104,3112,871],{},[20,3114,3115,3117,3121,3127,3129],{},[23,3116,876],{},[23,3118,784,3119],{},[33,3120,35],{},[23,3122,747,3123,750,3125,887],{},[33,3124,39],{},[33,3126,43],{},[23,3128,890],{},[23,3130,893],{},{"title":125,"searchDepth":895,"depth":895,"links":3132},[3133,3134,3135,3150,3153,3156,3157,3158,3159,3160],{"id":13,"depth":895,"text":18},{"id":50,"depth":895,"text":51},{"id":80,"depth":895,"text":81,"children":3136},[3137,3138,3139,3140,3141,3142,3143,3144,3145,3146,3147,3148,3149],{"id":109,"depth":902,"text":114},{"id":155,"depth":902,"text":158},{"id":187,"depth":902,"text":190},{"id":219,"depth":902,"text":222},{"id":254,"depth":902,"text":257},{"id":286,"depth":902,"text":287},{"id":316,"depth":902,"text":317},{"id":356,"depth":902,"text":357},{"id":386,"depth":902,"text":387},{"id":414,"depth":902,"text":417},{"id":443,"depth":902,"text":446},{"id":496,"depth":902,"text":497},{"id":511,"depth":902,"text":514},{"id":528,"depth":895,"text":531,"children":3151},[3152],{"id":551,"depth":902,"text":552},{"id":573,"depth":895,"text":576,"children":3154},[3155],{"id":609,"depth":902,"text":610},{"id":627,"depth":895,"text":628},{"id":669,"depth":895,"text":670},{"id":711,"depth":895,"text":714},{"id":801,"depth":895,"text":802},{"id":865,"depth":895,"text":868},{},{"title":5,"description":928},[245,944,945],{"id":3165,"title":3166,"audience":6,"body":3167,"contentType":926,"course":927,"description":4242,"estimateBasis":4243,"estimatedDiscussionMinutes":4244,"estimatedLiveMinutes":4245,"estimatedTotalMinutes":4246,"extension":933,"meta":4247,"module":935,"navigation":936,"order":1431,"path":4248,"promptAssist":939,"seo":4249,"status":941,"stem":4250,"tags":4251,"videoDuration":4255,"videoId":4256,"videoLink":4257,"videoTitle":4258,"week":935,"__hash__":4259},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh.md","Set Up GitHub SSH",{"type":8,"value":3168,"toc":4214},[3169,3195,3213,3238,3251,3278,3315,3392,3440,3507,3583,3625,3651,3683,3721,3766,3800,3869,3871,3874,3885,3957,3986,4020,4068,4114,4182],[11,3170,3172,3175],{"id":3171,"level":14},"goals",[16,3173,3174],{"id":3171},"Goals",[20,3176,3177,3180,3183,3186,3189,3192],{},[23,3178,3179],{},"Confirm Git works in the correct terminal",[23,3181,3182],{},"Sign in to GitHub with a school or personal account",[23,3184,3185],{},"Create or reuse an SSH key for GitHub",[23,3187,3188],{},"Add the public key to GitHub",[23,3190,3191],{},"Create and clone your course repository",[23,3193,3194],{},"Set Git identity inside the cloned repository",[11,3196,3198,3201,3210],{"id":3197,"level":14},"terminal-by-os",[16,3199,3200],{"id":3197},"Terminal By OS",[20,3202,3203,3205,3208],{},[23,3204,65],{},[23,3206,3207],{},"Apple macOS: Terminal or iTerm2",[23,3209,1569],{},[104,3211,3212],{},"Run these commands on your own computer",[11,3214,3216,3219],{"id":3215,"level":14},"git-and-ssh-terms",[16,3217,3218],{"id":3215},"Git And SSH Terms",[20,3220,3221,3224,3232,3235],{},[23,3222,3223],{},"Git identity: name and email attached to commits in a repository",[23,3225,3226,3227],{},"SSH key pair: private key stays on your computer, public key goes to GitHub\n",[20,3228,3229],{},[23,3230,3231],{},"This is how we'll authenticate to GitHub",[23,3233,3234],{},"SSH agent: helper that keeps your private key available to Git commands",[23,3236,3237],{},"Clone: local folder connected to a GitHub repository",[11,3239,3241,3244,3248],{"id":3240,"level":14},"ssh-key-flow",[16,3242,3243],{"id":3240},"SSH Key Flow",[3245,3246],"mermaid",{"code":3247},"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",[104,3249,3250],{},"GitHub receives only the public key. The private key stays on your computer",[11,3252,3254,3257],{"id":3253,"level":14},"step-1-check-git",[16,3255,3256],{"id":3253},"Step 1: Check Git",[116,3258,3259,3267],{"gap":118,"left-width":717,"right-width":717},[123,3260,3261,3263],{"v-slot:left":125},[104,3262,637],{},[595,3264],{"label":3265,"language":597,"src":3266},"check-git.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-1-check-git-01.sh",[123,3268,3269,3271,3275],{"v-slot:right":125},[104,3270,643],{},[595,3272],{"label":3273,"language":646,"src":3274},"example-output.txt","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-02.txt",[104,3276,3277],{},"A valid version means Git is installed and available in this terminal",[11,3279,3281,3285],{"id":3280,"level":14},"step-2-github-account",[16,3282,3284],{"id":3283},"step-2-sign-in-to-github","Step 2: Sign In To GitHub",[116,3286,3288,3307],{"gap":118,"left-width":717,"right-width":3287},"0.8fr",[123,3289,3290],{"v-slot:left":125},[20,3291,3292,3295,3298,3301,3304],{},[23,3293,3294],{},"Use an existing GitHub account or create one",[23,3296,3297],{},"School email recommended for course identity",[23,3299,3300],{},"Personal email is fine if you prefer it",[23,3302,3303],{},"Avoid work email so course access does not depend on an employer account",[23,3305,3306],{},"Confirm you can open GitHub Settings before continuing",[123,3308,3309],{"v-slot:right":125},[104,3310,3311],{},[129,3312],{"alt":3313,"src":3314,"variant":133},"GitHub account menu open with Settings visible","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fgithub-logged-in.png",[11,3316,3318,3322],{"id":3317,"level":14},"step-2-create-repo",[16,3319,3321],{"id":3320},"step-3-create-course-repository","Step 3: Create Course Repository",[116,3323,3325,3384],{"gap":118,"left-width":3324,"right-width":631},"0.95fr",[123,3326,3327,3330],{"v-slot:left":125},[104,3328,3329],{},"In GitHub:",[20,3331,3332,3337,3343,3349,3364,3370,3373,3381],{},[23,3333,1096,3334],{},[33,3335,3336],{},"+",[23,3338,3339,3340],{},"Choose ",[33,3341,3342],{},"New repository",[23,3344,3345,3346],{},"Name it ",[33,3347,3348],{},"\u003Cucid>-IT202-\u003Csection>-\u003CsemYear>",[23,3350,3351,3352,3355,3356,3359,3360,3363],{},"Semester code examples: ",[33,3353,3354],{},"S2026"," spring, ",[33,3357,3358],{},"M2026"," summer, ",[33,3361,3362],{},"F2026"," fall",[23,3365,3366,3367],{},"Set visibility to ",[33,3368,3369],{},"Private",[23,3371,3372],{},"Toggle \"Add README\"",[23,3374,3375,3376],{},"Do not toggle \"Add .gitignore\"",[20,3377,3378],{},[23,3379,3380],{},"A future lesson will discuss and add this important file",[23,3382,3383],{},"Do not add starter files unless instructed",[123,3385,3386],{"v-slot:right":125},[104,3387,3388],{},[129,3389],{"alt":3390,"src":3391,"variant":133},"GitHub new repository form with course naming pattern, private visibility, and README enabled","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fnew-repo.png",[11,3393,3395,3399,3426],{"id":3394,"level":14},"step-3-check-existing-key",[16,3396,3398],{"id":3397},"step-4-check-for-existing-ssh-key","Step 4: Check For Existing SSH Key",[116,3400,3401,3409],{"gap":118,"left-width":717,"right-width":717},[123,3402,3403,3405],{"v-slot:left":125},[104,3404,637],{},[595,3406],{"label":3407,"language":597,"src":3408},"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",[123,3410,3411,3414,3417],{"v-slot:right":125},[104,3412,3413],{},"Example output:",[595,3415],{"label":3273,"language":646,"src":3416},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-04.txt",[104,3418,3419,3420,750,3423],{},"Look for a matching GitHub-specific pair such as ",[33,3421,3422],{},"github_key",[33,3424,3425],{},"github_key.pub",[104,3427,3428,3429,3432,3433,2100,3436,3439],{},"You can reuse an existing matching pair only if it is ",[814,3430,3431],{},"NOT"," a default key such as ",[33,3434,3435],{},"id_ed25519",[33,3437,3438],{},"id_rsa",". Otherwise, create a GitHub-specific key in the next step",[11,3441,3443,3447,3449,3453,3455,3458],{"id":3442,"level":14},"step-4-create-key-if-needed",[16,3444,3446],{"id":3445},"step-5-create-ssh-key-if-needed","Step 5: Create SSH Key If Needed",[104,3448,637],{},[595,3450],{"label":3451,"language":597,"src":3452},"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",[104,3454,3413],{},[595,3456],{"label":3273,"language":646,"src":3457},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-06.txt",[20,3459,3460,3486,3491,3496],{},[23,3461,3462,3463],{},"Command flags:\n",[20,3464,3465,3471,3477],{},[23,3466,3467,3470],{},[33,3468,3469],{},"-t"," chooses the key type",[23,3472,3473,3476],{},[33,3474,3475],{},"-C"," adds a comment label, usually your GitHub email",[23,3478,3479,3481,3482,3485],{},[33,3480,2065],{}," chooses the output file path (must include ",[33,3483,3484],{},"~\u002F.ssh\u002F"," followed by the file name)",[23,3487,3488,3490],{},[33,3489,3422],{}," is the private key file",[23,3492,3493,3495],{},[33,3494,3425],{}," is the public key file for GitHub",[23,3497,3498,3499],{},"Passphrase is optional unless your instructor requires one\n",[20,3500,3501,3504],{},[23,3502,3503],{},"Pro: protects the key if someone gets the file",[23,3505,3506],{},"Con: adds an unlock prompt when the key is used",[11,3508,3510,3514,3531,3563],{"id":3509,"level":14},"step-5-start-agent-and-add-key",[16,3511,3513],{"id":3512},"step-6-start-ssh-agent-and-verify-key","Step 6: Start SSH Agent And Verify Key",[116,3515,3516,3524],{"gap":118,"left-width":673,"right-width":717},[123,3517,3518,3520],{"v-slot:left":125},[104,3519,637],{},[595,3521],{"label":3522,"language":597,"src":3523},"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",[123,3525,3526,3528],{"v-slot:right":125},[104,3527,3413],{},[595,3529],{"label":3273,"language":646,"src":3530},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-08.txt",[20,3532,3533,3539,3560],{},[23,3534,3535,3538],{},[33,3536,3537],{},"eval \"$(ssh-agent -s)\""," starts the SSH helper GitHub docs usually show",[23,3540,3541,3542,3545,3546,3549],{},"If that fails, run ",[33,3543,3544],{},"exec ssh-agent bash",", then run ",[33,3547,3548],{},"ssh-add ~\u002F.ssh\u002Fgithub_key",[20,3550,3551],{},[23,3552,747,3553,3556,3557,3559],{},[33,3554,3555],{},"~\u002F.ssh\u002Fgithub_key"," because ",[33,3558,1693],{}," avoids issues with spaces in home directory paths",[23,3561,3562],{},"Then verify the key is loaded",[116,3564,3565,3573],{"gap":118,"left-width":717,"right-width":717},[123,3566,3567,3569],{"v-slot:left":125},[104,3568,637],{},[595,3570],{"label":3571,"language":597,"src":3572},"verify-loaded-key.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fverify-loaded-key-09.sh",[123,3574,3575,3577,3580],{"v-slot:right":125},[104,3576,643],{},[595,3578],{"label":3273,"language":646,"src":3579},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-10.txt",[104,3581,3582],{},"One loaded key is enough for this lesson",[11,3584,3586,3590,3607],{"id":3585,"level":14},"step-6-copy-public-key",[16,3587,3589],{"id":3588},"step-7-copy-public-key","Step 7: Copy Public Key",[116,3591,3592,3600],{"gap":118,"left-width":717,"right-width":717},[123,3593,3594,3596],{"v-slot:left":125},[104,3595,637],{},[595,3597],{"label":3598,"language":597,"src":3599},"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",[123,3601,3602,3604],{"v-slot:right":125},[104,3603,3413],{},[595,3605],{"label":3273,"language":646,"src":3606},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-12.txt",[20,3608,3609,3619],{},[23,3610,3611,3612,3615,3616,3618],{},"Copy the full line starting with ",[33,3613,3614],{},"ssh-ed25519"," and ending with the value you set with ",[33,3617,3475],{}," earlier",[23,3620,3621,3622,3624],{},"Do not copy ",[33,3623,3422],{},", which is the private key (never share the private key)",[11,3626,3628,3632],{"id":3627,"level":14},"step-7-add-key-to-github",[16,3629,3631],{"id":3630},"step-8-add-key-to-github","Step 8: Add Key To GitHub",[20,3633,3634,3637,3642,3645,3648],{},[23,3635,3636],{},"In GitHub, open account settings",[23,3638,87,3639],{},[33,3640,3641],{},"SSH and GPG keys",[23,3643,3644],{},"Add a new authentication key",[23,3646,3647],{},"Paste the public key from the previous step",[23,3649,3650],{},"See the slides below for the GitHub screens",[11,3652,3654,3658],{"id":3653,"level":110},"step-8-open-github-settings",[112,3655,3657],{"id":3656},"open-github-settings","Open GitHub Settings",[116,3659,3660,3668],{"gap":118,"left-width":673,"right-width":120,"stack":121},[123,3661,3662],{"v-slot:left":125},[104,3663,3664],{},[129,3665],{"alt":3666,"src":3667,"variant":133},"GitHub profile menu with Settings highlighted","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fssh-key-01-gh-menu.png",[123,3669,3670],{"v-slot:right":125},[20,3671,3672,3675,3680],{},[23,3673,3674],{},"Click your GitHub profile photo",[23,3676,3339,3677],{},[33,3678,3679],{},"Settings",[23,3681,3682],{},"Use the account menu, not the repository settings",[11,3684,3686,3690],{"id":3685,"level":110},"step-8-open-ssh-keys-page",[112,3687,3689],{"id":3688},"open-ssh-and-gpg-keys","Open SSH And GPG Keys",[116,3691,3692,3700],{"gap":118,"left-width":673,"right-width":120,"stack":121},[123,3693,3694],{"v-slot:left":125},[104,3695,3696],{},[129,3697],{"alt":3698,"src":3699,"variant":133},"GitHub settings sidebar with SSH and GPG keys selected","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fssh-key-02-gh-ssh-link.png",[123,3701,3702],{"v-slot:right":125},[20,3703,3704,3711,3716],{},[23,3705,3706,3707,3710],{},"Find the ",[33,3708,3709],{},"Access"," section",[23,3712,3713,3714],{},"Open ",[33,3715,3641],{},[23,3717,3339,3718],{},[33,3719,3720],{},"New SSH key",[11,3722,3724,3728],{"id":3723,"level":110},"step-8-add-new-ssh-key",[112,3725,3727],{"id":3726},"add-new-ssh-key","Add New SSH Key",[116,3729,3731,3739],{"gap":118,"left-width":3730,"right-width":632,"stack":121},"1.35fr",[123,3732,3733],{"v-slot:left":125},[104,3734,3735],{},[129,3736],{"alt":3737,"src":3738,"variant":133},"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",[123,3740,3741],{"v-slot:right":125},[20,3742,3743,3749,3755,3758,3763],{},[23,3744,3745,3746],{},"Title it clearly, such as ",[33,3747,3748],{},"\u003Ccourse> Laptop",[23,3750,3751,3752],{},"Keep key type as ",[33,3753,3754],{},"Authentication Key",[23,3756,3757],{},"Paste the full public key line",[23,3759,1096,3760],{},[33,3761,3762],{},"Add SSH key",[23,3764,3765],{},"Never paste the private key",[11,3767,3769,3773],{"id":3768,"level":14},"step-8-test-auth",[16,3770,3772],{"id":3771},"step-9-test-github-ssh-access","Step 9: Test GitHub SSH Access",[116,3774,3775,3790],{"gap":118,"left-width":717,"right-width":673},[123,3776,3777,3779,3783],{"v-slot:left":125},[104,3778,637],{},[595,3780],{"label":3781,"language":597,"src":3782},"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",[104,3784,3785,3786,3789],{},"If prompted the first time, type ",[33,3787,3788],{},"yes"," to trust GitHub's host key",[123,3791,3792,3794,3797],{"v-slot:right":125},[104,3793,643],{},[595,3795],{"label":3273,"language":646,"src":3796},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-14.txt",[104,3798,3799],{},"This confirms authentication, then GitHub closes the connection",[11,3801,3803,3807],{"id":3802,"level":14},"step-9-clone-repo",[16,3804,3806],{"id":3805},"step-10-clone-course-repository","Step 10: Clone Course Repository",[116,3808,3809,3850],{"gap":118,"left-width":120,"right-width":673},[123,3810,3811,3815,3844],{"v-slot:left":125},[112,3812,3814],{"id":3813},"get-the-ssh-clone-url","Get The SSH Clone URL",[20,3816,3817,3823,3830,3837],{},[23,3818,3819,3820],{},"In your GitHub repository, click ",[33,3821,3822],{},"Code",[23,3824,3825,3826,3829],{},"Choose the ",[33,3827,3828],{},"SSH"," tab",[23,3831,3832,3833,3836],{},"Copy the ",[33,3834,3835],{},"git@github.com:..."," link",[23,3838,3839,3840,3843],{},"Use that link in the ",[33,3841,3842],{},"git clone"," command",[104,3845,3846],{},[129,3847],{"alt":3848,"src":3849,"variant":133},"GitHub repository Code menu with SSH clone URL selected","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fgithub-clone-url.png",[123,3851,3852,3855,3859],{"v-slot:right":125},[104,3853,3854],{},"Run from the folder that should contain your course repo:",[595,3856],{"label":3857,"language":597,"src":3858},"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",[342,3860,3862],{"type":3861},"tip",[104,3863,3864,3865,3868],{},"Before cloning, run ",[33,3866,3867],{},"git rev-parse --show-toplevel",". If it prints a path, move somewhere else first. Clone this repo only once.",[104,3870,3413],{},[595,3872],{"label":3273,"language":646,"src":3873},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-16.txt",[104,3875,3876,3877,3880,3881,3884],{},"If you see an empty repository warning, you probably forgot to add ",[33,3878,3879],{},"README.md"," when creating the repo. Create it with ",[33,3882,3883],{},"touch README.md",", then use the add\u002Fcommit\u002Fpush commands from the next lesson\n::\n::",[11,3886,3888,3892,3911,3930,3950],{"id":3887,"level":14},"step-10-set-repo-identity",[16,3889,3891],{"id":3890},"step-11-set-repo-git-identity","Step 11: Set Repo Git Identity",[116,3893,3894,3903],{"gap":118,"left-width":717,"right-width":717},[123,3895,3896,3899],{"v-slot:left":125},[104,3897,3898],{},"Run inside the cloned repository:",[595,3900],{"label":3901,"language":597,"src":3902},"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",[123,3904,3905,3907],{"v-slot:right":125},[104,3906,643],{},[595,3908],{"label":3909,"language":646,"src":3910},"config-output.txt","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-19.txt",[116,3912,3913,3922],{"gap":118,"left-width":717,"right-width":717},[123,3914,3915,3918],{"v-slot:left":125},[104,3916,3917],{},"Then verify:",[595,3919],{"label":3920,"language":597,"src":3921},"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",[123,3923,3924,3926],{"v-slot:right":125},[104,3925,643],{},[595,3927],{"label":3928,"language":646,"src":3929},"identity-output.txt","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-20.txt",[20,3931,3932,3938,3944],{},[23,3933,3934,3937],{},[33,3935,3936],{},"user.name"," can be your real or display name, though commonly it's your GitHub username",[23,3939,3940,3943],{},[33,3941,3942],{},"user.email"," should match a GitHub email or GitHub no-reply address for commit linking to work (this is important)",[23,3945,3946,3949],{},[33,3947,3948],{},"core.sshCommand"," tells this repository to use your course GitHub key",[104,3951,3952,3953,3956],{},"These commands set identity for this repository. The ",[33,3954,3955],{},"--global"," flag is an option only if you intentionally want the same identity for all repositories",[11,3958,3960,3964,3967,3983],{"id":3959,"level":14},"step-11-invite-collaborators",[16,3961,3963],{"id":3962},"step-12-invite-course-collaborators","Step 12: Invite Course Collaborators",[104,3965,3966],{},"In GitHub, open your course repository:",[20,3968,3969,3972,3977,3980],{},[23,3970,3971],{},"Settings -> Collaborators and teams",[23,3973,3974,3975],{},"Invite ",[33,3976,1303],{},[23,3978,3979],{},"Invite your TA if your section has one",[23,3981,3982],{},"Wait until the invitation shows as sent or accepted",[104,3984,3985],{},"This is so it can be accessed for grading and assistance",[11,3987,3989,3992],{"id":3988,"level":14},"troubleshooting-auth",[16,3990,3991],{"id":3988},"Troubleshooting Auth",[20,3993,3994,4000,4007,4014,4017],{},[23,3995,3996,3999],{},[33,3997,3998],{},"Permission denied (publickey)",": GitHub did not accept a loaded key",[23,4001,4002,4003,4006],{},"No loaded key in ",[33,4004,4005],{},"ssh-add -l",": start the agent and add the key again",[23,4008,4009,4010,4013],{},"Wrong key in GitHub: delete it and paste the ",[33,4011,4012],{},".pub"," key again",[23,4015,4016],{},"Wrong account: make sure the success message names your GitHub account",[23,4018,4019],{},"See the slide below for a quick reset sequence",[11,4021,4023,4027,4029,4056],{"id":4022,"level":110},"troubleshooting-auth-recovery",[112,4024,4026],{"id":4025},"quick-reset-sequence","Quick Reset Sequence",[104,4028,637],{},[83,4030,4031,4035,4039,4043,4048,4051],{},[23,4032,4033],{},[33,4034,3537],{},[23,4036,4037],{},[33,4038,3548],{},[23,4040,4041],{},[33,4042,4005],{},[23,4044,4045],{},[33,4046,4047],{},"cat ~\u002F.ssh\u002Fgithub_key.pub",[23,4049,4050],{},"Re-paste the public key in GitHub if needed",[23,4052,4053],{},[33,4054,4055],{},"ssh -T git@github.com",[104,4057,587,4058,4060,4061,4063,4064,4067],{},[33,4059,3537],{}," fails in Git Bash, use ",[33,4062,3544],{},", then repeat the ",[33,4065,4066],{},"ssh-add"," steps",[11,4069,4070,4072,4075],{"id":1361,"level":14},[16,4071,1364],{"id":1361},[104,4073,4074],{},"You are done when all are true:",[20,4076,4077,4082,4089,4094,4097,4102,4105],{},[23,4078,4079,4081],{},[33,4080,35],{}," works",[23,4083,4084,4086,4087],{},[33,4085,4005],{}," shows ",[33,4088,3422],{},[23,4090,4091,4093],{},[33,4092,4055],{}," names your GitHub account",[23,4095,4096],{},"Your private course repository exists on GitHub",[23,4098,4099,4101],{},[33,4100,1303],{}," and your TA, if applicable, are invited as collaborators",[23,4103,4104],{},"Your local terminal is open to the cloned repository",[23,4106,4107,750,4110,4113],{},[33,4108,4109],{},"git config user.name",[33,4111,4112],{},"git config user.email"," return your repo identity",[11,4115,4116,4118],{"id":798,"level":14},[16,4117,802],{"id":801},[116,4119,4120,4148],{"gap":118,"left-width":717,"right-width":717},[123,4121,4122,4124,4130,4136,4142],{"v-slot:left":125},[112,4123,810],{"id":809},[104,4125,4126,4129],{},[814,4127,4128],{},"Git identity"," - commit name and email saved in repo config",[104,4131,4132,4135],{},[814,4133,4134],{},"SSH key pair"," - private key on your computer, public key in GitHub",[104,4137,4138,4141],{},[814,4139,4140],{},"SSH agent"," - background helper that makes your private key available",[104,4143,4144,4147],{},[814,4145,4146],{},"Clone"," - local copy of a GitHub repository",[123,4149,4150,4152],{"v-slot:right":125},[112,4151,834],{"id":798},[20,4153,4154,4161,4168,4175],{},[23,4155,4156],{},[89,4157,4160],{"href":4158,"rel":4159},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fauthentication\u002Fconnecting-to-github-with-ssh\u002Fgenerating-a-new-ssh-key-and-adding-it-to-the-ssh-agent",[93],"GitHub Docs: Generate a new SSH key and add it to the ssh-agent",[23,4162,4163],{},[89,4164,4167],{"href":4165,"rel":4166},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fauthentication\u002Fconnecting-to-github-with-ssh\u002Ftesting-your-ssh-connection",[93],"GitHub Docs: Testing your SSH connection",[23,4169,4170],{},[89,4171,4174],{"href":4172,"rel":4173},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Frepositories\u002Fcreating-and-managing-repositories\u002Fcreating-a-new-repository",[93],"GitHub Docs: Create a repository",[23,4176,4177],{},[89,4178,4181],{"href":4179,"rel":4180},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Frepositories\u002Fcreating-and-managing-repositories\u002Fcloning-a-repository",[93],"GitHub Docs: Cloning a repository",[11,4183,4184,4186,4188],{"id":865,"level":14},[16,4185,868],{"id":865},[104,4187,2415],{},[20,4189,4190,4193,4196,4199,4202,4205,4211],{},[23,4191,4192],{},"Use the correct terminal for your operating system",[23,4194,4195],{},"Authenticate to GitHub with SSH",[23,4197,4198],{},"Find your private course repository on GitHub",[23,4200,4201],{},"Invite course collaborators",[23,4203,4204],{},"Open the local clone in the terminal",[23,4206,4207,4208],{},"Show repo-local Git identity with ",[33,4209,4210],{},"git config",[23,4212,4213],{},"Next: practice the Git commands used for course work",{"title":125,"searchDepth":895,"depth":895,"links":4215},[4216,4217,4218,4219,4220,4221,4222,4223,4224,4225,4226,4227,4232,4233,4234,4235,4236,4239,4240,4241],{"id":3171,"depth":895,"text":3174},{"id":3197,"depth":895,"text":3200},{"id":3215,"depth":895,"text":3218},{"id":3240,"depth":895,"text":3243},{"id":3253,"depth":895,"text":3256},{"id":3283,"depth":895,"text":3284},{"id":3320,"depth":895,"text":3321},{"id":3397,"depth":895,"text":3398},{"id":3445,"depth":895,"text":3446},{"id":3512,"depth":895,"text":3513},{"id":3588,"depth":895,"text":3589},{"id":3630,"depth":895,"text":3631,"children":4228},[4229,4230,4231],{"id":3656,"depth":902,"text":3657},{"id":3688,"depth":902,"text":3689},{"id":3726,"depth":902,"text":3727},{"id":3771,"depth":895,"text":3772},{"id":3805,"depth":895,"text":3806},{"id":3890,"depth":895,"text":3891},{"id":3962,"depth":895,"text":3963},{"id":3988,"depth":895,"text":3991,"children":4237},[4238],{"id":4025,"depth":902,"text":4026},{"id":1361,"depth":895,"text":1364},{"id":801,"depth":895,"text":802},{"id":865,"depth":895,"text":868},"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","70","85",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh",{"title":3166,"description":4242},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh",[245,4252,4253,4254],"github","ssh","repository","48:26","HZG3_HfczOk","https:\u002F\u002Fyoutu.be\u002FHZG3_HfczOk","Setup Git SSH and GitHub","rJ2RP6nrPEoOj98kzeevFpO0YOXaJl-M5ajP_tsjwvA",{"id":4261,"title":4262,"audience":6,"body":4263,"contentType":926,"course":927,"description":5183,"estimateBasis":5184,"estimatedDiscussionMinutes":937,"estimatedLiveMinutes":4245,"estimatedTotalMinutes":5185,"extension":933,"meta":5186,"module":935,"navigation":936,"order":5187,"path":5188,"promptAssist":939,"seo":5189,"status":941,"stem":5190,"tags":5191,"videoDuration":5194,"videoId":5195,"videoLink":5196,"videoTitle":5197,"week":935,"__hash__":5198},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs.md","Git Commands And Pull Requests",{"type":8,"value":4264,"toc":5148},[4265,4294,4315,4332,4364,4398,4449,4465,4486,4517,4549,4591,4622,4657,4681,4726,4753,4783,4801,4813,4849,4882,4918,4952,4978,5006,5036,5103,5145],[11,4266,4268,4271,4274],{"id":4267,"level":14},"objectives",[16,4269,4270],{"id":4267},"Objectives",[104,4272,4273],{},"By the end, you should be able to:",[20,4275,4276,4279,4282,4285,4288,4291],{},[23,4277,4278],{},"Explain what the common Git commands do",[23,4280,4281],{},"Connect commands to the working folder, staging area, local commits, and GitHub remote",[23,4283,4284],{},"Create a branch for practice work",[23,4286,4287],{},"Stage, commit, and push a small change",[23,4289,4290],{},"Open a pull request on GitHub",[23,4292,4293],{},"Investigate a failed push and a merge conflict",[11,4295,4297,4301,4304,4307],{"id":4296,"level":14},"git-vs-github",[16,4298,4300],{"id":4299},"git-versus-github","Git Versus GitHub",[104,4302,4303],{},"Git is the tool that tracks file history",[104,4305,4306],{},"GitHub is a website that hosts a remote copy of a Git repository",[20,4308,4309,4312],{},[23,4310,4311],{},"Git: local terminal workflow",[23,4313,4314],{},"GitHub: remote branches, pull requests, issues, and project evidence",[11,4316,4318,4322,4326,4329],{"id":4317,"level":14},"git-stages",[16,4319,4321],{"id":4320},"the-git-stages","The Git Stages",[595,4323],{"language":4324,"src":4325},"text","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fthe-git-stages-01.txt",[104,4327,4328],{},"Common commands:",[595,4330],{"language":4324,"src":4331},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fthe-git-stages-02.txt",[11,4333,4335,4339,4341,4344,4347,4350],{"id":4334,"level":14},"status-first",[16,4336,4338],{"id":4337},"command-1-git-status","Command 1: git status",[104,4340,637],{},[595,4342],{"language":597,"src":4343},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-1-git-status-03.sh",[104,4345,4346],{},"Use this before and after every important Git action",[104,4348,4349],{},"It tells you:",[20,4351,4352,4355,4358,4361],{},[23,4353,4354],{},"Current branch",[23,4356,4357],{},"Changed files",[23,4359,4360],{},"Staged files",[23,4362,4363],{},"Whether your working tree is clean",[11,4365,4367,4371,4373,4376],{"id":4366,"level":14},"branch-command",[16,4368,4370],{"id":4369},"command-2-git-branch","Command 2: git branch",[104,4372,637],{},[595,4374],{"language":597,"src":4375},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-2-git-branch-04.sh",[20,4377,4378,4381,4384],{},[23,4379,4380],{},"Active branch has an asterisk",[23,4382,4383],{},"Branches are separate timelines for work",[23,4385,4386,4387],{},"Branch names are case-sensitive\n",[20,4388,4389],{},[23,4390,4391,750,4394,4397],{},[33,4392,4393],{},"Practice",[33,4395,4396],{},"practice"," are different names",[11,4399,4401,4405,4410,4413],{"id":4400,"level":14},"create-branch",[16,4402,4404],{"id":4403},"practice-step-1-create-a-branch","Practice Step 1: Create A Branch",[104,4406,4407,4408,2157],{},"Start from ",[33,4409,210],{},[595,4411],{"language":597,"src":4412},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpractice-step-1-create-a-05.sh",[20,4414,4415,4426],{},[23,4416,4417,4418,4420,4421],{},"First two commands: make sure ",[33,4419,210],{}," is current\n",[20,4422,4423],{},[23,4424,4425],{},"Explained more later",[23,4427,4428,4429],{},"Branch control commands\n",[20,4430,4431,4437,4443],{},[23,4432,4433,4436],{},[33,4434,4435],{},"git checkout -b practice",": create and switch",[23,4438,4439,4442],{},[33,4440,4441],{},"git branch practice",": create only",[23,4444,4445,4448],{},[33,4446,4447],{},"git checkout practice",": switch to existing",[11,4450,4452,4456,4459,4462],{"id":4451,"level":14},"make-file",[16,4453,4455],{"id":4454},"practice-step-2-make-a-small-file","Practice Step 2: Make A Small File",[104,4457,4458],{},"Create a small practice file:",[595,4460],{"language":597,"src":4461},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpractice-step-2-make-a-s-06.sh",[104,4463,4464],{},"Expected result: Git shows the new file as untracked",[11,4466,4468,4472,4475,4478,4481],{"id":4467,"level":14},"add-command",[16,4469,4471],{"id":4470},"command-3-git-add","Command 3: git add",[104,4473,4474],{},"Stage the new file:",[595,4476],{"language":597,"src":4477},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-3-git-add-07.sh",[104,4479,4480],{},"Staging means: include this change in the next commit",[20,4482,4483],{},[23,4484,4485],{},"See below for add patterns and verification checks",[11,4487,4489,4493,4496,4499],{"id":4488,"level":110},"add-variants",[112,4490,4492],{"id":4491},"common-git-add-patterns","Common git add Patterns",[104,4494,4495],{},"Use the smallest clear target when possible",[595,4497],{"language":597,"src":4498},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommon-git-add-patterns-08.sh",[20,4500,4501,4504,4507],{},[23,4502,4503],{},"Single file: safest when you changed one file",[23,4505,4506],{},"Folder: useful when one feature is grouped in one folder",[23,4508,4509,4512,4513,4516],{},[33,4510,4511],{},"git add .",": convenient, but review ",[33,4514,4515],{},"git status"," first",[11,4518,4520,4524,4527,4530],{"id":4519,"level":14},"diff-command",[16,4521,4523],{"id":4522},"command-4-git-diff","Command 4: git diff",[104,4525,4526],{},"Before committing, inspect what changed:",[595,4528],{"language":597,"src":4529},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-4-git-diff-09.sh",[20,4531,4532,4539,4542,4547],{},[23,4533,4534,4535,4538],{},"New untracked file: ",[33,4536,4537],{},"git diff"," may show nothing",[23,4540,4541],{},"That does not mean the file is missing",[23,4543,747,4544,4546],{},[33,4545,4515],{}," to confirm untracked files",[23,4548,2219],{},[11,4550,4552,4556,4559,4562,4565,4568],{"id":4551,"level":110},"cached-rm",[112,4553,4555],{"id":4554},"if-you-staged-the-wrong-file","If You Staged The Wrong File",[104,4557,4558],{},"If a file was staged by mistake, remove it from staging:",[595,4560],{"language":597,"src":4561},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fif-you-staged-the-wrong--10.sh",[104,4563,4564],{},"For a folder:",[595,4566],{"language":597,"src":4567},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fif-you-staged-the-wrong--11.sh",[20,4569,4570,4581],{},[23,4571,4572,4575,4576],{},[33,4573,4574],{},"--cached",": remove from staging only\n",[20,4577,4578],{},[23,4579,4580],{},"Keeps the file in your working folder",[23,4582,4583,4585,4586],{},[33,4584,1532],{},": folder mode\n",[20,4587,4588],{},[23,4589,4590],{},"Recursive: include files inside the folder",[11,4592,4594,4598,4601,4604,4607],{"id":4593,"level":14},"commit-command",[16,4595,4597],{"id":4596},"command-5-git-commit","Command 5: git commit",[104,4599,4600],{},"Commit the staged file:",[595,4602],{"language":597,"src":4603},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-5-git-commit-12.sh",[104,4605,4606],{},"A commit is a saved checkpoint in your local repository",[20,4608,4609,4620],{},[23,4610,4611,4614,4615],{},[33,4612,4613],{},"-m",": commit message",[20,4616,4617],{},[23,4618,4619],{},"Required, even if the message is an empty string",[23,4621,2219],{},[11,4623,4625,4629,4631,4634,4654],{"id":4624,"level":110},"log-command",[112,4626,4628],{"id":4627},"check-the-local-history","Check The Local History",[104,4630,637],{},[595,4632],{"language":597,"src":4633},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcheck-the-local-history-13.sh",[20,4635,4636,4642,4648],{},[23,4637,4638,4641],{},[33,4639,4640],{},"log",": show commit history",[23,4643,4644,4647],{},[33,4645,4646],{},"--oneline",": one commit per line",[23,4649,4650,4653],{},[33,4651,4652],{},"-5",": show the latest five commits",[104,4655,4656],{},"You should see your latest commit near the top",[11,4658,4660,4664,4667,4670],{"id":4659,"level":14},"push-command",[16,4661,4663],{"id":4662},"command-6-git-push","Command 6: git push",[104,4665,4666],{},"Send the branch to GitHub:",[595,4668],{"language":597,"src":4669},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-6-git-push-14.sh",[20,4671,4672,4678],{},[23,4673,4674,4677],{},[33,4675,4676],{},"origin",": common remote name for GitHub",[23,4679,4680],{},"Final part: branch you are pushing",[11,4682,4684,4688],{"id":4683,"level":14},"open-pr",[16,4685,4687],{"id":4686},"pull-request","Pull Request",[116,4689,4690,4718],{"gap":118,"left-width":717,"right-width":717},[123,4691,4692,4695,4698,4701,4704,4707],{"v-slot:left":125},[104,4693,4694],{},"On GitHub, open a pull request",[104,4696,4697],{},"Use this direction:",[595,4699],{"language":4324,"src":4700},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-request-15.txt",[104,4702,4703],{},"Use a clear description:",[595,4705],{"language":4324,"src":4706},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-request-description-16.txt",[20,4708,4709,4712,4715],{},[23,4710,4711],{},"Review page before merge",[23,4713,4714],{},"Shows what will change",[23,4716,4717],{},"Captures branch evidence",[123,4719,4720],{"v-slot:right":125},[104,4721,4722],{},[129,4723],{"alt":4724,"src":4725,"variant":133},"GitHub pull request creation page showing base main and compare practice","\u002Fimages\u002Fshared\u002Fgit-workflow\u002Fgithub-create-pull-request.png",[11,4727,4729,4733,4736,4744,4747,4750],{"id":4728,"level":14},"merge-pr",[16,4730,4732],{"id":4731},"merge-and-sync","Merge And Sync",[104,4734,4735],{},"After GitHub merge:",[20,4737,4738],{},[23,4739,4740,4741,4743],{},"Local ",[33,4742,210],{}," is not updated automatically",[104,4745,4746],{},"Sync it:",[595,4748],{"language":597,"src":4749},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fmerge-and-sync-15.sh",[104,4751,4752],{},"Remote changes must be pulled down intentionally",[11,4754,4756,4760,4763,4780],{"id":4755,"level":14},"why-prs",[16,4757,4759],{"id":4758},"why-pull-requests-matter","Why Pull Requests Matter",[104,4761,4762],{},"Pull requests create evidence:",[20,4764,4765,4768,4771,4774,4777],{},[23,4766,4767],{},"Which branch changed",[23,4769,4770],{},"Which files changed",[23,4772,4773],{},"What discussion or explanation was provided",[23,4775,4776],{},"Chance to review risky changes before merging",[23,4778,4779],{},"When the change was merged",[104,4781,4782],{},"For this course, pull requests are part of the workflow evidence, not just a GitHub feature",[11,4784,4786,4790,4793],{"id":4785,"level":14},"exploration-intro",[16,4787,4789],{"id":4788},"troubleshooting-explorations","Troubleshooting Explorations",[104,4791,4792],{},"The next slides use controlled problems to practice recovery",[20,4794,4795,4798],{},[23,4796,4797],{},"The goal is not avoiding every error",[23,4799,4800],{},"The goal is reading output, identifying state, and recovering without guessing",[11,4802,4804,4807,4810],{"id":4803,"level":14},"exploration-setup",[16,4805,4806],{"id":4803},"Exploration Setup",[104,4808,4809],{},"Create a conflict practice branch:",[595,4811],{"language":597,"src":4812},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-setup-16.sh",[11,4814,4816,4820,4826,4833,4838,4841,4844],{"id":4815,"level":14},"exploration-issue-1",[16,4817,4819],{"id":4818},"exploration-issue-1-push-rejected","Exploration Issue 1: Push Rejected",[104,4821,4822,4823],{},"On GitHub, switch to ",[33,4824,4825],{},"practice-conflict",[104,4827,4828,4829,4832],{},"Edit one line in ",[33,4830,4831],{},"myFile.txt"," directly on GitHub and commit the change",[20,4834,4835],{},[23,4836,4837],{},"Use the same line you will change locally",[104,4839,4840],{},"Back locally, edit that same line and commit:",[595,4842],{"language":597,"src":4843},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-issue-1-push-17.sh",[20,4845,4846],{},[23,4847,4848],{},"See the slides below for the rejected push and the pull that creates the conflict",[11,4850,4852,4856,4859],{"id":4851,"level":110},"issue-1-push-without-pulling",[112,4853,4855],{"id":4854},"try-push-without-pulling","Try Push Without Pulling",[104,4857,4858],{},"Push the local commit before pulling the GitHub commit:",[116,4860,4861,4874],{"gap":118,"left-width":717,"right-width":717},[123,4862,4863,4866],{"v-slot:left":125},[595,4864],{"language":597,"src":4865},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Ftry-push-without-pulling-20.sh",[20,4867,4868,4871],{},[23,4869,4870],{},"Expected result: push rejected",[23,4872,4873],{},"Reason: GitHub has a commit your local branch does not have",[123,4875,4876],{"v-slot:right":125},[104,4877,4878],{},[129,4879],{"alt":4880,"src":4881,"variant":133},"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,4883,4885,4889],{"id":4884,"level":110},"issue-1-read-output",[112,4886,4888],{"id":4887},"pull-the-remote-change","Pull The Remote Change",[116,4890,4891,4910],{"gap":118,"left-width":717,"right-width":717},[123,4892,4893,4896,4899,4902,4907],{"v-slot:left":125},[104,4894,4895],{},"The usual next command is:",[595,4897],{"language":597,"src":4898},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-the-remote-change-20.sh",[104,4900,4901],{},"If Git asks how to reconcile divergent branches:",[20,4903,4904],{},[23,4905,4906],{},"Use merge behavior for this course practice",[595,4908],{"language":597,"src":4909},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-the-remote-change-21.sh",[123,4911,4912],{"v-slot:right":125},[104,4913,4914],{},[129,4915],{"alt":4916,"src":4917,"variant":133},"Git pull output asking how to reconcile divergent branches","\u002Fimages\u002Fshared\u002Fgit-workflow\u002Fgit-pull-divergent-branches.png",[11,4919,4921,4925,4928,4932,4935,4938,4941],{"id":4920,"level":14},"exploration-issue-2",[16,4922,4924],{"id":4923},"exploration-issue-2-merge-conflict","Exploration Issue 2: Merge Conflict",[104,4926,4927],{},"After pulling, Git should report a conflict",[104,4929,3713,4930],{},[33,4931,4831],{},[104,4933,4934],{},"You may see markers like:",[595,4936],{"language":4324,"src":4937},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-issue-2-merg-18.txt",[104,4939,4940],{},"Conflict markers show:",[20,4942,4943,4946,4949],{},[23,4944,4945],{},"Your local version",[23,4947,4948],{},"The GitHub version",[23,4950,4951],{},"The part Git could not combine automatically",[11,4953,4955,4959,4965,4968,4971,4974],{"id":4954,"level":110},"resolve-conflict",[112,4956,4958],{"id":4957},"resolve-the-conflict","Resolve The Conflict",[104,4960,4961,4962,4964],{},"Edit ",[33,4963,4831],{}," so it contains the final text you want",[104,4966,4967],{},"Remove all conflict markers",[104,4969,4970],{},"Then run:",[595,4972],{"language":597,"src":4973},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fresolve-the-conflict-19.sh",[20,4975,4976],{},[23,4977,2219],{},[11,4979,4981,4985,4988],{"id":4980,"level":110},"verify-conflict-resolution",[112,4982,4984],{"id":4983},"verify-the-recovery","Verify The Recovery",[104,4986,4987],{},"Check:",[20,4989,4990,4995,4998,5003],{},[23,4991,4992,4994],{},[33,4993,4515],{}," is clean",[23,4996,4997],{},"GitHub shows the updated branch",[23,4999,5000,5002],{},[33,5001,4831],{}," contains the final text",[23,5004,5005],{},"No conflict markers remain",[11,5007,5008,5010],{"id":711,"level":14},[16,5009,714],{"id":711},[20,5011,5012,5015,5018,5021,5024,5033],{},[23,5013,5014],{},"Committing on the wrong branch",[23,5016,5017],{},"Forgetting to push after committing",[23,5019,5020],{},"Forgetting to pull after merging on GitHub",[23,5022,5023],{},"Leaving conflict markers in a file",[23,5025,5026,5027,2100,5030],{},"Using vague branch names like ",[33,5028,5029],{},"stuff",[33,5031,5032],{},"final",[23,5034,5035],{},"Making several unrelated changes in one commit",[11,5037,5038,5040],{"id":798,"level":14},[16,5039,802],{"id":801},[116,5041,5042,5066],{"gap":118,"left-width":717,"right-width":717},[123,5043,5044,5046],{"v-slot:left":125},[112,5045,810],{"id":809},[20,5047,5048,5051,5054,5057,5060,5063],{},[23,5049,5050],{},"Working folder: files you can edit",[23,5052,5053],{},"Staging area: changes selected for the next commit",[23,5055,5056],{},"Commit: local saved checkpoint",[23,5058,5059],{},"Remote: GitHub copy of the repository",[23,5061,5062],{},"Pull request: GitHub page for reviewing and merging branch work",[23,5064,5065],{},"Conflict: a change Git cannot merge automatically",[123,5067,5068,5070],{"v-slot:right":125},[112,5069,834],{"id":798},[20,5071,5072,5080,5087,5095],{},[23,5073,5074,5075],{},"Pro Git Book: ",[89,5076,5079],{"href":5077,"rel":5078},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Basics-Getting-a-Git-Repository",[93],"Git Basics",[23,5081,5074,5082],{},[89,5083,5086],{"href":5084,"rel":5085},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Branching-Basic-Branching-and-Merging",[93],"Basic Branching and Merging",[23,5088,5089,5090],{},"GitHub Docs: ",[89,5091,5094],{"href":5092,"rel":5093},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fpull-requests\u002Fcollaborating-with-pull-requests\u002Fproposing-changes-to-your-work-with-pull-requests\u002Fcreating-a-pull-request",[93],"Creating a pull request",[23,5096,5097,5098],{},"Oh Shit, Git!?!: ",[89,5099,5102],{"href":5100,"rel":5101},"https:\u002F\u002Fohshitgit.com\u002F",[93],"Common Git recovery situations",[11,5104,5105,5107],{"id":865,"level":14},[16,5106,868],{"id":865},[116,5108,5111,5135],{"gap":933,"left-width":5109,"right-width":5110},"0.72fr","1.38fr",[123,5112,5113,5115],{"v-slot:left":125},[104,5114,2415],{},[20,5116,5117,5123,5126,5129,5132],{},[23,5118,5119,5120,5122],{},"Read ",[33,5121,4515],{}," before choosing the next command",[23,5124,5125],{},"Move a change from working folder to staging area to commit",[23,5127,5128],{},"Push a branch to GitHub and open a pull request",[23,5130,5131],{},"Recognize when a failed push or conflict needs recovery",[23,5133,5134],{},"Next: open the cloned repository in VS Code",[123,5136,5137,5140],{"v-slot:right":125},[104,5138,5139],{},"Git\u002FGitHub flow:",[5141,5142],"figure-image",{"alt":5143,"src":5144},"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",[104,5146,5147],{},"::",{"title":125,"searchDepth":895,"depth":895,"links":5149},[5150,5151,5152,5153,5154,5155,5156,5157,5160,5163,5166,5167,5168,5169,5170,5171,5172,5176,5180,5181,5182],{"id":4267,"depth":895,"text":4270},{"id":4299,"depth":895,"text":4300},{"id":4320,"depth":895,"text":4321},{"id":4337,"depth":895,"text":4338},{"id":4369,"depth":895,"text":4370},{"id":4403,"depth":895,"text":4404},{"id":4454,"depth":895,"text":4455},{"id":4470,"depth":895,"text":4471,"children":5158},[5159],{"id":4491,"depth":902,"text":4492},{"id":4522,"depth":895,"text":4523,"children":5161},[5162],{"id":4554,"depth":902,"text":4555},{"id":4596,"depth":895,"text":4597,"children":5164},[5165],{"id":4627,"depth":902,"text":4628},{"id":4662,"depth":895,"text":4663},{"id":4686,"depth":895,"text":4687},{"id":4731,"depth":895,"text":4732},{"id":4758,"depth":895,"text":4759},{"id":4788,"depth":895,"text":4789},{"id":4803,"depth":895,"text":4806},{"id":4818,"depth":895,"text":4819,"children":5173},[5174,5175],{"id":4854,"depth":902,"text":4855},{"id":4887,"depth":902,"text":4888},{"id":4923,"depth":895,"text":4924,"children":5177},[5178,5179],{"id":4957,"depth":902,"text":4958},{"id":4983,"depth":902,"text":4984},{"id":711,"depth":895,"text":714},{"id":801,"depth":895,"text":802},{"id":865,"depth":895,"text":868},"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.","90",{},"40","\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs",{"title":4262,"description":5183},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs",[245,5192,5193],"branches","pull-requests","48:54","MOa9zIUOqaI","https:\u002F\u002Fyoutu.be\u002FMOa9zIUOqaI","Git Commands and PRs","GTIGHU5IyAE7RcRy68evvCM5YPZVDAWUbiTdBfC9nCI",{"id":5200,"title":5201,"audience":6,"body":5202,"contentType":926,"course":927,"description":5974,"estimateBasis":5975,"estimatedDiscussionMinutes":930,"estimatedLiveMinutes":1431,"estimatedTotalMinutes":5187,"extension":933,"meta":5976,"module":935,"navigation":936,"order":5977,"path":5978,"promptAssist":939,"seo":5979,"status":941,"stem":5980,"tags":5981,"videoDuration":5985,"videoId":5986,"videoLink":5987,"videoTitle":5988,"week":935,"__hash__":5989},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment.md","Local Development Environment Setup",{"type":8,"value":5203,"toc":5952},[5204,5221,5239,5260,5285,5320,5352,5430,5507,5609,5637,5702,5779,5803,5830,5848,5872,5923],[11,5205,5207,5210],{"id":5206,"level":14},"local-development-environment-title",[16,5208,5201],{"id":5209},"local-development-environment-setup",[20,5211,5212,5215,5218],{},[23,5213,5214],{},"VS Code for editing course files",[23,5216,5217],{},"Course profile for Internet Applications extensions",[23,5219,5220],{},"Optional local PHP check on your own computer",[11,5222,5223,5225],{"id":13,"level":14},[16,5224,18],{"id":13},[20,5226,5227,5230,5233,5236],{},[23,5228,5229],{},"Install VS Code",[23,5231,5232],{},"Open the course repository root",[23,5234,5235],{},"Install the required extensions for the course",[23,5237,5238],{},"Have a local php install as a light weight dev server (as a backup for the VM lessons)",[11,5240,5242,5245],{"id":5241,"level":14},"what-this-setup-does",[16,5243,5244],{"id":5241},"What This Setup Does",[20,5246,5247,5250,5253],{},[23,5248,5249],{},"VS Code: editor for course files",[23,5251,5252],{},"Extensions: syntax help, Git visibility, database viewing, time tracking",[23,5254,5255,5256,5259],{},"Optional host PHP: quick ",[33,5257,5258],{},"php -v"," check and editor support",[11,5261,5263,5266],{"id":5262,"level":14},"step-1-install-vs-code",[16,5264,5265],{"id":5262},"Step 1: Install VS Code",[20,5267,5268,5276,5279,5282],{},[23,5269,5270,5271],{},"Download: ",[89,5272,5275],{"href":5273,"rel":5274},"https:\u002F\u002Fcode.visualstudio.com\u002FDownload",[93],"Visual Studio Code",[23,5277,5278],{},"Install like a normal desktop app",[23,5280,5281],{},"Do not install VS Code inside your repository folder",[23,5283,5284],{},"VS Code is the editor; the repo is the workspace folder",[11,5286,5288,5291,5294,5317],{"id":5287,"level":14},"step-2-open-the-repository",[16,5289,5290],{"id":5287},"Step 2: Open The Repository",[104,5292,5293],{},"After the course repo is cloned:",[20,5295,5296,5306,5309,5314],{},[23,5297,5298,5299,5302,5303],{},"VS Code -> ",[33,5300,5301],{},"File"," -> ",[33,5304,5305],{},"Open Folder",[23,5307,5308],{},"Choose the repository root",[23,5310,5311,5312],{},"Folder name should match ",[33,5313,3348],{},[23,5315,5316],{},"Trust the workspace only if it is your cloned GitHub repo",[104,5318,5319],{},"Do not open a ZIP copy or clone the same repo again",[11,5321,5323,5327,5349],{"id":5322,"level":14},"step-3-create-course-profile",[16,5324,5326],{"id":5325},"step-3-create-a-course-profile","Step 3: Create A Course Profile",[20,5328,5329,5335,5343,5346],{},[23,5330,5331,5332],{},"Gear icon -> ",[33,5333,5334],{},"Profiles",[23,5336,5337,5338,2100,5340],{},"Create ",[33,5339,927],{},[33,5341,5342],{},"PHP",[23,5344,5345],{},"Switch into that profile",[23,5347,5348],{},"Install course extensions there",[104,5350,5351],{},"Profiles keep this course setup separate from other projects",[11,5353,5355,5358,5362],{"id":5354,"level":14},"step-4-install-extensions",[16,5356,5357],{"id":5354},"Step 4: Install Extensions",[112,5359,5361],{"id":5360},"start-with-these","Start With These",[20,5363,5364,5372,5380,5388,5396,5404,5419,5427],{},[23,5365,5366,5367],{},"Auto Rename Tag (Jun Han)\n",[20,5368,5369],{},[23,5370,5371],{},"Auto-completes matching HTML tags while you edit",[23,5373,5374,5375],{},"Bracket Lens (wraith13)\n",[20,5376,5377],{},[23,5378,5379],{},"Adds readability cues for closing brackets",[23,5381,5382,5383],{},"GitLens (GitKraken)\n",[20,5384,5385],{},[23,5386,5387],{},"Required: Git history, blame, and branch visibility in-editor",[23,5389,5390,5391],{},"MySQL (cweijan)\n",[20,5392,5393],{},[23,5394,5395],{},"Required later: connect to and inspect course database tables",[23,5397,5398,5399],{},"PHP Intelephense (Ben Mewburn)\n",[20,5400,5401],{},[23,5402,5403],{},"PHP language support, syntax checks, and warnings",[23,5405,5406,5407],{},"Todo Tree (Gruntfuggly)\n",[20,5408,5409],{},[23,5410,5411,5412,36,5415,5418],{},"Finds and lists ",[33,5413,5414],{},"TODO",[33,5416,5417],{},"FIXME",", and similar comments",[23,5420,5421,5422],{},"WakaTime\n",[20,5423,5424],{},[23,5425,5426],{},"Required in sections that use time tracking; needs your API key",[23,5428,5429],{},"See the slides below for MySQL and WakaTime setup",[11,5431,5433,5437],{"id":5432,"level":110},"step-4a-setup-mysql-extension",[16,5434,5436],{"id":5435},"step-4a-configure-mysql-extension","Step 4A: Configure MySQL Extension",[116,5438,5440,5499],{"gap":118,"left-width":120,"right-width":673,"align":5439},"center",[123,5441,5442,5446],{"v-slot:left":125},[112,5443,5445],{"id":5444},"connection-settings","Connection Settings",[20,5447,5448,5451,5496],{},[23,5449,5450],{},"Open the MySQL panel from the VS Code sidebar",[23,5452,5453,5454],{},"Create a new connection with your course database details",[20,5455,5456,5462,5468,5471,5474],{},[23,5457,5458,5459],{},"Host: ",[33,5460,5461],{},"db.ethereallab.app",[23,5463,5464,5465],{},"Port: ",[33,5466,5467],{},"3306",[23,5469,5470],{},"Username: your UCID",[23,5472,5473],{},"Database: your UCID",[23,5475,5476,5477],{},"Password: from your generated connection string\n",[20,5478,5479,5487],{},[23,5480,5481,5482],{},"Get it from the ",[89,5483,5486],{"href":5484,"rel":5485},"https:\u002F\u002Fcourses.ethereallab.app\u002Fdatabase",[93],"course database page",[23,5488,5489,5490,750,5493],{},"Use the 12 characters between ",[33,5491,5492],{},"ucid:",[33,5494,5495],{},"@",[23,5497,5498],{},"Save this connection; you will reuse it in later database lessons",[123,5500,5501],{"v-slot:right":125},[104,5502,5503],{},[129,5504],{"alt":5505,"src":5506,"variant":133},"MySQL extension connection setup for the course database","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fmysql-setup.png",[11,5508,5510,5514],{"id":5509,"level":110},"step-4b-setup-wakatime",[16,5511,5513],{"id":5512},"step-4b-configure-wakatime","Step 4B: Configure WakaTime",[116,5515,5517,5572],{"gap":118,"left-width":3324,"right-width":5516,"align":5439},"1.05fr",[123,5518,5519,5523],{"v-slot:left":125},[112,5520,5522],{"id":5521},"setup-order","Setup Order",[20,5524,5525,5532,5535,5538,5541,5544,5561,5566,5569],{},[23,5526,87,5527],{},[89,5528,5531],{"href":5529,"rel":5530},"https:\u002F\u002Fwakatime.com\u002Fsignup",[93],"WakaTime",[23,5533,5534],{},"Create or open your account",[23,5536,5537],{},"Copy your API key from account settings",[23,5539,5540],{},"In VS Code, search Extensions for WakaTime",[23,5542,5543],{},"Install the WakaTime extension",[23,5545,5546,5547],{},"Open Command Palette:",[20,5548,5549,5555],{},[23,5550,5551,5552],{},"Windows\u002FLinux: ",[33,5553,5554],{},"Ctrl+Shift+P",[23,5556,5557,5558],{},"macOS: ",[33,5559,5560],{},"Cmd+Shift+P",[23,5562,784,5563],{},[33,5564,5565],{},"WakaTime: API Key",[23,5567,5568],{},"Paste your API key",[23,5570,5571],{},"Restart VS Code if tracking does not appear right away",[123,5573,5574,5579,5586,5591,5598,5603],{"v-slot:right":125},[83,5575,5576],{},[23,5577,5578],{},"WakaTime account settings:",[104,5580,5581],{},[129,5582],{"alt":5583,"src":5584,"variant":133,"max-height":5585},"WakaTime account settings API key detail","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fsettings-api-key-detail.png","14rem",[83,5587,5588],{"start":895},[23,5589,5590],{},"VS Code extension search:",[104,5592,5593],{},[129,5594],{"alt":5595,"src":5596,"variant":133,"max-height":5597},"VS Code Extensions search results showing WakaTime","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fvs-code-search.png","9rem",[83,5599,5600],{"start":902},[23,5601,5602],{},"VS Code API key command:",[104,5604,5605],{},[129,5606],{"alt":5607,"src":5608,"variant":133,"max-height":5597},"Command Palette with WakaTime API key command","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fvs-code-prompt.png",[11,5610,5612,5615],{"id":5611,"level":14},"step-5-optional-local-php",[16,5613,5614],{"id":5611},"Step 5: Optional Local PHP",[20,5616,5617,5620,5623,5631,5634],{},[23,5618,5619],{},"Useful for editor support",[23,5621,5622],{},"Useful for quick terminal checks",[23,5624,5625,5626],{},"Not the main course runtime\n",[20,5627,5628],{},[23,5629,5630],{},"Viable backup solution if VM lesson has issues",[23,5632,5633],{},"VM and Render still run the real app path",[23,5635,5636],{},"See the slides below for OS-specific install notes",[11,5638,5640,5643],{"id":5639,"level":110},"step-5a-windows-php-zip",[16,5641,5642],{"id":5639},"Step 5A: Windows PHP ZIP",[116,5644,5645,5676],{"gap":118,"left-width":717,"right-width":717},[123,5646,5647,5651],{"v-slot:left":125},[112,5648,5650],{"id":5649},"download-and-extract","Download And Extract",[20,5652,5653,5656,5666,5671],{},[23,5654,5655],{},"Download PHP for Windows as a ZIP",[23,5657,5658,5659],{},"Extract it outside your repository",[20,5660,5661],{},[23,5662,1679,5663],{},[33,5664,5665],{},"C:\\tools\\php",[23,5667,5668,5669],{},"Add that extracted PHP folder to the user ",[33,5670,2366],{},[23,5672,5673,5674],{},"Restart Git Bash, PowerShell, and VS Code after editing ",[33,5675,2366],{},[123,5677,5678,5682,5698],{"v-slot:right":125},[112,5679,5681],{"id":5680},"visual-checks","Visual Checks",[20,5683,5684,5690,5695],{},[23,5685,5686,5687],{},"The extracted folder contains ",[33,5688,5689],{},"php.exe",[23,5691,5692,5693],{},"The Path entry points to the folder, not to ",[33,5694,5689],{},[23,5696,5697],{},"A new terminal can run:",[595,5699],{"language":597,"src":5700,"label":5701},"\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,5703,5705,5708],{"id":5704,"level":110},"step-5b-macos-homebrew-php",[16,5706,5707],{"id":5704},"Step 5B: macOS Homebrew PHP",[116,5709,5710,5741],{"gap":118,"left-width":717,"right-width":717},[123,5711,5712,5716],{"v-slot:left":125},[112,5713,5715],{"id":5714},"install-homebrew","Install Homebrew",[20,5717,5718,5721,5729,5732,5735,5738],{},[23,5719,5720],{},"Open Terminal",[23,5722,5723,5724],{},"Copy the install command from ",[89,5725,5728],{"href":5726,"rel":5727},"https:\u002F\u002Fbrew.sh\u002F",[93],"brew.sh",[23,5730,5731],{},"Expect Terminal to ask for your Mac password",[23,5733,5734],{},"Expect Homebrew to mention Command Line Tools if needed",[23,5736,5737],{},"At the end, Homebrew may print \"Next steps\"",[23,5739,5740],{},"Run those \"Next steps\" commands if shown",[123,5742,5743,5747,5751,5754],{"v-slot:right":125},[112,5744,5746],{"id":5745},"then-install-php","Then Install PHP",[595,5748],{"language":597,"src":5749,"label":5750},"\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",[104,5752,5753],{},"Look for:",[20,5755,5756,5762,5767,5773],{},[23,5757,5758,5761],{},[33,5759,5760],{},"brew --version"," prints a version",[23,5763,5764,5766],{},[33,5765,5258],{}," prints PHP 8 output",[23,5768,5769,5770],{},"Apple Silicon Macs commonly use ",[33,5771,5772],{},"\u002Fopt\u002Fhomebrew",[23,5774,5775,5776],{},"Intel Macs commonly use ",[33,5777,5778],{},"\u002Fusr\u002Flocal",[11,5780,5782,5786,5788,5792],{"id":5781,"level":110},"step-5c-linux-php-cli",[16,5783,5785],{"id":5784},"step-5c-ubuntulinux-php-cli","Step 5C: Ubuntu\u002FLinux PHP CLI",[104,5787,637],{},[595,5789],{"language":597,"src":5790,"label":5791},"\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",[20,5793,5794,5797,5800],{},[23,5795,5796],{},"This installs command-line PHP",[23,5798,5799],{},"This is only for local terminal checks",[23,5801,5802],{},"The later VM lesson installs Apache, PHP, and MySQL together",[11,5804,5806,5809,5811,5814,5816,5819],{"id":5805,"level":14},"step-6-verify-optional-php",[16,5807,5808],{"id":5805},"Step 6: Verify Optional PHP",[104,5810,637],{},[595,5812],{"language":597,"src":5813},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Fstep-6-verify-optional-p-01.sh",[104,5815,3413],{},[595,5817],{"language":4324,"src":5818},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Fexample-output-02.txt",[20,5820,5821,5824,5827],{},[23,5822,5823],{},"Exact version can differ",[23,5825,5826],{},"PHP 8 output means the terminal can find PHP",[23,5828,5829],{},"Windows may need a terminal or VS Code restart after PATH changes",[11,5831,5832,5834],{"id":711,"level":14},[16,5833,714],{"id":711},[20,5835,5836,5839,5842,5845],{},[23,5837,5838],{},"Installing tools inside the repository folder",[23,5840,5841],{},"Opening the parent folder instead of the repo root",[23,5843,5844],{},"Editing a ZIP copy instead of the cloned repo",[23,5846,5847],{},"Installing extensions in the wrong VS Code profile",[11,5849,5850,5852],{"id":1361,"level":14},[16,5851,1364],{"id":1361},[20,5853,5854,5857,5860,5863,5866],{},[23,5855,5856],{},"VS Code opens your course repository root",[23,5858,5859],{},"Course profile is active",[23,5861,5862],{},"PHP Intelephense is installed",[23,5864,5865],{},"GitLens is installed",[23,5867,5868,5869,5871],{},"Optional: ",[33,5870,5258],{}," prints a PHP 8 version",[11,5873,5874,5876],{"id":801,"level":14},[16,5875,802],{"id":801},[116,5877,5878,5896],{"gap":118,"left-width":717,"right-width":717},[123,5879,5880,5882],{"v-slot:left":125},[112,5881,810],{"id":809},[20,5883,5884,5887,5890,5893],{},[23,5885,5886],{},"IDE: editor with development tools",[23,5888,5889],{},"Extension: add-on that changes VS Code behavior",[23,5891,5892],{},"Profile: saved VS Code setup",[23,5894,5895],{},"PATH: system setting used to find commands",[123,5897,5898,5900],{"v-slot:right":125},[112,5899,834],{"id":798},[20,5901,5902,5909,5916],{},[23,5903,5904],{},[89,5905,5908],{"href":5906,"rel":5907},"https:\u002F\u002Fcode.visualstudio.com\u002Fdocs\u002Fintrovideos\u002Fbasics",[93],"VS Code Getting Started",[23,5910,5911],{},[89,5912,5915],{"href":5913,"rel":5914},"https:\u002F\u002Fcode.visualstudio.com\u002Fdocs\u002Fconfigure\u002Fprofiles",[93],"VS Code Profiles",[23,5917,5918],{},[89,5919,5922],{"href":5920,"rel":5921},"https:\u002F\u002Fwww.php.net\u002Fmanual\u002Fen\u002Finstall.php",[93],"PHP Installation",[11,5924,5925,5927],{"id":865,"level":14},[16,5926,868],{"id":865},[20,5928,5929,5932,5935,5938,5949],{},[23,5930,5931],{},"VS Code installed as the course editor",[23,5933,5934],{},"Repository opens from its root folder",[23,5936,5937],{},"Course extensions live in a course profile",[23,5939,5940,5941],{},"Local PHP is optional for this Internet Applications path\n",[20,5942,5943,5946],{},[23,5944,5945],{},"Summer 2026 added information about VM setup in a future lesson to teach clearer Apache\u002FMySQL topics",[23,5947,5948],{},"VM, Apache, Render QA, and Render production remain the real runtime checks",[23,5950,5951],{},"Next: copy the instructor template into the repository",{"title":125,"searchDepth":895,"depth":895,"links":5953},[5954,5955,5956,5957,5958,5959,5960,5963,5964,5965,5966,5967,5968,5969,5970,5971,5972,5973],{"id":5209,"depth":895,"text":5201},{"id":13,"depth":895,"text":18},{"id":5241,"depth":895,"text":5244},{"id":5262,"depth":895,"text":5265},{"id":5287,"depth":895,"text":5290},{"id":5325,"depth":895,"text":5326},{"id":5354,"depth":895,"text":5357,"children":5961},[5962],{"id":5360,"depth":902,"text":5361},{"id":5435,"depth":895,"text":5436},{"id":5512,"depth":895,"text":5513},{"id":5611,"depth":895,"text":5614},{"id":5639,"depth":895,"text":5642},{"id":5704,"depth":895,"text":5707},{"id":5784,"depth":895,"text":5785},{"id":5805,"depth":895,"text":5808},{"id":711,"depth":895,"text":714},{"id":1361,"depth":895,"text":1364},{"id":801,"depth":895,"text":802},{"id":865,"depth":895,"text":868},"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":5201,"description":5974},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment",[5982,5983,5984],"vscode","local-development","php","44:26","0s1N-m3LABc","https:\u002F\u002Fyoutu.be\u002F0s1N-m3LABc","Local Development Environment setup","X5U0DDKjg7X7HrYtDDcsE4QqlBLimZ9weKgnZlc8H2s",{"id":5991,"title":5992,"audience":6,"body":5993,"contentType":926,"course":927,"description":7044,"estimateBasis":7045,"estimatedDiscussionMinutes":4244,"estimatedLiveMinutes":932,"estimatedTotalMinutes":7046,"extension":933,"meta":7047,"module":935,"navigation":936,"order":7046,"path":7048,"promptAssist":939,"seo":7049,"status":941,"stem":7050,"tags":7051,"videoDuration":7052,"videoId":7053,"videoLink":7054,"videoTitle":7055,"week":935,"__hash__":7056},"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":5994,"toc":7016},[5995,6024,6066,6094,6127,6158,6204,6297,6341,6386,6431,6476,6548,6607,6680,6734,6810,6879,6911,6963,6987],[11,5996,5997,5999,6002],{"id":4267,"level":14},[16,5998,4270],{"id":4267},[104,6000,6001],{},"By the end, you should have:",[20,6003,6004,6007,6010,6016,6021],{},[23,6005,6006],{},"Cloned course repository open in the terminal",[23,6008,6009],{},"Starter template copied into the repository root",[23,6011,6012,6013],{},"Baseline commit on ",[33,6014,6015],{},"Module01-Course-Template",[23,6017,6018,6019],{},"Pull request merged into ",[33,6020,210],{},[23,6022,6023],{},"Clean working tree before moving on",[11,6025,6027,6031],{"id":6026,"level":14},"step-1-open-clone",[16,6028,6030],{"id":6029},"step-1-open-the-cloned-repository","Step 1: Open The Cloned Repository",[116,6032,6033,6041],{"gap":118,"left-width":717,"right-width":717},[123,6034,6035,6037],{"v-slot:left":125},[104,6036,637],{},[595,6038],{"language":597,"src":6039,"label":6040},"\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",[123,6042,6043,6045,6048],{"v-slot:right":125},[104,6044,3413],{},[595,6046],{"language":646,"src":6047,"label":3273},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fopen-cloned-repository-output.txt",[20,6049,6050,6055,6060],{},[23,6051,6052,6054],{},[33,6053,39],{},": current working directory",[23,6056,6057,6059],{},[33,6058,4515],{},": current branch and file state",[23,6061,6062,6063,6065],{},"Important check: ",[33,6064,39],{}," ends with your repository folder",[11,6067,6069,6073,6076,6079],{"id":6068,"level":14},"step-2-open-vscode",[16,6070,6072],{"id":6071},"step-2-open-the-repository-root","Step 2: Open The Repository Root",[104,6074,6075],{},"Run from inside the cloned repository folder:",[595,6077],{"language":597,"src":6078},"\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",[20,6080,6081,6086,6091],{},[23,6082,6083,6085],{},[33,6084,33],{},": opens VS Code from the terminal",[23,6087,6088,6090],{},[33,6089,1661],{}," means \"this current folder\"",[23,6092,6093],{},"VS Code should show your repository folder, not the parent folder",[11,6095,6097,6101],{"id":6096,"level":14},"step-3-download-template",[16,6098,6100],{"id":6099},"step-3-download-the-instructor-template","Step 3: Download The Instructor Template",[20,6102,6103,6115,6118,6121,6124],{},[23,6104,6105,6106],{},"Open the instructor template repository",[20,6107,6108],{},[23,6109,6110],{},[89,6111,6114],{"href":6112,"rel":6113},"https:\u002F\u002Fgithub.com\u002FMattToegel\u002FIT202-2026",[93],"IT202-2026",[23,6116,6117],{},"Download the ZIP",[23,6119,6120],{},"Extract the ZIP",[23,6122,6123],{},"Copy scaffold contents into your repository root",[23,6125,6126],{},"See the slide below for the copy rule",[11,6128,6130,6134,6137,6140,6155],{"id":6129,"level":110},"template-copy-rule",[112,6131,6133],{"id":6132},"copy-rule","Copy Rule",[104,6135,6136],{},"Copy the contents of the extracted template folder",[104,6138,6139],{},"Do not copy:",[20,6141,6142,6145,6152],{},[23,6143,6144],{},"The extracted wrapper folder as one extra nested folder",[23,6146,6147,6148,6151],{},"The template repository's hidden ",[33,6149,6150],{},".git"," folder",[23,6153,6154],{},"Old files from a different semester",[104,6156,6157],{},"Repository root should contain the starter folders directly",[11,6159,6161,6165,6168,6171],{"id":6160,"level":14},"step-4-check-structure",[16,6162,6164],{"id":6163},"step-4-check-the-starter-structure","Step 4: Check The Starter Structure",[104,6166,6167],{},"After copying, repository root should look similar to:",[595,6169],{"language":4324,"src":6170},"\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",[20,6172,6173,6178,6187,6201],{},[23,6174,6175,6177],{},[33,6176,1728],{}," should be directly inside your repository root",[23,6179,6180,6181,6184,6185],{},"Module folders and ",[33,6182,6183],{},"project"," live inside ",[33,6186,1728],{},[23,6188,6189,36,6192,40,6195,6198,6199],{},[33,6190,6191],{},"lib",[33,6193,6194],{},"partials",[33,6196,6197],{},"sql"," stay outside ",[33,6200,1728],{},[23,6202,6203],{},"See the slide below for the public\u002Fprivate folder boundary",[11,6205,6207,6211,6294],{"id":6206,"level":110},"public-html-boundary",[112,6208,6210],{"id":6209},"public-and-private-boundary","Public And Private Boundary",[20,6212,6213,6247,6269,6274,6279,6285,6291],{},[23,6214,6215,6217,6218],{},[33,6216,1728],{},": web root Apache can serve\n",[20,6219,6220,6230,6235,6241],{},[23,6221,6222,6225,6226,6229],{},[33,6223,6224],{},"m01"," through ",[33,6227,6228],{},"m10",": module practice folders",[23,6231,6232,6234],{},[33,6233,6183],{},": course project folder",[23,6236,6237,6240],{},[33,6238,6239],{},"index.php",": first browser entry point",[23,6242,6243,6246],{},[33,6244,6245],{},"test_db.php",": database connection check",[23,6248,6249,6251,6252],{},[33,6250,6191],{},": reusable PHP helpers\n",[20,6253,6254,6260],{},[23,6255,6256,6259],{},[33,6257,6258],{},".env.sample",": example local config file",[23,6261,6262,750,6265,6268],{},[33,6263,6264],{},"config.php",[33,6266,6267],{},"db.php",": config and database helpers",[23,6270,6271,6273],{},[33,6272,6194],{},": shared page pieces",[23,6275,6276,6278],{},[33,6277,6197],{},": database setup scripts",[23,6280,6281,6284],{},[33,6282,6283],{},"Dockerfile",": consistent runtime setup",[23,6286,6287,6290],{},[33,6288,6289],{},"structure.md",": starter layout notes",[23,6292,6293],{},"Private folders should not be opened directly in the browser",[104,6295,6296],{},"Later server setup expects this folder boundary",[11,6298,6300,6304],{"id":6299,"level":14},"step-5-check-status",[16,6301,6303],{"id":6302},"step-5-create-the-template-branch","Step 5: Create The Template Branch",[116,6305,6306,6314],{"gap":118,"left-width":717,"right-width":717},[123,6307,6308,6310],{"v-slot:left":125},[104,6309,637],{},[595,6311],{"language":597,"src":6312,"label":6313},"\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",[123,6315,6316,6319,6322],{"v-slot:right":125},[104,6317,6318],{},"Expected idea:",[595,6320],{"language":4324,"src":6321,"label":3273},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstatus-after-template-copy.txt",[20,6323,6324,6330,6335,6338],{},[23,6325,6326,6329],{},[33,6327,6328],{},"git checkout -b",": create and move to a new branch",[23,6331,6332,6333],{},"Branch name: ",[33,6334,6015],{},[23,6336,6337],{},"New files listed as untracked",[23,6339,6340],{},"No changes means likely wrong folder or copy missed",[11,6342,6344,6348],{"id":6343,"level":14},"step-6-stage",[16,6345,6347],{"id":6346},"step-6-stage-the-baseline-files","Step 6: Stage The Baseline Files",[116,6349,6350,6358],{"gap":118,"left-width":717,"right-width":717},[123,6351,6352,6354],{"v-slot:left":125},[104,6353,637],{},[595,6355],{"language":597,"src":6356,"label":6357},"\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",[123,6359,6360,6363,6381,6383],{"v-slot:right":125},[104,6361,6362],{},"What this means:",[20,6364,6365,6371,6376],{},[23,6366,6367,6370],{},[33,6368,6369],{},"git add",": choose files for the next commit",[23,6372,6373,6375],{},[33,6374,1661],{}," means current folder and contents",[23,6377,6378,6380],{},[33,6379,4515],{},": verify what is staged before committing",[104,6382,6318],{},[595,6384],{"language":4324,"src":6385,"label":3273},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstatus-after-stage.txt",[11,6387,6389,6393],{"id":6388,"level":14},"step-7-commit",[16,6390,6392],{"id":6391},"step-7-commit-the-baseline","Step 7: Commit The Baseline",[116,6394,6395,6403],{"gap":118,"left-width":717,"right-width":717},[123,6396,6397,6399],{"v-slot:left":125},[104,6398,637],{},[595,6400],{"language":597,"src":6401,"label":6402},"\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",[123,6404,6405,6407,6410],{"v-slot:right":125},[104,6406,6318],{},[595,6408],{"language":4324,"src":6409,"label":3273},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fcommit-baseline-output.txt",[20,6411,6412,6418,6428],{},[23,6413,6414,6417],{},[33,6415,6416],{},"git commit",": save staged changes in local history",[23,6419,6420,6422,6423],{},[33,6421,4613],{},": commit message\n",[20,6424,6425],{},[23,6426,6427],{},"Message is required, even if empty",[23,6429,6430],{},"Baseline commit: starter state before custom work",[11,6432,6434,6438],{"id":6433,"level":14},"step-8-push",[16,6435,6437],{"id":6436},"step-8-push-the-template-branch","Step 8: Push The Template Branch",[116,6439,6440,6448],{"gap":118,"left-width":717,"right-width":717},[123,6441,6442,6444],{"v-slot:left":125},[104,6443,637],{},[595,6445],{"language":597,"src":6446,"label":6447},"\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",[123,6449,6450,6452,6455],{"v-slot:right":125},[104,6451,6318],{},[595,6453],{"language":4324,"src":6454,"label":3273},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fpush-baseline-output.txt",[20,6456,6457,6462,6468,6473],{},[23,6458,6459,6461],{},[33,6460,4676],{},": GitHub remote",[23,6463,6464,6467],{},[33,6465,6466],{},"-u",": remembers this branch's GitHub tracking branch",[23,6469,6470,6472],{},[33,6471,6015],{},": branch being sent",[23,6474,6475],{},"Refresh GitHub after the push",[11,6477,6479,6483],{"id":6478,"level":14},"step-9-open-pull-request",[16,6480,6482],{"id":6481},"step-9-open-the-pull-request","Step 9: Open The Pull Request",[116,6484,6485,6528],{"gap":118,"left-width":717,"right-width":717},[123,6486,6487,6489],{"v-slot:left":125},[104,6488,3329],{},[20,6490,6491,6494,6510,6515,6520,6523],{},[23,6492,6493],{},"Open your course repository",[23,6495,1096,6496,6499],{},[814,6497,6498],{},"Compare & pull request",[20,6500,6501],{},[23,6502,6503,6504,5302,6507],{},"Or use ",[814,6505,6506],{},"Pull requests",[814,6508,6509],{},"New pull request",[23,6511,6512,6513],{},"Set base branch to ",[33,6514,210],{},[23,6516,6517,6518],{},"Set compare branch to ",[33,6519,6015],{},[23,6521,6522],{},"Confirm the changed files are the starter template files",[23,6524,1096,6525],{},[814,6526,6527],{},"Create pull request",[123,6529,6530,6533,6537],{"v-slot:right":125},[104,6531,6532],{},"Use a short title and description:",[595,6534],{"language":4324,"src":6535,"label":6536},"\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",[20,6538,6539,6542,6545],{},[23,6540,6541],{},"Base receives the changes",[23,6543,6544],{},"Compare contains your branch work",[23,6546,6547],{},"If base and compare are reversed, do not create the pull request",[11,6549,6551,6557],{"id":6550,"level":14},"step-10-merge-sync-main",[16,6552,6554,6555],{"id":6553},"step-10-merge-and-sync-main","Step 10: Merge And Sync ",[33,6556,210],{},[116,6558,6559,6581],{"gap":118,"left-width":717,"right-width":717},[123,6560,6561,6563,6575,6577],{"v-slot:left":125},[104,6562,3329],{},[20,6564,6565,6570],{},[23,6566,1096,6567],{},[814,6568,6569],{},"Merge pull request",[23,6571,1096,6572],{},[814,6573,6574],{},"Confirm merge",[104,6576,4970],{},[595,6578],{"language":597,"src":6579,"label":6580},"\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",[123,6582,6583,6585,6588],{"v-slot:right":125},[104,6584,6318],{},[595,6586],{"language":4324,"src":6587,"label":3273},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fsync-main-after-pr-output.txt",[20,6589,6590,6596,6602],{},[23,6591,6592,6595],{},[33,6593,6594],{},"git checkout main",": return to the main branch",[23,6597,6598,6601],{},[33,6599,6600],{},"git pull origin main",": download the merged template files",[23,6603,6604,6605,4994],{},"Continue only when local ",[33,6606,210],{},[11,6608,6610,6616],{"id":6609,"level":14},"step-11-create-local-env",[16,6611,6612,6613],{"id":6609},"Step 11: Create Local ",[33,6614,6615],{},".env",[116,6617,6618,6640],{"gap":118,"left-width":717,"right-width":717},[123,6619,6620,6623,6627],{"v-slot:left":125},[104,6621,6622],{},"Run from the repository root:",[595,6624],{"language":597,"src":6625,"label":6626},"\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",[20,6628,6629],{},[23,6630,6631,6632,6635,6636],{},"Get ",[33,6633,6634],{},"DB_URL"," from ",[89,6637,6639],{"href":5484,"rel":6638},[93],"courses.ethereallab.app\u002Fdatabase",[123,6641,6642,6645,6650],{"v-slot:right":125},[104,6643,6644],{},"Fill in values similar to:",[595,6646],{"language":6647,"src":6648,"label":6649},"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",[20,6651,6652,6657,6662,6665,6670,6675],{},[23,6653,6654,6656],{},[33,6655,6615],{}," stores local secrets",[23,6658,143,6659,6661],{},[33,6660,6615],{}," on your computer only",[23,6663,6664],{},"Do not commit your real connection string",[23,6666,6667,6668],{},"Paste the generated database connection string as ",[33,6669,6634],{},[23,6671,6672,6674],{},[33,6673,6264],{}," loads local or hosted environment variables",[23,6676,6677,6678],{},"Do not paste secrets directly into ",[33,6679,6264],{},[11,6681,6683,6687],{"id":6682,"level":14},"step-12-test-local-db",[16,6684,6686],{"id":6685},"step-12-test-local-database-connection","Step 12: Test Local Database Connection",[116,6688,6689,6697],{"gap":118,"left-width":717,"right-width":717},[123,6690,6691,6693],{"v-slot:left":125},[104,6692,6622],{},[595,6694],{"language":597,"src":6695,"label":6696},"\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",[123,6698,6699,6702,6706],{"v-slot:right":125},[104,6700,6701],{},"Then open:",[595,6703],{"language":4324,"src":6704,"label":6705},"\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",[20,6707,6708,6714,6720,6728],{},[23,6709,6710,6713],{},[33,6711,6712],{},"php -S",": starts PHP's built-in local server",[23,6715,6716,6719],{},[33,6717,6718],{},"-t public_html",": serves the course web root",[23,6721,6722,6724,6725,6727],{},[33,6723,6245],{},": confirms PHP can read ",[33,6726,6615],{}," and connect to MySQL",[23,6729,6730,6731,6733],{},"Stop the server with ",[33,6732,2323],{}," when finished",[11,6735,6737,6745,6751],{"id":6736,"level":14},"step-13-enable-pdo-mysql",[16,6738,6740,6741,6744],{"id":6739},"step-13-enable-pdo_mysql-if-needed","Step 13: Enable ",[33,6742,6743],{},"pdo_mysql"," If Needed",[104,6746,6747,6748,1661],{},"This is usually a Windows PHP ZIP setup issue. macOS and Linux usually install MySQL support through Homebrew or ",[33,6749,6750],{},"apt",[116,6752,6753,6784],{"gap":118,"left-width":717,"right-width":717},[123,6754,6755,6758,6762,6765],{"v-slot:left":125},[104,6756,6757],{},"Find the PHP folder:",[595,6759],{"language":597,"src":6760,"label":6761},"\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",[104,6763,6764],{},"In that folder:",[20,6766,6767,6773,6779],{},[23,6768,6769,6770],{},"Find ",[33,6771,6772],{},"php.ini-development",[23,6774,6775,6776],{},"Copy it as ",[33,6777,6778],{},"php.ini",[23,6780,3713,6781,6783],{},[33,6782,6778],{}," in your editor",[123,6785,6786,6789,6793,6796,6800],{"v-slot:right":125},[104,6787,6788],{},"Uncomment these lines:",[595,6790],{"language":6791,"src":6792,"label":6778},"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",[104,6794,6795],{},"Mac\u002FLinux usually use:",[595,6797],{"language":597,"src":6798,"label":6799},"\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",[20,6801,6802,6807],{},[23,6803,6804,6805],{},"Restart the php dev server after changing ",[33,6806,6778],{},[23,6808,6809],{},"Run Step 12 again after enabling the extension",[11,6811,6813,6815,6818],{"id":6812,"level":14},"quick-check-final",[16,6814,1364],{"id":1361},[104,6816,6817],{},"Confirm all of these:",[20,6819,6820,6823,6831,6834,6839,6848,6854,6859,6864,6870],{},[23,6821,6822],{},"GitHub shows the starter files",[23,6824,6825,6826,6828,6829],{},"GitHub shows a pull request from ",[33,6827,6015],{}," into ",[33,6830,210],{},[23,6832,6833],{},"The pull request is merged",[23,6835,4740,6836,6838],{},[33,6837,210],{}," says the working tree is clean",[23,6840,6841,6225,6844,6847],{},[33,6842,6843],{},"public_html\u002Fm01",[33,6845,6846],{},"public_html\u002Fm10"," exist",[23,6849,6850,6853],{},[33,6851,6852],{},"public_html\u002Fproject"," exists",[23,6855,6856,6858],{},[33,6857,1728],{}," is not nested inside another accidental folder",[23,6860,6861,6863],{},[33,6862,6649],{}," exists locally and is not committed with real secrets",[23,6865,6866,6869],{},[33,6867,6868],{},"http:\u002F\u002Flocalhost:3000\u002Ftest_db.php"," confirms the database connection",[23,6871,6872,6873,6875,6876,6878],{},"Windows PHP has ",[33,6874,6743],{}," enabled if ",[33,6877,6245],{}," reports a missing driver",[11,6880,6882,6886,6888,6891,6900],{"id":6881,"level":14},"reset-check",[16,6883,6885],{"id":6884},"if-something-looks-wrong","If Something Looks Wrong",[104,6887,637],{},[595,6889],{"language":597,"src":6890},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fif-something-looks-wrong-03.sh",[6892,6893,6894],"blockquote",{},[104,6895,6896,6897,6899],{},"Tip: ",[33,6898,3867],{}," prints the repository root when your current folder is inside a Git repository",[20,6901,6902,6905,6908],{},[23,6903,6904],{},"Output should point to your course repository",[23,6906,6907],{},"If it points somewhere else, move folders before continuing",[23,6909,6910],{},"Avoid cloning inside another cloned repository",[11,6912,6913,6915],{"id":711,"level":14},[16,6914,714],{"id":711},[20,6916,6917,6920,6923,6928,6931,6934,6939,6949,6954,6957],{},[23,6918,6919],{},"Opening the parent folder instead of the repository root",[23,6921,6922],{},"Copying the instructor template folder as a nested folder",[23,6924,6925,6926,6151],{},"Copying the template ",[33,6927,6150],{},[23,6929,6930],{},"Keeping the downloaded ZIP inside the repository",[23,6932,6933],{},"Re-cloning the repository instead of opening the existing clone",[23,6935,6936,6937],{},"Putting module folders outside ",[33,6938,1728],{},[23,6940,6941,6942,6944,6945,6948],{},"Renaming ",[33,6943,6224],{}," to ",[33,6946,6947],{},"M1"," or mixing folder casing",[23,6950,6951,6952],{},"Doing template work directly on ",[33,6953,210],{},[23,6955,6956],{},"Reversing base and compare branches in the pull request",[23,6958,6959,6960,6962],{},"Forgetting to sync local ",[33,6961,210],{}," after the pull request is merged",[11,6964,6965,6967],{"id":809,"level":14},[16,6966,810],{"id":809},[20,6968,6969,6972,6975,6978,6981,6984],{},[23,6970,6971],{},"Repository root: top folder of the cloned project",[23,6973,6974],{},"Baseline: starter state before custom work begins",[23,6976,6977],{},"Pull request: GitHub review page used to merge branch work",[23,6979,6980],{},"Web root: folder served to the browser",[23,6982,6983],{},"Scaffold: starter folders that organize future work",[23,6985,6986],{},"Staging: choosing files for the next commit",[11,6988,6989,6991,6994],{"id":865,"level":14},[16,6990,868],{"id":865},[104,6992,6993],{},"Before leaving this presentation, confirm the following:",[20,6995,6996,6999,7002,7005,7011],{},[23,6997,6998],{},"You still have one clone for your repository",[23,7000,7001],{},"Your VS Code is able to open directly to your repository",[23,7003,7004],{},"Your repository has the full starter baseline correctly structured",[23,7006,7007,7008,7010],{},"GitHub remote ",[33,7009,210],{}," has the baseline content",[23,7012,4740,7013,7015],{},[33,7014,210],{}," was synchronized",{"title":125,"searchDepth":895,"depth":895,"links":7017},[7018,7019,7020,7021,7024,7027,7028,7029,7030,7031,7032,7034,7036,7037,7039,7040,7041,7042,7043],{"id":4267,"depth":895,"text":4270},{"id":6029,"depth":895,"text":6030},{"id":6071,"depth":895,"text":6072},{"id":6099,"depth":895,"text":6100,"children":7022},[7023],{"id":6132,"depth":902,"text":6133},{"id":6163,"depth":895,"text":6164,"children":7025},[7026],{"id":6209,"depth":902,"text":6210},{"id":6302,"depth":895,"text":6303},{"id":6346,"depth":895,"text":6347},{"id":6391,"depth":895,"text":6392},{"id":6436,"depth":895,"text":6437},{"id":6481,"depth":895,"text":6482},{"id":6553,"depth":895,"text":7033},"Step 10: Merge And Sync main",{"id":6609,"depth":895,"text":7035},"Step 11: Create Local .env",{"id":6685,"depth":895,"text":6686},{"id":6739,"depth":895,"text":7038},"Step 13: Enable pdo_mysql If Needed",{"id":1361,"depth":895,"text":1364},{"id":6884,"depth":895,"text":6885},{"id":711,"depth":895,"text":714},{"id":809,"depth":895,"text":810},{"id":865,"depth":895,"text":868},"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":5992,"description":7044},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository",[4254,123,245],"47:11","4n0-QuXO_Aw","https:\u002F\u002Fyoutu.be\u002F4n0-QuXO_Aw","Adding Instructor\u002FCourse Template","iYq9WdND1ODBRrXLU2gX9dNCXvDc-Kvqufsokl_jg3E",{"id":7058,"title":7059,"audience":6,"body":7060,"contentType":926,"course":927,"description":7770,"estimateBasis":7771,"estimatedDiscussionMinutes":4244,"estimatedLiveMinutes":5187,"estimatedTotalMinutes":2492,"extension":933,"meta":7772,"module":935,"navigation":936,"order":4245,"path":7773,"promptAssist":939,"seo":7774,"status":941,"stem":7775,"tags":7776,"videoDuration":7778,"videoId":7779,"videoLink":7780,"videoTitle":7781,"week":935,"__hash__":7782},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches.md","QA And Prod Branches",{"type":8,"value":7061,"toc":7749},[7062,7096,7144,7166,7220,7285,7343,7393,7458,7499,7591,7631,7658,7716],[11,7063,7064,7066,7068],{"id":4267,"level":14},[16,7065,4270],{"id":4267},[104,7067,4273],{},[20,7069,7070,7079,7084,7088,7093],{},[23,7071,7072,7073,750,7076],{},"Understand the purpose and usage of ",[33,7074,7075],{},"qa",[33,7077,7078],{},"prod",[23,7080,7081,7082],{},"Create and push ",[33,7083,7075],{},[23,7085,7081,7086],{},[33,7087,7078],{},[23,7089,7090,7091],{},"Keep local work pointed at ",[33,7092,7075],{},[23,7094,7095],{},"Confirm GitHub has the expected branches",[11,7097,7099,7102,7137],{"id":7098,"level":14},"branch-roles",[16,7100,7101],{"id":7098},"Branch Roles",[20,7103,7104,7114,7124,7134],{},[23,7105,7106,7108,7109],{},[33,7107,210],{},": starter baseline and shared source branch\n",[20,7110,7111],{},[23,7112,7113],{},"Most projects stick with this; we'll split ours into development lanes",[23,7115,7116,7118,7119],{},[33,7117,7075],{},": public testing and evidence branch\n",[20,7120,7121],{},[23,7122,7123],{},"Normal branch to return to before new course work",[23,7125,7126,7128,7129],{},[33,7127,7078],{},": stable grading and evaluation branch\n",[20,7130,7131],{},[23,7132,7133],{},"Protected from everyday local edits",[23,7135,7136],{},"Later deployment setup connects Render to these branches",[104,7138,7139,7140,5302,7142],{},"Course flow: feature or homework branch -> ",[33,7141,7075],{},[33,7143,7078],{},[11,7145,7146,7148,7151,7155],{"id":1544,"level":14},[16,7147,1547],{"id":1544},[104,7149,7150],{},"Run inside the course repository:",[595,7152],{"label":7153,"language":597,"src":7154},"before-you-start.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fbefore-you-start.sh",[20,7156,7157,7160,7163],{},[23,7158,7159],{},"Working tree should be clean",[23,7161,7162],{},"Starter baseline already pushed to GitHub",[23,7164,7165],{},"Stop if Git says files are modified or untracked",[11,7167,7169,7175],{"id":7168,"level":14},"step-1-sync-main",[16,7170,7172,7173],{"id":7171},"step-1-start-from-main","Step 1: Start From ",[33,7174,210],{},[116,7176,7177,7185],{"gap":118,"left-width":717,"right-width":717},[123,7178,7179,7181],{"v-slot:left":125},[104,7180,637],{},[595,7182],{"label":7183,"language":597,"src":7184},"sync-main.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fsync-main.sh",[123,7186,7187,7189,7192],{"v-slot:right":125},[104,7188,3413],{},[595,7190],{"label":3273,"language":4324,"src":7191},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fsync-main-output.txt",[20,7193,7194,7201],{},[23,7195,7196,7198,7199],{},[33,7197,6594],{},": switch to ",[33,7200,210],{},[23,7202,7203,7205,7206,7208,7209],{},[33,7204,6600],{},": get the latest ",[33,7207,210],{}," from GitHub\n",[20,7210,7211,7215],{},[23,7212,7213,6461],{},[33,7214,4676],{},[23,7216,7217,7219],{},[33,7218,210],{},": remote branch being pulled",[11,7221,7223,7229],{"id":7222,"level":14},"step-2-create-qa",[16,7224,7226,7227],{"id":7225},"step-2-create-and-push-qa","Step 2: Create And Push ",[33,7228,7075],{},[116,7230,7231,7239],{"gap":118,"left-width":717,"right-width":717},[123,7232,7233,7235],{"v-slot:left":125},[104,7234,637],{},[595,7236],{"label":7237,"language":597,"src":7238},"create-qa.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-qa.sh",[123,7240,7241,7243,7246],{"v-slot:right":125},[104,7242,3413],{},[595,7244],{"label":3273,"language":4324,"src":7245},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-qa-output.txt",[20,7247,7248,7265],{},[23,7249,7250,7253,7254,7256,7257],{},[33,7251,7252],{},"git checkout -b qa",": create ",[33,7255,7075],{}," and switch to it\n",[20,7258,7259],{},[23,7260,7261,7264],{},[33,7262,7263],{},"-b",": creates a new branch of the following name",[23,7266,7267,7270,7271,7273,7274],{},[33,7268,7269],{},"git push -u origin qa",": send ",[33,7272,7075],{}," to GitHub\n",[20,7275,7276],{},[23,7277,7278,7280,7281,7284],{},[33,7279,6466],{},": remember ",[33,7282,7283],{},"origin\u002Fqa"," as the upstream branch",[11,7286,7288,7294],{"id":7287,"level":14},"step-3-create-prod",[16,7289,7291,7292],{"id":7290},"step-3-create-and-push-prod","Step 3: Create And Push ",[33,7293,7078],{},[116,7295,7296,7304],{"gap":118,"left-width":717,"right-width":717},[123,7297,7298,7300],{"v-slot:left":125},[104,7299,637],{},[595,7301],{"label":7302,"language":597,"src":7303},"create-prod.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-prod.sh",[123,7305,7306,7308,7311],{"v-slot:right":125},[104,7307,3413],{},[595,7309],{"label":3273,"language":4324,"src":7310},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-prod-output.txt",[20,7312,7313,7321,7326,7338],{},[23,7314,5337,7315,7317,7318,7320],{},[33,7316,7078],{}," from the current ",[33,7319,7075],{}," branch",[23,7322,7323],{},[33,7324,7325],{},"git checkout -b prod",[23,7327,7328,7329,7273,7331],{},"Push ",[33,7330,7078],{},[20,7332,7333],{},[23,7334,7335],{},[33,7336,7337],{},"git push origin prod",[23,7339,7340,7342],{},[33,7341,7078],{}," starts from the same clean baseline",[11,7344,7346,7351],{"id":7345,"level":14},"step-4-return-to-qa",[16,7347,7348,7349],{"id":7345},"Step 4: Return To ",[33,7350,7075],{},[116,7352,7353,7361],{"gap":118,"left-width":717,"right-width":717},[123,7354,7355,7357],{"v-slot:left":125},[104,7356,637],{},[595,7358],{"label":7359,"language":597,"src":7360},"return-to-qa.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Freturn-to-qa.sh",[123,7362,7363,7365,7368],{"v-slot:right":125},[104,7364,3413],{},[595,7366],{"label":3273,"language":4324,"src":7367},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Freturn-to-qa-output.txt",[20,7369,7370,7375,7380],{},[23,7371,7372,7374],{},[33,7373,7075],{}," should have the asterisk",[23,7376,7377,7379],{},[33,7378,7078],{}," should still exist on GitHub",[23,7381,7382,7383,7385],{},"Do not start normal course work from ",[33,7384,7078],{},[20,7386,7387],{},[23,7388,7389,7390,7392],{},"We'll remove local ",[33,7391,7078],{}," to avoid this issue",[11,7394,7396,7402],{"id":7395,"level":14},"step-5-delete-local-prod",[16,7397,7399,7400],{"id":7398},"step-5-remove-local-prod","Step 5: Remove Local ",[33,7401,7078],{},[116,7403,7404,7412],{"gap":118,"left-width":717,"right-width":717},[123,7405,7406,7408],{"v-slot:left":125},[104,7407,637],{},[595,7409],{"label":7410,"language":597,"src":7411},"delete-local-prod.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fdelete-local-prod.sh",[123,7413,7414,7416,7419],{"v-slot:right":125},[104,7415,3413],{},[595,7417],{"label":3273,"language":4324,"src":7418},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fdelete-local-prod-output.txt",[20,7420,7421,7443],{},[23,7422,7423,7426,7427,7429],{},[33,7424,7425],{},"git branch -d prod",": delete local ",[33,7428,7078],{},[20,7430,7431,7437],{},[23,7432,7433,7436],{},[33,7434,7435],{},"-d",": delete only if Git considers it safe",[23,7438,7439,7442],{},[33,7440,7441],{},"-D",": can be used as a forced delete",[23,7444,7445,7448,7449],{},[33,7446,7447],{},"git branch -r",": list remote branches\n",[20,7450,7451],{},[23,7452,7453,7454,7457],{},"Confirms ",[33,7455,7456],{},"origin\u002Fprod"," still exists",[11,7459,7461,7464,7467,7470,7484,7487],{"id":7460,"level":14},"github-check",[16,7462,7463],{"id":7460},"GitHub Check",[104,7465,7466],{},"Open the branch dropdown on GitHub",[104,7468,7469],{},"You should see:",[20,7471,7472,7476,7480],{},[23,7473,7474],{},[33,7475,210],{},[23,7477,7478],{},[33,7479,7075],{},[23,7481,7482],{},[33,7483,7078],{},[104,7485,7486],{},"Branch roles:",[20,7488,7489,7494],{},[23,7490,7491,7493],{},[33,7492,7075],{},": testing and evidence",[23,7495,7496,7498],{},[33,7497,7078],{},": stable grading target",[11,7500,7502,7506],{"id":7501,"level":14},"normal-workflow",[16,7503,7505],{"id":7504},"normal-workflow-after-setup","Normal Workflow After Setup",[83,7507,7508,7525,7533,7544,7549,7563,7566,7573,7585],{},[23,7509,7510,7511,7513],{},"Return to ",[33,7512,7075],{},[20,7514,7515,7520],{},[23,7516,7517],{},[33,7518,7519],{},"git checkout qa",[23,7521,7522],{},[33,7523,7524],{},"git pull origin qa",[23,7526,7527,7528],{},"Create a feature or homework branch\n",[20,7529,7530],{},[23,7531,7532],{},"Branch name matches the task",[23,7534,7535,7536],{},"Commit the work on that branch\n",[20,7537,7538],{},[23,7539,7540,7541,7543],{},"Check ",[33,7542,4515],{}," before each Git command",[23,7545,7546,7547],{},"Push the branch and open a pull request into ",[33,7548,7075],{},[23,7550,7551,7552,7554,7555],{},"Merge into ",[33,7553,7075],{}," after review\n",[20,7556,7557],{},[23,7558,7559,7560,7562],{},"QA deployment will update from ",[33,7561,7075],{}," after Render setup",[23,7564,7565],{},"Test the QA version",[23,7567,7568,7569,6828,7571],{},"Open a pull request from ",[33,7570,7075],{},[33,7572,7078],{},[23,7574,7551,7575,7577,7578],{},[33,7576,7078],{}," when stable\n",[20,7579,7580],{},[23,7581,7582,7583,7562],{},"Production deployment will use ",[33,7584,7078],{},[23,7586,7587,7588,7590],{},"Return locally to ",[33,7589,7075],{}," and pull before the next task",[11,7592,7593,7595],{"id":711,"level":14},[16,7594,714],{"id":711},[20,7596,7597,7602,7607,7615,7623,7626],{},[23,7598,7599,7600],{},"Working directly on ",[33,7601,7078],{},[23,7603,7604,7605],{},"Forgetting to return to ",[33,7606,7075],{},[23,7608,7609,7610,7612,7613],{},"Pushing ",[33,7611,7075],{}," but not ",[33,7614,7078],{},[23,7616,7617,7618,7620,7621],{},"Deleting remote ",[33,7619,7078],{}," instead of local ",[33,7622,7078],{},[23,7624,7625],{},"Assuming GitHub has the branch without checking",[23,7627,7628,7629,4994],{},"Starting new work before ",[33,7630,4515],{},[11,7632,7633,7635,7638],{"id":1361,"level":14},[16,7634,1364],{"id":1361},[104,7636,7637],{},"Answer before moving on:",[20,7639,7640,7643,7646,7649,7655],{},[23,7641,7642],{},"Which branch should QA deployment watch?",[23,7644,7645],{},"Which branch should production grading use?",[23,7647,7648],{},"Which branch should you return to before new work?",[23,7650,7651,7652,7654],{},"Why remove local ",[33,7653,7078],{}," after pushing it?",[23,7656,7657],{},"What future setup connects Render to these branches?",[11,7659,7660,7662],{"id":798,"level":14},[16,7661,802],{"id":801},[116,7663,7664,7689],{"gap":118,"left-width":717,"right-width":717},[123,7665,7666,7668],{"v-slot:left":125},[112,7667,810],{"id":809},[20,7669,7670,7673,7676,7681,7686],{},[23,7671,7672],{},"Branch: named line of Git history",[23,7674,7675],{},"Upstream: remote branch Git remembers for push\u002Fpull",[23,7677,7678,7680],{},[33,7679,7075],{},": public testing branch",[23,7682,7683,7685],{},[33,7684,7078],{},": stable grading branch",[23,7687,7688],{},"Remote-only branch: exists on GitHub, not locally",[123,7690,7691,7693],{"v-slot:right":125},[112,7692,834],{"id":798},[20,7694,7695,7702,7709],{},[23,7696,5089,7697],{},[89,7698,7701],{"href":7699,"rel":7700},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fget-started\u002Fusing-git\u002Fabout-git#about-branches",[93],"About branches",[23,7703,5089,7704],{},[89,7705,7708],{"href":7706,"rel":7707},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fpull-requests\u002Fcollaborating-with-pull-requests\u002Fproposing-changes-to-your-work-with-pull-requests\u002Fabout-pull-requests",[93],"About pull requests",[23,7710,5074,7711],{},[89,7712,7715],{"href":7713,"rel":7714},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Branching-Branches-in-a-Nutshell",[93],"Git Branching",[11,7717,7718,7720,7722],{"id":865,"level":14},[16,7719,868],{"id":865},[104,7721,2415],{},[20,7723,7724,7733,7737,7741,7746],{},[23,7725,7726,7727,36,7729,40,7731],{},"Explain ",[33,7728,210],{},[33,7730,7075],{},[33,7732,7078],{},[23,7734,7081,7735],{},[33,7736,7075],{},[23,7738,7081,7739],{},[33,7740,7078],{},[23,7742,7743,7744],{},"Keep local work branched from ",[33,7745,7075],{},[23,7747,7748],{},"Verify remote branches on GitHub",{"title":125,"searchDepth":895,"depth":895,"links":7750},[7751,7752,7753,7754,7756,7758,7760,7762,7764,7765,7766,7767,7768,7769],{"id":4267,"depth":895,"text":4270},{"id":7098,"depth":895,"text":7101},{"id":1544,"depth":895,"text":1547},{"id":7171,"depth":895,"text":7755},"Step 1: Start From main",{"id":7225,"depth":895,"text":7757},"Step 2: Create And Push qa",{"id":7290,"depth":895,"text":7759},"Step 3: Create And Push prod",{"id":7345,"depth":895,"text":7761},"Step 4: Return To qa",{"id":7398,"depth":895,"text":7763},"Step 5: Remove Local prod",{"id":7460,"depth":895,"text":7463},{"id":7504,"depth":895,"text":7505},{"id":711,"depth":895,"text":714},{"id":1361,"depth":895,"text":1364},{"id":801,"depth":895,"text":802},{"id":865,"depth":895,"text":868},"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":7059,"description":7770},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches",[245,5192,7075,7777],"production","10:35","32XilHQwRiY","https:\u002F\u002Fyoutu.be\u002F32XilHQwRiY","Create QA and Prod Branches","GZx1sXtI0BMbyb6Gbpj7aoBvczhhR-FV7YpFE4j4UCs",{"id":7784,"title":7785,"audience":6,"body":7786,"contentType":926,"course":927,"description":8593,"estimateBasis":8594,"estimatedDiscussionMinutes":4244,"estimatedLiveMinutes":2492,"estimatedTotalMinutes":4245,"extension":933,"meta":8595,"module":935,"navigation":936,"order":8596,"path":8597,"promptAssist":939,"seo":8598,"status":941,"stem":8599,"tags":8600,"videoDuration":8603,"videoId":8604,"videoLink":8605,"videoTitle":8606,"week":935,"__hash__":8607},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F08-render-setup.md","Render Setup",{"type":8,"value":7787,"toc":8572},[7788,7815,7838,7867,7935,7996,8031,8067,8104,8154,8200,8235,8281,8318,8346,8378,8425,8458,8526],[11,7789,7791,7794],{"id":7790,"level":14},"render-setup-title",[16,7792,7785],{"id":7793},"render-setup",[20,7795,7796,7799,7804,7809,7812],{},[23,7797,7798],{},"Connect GitHub repo to Render",[23,7800,7801,7802],{},"Create a QA service from ",[33,7803,7075],{},[23,7805,7806,7807],{},"Create a production service from ",[33,7808,7078],{},[23,7810,7811],{},"Add the course database connection string",[23,7813,7814],{},"Verify live URLs and deploy logs",[11,7816,7817,7819,7821],{"id":3171,"level":14},[16,7818,3174],{"id":3171},[104,7820,4273],{},[20,7822,7823,7826,7829,7832,7835],{},[23,7824,7825],{},"Explain what Render does in the course workflow",[23,7827,7828],{},"Create separate QA and production services",[23,7830,7831],{},"Connect each service to the correct branch",[23,7833,7834],{},"Read Render logs when a deploy fails",[23,7836,7837],{},"Identify which deployed URL to submit or test",[11,7839,7841,7844,7861],{"id":7840,"level":14},"what-render-does",[16,7842,7843],{"id":7840},"What Render Does",[20,7845,7846,7849,7852,7855,7858],{},[23,7847,7848],{},"Hosts your PHP app from GitHub",[23,7850,7851],{},"Watches a selected branch",[23,7853,7854],{},"Rebuilds when that branch changes",[23,7856,7857],{},"Stores secrets as environment variables",[23,7859,7860],{},"Gives each service a public URL",[104,7862,7863,7864],{},"Course loop: ",[33,7865,7866],{},"local work -> GitHub branch -> Render URL",[11,7868,7870,7872],{"id":7869,"level":14},"free-tier-and-before-start",[16,7871,1547],{"id":1544},[116,7873,7874,7903],{"gap":118,"left-width":717,"right-width":717},[123,7875,7876,7880],{"v-slot:left":125},[112,7877,7879],{"id":7878},"free-tier","Free Tier",[20,7881,7882,7892,7900],{},[23,7883,3339,7884,7887],{},[33,7885,7886],{},"Free",[20,7888,7889],{},[23,7890,7891],{},"Render may default to a paid plan",[23,7893,7894,7895],{},"Free services can sleep",[20,7896,7897],{},[23,7898,7899],{},"First visit after sleep may be slow",[23,7901,7902],{},"Avoid extra services unless instructed",[123,7904,7905,7909],{"v-slot:right":125},[112,7906,7908],{"id":7907},"repo-ready","Repo Ready",[20,7910,7911,7914,7919,7928],{},[23,7912,7913],{},"Starter files committed and pushed",[23,7915,7916,7918],{},[33,7917,6283],{}," in repo root",[23,7920,7921,36,7923,40,7925,7927],{},[33,7922,1728],{},[33,7924,6191],{},[33,7926,6194],{}," present",[23,7929,7930,750,7932,7934],{},[33,7931,7075],{},[33,7933,7078],{}," branches exist on GitHub",[11,7936,7938,7941],{"id":7937,"level":14},"target-architecture",[16,7939,7940],{"id":7937},"Target Architecture",[116,7942,7943,7971],{"gap":118,"left-width":717,"right-width":717},[123,7944,7945,7949],{"v-slot:left":125},[112,7946,7948],{"id":7947},"qa-service","QA Service",[20,7950,7951,7957,7962,7965],{},[23,7952,7953,7954],{},"Name: ",[33,7955,7956],{},"\u003Cucid>-it202-\u003Csection>-qa",[23,7958,7959,7960],{},"Watches ",[33,7961,7075],{},[23,7963,7964],{},"Used for testing and evidence",[23,7966,7967,7968],{},"URL ends with ",[33,7969,7970],{},"-qa.onrender.com",[123,7972,7973,7977],{"v-slot:right":125},[112,7974,7976],{"id":7975},"production-service","Production Service",[20,7978,7979,7984,7988,7991],{},[23,7980,7953,7981],{},[33,7982,7983],{},"\u003Cucid>-it202-\u003Csection>-prod",[23,7985,7959,7986],{},[33,7987,7078],{},[23,7989,7990],{},"Stable version after QA checks",[23,7992,7967,7993],{},[33,7994,7995],{},"-prod.onrender.com",[11,7997,7999,8003],{"id":7998,"level":14},"step-1-sign-up",[16,8000,8002],{"id":8001},"step-1-sign-up-with-github","Step 1: Sign Up With GitHub",[116,8004,8005,8023],{"gap":118,"left-width":632,"right-width":631},[123,8006,8007],{"v-slot:left":125},[20,8008,8009,8014,8017,8020],{},[23,8010,87,8011],{},[33,8012,8013],{},"render.com",[23,8015,8016],{},"Choose GitHub sign-in",[23,8018,8019],{},"Authorize Render when prompted",[23,8021,8022],{},"Land on the Render dashboard",[123,8024,8025],{"v-slot:right":125},[104,8026,8027],{},[129,8028],{"alt":8029,"src":8030,"variant":133},"Render GitHub sign-in screen","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-01-github-signin.png",[11,8032,8034,8037],{"id":8033,"level":14},"step-2-new-web-service",[16,8035,8036],{"id":8033},"Step 2: New Web Service",[116,8038,8039,8059],{"gap":118,"left-width":632,"right-width":631},[123,8040,8041],{"v-slot:left":125},[20,8042,8043,8048,8053,8056],{},[23,8044,1096,8045],{},[33,8046,8047],{},"New +",[23,8049,3339,8050],{},[33,8051,8052],{},"Web Service",[23,8054,8055],{},"Do not choose a database service here",[23,8057,8058],{},"This creates the hosted PHP app",[123,8060,8061],{"v-slot:right":125},[104,8062,8063],{},[129,8064],{"alt":8065,"src":8066,"variant":133},"Render New menu with Web Service option","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-04-new-menu.png",[11,8068,8070,8074],{"id":8069,"level":14},"step-3-connect-repo",[16,8071,8073],{"id":8072},"step-3-connect-repository","Step 3: Connect Repository",[116,8075,8076,8096],{"gap":118,"left-width":120,"right-width":673},[123,8077,8078],{"v-slot:left":125},[20,8079,8080,8083,8086,8093],{},[23,8081,8082],{},"Select your student course repository",[23,8084,8085],{},"Authorize repository access if Render asks",[23,8087,8088,8089,8092],{},"Ensure it's the proper repository (format: ",[33,8090,8091],{},"ucid-course-section-semYear",")",[23,8094,8095],{},"Continue to service settings",[123,8097,8098],{"v-slot:right":125},[104,8099,8100],{},[129,8101],{"alt":8102,"src":8103,"variant":133},"Render repository selection screen","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-07-select-repo.png",[11,8105,8107,8111],{"id":8106,"level":14},"step-4-configure-qa",[16,8108,8110],{"id":8109},"step-4-configure-qa-service","Step 4: Configure QA Service",[116,8112,8113,8146],{"gap":118,"left-width":632,"right-width":631},[123,8114,8115,8118],{"v-slot:left":125},[104,8116,8117],{},"Use these settings:",[20,8119,8120,8124,8129,8135,8140,8143],{},[23,8121,7953,8122],{},[33,8123,7956],{},[23,8125,8126,8127],{},"Branch: ",[33,8128,7075],{},[23,8130,8131,8132],{},"Runtime: ",[33,8133,8134],{},"Docker",[23,8136,8137,8138],{},"Instance type: ",[33,8139,7886],{},[23,8141,8142],{},"Root directory: blank",[23,8144,8145],{},"Build\u002Fstart commands: blank",[123,8147,8148],{"v-slot:right":125},[104,8149,8150],{},[129,8151],{"alt":8152,"src":8153,"variant":133},"Render QA service configuration","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-08-qa-config-basic.png",[11,8155,8157,8161],{"id":8156,"level":14},"step-5-env-vars",[16,8158,8160],{"id":8159},"step-5-add-environment-variables","Step 5: Add Environment Variables",[116,8162,8163,8192],{"gap":118,"left-width":3324,"right-width":5516},[123,8164,8165],{"v-slot:left":125},[20,8166,8167,8180,8186,8189],{},[23,8168,8169,8170,8172],{},"Add ",[33,8171,6634],{},[20,8173,8174],{},[23,8175,8176,8177],{},"Get it from ",[89,8178,6639],{"href":5484,"rel":8179},[93],[23,8181,8182,8183,8185],{},"Do not use \"add from ",[33,8184,6615],{},"\"",[23,8187,8188],{},"Add later API keys only when a later lesson requires them",[23,8190,8191],{},"Repeat required env vars on both QA and production",[123,8193,8194],{"v-slot:right":125},[104,8195,8196],{},[129,8197],{"alt":8198,"src":8199,"variant":133},"Render environment variables section","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-09-env-vars.png",[11,8201,8203,8206],{"id":8202,"level":14},"step-6-deploy-qa",[16,8204,8205],{"id":8202},"Step 6: Deploy QA",[116,8207,8208,8227],{"gap":118,"left-width":120,"right-width":673},[123,8209,8210],{"v-slot:left":125},[20,8211,8212,8215,8218,8221,8224],{},[23,8213,8214],{},"Create the QA service",[23,8216,8217],{},"Watch the first deploy log",[23,8219,8220],{},"Wait for a success state",[23,8222,8223],{},"Open the QA URL",[23,8225,8226],{},"Confirm the starter page loads",[123,8228,8229],{"v-slot:right":125},[104,8230,8231],{},[129,8232],{"alt":8233,"src":8234,"variant":133},"Successful Render QA deployment","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-10-qa-deployed.png",[11,8236,8238,8242],{"id":8237,"level":14},"step-7-create-prod",[16,8239,8241],{"id":8240},"step-7-create-production-service","Step 7: Create Production Service",[116,8243,8244,8273],{"gap":118,"left-width":632,"right-width":631},[123,8245,8246,8249],{"v-slot:left":125},[104,8247,8248],{},"Create a second web service:",[20,8250,8251,8254,8258,8262,8266,8270],{},[23,8252,8253],{},"Same repository",[23,8255,7953,8256],{},[33,8257,7983],{},[23,8259,8126,8260],{},[33,8261,7078],{},[23,8263,8131,8264],{},[33,8265,8134],{},[23,8267,8137,8268],{},[33,8269,7886],{},[23,8271,8272],{},"Same required env vars",[123,8274,8275],{"v-slot:right":125},[104,8276,8277],{},[129,8278],{"alt":8279,"src":8280,"variant":133},"Render production service configuration","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-11-prod-config.png",[11,8282,8283,8286],{"id":7501,"level":14},[16,8284,8285],{"id":7501},"Normal Workflow",[83,8287,8288,8291,8294,8299,8302,8305,8308,8315],{},[23,8289,8290],{},"Work locally on a feature or homework branch",[23,8292,8293],{},"Commit and push that branch to GitHub",[23,8295,8296,8297],{},"Open a pull request into ",[33,8298,7075],{},[23,8300,8301],{},"Merge after review",[23,8303,8304],{},"Render updates the QA URL",[23,8306,8307],{},"Test the QA URL",[23,8309,7568,8310,6828,8312,8314],{},[33,8311,7075],{},[33,8313,7078],{}," after evidence gathering",[23,8316,8317],{},"Render updates the production URL",[11,8319,8321,8324],{"id":8320,"level":14},"urls-and-cold-starts",[16,8322,8323],{"id":8320},"URLs And Cold Starts",[20,8325,8326,8329,8332,8335,8343],{},[23,8327,8328],{},"QA URL shows the test deployment",[23,8330,8331],{},"Production URL shows the stable deployment",[23,8333,8334],{},"Homework evidence usually starts with QA",[23,8336,8337,8338],{},"Free services may sleep after inactivity\n",[20,8339,8340],{},[23,8341,8342],{},"First visit after sleep may take extra time (2 - 5 minutes)",[23,8344,8345],{},"Do not submit before Render finishes deploying",[11,8347,8349,8352],{"id":8348,"level":14},"logs-and-status",[16,8350,8351],{"id":8348},"Logs And Status",[116,8353,8354,8370],{"gap":118,"left-width":120,"right-width":673},[123,8355,8356],{"v-slot:left":125},[20,8357,8358,8361,8364,8367],{},[23,8359,8360],{},"Logs show build and startup output",[23,8362,8363],{},"Dashboard status shows deploy progress",[23,8365,8366],{},"Failed deploys usually show the first useful clue",[23,8368,8369],{},"Read the first clear error before changing settings",[123,8371,8372],{"v-slot:right":125},[104,8373,8374],{},[129,8375],{"alt":8376,"src":8377,"variant":133},"Render deploy logs","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-12-logs.png",[11,8379,8381,8384],{"id":8380,"level":14},"troubleshooting",[16,8382,8383],{"id":8380},"Troubleshooting",[20,8385,8386,8396,8404,8414],{},[23,8387,8388,8389],{},"Build fails\n",[20,8390,8391],{},[23,8392,7540,8393,8395],{},[33,8394,6283],{},", root directory, runtime, and instance type",[23,8397,8398,8399],{},"App deploys but page fails\n",[20,8400,8401],{},[23,8402,8403],{},"Check logs for PHP errors",[23,8405,8406,8407],{},"Database connection fails\n",[20,8408,8409],{},[23,8410,7540,8411,8413],{},[33,8412,6634],{}," spelling and copied value",[23,8415,8416,8417],{},"Wrong version appears\n",[20,8418,8419,8422],{},[23,8420,8421],{},"Confirm the service watches the expected branch",[23,8423,8424],{},"Clear browser cache or test in a private window",[11,8426,8427,8429],{"id":711,"level":14},[16,8428,714],{"id":711},[20,8430,8431,8441,8444,8449,8452,8455],{},[23,8432,8433,8434,8436,8437,2100,8439],{},"Choosing ",[33,8435,210],{}," instead of ",[33,8438,7075],{},[33,8440,7078],{},[23,8442,8443],{},"Creating one service for both environments",[23,8445,8446,8447],{},"Forgetting ",[33,8448,6634],{},[23,8450,8451],{},"Using a paid instance type by accident",[23,8453,8454],{},"Checking GitHub but not the Render URL",[23,8456,8457],{},"Changing code locally but forgetting to push and merge",[11,8459,8460,8462],{"id":801,"level":14},[16,8461,802],{"id":801},[116,8463,8464,8492],{"gap":118,"left-width":717,"right-width":717},[123,8465,8466,8468,8474,8480,8486],{"v-slot:left":125},[112,8467,810],{"id":809},[104,8469,8470,8473],{},[814,8471,8472],{},"Service"," - one deployed app on Render",[104,8475,8476,8479],{},[814,8477,8478],{},"Watched branch"," - Git branch Render deploys from",[104,8481,8482,8485],{},[814,8483,8484],{},"Environment variable"," - setting stored outside code",[104,8487,8488,8491],{},[814,8489,8490],{},"Deploy log"," - output from Render's build\u002Fstart process",[123,8493,8494,8496],{"v-slot:right":125},[112,8495,834],{"id":798},[20,8497,8498,8505,8512,8519],{},[23,8499,8500],{},[89,8501,8504],{"href":8502,"rel":8503},"https:\u002F\u002Frender.com\u002Fdocs\u002Fweb-services",[93],"Render Docs: Web Services",[23,8506,8507],{},[89,8508,8511],{"href":8509,"rel":8510},"https:\u002F\u002Frender.com\u002Fdocs\u002Fdeploys",[93],"Render Docs: Deploys",[23,8513,8514],{},[89,8515,8518],{"href":8516,"rel":8517},"https:\u002F\u002Frender.com\u002Fdocs\u002Fconfigure-environment-variables",[93],"Render Docs: Environment Variables",[23,8520,8521],{},[89,8522,8525],{"href":8523,"rel":8524},"https:\u002F\u002Frender.com\u002Fdocs\u002Ffree",[93],"Render Docs: Free Instance Types",[11,8527,8528,8530,8533],{"id":865,"level":14},[16,8529,868],{"id":865},[104,8531,8532],{},"Before leaving this presentation, confirm you:",[20,8534,8535,8538,8541,8548,8551,8554],{},[23,8536,8537],{},"Created QA and production Render services",[23,8539,8540],{},"Matched each service to the correct branch",[23,8542,8543,8544,6635,8546],{},"Added ",[33,8545,6634],{},[33,8547,6639],{},[23,8549,8550],{},"Opened each deployed URL",[23,8552,8553],{},"Read logs instead of assuming it worked",[23,8555,8556,8557],{},"Understand the local -> GitHub -> Render loop\n",[20,8558,8559,8562,8567],{},[23,8560,8561],{},"Majority of your work will be done locally and tested locally",[23,8563,8564,8566],{},[33,8565,7075],{}," is just for gathering evidence for submissions",[23,8568,8569,8571],{},[33,8570,7078],{}," is what will be verified during grading",{"title":125,"searchDepth":895,"depth":895,"links":8573},[8574,8575,8576,8577,8578,8579,8580,8581,8582,8583,8584,8585,8586,8587,8588,8589,8590,8591,8592],{"id":7793,"depth":895,"text":7785},{"id":3171,"depth":895,"text":3174},{"id":7840,"depth":895,"text":7843},{"id":1544,"depth":895,"text":1547},{"id":7937,"depth":895,"text":7940},{"id":8001,"depth":895,"text":8002},{"id":8033,"depth":895,"text":8036},{"id":8072,"depth":895,"text":8073},{"id":8109,"depth":895,"text":8110},{"id":8159,"depth":895,"text":8160},{"id":8202,"depth":895,"text":8205},{"id":8240,"depth":895,"text":8241},{"id":7501,"depth":895,"text":8285},{"id":8320,"depth":895,"text":8323},{"id":8348,"depth":895,"text":8351},{"id":8380,"depth":895,"text":8383},{"id":711,"depth":895,"text":714},{"id":801,"depth":895,"text":802},{"id":865,"depth":895,"text":868},"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":7785,"description":8593},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F08-render-setup",[8601,8602,7075,7777],"render","deployment","21:42","esZd5RIpqCQ","https:\u002F\u002Fyoutu.be\u002FesZd5RIpqCQ","Render.com Setup (QA and Prod)","_1jV7vdhppggQ8TAOecx_1jFvjG90__8eGGlaXbnc28",{"id":8609,"title":8610,"audience":6,"body":8611,"contentType":926,"course":927,"description":11285,"estimateBasis":11286,"estimatedDiscussionMinutes":11287,"estimatedLiveMinutes":11288,"estimatedTotalMinutes":11289,"extension":933,"meta":11290,"module":935,"navigation":936,"order":5185,"path":11291,"promptAssist":939,"seo":11292,"status":941,"stem":11293,"tags":11294,"videoDuration":11299,"videoId":11300,"videoLink":11301,"videoTitle":11302,"week":935,"__hash__":11303},"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":8612,"toc":11217},[8613,8642,8687,8723,8792,8824,8851,8883,8909,8938,8967,8994,9025,9053,9089,9154,9189,9235,9278,9322,9369,9432,9468,9503,9540,9573,9610,9643,9673,9703,9733,9763,9793,9827,9859,9891,9923,9972,9974,10017,10043,10084,10136,10215,10266,10297,10327,10357,10407,10432,10482,10530,10588,10646,10687,10717,10751,10785,10819,10870,10922,10941,10969,11017,11089,11189],[11,8614,8616,8619],{"id":8615,"level":14},"virtualbox-title",[16,8617,8610],{"id":8618},"local-ubuntu-web-server-with-virtualbox",[20,8620,8621,8624,8627,8630,8633,8639],{},[23,8622,8623],{},"Primary course path for the local Ubuntu VM",[23,8625,8626],{},"Create an Ubuntu Server VM in VirtualBox",[23,8628,8629],{},"Connect from your host terminal with SSH",[23,8631,8632],{},"Share the course repo into Ubuntu",[23,8634,8635,8636,8638],{},"Serve ",[33,8637,1728],{}," through Apache and PHP",[23,8640,8641],{},"Create a local MySQL database for testing",[11,8643,8645,8648,8651,8662,8665],{"id":8644,"level":14},"main-goal",[16,8646,8647],{"id":8644},"Main Goal",[104,8649,8650],{},"Your host computer and Ubuntu VM have different jobs:",[20,8652,8653,8656,8659],{},[23,8654,8655],{},"Host computer: edit files with VS Code and open the browser",[23,8657,8658],{},"Ubuntu VM: run Apache, PHP, MySQL, and server commands",[23,8660,8661],{},"Shared folder: lets both use the same course repo files",[104,8663,8664],{},"Target result:",[20,8666,8667,8673,8678,8681,8684],{},[23,8668,8669,8670],{},"Host browser opens ",[33,8671,8672],{},"http:\u002F\u002Flocalhost:3000",[23,8674,8675,8676],{},"Apache serves the repo's ",[33,8677,1728],{},[23,8679,8680],{},"PHP executes inside Ubuntu",[23,8682,8683],{},"Local MySQL has a database and user named after your UCID",[23,8685,8686],{},"Edits made on the host appear after browser refresh",[11,8688,8690,8693,8696,8715,8718],{"id":8689,"level":14},"virtualbox-caveat",[16,8691,8692],{"id":8689},"VirtualBox Caveat",[104,8694,8695],{},"VirtualBox is the primary local VM path for this course:",[20,8697,8698,8701,8704,8712],{},[23,8699,8700],{},"Works well on modern Windows, Linux, and Intel Mac hosts",[23,8702,8703],{},"Apple Silicon Mac requires an ARM64 Ubuntu Server ISO",[23,8705,8706,8707],{},"Windows on Arm support is experimental in VirtualBox\n",[20,8708,8709],{},[23,8710,8711],{},"Avoid unless your instructor confirms it for your machine",[23,8713,8714],{},"Arm hosts cannot run x86\u002FAMD64 guest images",[104,8716,8717],{},"VMware is the fallback path if VirtualBox is not a good fit for your machine",[342,8719,8720],{"type":3861},[104,8721,8722],{},"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,8724,8725,8727],{"id":1544,"level":14},[16,8726,1547],{"id":1544},[20,8728,8729,8747,8765,8768,8771,8774,8789],{},[23,8730,8731,8732],{},"VirtualBox downloaded\n",[20,8733,8734,8741,8744],{},[23,8735,8736],{},[89,8737,8740],{"href":8738,"rel":8739},"https:\u002F\u002Fwww.virtualbox.org\u002Fwiki\u002FDownloads",[93],"VirtualBox downloads",[23,8742,8743],{},"Windows\u002FLinux\u002FIntel Mac: use the standard host installer",[23,8745,8746],{},"Apple Silicon Mac: use the macOS Arm64 host installer",[23,8748,8749,8750],{},"Ubuntu Server ISO downloaded\n",[20,8751,8752,8759,8762],{},[23,8753,8754],{},[89,8755,8758],{"href":8756,"rel":8757},"https:\u002F\u002Fubuntu.com\u002Fdownload\u002Fserver#how-to-install-tab-lts",[93],"Ubuntu Server installer",[23,8760,8761],{},"Apple Silicon Mac: use the ARM64 server ISO",[23,8763,8764],{},"Windows, Linux, and Intel Mac: use the AMD64 server ISO",[23,8766,8767],{},"Internet Applications course repo cloned on host computer",[23,8769,8770],{},"Git\u002FGitHub setup already working",[23,8772,8773],{},"Administrator access on your computer",[23,8775,8776,8777,8780,8781],{},"At least ",[33,8778,8779],{},"10 GB"," free disk space for the VM\n",[20,8782,8783],{},[23,8784,8785,8788],{},[33,8786,8787],{},"20-25 GB"," is safer if your computer has room",[23,8790,8791],{},"Stable internet for package installs",[11,8793,8795,8798],{"id":8794,"level":14},"setup-parts",[16,8796,8797],{"id":8794},"Setup Parts",[20,8799,8800,8803,8806,8809,8815,8818,8821],{},[23,8801,8802],{},"VM: Ubuntu Server running inside VirtualBox",[23,8804,8805],{},"NAT adapter: gives the VM internet access",[23,8807,8808],{},"Port forwarding: lets the host reach SSH and Apache",[23,8810,8811,8812],{},"SSH: lets the host terminal control Ubuntu through ",[33,8813,8814],{},"localhost",[23,8816,8817],{},"Shared folder: exposes the host repo inside Ubuntu",[23,8819,8820],{},"Apache\u002FPHP: serves and executes the web app",[23,8822,8823],{},"MySQL: local database server for local testing",[11,8825,8827,8831],{"id":8826,"level":14},"install-virtualbox-windows",[16,8828,8830],{"id":8829},"install-virtualbox-on-windows","Install VirtualBox On Windows",[20,8832,8833,8836,8839,8842,8845,8848],{},[23,8834,8835],{},"Download VirtualBox for Windows hosts",[23,8837,8838],{},"Run the installer as an administrator if prompted",[23,8840,8841],{},"Keep the default install path and features",[23,8843,8844],{},"Accept the network reset warning",[23,8846,8847],{},"Open VirtualBox after installation",[23,8849,8850],{},"See the slides below for the Windows installer screens",[11,8852,8854,8857],{"id":8853,"level":110},"windows-installer-start",[16,8855,8856],{"id":8853},"Windows Installer: Start",[116,8858,8859,8867],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,8860,8861],{"v-slot:left":125},[104,8862,8863],{},[129,8864],{"alt":8865,"src":8866,"variant":133},"VirtualBox Windows installer start screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step1.png",[123,8868,8869],{"v-slot:right":125},[20,8870,8871,8877,8880],{},[23,8872,8873,8874],{},"Launch the downloaded ",[33,8875,8876],{},".exe",[23,8878,8879],{},"Approve the Windows security prompt if shown",[23,8881,8882],{},"Start the setup wizard",[11,8884,8886,8889],{"id":8885,"level":110},"windows-installer-features",[16,8887,8888],{"id":8885},"Windows Installer: Features",[116,8890,8891,8899],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,8892,8893],{"v-slot:left":125},[104,8894,8895],{},[129,8896],{"alt":8897,"src":8898,"variant":133},"VirtualBox Windows installer feature selection screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step2.png",[123,8900,8901],{"v-slot:right":125},[20,8902,8903,8906],{},[23,8904,8905],{},"Keep the default install location",[23,8907,8908],{},"Keep the default features selected",[11,8910,8912,8915],{"id":8911,"level":110},"windows-installer-network-warning",[16,8913,8914],{"id":8911},"Windows Installer: Network Warning",[116,8916,8917,8925],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,8918,8919],{"v-slot:left":125},[104,8920,8921],{},[129,8922],{"alt":8923,"src":8924,"variant":133},"VirtualBox Windows installer network warning","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step3.png",[123,8926,8927],{"v-slot:right":125},[20,8928,8929,8932,8935],{},[23,8930,8931],{},"VirtualBox may reset network adapters briefly",[23,8933,8934],{},"This is expected during install",[23,8936,8937],{},"Save web work before continuing if needed",[11,8939,8941,8944],{"id":8940,"level":110},"windows-installer-ready",[16,8942,8943],{"id":8940},"Windows Installer: Ready",[116,8945,8946,8954],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,8947,8948],{"v-slot:left":125},[104,8949,8950],{},[129,8951],{"alt":8952,"src":8953,"variant":133},"VirtualBox Windows installer ready screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step4.png",[123,8955,8956],{"v-slot:right":125},[20,8957,8958,8961,8964],{},[23,8959,8960],{},"Start the installation",[23,8962,8963],{},"Keep the default choices",[23,8965,8966],{},"Wait for the installer to request permissions if needed",[11,8968,8970,8974],{"id":8969,"level":110},"windows-installer-progress",[16,8971,8973],{"id":8972},"windows-installer-start-options","Windows Installer: Start Options",[116,8975,8976,8984],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,8977,8978],{"v-slot:left":125},[104,8979,8980],{},[129,8981],{"alt":8982,"src":8983,"variant":133},"VirtualBox Windows installer progress screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step5.png",[123,8985,8986],{"v-slot:right":125},[20,8987,8988,8991],{},[23,8989,8990],{},"No need to create a Start Menu item or desktop shortcut unless desired",[23,8992,8993],{},"Third option is likely optional too since we'll be using the VirtualBox Manager",[11,8995,8997,9000],{"id":8996,"level":110},"windows-installer-permission",[16,8998,8999],{"id":8996},"Windows Installer: Permission",[116,9001,9002,9010],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,9003,9004],{"v-slot:left":125},[104,9005,9006],{},[129,9007],{"alt":9008,"src":9009,"variant":133},"VirtualBox Windows installer permission prompt","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step6.png",[123,9011,9012],{"v-slot:right":125},[20,9013,9014,9017],{},[23,9015,9016],{},"Proceed with install",[23,9018,9019,9020],{},"Approve VirtualBox driver prompts\n",[20,9021,9022],{},[23,9023,9024],{},"These let VirtualBox create virtual hardware",[11,9026,9028,9031],{"id":9027,"level":110},"windows-installer-complete",[16,9029,9030],{"id":9027},"Windows Installer: Complete",[116,9032,9033,9041],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,9034,9035],{"v-slot:left":125},[104,9036,9037],{},[129,9038],{"alt":9039,"src":9040,"variant":133},"VirtualBox Windows installer completion screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step7.png",[123,9042,9043],{"v-slot:right":125},[20,9044,9045,9047,9050],{},[23,9046,490],{},[23,9048,9049],{},"Open VirtualBox",[23,9051,9052],{},"Continue to VM creation",[11,9054,9056,9060],{"id":9055,"level":14},"install-virtualbox-macos",[16,9057,9059],{"id":9058},"install-virtualbox-on-macos","Install VirtualBox On macOS",[116,9061,9062,9081],{"gap":118,"left-width":3324,"right-width":5516,"stack":121},[123,9063,9064],{"v-slot:left":125},[20,9065,9066,9069,9072,9075,9078],{},[23,9067,9068],{},"Install the VirtualBox host package for your Mac CPU type",[23,9070,9071],{},"Intel Mac: standard macOS host installer",[23,9073,9074],{},"Apple Silicon Mac: Arm64 host installer and Arm64 Ubuntu Server ISO",[23,9076,9077],{},"Approve macOS security prompts if needed",[23,9079,9080],{},"If VirtualBox is not a good fit, use the VMware fallback lesson",[123,9082,9083],{"v-slot:right":125},[104,9084,9085],{},[129,9086],{"alt":9087,"src":9088,"variant":133},"Summary of macOS VirtualBox setup notes","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvm_summary_mac.png",[11,9090,9092,9096,9099],{"id":9091,"level":14},"step-1-create-vm",[16,9093,9095],{"id":9094},"step-1-create-the-vm","Step 1: Create The VM",[104,9097,9098],{},"Create a lightweight Ubuntu Server VM:",[20,9100,9101,9104,9112,9127,9139,9145,9148,9151],{},[23,9102,9103],{},"Type: Linux",[23,9105,9106,9107],{},"Version: Ubuntu 64-bit or Ubuntu Arm64\n",[20,9108,9109],{},[23,9110,9111],{},"Match the version to the ISO you downloaded",[23,9113,9114,9115,9118,9119],{},"Memory: ",[33,9116,9117],{},"1 GB"," course target\n",[20,9120,9121],{},[23,9122,747,9123,9126],{},[33,9124,9125],{},"1.5-2 GB"," if the installer is too slow or refuses to continue (you shouldn't need to do this)",[23,9128,9129,9130,9132,9133],{},"Disk: ",[33,9131,8779],{}," course minimum\n",[20,9134,9135],{},[23,9136,9137,8788],{},[33,9138,8787],{},[23,9140,9141,9142,9144],{},"CPU: ",[33,9143,935],{}," core is enough for this course VM",[23,9146,9147],{},"Enable OpenSSH during install if prompted",[23,9149,9150],{},"Username: use your UCID",[23,9152,9153],{},"See the slides below for VM settings and Ubuntu install screens",[11,9155,9157,9160],{"id":9156,"level":110},"vm-setup-name-and-iso",[16,9158,9159],{"id":9156},"VM Setup: Name And ISO",[116,9161,9162,9170],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,9163,9164],{"v-slot:left":125},[104,9165,9166],{},[129,9167],{"alt":9168,"src":9169,"variant":133},"VirtualBox VM name and ISO setup","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_1.png",[123,9171,9172],{"v-slot:right":125},[20,9173,9174,9177,9183,9186],{},[23,9175,9176],{},"Start a new virtual machine",[23,9178,9179,9180],{},"Name it clearly, such as ",[33,9181,9182],{},"it202-vm",[23,9184,9185],{},"Choose the Ubuntu Server ISO file next",[23,9187,9188],{},"OS fields may look wrong until the ISO is selected",[11,9190,9192,9195],{"id":9191,"level":110},"vm-setup-confirm-ubuntu-iso",[16,9193,9194],{"id":9191},"VM Setup: Confirm Ubuntu ISO",[116,9196,9197,9205],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,9198,9199],{"v-slot:left":125},[104,9200,9201],{},[129,9202],{"alt":9203,"src":9204,"variant":133},"VirtualBox VM name and Ubuntu ISO selected","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_2.png",[123,9206,9207],{"v-slot:right":125},[20,9208,9209,9215,9221,9224],{},[23,9210,9211,9212],{},"Confirm OS is ",[33,9213,9214],{},"Linux",[23,9216,9217,9218],{},"Confirm distribution is ",[33,9219,9220],{},"Ubuntu",[23,9222,9223],{},"Confirm version matches your ISO",[23,9225,143,9226,9229,9230],{},[33,9227,9228],{},"Unattended Installation"," off\n",[20,9231,9232],{},[23,9233,9234],{},"The Ubuntu installer screens are easier to teach manually",[11,9236,9238,9241],{"id":9237,"level":110},"vm-setup-memory-and-cpu",[16,9239,9240],{"id":9237},"VM Setup: Memory And CPU",[116,9242,9243,9251],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,9244,9245],{"v-slot:left":125},[104,9246,9247],{},[129,9248],{"alt":9249,"src":9250,"variant":133},"VirtualBox VM memory and CPU settings","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_4.png",[123,9252,9253],{"v-slot:right":125},[20,9254,9255,9268,9272,9275],{},[23,9256,9114,9257,9118,9260],{},[33,9258,9259],{},"1024 MB",[20,9261,9262,9265],{},[23,9263,9264],{},"The goal is to match free-tier cloud services",[23,9266,9267],{},"Demonstrates that small apps can run with limited resources",[23,9269,9141,9270],{},[33,9271,935],{},[23,9273,9274],{},"Keep EFI off unless your machine requires it",[23,9276,9277],{},"This VM is for Apache, PHP, MySQL, and local development\u002Ftesting",[11,9279,9281,9284],{"id":9280,"level":110},"vm-setup-virtual-disk",[16,9282,9283],{"id":9280},"VM Setup: Virtual Disk",[116,9285,9286,9294],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,9287,9288],{"v-slot:left":125},[104,9289,9290],{},[129,9291],{"alt":9292,"src":9293,"variant":133},"VirtualBox virtual hard disk settings","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_5.png",[123,9295,9296],{"v-slot:right":125},[20,9297,9298,9304,9307,9319],{},[23,9299,9300,9301],{},"Disk type: ",[33,9302,9303],{},"VDI",[23,9305,9306],{},"Storage: dynamically allocated",[23,9308,9309,9310,9312],{},"Minimum: ",[33,9311,8779],{},[20,9313,9314],{},[23,9315,9316,9318],{},[33,9317,8787],{}," is safer if you have room",[23,9320,9321],{},"Dynamic disk uses space as needed, not all at once",[11,9323,9325,9328],{"id":9324,"level":110},"vm-setup-start-with-gui",[16,9326,9327],{"id":9324},"VM Setup: Start With GUI",[116,9329,9330,9338],{"gap":118,"left-width":119,"right-width":120,"stack":121},[123,9331,9332],{"v-slot:left":125},[104,9333,9334],{},[129,9335],{"alt":9336,"src":9337,"variant":133},"VirtualBox VM selected with the Start button visible","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_6.png",[123,9339,9340],{"v-slot:right":125},[20,9341,9342,9345,9355,9358],{},[23,9343,9344],{},"Select the newly created VM",[23,9346,1096,9347,9350],{},[33,9348,9349],{},"Start",[20,9351,9352],{},[23,9353,9354],{},"Choose the normal GUI start for the first boot",[23,9356,9357],{},"Complete the Ubuntu installer in the VM window",[23,9359,9360,9361],{},"After install and SSH setup, future starts can be headless\n",[20,9362,9363],{},[23,9364,9365,9366,9368],{},"You will connect with ",[33,9367,4253],{}," when you need the VM",[11,9370,9372,9376,9379],{"id":9371,"level":14},"ubuntu-installer",[16,9373,9375],{"id":9374},"step-2-ubuntu-installer","Step 2: Ubuntu Installer",[104,9377,9378],{},"Use the Ubuntu Server installer after the VM starts:",[20,9380,9381,9384,9387,9390,9393,9396,9429],{},[23,9382,9383],{},"Choose the default course options unless noted",[23,9385,9386],{},"Continue without updating the installer if instructed",[23,9388,9389],{},"Use your UCID for the Ubuntu username",[23,9391,9392],{},"Install OpenSSH server during setup",[23,9394,9395],{},"Skip optional server snaps",[23,9397,9398,9399],{},"Keyboard navigation:\n",[20,9400,9401,9408,9418,9424],{},[23,9402,9403,9407],{},[9404,9405,9406],"kbd",{},"Tab"," moves between fields and buttons",[23,9409,9410,9413,9414,9417],{},[9404,9411,9412],{},"Up"," \u002F ",[9404,9415,9416],{},"Down"," moves through lists",[23,9419,9420,9423],{},[9404,9421,9422],{},"Space"," toggles checkboxes",[23,9425,9426,9428],{},[9404,9427,2133],{}," confirms the selected option",[23,9430,9431],{},"See the slides below for the installer screens",[11,9433,9435,9439],{"id":9434,"level":110},"ubuntu-installer-boot-menu",[16,9436,9438],{"id":9437},"step-21-boot-menu","Step 2.1: Boot Menu",[116,9440,9443,9452],{"gap":933,"left-width":9441,"right-width":9442,"stack":121},"1.75fr","0.65fr",[123,9444,9445],{"v-slot:left":125},[104,9446,9447],{},[129,9448],{"alt":9449,"src":9450,"variant":9451},"Ubuntu Server boot menu in VirtualBox","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_1.png","slide-screenshot",[123,9453,9454],{"v-slot:right":125},[20,9455,9456,9461,9465],{},[23,9457,3339,9458],{},[33,9459,9460],{},"Try or Install Ubuntu Server",[23,9462,2165,9463],{},[9404,9464,2133],{},[23,9466,9467],{},"This starts the Ubuntu Server installer",[11,9469,9471,9475],{"id":9470,"level":110},"ubuntu-installer-language",[16,9472,9474],{"id":9473},"step-22-language","Step 2.2: Language",[116,9476,9477,9485],{"gap":933,"left-width":9441,"right-width":9442,"stack":121},[123,9478,9479],{"v-slot:left":125},[104,9480,9481],{},[129,9482],{"alt":9483,"src":9484,"variant":9451},"Ubuntu Server installer language screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_2.0.png",[123,9486,9487],{"v-slot:right":125},[20,9488,9489,9492,9498],{},[23,9490,9491],{},"Choose your preferred language",[23,9493,9494,9497],{},[33,9495,9496],{},"English"," is the expected course screenshot path",[23,9499,2165,9500,9502],{},[9404,9501,2133],{}," to continue",[11,9504,9506,9510],{"id":9505,"level":110},"ubuntu-installer-update",[16,9507,9509],{"id":9508},"step-23-update-prompt","Step 2.3: Update Prompt",[116,9511,9512,9520],{"gap":933,"left-width":9441,"right-width":9442,"stack":121},[123,9513,9514],{"v-slot:left":125},[104,9515,9516],{},[129,9517],{"alt":9518,"src":9519,"variant":9451},"Ubuntu Server installer update prompt","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_2.5.png",[123,9521,9522],{"v-slot:right":125},[20,9523,9524,9534,9537],{},[23,9525,3339,9526,9529],{},[33,9527,9528],{},"Continue without updating",[20,9530,9531],{},[23,9532,9533],{},"If I forget to update the image, it's the second option",[23,9535,9536],{},"Keeps the install path consistent",[23,9538,9539],{},"Package updates happen after Ubuntu is installed",[11,9541,9543,9547],{"id":9542,"level":110},"ubuntu-installer-keyboard",[16,9544,9546],{"id":9545},"step-24-keyboard","Step 2.4: Keyboard",[116,9548,9549,9557],{"gap":933,"left-width":9441,"right-width":9442,"stack":121},[123,9550,9551],{"v-slot:left":125},[104,9552,9553],{},[129,9554],{"alt":9555,"src":9556,"variant":9451},"Ubuntu Server installer keyboard screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_3.png",[123,9558,9559],{"v-slot:right":125},[20,9560,9561,9564,9570],{},[23,9562,9563],{},"Keep the detected keyboard layout if it matches",[23,9565,9566,9567],{},"Common setting: ",[33,9568,9569],{},"English (US)",[23,9571,9572],{},"Use Identify keyboard only if typing is wrong",[11,9574,9576,9580],{"id":9575,"level":110},"ubuntu-installer-install-type",[16,9577,9579],{"id":9578},"step-25-install-type","Step 2.5: Install Type",[116,9581,9582,9590],{"gap":933,"left-width":9441,"right-width":9442,"stack":121},[123,9583,9584],{"v-slot:left":125},[104,9585,9586],{},[129,9587],{"alt":9588,"src":9589,"variant":9451},"Ubuntu Server installer installation type screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_4.png",[123,9591,9592],{"v-slot:right":125},[20,9593,9594,9604,9607],{},[23,9595,9596,9597,9600,9601],{},"Select ",[33,9598,9599],{},"Ubuntu Server (minimized)","; don't choose full ",[33,9602,9603],{},"Ubuntu Server",[23,9605,9606],{},"Keep third-party drivers unchecked",[23,9608,9609],{},"Minimized keeps the VM lighter and aids future lessons",[11,9611,9613,9617],{"id":9612,"level":110},"ubuntu-installer-network",[16,9614,9616],{"id":9615},"step-26-network","Step 2.6: Network",[116,9618,9619,9627],{"gap":933,"left-width":9441,"right-width":9442,"stack":121},[123,9620,9621],{"v-slot:left":125},[104,9622,9623],{},[129,9624],{"alt":9625,"src":9626,"variant":9451},"Ubuntu Server installer network configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_5.png",[123,9628,9629],{"v-slot:right":125},[20,9630,9631,9634,9640],{},[23,9632,9633],{},"DHCP address is expected",[23,9635,9636,9639],{},[33,9637,9638],{},"10.0.2.15"," is normal for VirtualBox NAT",[23,9641,9642],{},"Leave the network settings alone",[11,9644,9646,9650],{"id":9645,"level":110},"ubuntu-installer-proxy",[16,9647,9649],{"id":9648},"step-27-proxy","Step 2.7: Proxy",[116,9651,9652,9660],{"gap":933,"left-width":9441,"right-width":9442,"stack":121},[123,9653,9654],{"v-slot:left":125},[104,9655,9656],{},[129,9657],{"alt":9658,"src":9659,"variant":9451},"Ubuntu Server installer proxy screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_6.png",[123,9661,9662],{"v-slot:right":125},[20,9663,9664,9667,9670],{},[23,9665,9666],{},"Leave proxy blank",[23,9668,9669],{},"Only fill this in if your network requires a proxy",[23,9671,9672],{},"Most student home networks do not need one",[11,9674,9676,9680],{"id":9675,"level":110},"ubuntu-installer-mirror",[16,9677,9679],{"id":9678},"step-28-mirror","Step 2.8: Mirror",[116,9681,9682,9690],{"gap":933,"left-width":9441,"right-width":9442,"stack":121},[123,9683,9684],{"v-slot:left":125},[104,9685,9686],{},[129,9687],{"alt":9688,"src":9689,"variant":9451},"Ubuntu Server installer archive mirror screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_7.png",[123,9691,9692],{"v-slot:right":125},[20,9693,9694,9697,9700],{},[23,9695,9696],{},"Keep the default Ubuntu archive mirror",[23,9698,9699],{},"Wait for the mirror check to finish",[23,9701,9702],{},"Continue when the installer allows it",[11,9704,9706,9710],{"id":9705,"level":110},"ubuntu-installer-storage-guided",[16,9707,9709],{"id":9708},"step-29-guided-storage","Step 2.9: Guided Storage",[116,9711,9712,9720],{"gap":933,"left-width":9441,"right-width":9442,"stack":121},[123,9713,9714],{"v-slot:left":125},[104,9715,9716],{},[129,9717],{"alt":9718,"src":9719,"variant":9451},"Ubuntu Server installer guided storage screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_8.png",[123,9721,9722],{"v-slot:right":125},[20,9723,9724,9727,9730],{},[23,9725,9726],{},"Use the entire virtual disk",[23,9728,9729],{},"LVM is optional, not needed for this course VM",[23,9731,9732],{},"Leave encryption off",[11,9734,9736,9740],{"id":9735,"level":110},"ubuntu-installer-storage-summary",[16,9737,9739],{"id":9738},"step-210-storage-summary","Step 2.10: Storage Summary",[116,9741,9742,9750],{"gap":933,"left-width":9441,"right-width":9442,"stack":121},[123,9743,9744],{"v-slot:left":125},[104,9745,9746],{},[129,9747],{"alt":9748,"src":9749,"variant":9451},"Ubuntu Server installer storage summary screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_9.png",[123,9751,9752],{"v-slot:right":125},[20,9753,9754,9757,9760],{},[23,9755,9756],{},"Confirm the virtual disk is selected",[23,9758,9759],{},"This only affects the VM disk file",[23,9761,9762],{},"Continue when the layout looks correct",[11,9764,9766,9770],{"id":9765,"level":110},"ubuntu-installer-confirm-storage",[16,9767,9769],{"id":9768},"step-211-confirm-storage","Step 2.11: Confirm Storage",[116,9771,9772,9780],{"gap":933,"left-width":9441,"right-width":9442,"stack":121},[123,9773,9774],{"v-slot:left":125},[104,9775,9776],{},[129,9777],{"alt":9778,"src":9779,"variant":9451},"Ubuntu Server installer destructive action confirmation","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_10.png",[123,9781,9782],{"v-slot:right":125},[20,9783,9784,9787,9790],{},[23,9785,9786],{},"Confirm the virtual disk format",[23,9788,9789],{},"This does not erase your host computer files",[23,9791,9792],{},"It formats the VM's virtual disk",[11,9794,9796,9800],{"id":9795,"level":110},"ubuntu-installer-profile",[16,9797,9799],{"id":9798},"step-212-profile","Step 2.12: Profile",[116,9801,9802,9810],{"gap":933,"left-width":9441,"right-width":9442,"stack":121},[123,9803,9804],{"v-slot:left":125},[104,9805,9806],{},[129,9807],{"alt":9808,"src":9809,"variant":9451},"Ubuntu Server installer profile configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_11.png",[123,9811,9812],{"v-slot:right":125},[20,9813,9814,9817,9822,9824],{},[23,9815,9816],{},"Your name: your UCID or name is fine",[23,9818,9819,9820],{},"Server name: ",[33,9821,9182],{},[23,9823,5470],{},[23,9825,9826],{},"Choose a password you can type reliably (it can be simple since it's only for local work)",[11,9828,9830,9834],{"id":9829,"level":110},"ubuntu-installer-pro",[16,9831,9833],{"id":9832},"step-213-ubuntu-pro","Step 2.13: Ubuntu Pro",[116,9835,9836,9844],{"gap":933,"left-width":9441,"right-width":9442,"stack":121},[123,9837,9838],{"v-slot:left":125},[104,9839,9840],{},[129,9841],{"alt":9842,"src":9843,"variant":9451},"Ubuntu Server installer Ubuntu Pro screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_12.png",[123,9845,9846],{"v-slot:right":125},[20,9847,9848,9853,9856],{},[23,9849,3339,9850],{},[33,9851,9852],{},"Skip for now",[23,9854,9855],{},"Ubuntu Pro is not needed for the course VM",[23,9857,9858],{},"You can continue without an Ubuntu account",[11,9860,9862,9866],{"id":9861,"level":110},"ubuntu-installer-ssh",[16,9863,9865],{"id":9864},"step-214-ssh","Step 2.14: SSH",[116,9867,9868,9876],{"gap":933,"left-width":9441,"right-width":9442,"stack":121},[123,9869,9870],{"v-slot:left":125},[104,9871,9872],{},[129,9873],{"alt":9874,"src":9875,"variant":9451},"Ubuntu Server installer SSH configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_13.png",[123,9877,9878],{"v-slot:right":125},[20,9879,9880,9885,9888],{},[23,9881,7540,9882],{},[33,9883,9884],{},"Install OpenSSH server",[23,9886,9887],{},"Password authentication is fine for this local VM",[23,9889,9890],{},"No need to import SSH keys for this course setup",[11,9892,9894,9898],{"id":9893,"level":110},"ubuntu-installer-snaps",[16,9895,9897],{"id":9896},"step-215-featured-snaps","Step 2.15: Featured Snaps",[116,9899,9900,9908],{"gap":933,"left-width":9441,"right-width":9442,"stack":121},[123,9901,9902],{"v-slot:left":125},[104,9903,9904],{},[129,9905],{"alt":9906,"src":9907,"variant":9451},"Ubuntu Server installer featured server snaps screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_14.png",[123,9909,9910],{"v-slot:right":125},[20,9911,9912,9915,9920],{},[23,9913,9914],{},"Leave all featured snaps unchecked",[23,9916,9917,9918],{},"Apache, PHP, and MySQL are installed later with ",[33,9919,6750],{},[23,9921,9922],{},"Continue without selecting extra packages",[11,9924,9926,9930],{"id":9925,"level":110},"ubuntu-installer-installing",[16,9927,9929],{"id":9928},"step-216-installing","Step 2.16: Installing",[116,9931,9932,9940],{"gap":933,"left-width":9441,"right-width":9442,"stack":121},[123,9933,9934],{"v-slot:left":125},[104,9935,9936],{},[129,9937],{"alt":9938,"src":9939,"variant":9451},"Ubuntu Server installer installing system screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_15.png",[123,9941,9942,9967],{"v-slot:right":125},[20,9943,9944,9947,9950,9958,9964],{},[23,9945,9946],{},"Installation can take a while",[23,9948,9949],{},"High CPU during install is normal",[23,9951,9952,9953,9955,9956],{},"If install struggles at ",[33,9954,9117],{},", recreate the VM with ",[33,9957,9125],{},[23,9959,9960,9961,9963],{},"Keep the course target at ",[33,9962,9117],{}," after setup if possible",[23,9965,9966],{},"Reboot once complete",[342,9968,9969],{"type":3861},[104,9970,9971],{},"These target resources stay close to common cloud free-tier VMs",[104,9973,350],{},[11,9975,9977,9981,9984],{"id":9976,"level":14},"step-2-networking",[16,9978,9980],{"id":9979},"virtualbox-configure-networking","VirtualBox: Configure Networking",[104,9982,9983],{},"Use one NAT adapter with port forwarding:",[20,9985,9986,9992,10001,10009,10014],{},[23,9987,9988,9989],{},"VM internet: ",[33,9990,9991],{},"NAT",[23,9993,9994,9995,9998,9999],{},"Host SSH: host ",[33,9996,9997],{},"22"," -> guest ",[33,10000,9997],{},[23,10002,10003,10004,9998,10007],{},"Host browser: host ",[33,10005,10006],{},"3000",[33,10008,8596],{},[23,10010,747,10011,10013],{},[33,10012,8814],{}," from the host computer",[23,10015,10016],{},"See the slides below for adapter and port-forwarding screens",[11,10018,10020,10024,10037],{"id":10019,"level":110},"adapter-settings-screen",[16,10021,10023],{"id":10022},"adapter-settings","Adapter Settings",[20,10025,10026,10029,10034],{},[23,10027,10028],{},"Adapter 1 enabled",[23,10030,10031,10032],{},"Attached to ",[33,10033,9991],{},[23,10035,10036],{},"No second adapter needed for the baseline path",[104,10038,10039],{},[129,10040],{"alt":10041,"src":10042,"variant":9451},"VirtualBox Adapter 1 configured as NAT","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_adapter_1.png",[11,10044,10046,10050,10078],{"id":10045,"level":110},"port-forwarding-screen",[16,10047,10049],{"id":10048},"port-forwarding","Port Forwarding",[20,10051,10052,10060,10067],{},[23,10053,10054,10055,10057,10058],{},"SSH: host ",[33,10056,9997],{}," to guest ",[33,10059,9997],{},[23,10061,10062,10063,10057,10065],{},"Apache HTTP: host ",[33,10064,10006],{},[33,10066,8596],{},[23,10068,10069,10070,10072,10073,10057,10076],{},"If host ",[33,10071,9997],{}," is already busy, use host ",[33,10074,10075],{},"2222",[33,10077,9997],{},[104,10079,10080],{},[129,10081],{"alt":10082,"src":10083,"variant":9451},"VirtualBox NAT port forwarding rules","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_adapter_1_ports.png",[11,10085,10087,10091,10094,10097,10100,10103],{"id":10086,"level":14},"step-3-connect-ssh",[16,10088,10090],{"id":10089},"step-3-connect-with-ssh","Step 3: Connect With SSH",[104,10092,10093],{},"Run from your host terminal:",[595,10095],{"language":597,"src":10096},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-3-connect-with-ssh-01.sh",[104,10098,10099],{},"First connection prompt:",[595,10101],{"language":4324,"src":10102},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-3-connect-with-ssh-02.txt",[20,10104,10105,10112,10121,10124,10127],{},[23,10106,10107,10108,10111],{},"Replace ",[33,10109,10110],{},"your_ucid"," with your UCID",[23,10113,10114,10115,10117,10118,10120],{},"Type ",[33,10116,3788],{}," once for this course VM on ",[33,10119,8814],{}," (if prompted like the example above)",[23,10122,10123],{},"Enter your Ubuntu password",[23,10125,10126],{},"After login, commands run inside Ubuntu",[23,10128,10129,2100,10132,10135],{},[33,10130,10131],{},"exit",[33,10133,10134],{},"logout"," disconnects from the VM",[11,10137,10139,10143,10146],{"id":10138,"level":14},"step-4-confirm-network",[16,10140,10142],{"id":10141},"step-4-confirm-vm-network","Step 4: Confirm VM Network",[104,10144,10145],{},"Run inside Ubuntu through SSH:",[116,10147,10148,10190],{"gap":118,"left-width":673,"right-width":717,"stack":121},[123,10149,10150,10153,10156],{"v-slot:left":125},[104,10151,10152],{},"Network check:",[595,10154],{"language":597,"src":10155},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-4-confirm-vm-networ-03.sh",[20,10157,10158,10164,10170,10176,10182],{},[23,10159,10160,10163],{},[33,10161,10162],{},"ping",": confirms basic network access",[23,10165,10166,10169],{},[33,10167,10168],{},"-c 4",": stop after four replies",[23,10171,10172,10175],{},[33,10173,10174],{},"apt update",": refreshes package indexes",[23,10177,10178,10181],{},[33,10179,10180],{},"apt upgrade",": applies available package updates",[23,10183,587,10184,10186,10187],{},[33,10185,10162],{}," is not found, run ",[33,10188,10189],{},"sudo apt install iputils-ping",[123,10191,10192,10195,10198],{"v-slot:right":125},[104,10193,10194],{},"Port-forwarding check:",[595,10196],{"language":597,"src":10197},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fslide-id-summary-level-2-04.sh",[20,10199,10200,10205,10208,10212],{},[23,10201,10202,10203],{},"The VM may show ",[33,10204,9638],{},[23,10206,10207],{},"That is normal for VirtualBox NAT",[23,10209,747,10210,10013],{},[33,10211,8814],{},[23,10213,10214],{},"Port forwarding routes host traffic into the VM",[11,10216,10218,10222],{"id":10217,"level":14},"step-5-shared-folder",[16,10219,10221],{"id":10220},"step-5-enable-shared-folder","Step 5: Enable Shared Folder",[116,10223,10224,10258],{"gap":118,"left-width":120,"right-width":673,"stack":121},[123,10225,10226,10229],{"v-slot:left":125},[104,10227,10228],{},"In VirtualBox:",[20,10230,10231,10234,10237,10240,10243,10246,10249,10252,10255],{},[23,10232,10233],{},"Open VM settings",[23,10235,10236],{},"Choose Shared Folders",[23,10238,10239],{},"Folder Path: your cloned course repository folder",[23,10241,10242],{},"Folder Name: a simple repo name with no spaces",[23,10244,10245],{},"Mount Point: leave blank",[23,10247,10248],{},"Read-only: off",[23,10250,10251],{},"Auto-mount: on",[23,10253,10254],{},"Make Machine-permanent: on",[23,10256,10257],{},"Make Global: off",[123,10259,10260],{"v-slot:right":125},[104,10261,10262],{},[129,10263],{"alt":10264,"src":10265,"variant":133},"VirtualBox shared folder settings with the course repo selected","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_shared_folder.png",[11,10267,10269,10273,10276,10279],{"id":10268,"level":14},"step-6-guest-additions",[16,10270,10272],{"id":10271},"step-6-install-shared-folder-support","Step 6: Install Shared Folder Support",[104,10274,10275],{},"Run inside Ubuntu:",[595,10277],{"language":597,"src":10278},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-6-install-shared-fo-05.sh",[20,10280,10281,10288,10294],{},[23,10282,784,10283,750,10285,10287],{},[33,10284,10174],{},[33,10286,10180],{}," first only if you skipped the Step 4 updates",[23,10289,10290,10293],{},[33,10291,10292],{},"virtualbox-guest-utils",": VirtualBox shared-folder support",[23,10295,10296],{},"Reboot after the group step on the next slide",[11,10298,10300,10304,10307,10310],{"id":10299,"level":110},"step-6b-confirm-vboxsf",[16,10301,10303],{"id":10302},"step-61-check-the-shared-folder","Step 6.1: Check The Shared Folder",[104,10305,10306],{},"Reconnect with SSH, then run inside Ubuntu:",[595,10308],{"language":597,"src":10309},"\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",[20,10311,10312,10318,10324],{},[23,10313,10314,10317],{},[33,10315,10316],{},"ls \u002Fmedia",": shows available mounted folders",[23,10319,10320,10323],{},[33,10321,10322],{},"ls \u002Fmedia\u002F\u003Cshared-folder>",": checks your course repo share",[23,10325,10326],{},"Permission denied is common the first time",[11,10328,10330,10334,10337,10340],{"id":10329,"level":14},"step-7-locate-share",[16,10331,10333],{"id":10332},"step-7-allow-shared-folder-access","Step 7: Allow Shared Folder Access",[104,10335,10336],{},"If the shared folder exists but says permission denied:",[595,10338],{"language":597,"src":10339},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-7-allow-shared-fold-07.sh",[20,10341,10342,10348,10354],{},[23,10343,10344,10347],{},[33,10345,10346],{},"vboxsf",": group allowed to read VirtualBox shared folders",[23,10349,10350,10353],{},[33,10351,10352],{},"$USER",": your Ubuntu login user for terminal access",[23,10355,10356],{},"Reboot applies the shared-folder support and new group membership",[11,10358,10360,10364,10366,10369,10386,10389],{"id":10359,"level":110},"step-7b-locate-share",[16,10361,10363],{"id":10362},"step-71-locate-the-shared-repo","Step 7.1: Locate The Shared Repo",[104,10365,10306],{},[595,10367],{"language":597,"src":10368},"\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",[20,10370,10371,10377,10383],{},[23,10372,10373,10376],{},[33,10374,10375],{},"\u002Fmedia",": VirtualBox auto-mounted shared folders",[23,10378,10379,10382],{},[33,10380,10381],{},"\u003Cshared-folder>",": your shared course repo folder name",[23,10384,10385],{},"Use the folder that points to your repository",[104,10387,10388],{},"Expected repo folders:",[20,10390,10391,10395,10399,10403],{},[23,10392,10393],{},[33,10394,1728],{},[23,10396,10397],{},[33,10398,6191],{},[23,10400,10401],{},[33,10402,6194],{},[23,10404,10405],{},[33,10406,6197],{},[11,10408,10410,10414,10429],{"id":10409,"level":110},"step-7-2-shared-folder-check",[16,10411,10413],{"id":10412},"step-72-shared-folder-check","Step 7.2: Shared Folder Check",[20,10415,10416,10419,10426],{},[23,10417,10418],{},"Edit a small file from VS Code on host",[23,10420,784,10421,2100,10423,10425],{},[33,10422,1717],{},[33,10424,1934],{}," inside Ubuntu",[23,10427,10428],{},"Confirm Ubuntu sees the same file content",[104,10430,10431],{},"If the file does not match, stop and fix the share before Apache setup",[11,10433,10435,10439,10441,10444],{"id":10434,"level":14},"step-8-install-apache-php-mysql",[16,10436,10438],{"id":10437},"step-8-install-apache-php-and-mysql","Step 8: Install Apache, PHP, And MySQL",[104,10440,10275],{},[595,10442],{"language":597,"src":10443},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-8-install-apache-ph-09.sh",[20,10445,10446,10452,10457,10463,10469,10475],{},[23,10447,10448,10451],{},[33,10449,10450],{},"apache2",": web server",[23,10453,10454,10456],{},[33,10455,5984],{},": PHP runtime",[23,10458,10459,10462],{},[33,10460,10461],{},"libapache2-mod-php",": lets Apache execute PHP files",[23,10464,10465,10468],{},[33,10466,10467],{},"mysql-server",": local MySQL database server",[23,10470,10471,10474],{},[33,10472,10473],{},"php-mysql",": lets PHP connect to MySQL",[23,10476,784,10477,750,10479,10481],{},[33,10478,10174],{},[33,10480,10180],{}," first only if they have not been run recently",[11,10483,10485,10489,10496],{"id":10484,"level":110},"optional-swap-check",[16,10486,10488],{"id":10487},"optional-add-swap-if-swap-is-off","Optional: Add Swap If Swap Is Off",[104,10490,10491,10492,10495],{},"Ubuntu usually has swap already. Only add this if ",[33,10493,10494],{},"swapon --show"," prints nothing.",[116,10497,10498,10512],{"gap":118,"left-width":717,"right-width":717},[123,10499,10500,10503,10506,10509],{"v-slot:left":125},[104,10501,10502],{},"Check first:",[595,10504],{"language":597,"src":10505},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-add-swap-if-swa-10.sh",[104,10507,10508],{},"Add a small swap file only if swap is off:",[595,10510],{"language":597,"src":10511},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-add-swap-if-swa-11.sh",[123,10513,10514],{"v-slot:right":125},[20,10515,10516,10519,10524,10527],{},[23,10517,10518],{},"Swap gives Ubuntu emergency disk-backed memory",[23,10520,10521,10522],{},"It helps when installs or MySQL briefly need more than ",[33,10523,9117],{},[23,10525,10526],{},"It is slower than RAM, so it is not a performance upgrade",[23,10528,10529],{},"Do not run the setup again if swap already exists",[11,10531,10533,10537,10543],{"id":10532,"level":110},"optional-apache-low-memory",[16,10534,10536],{"id":10535},"optional-limit-apache-memory-use","Optional: Limit Apache Memory Use",[104,10538,10539,10540,10542],{},"Use this if the ",[33,10541,9117],{}," VM feels unstable or Apache starts too many PHP workers.",[116,10544,10545,10558],{"gap":118,"left-width":717,"right-width":717},[123,10546,10547,10550,10555],{"v-slot:left":125},[104,10548,10549],{},"Edit Apache prefork settings in:",[104,10551,10552],{},[33,10553,10554],{},"\u002Fetc\u002Fapache2\u002Fmods-available\u002Fmpm_prefork.conf",[595,10556],{"language":597,"src":10557},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-apache-me-12.sh",[123,10559,10560,10563,10567],{"v-slot:right":125},[104,10561,10562],{},"Change the existing values to:",[595,10564],{"language":10565,"src":10566},"apache","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-apache-me-13.txt",[20,10568,10569,10575,10578,10585],{},[23,10570,10571,10572],{},"Edit the existing lines inside ",[33,10573,10574],{},"\u003CIfModule mpm_prefork_module>",[23,10576,10577],{},"If a line is missing, add it inside that same block",[23,10579,10580,10581,10584],{},"Do not paste a second ",[33,10582,10583],{},"\u003CIfModule>"," block",[23,10586,10587],{},"Restart Apache after config changes",[11,10589,10591,10595,10601],{"id":10590,"level":110},"optional-mysql-low-memory",[16,10592,10594],{"id":10593},"optional-limit-mysql-memory-use","Optional: Limit MySQL Memory Use",[104,10596,10597,10598,10600],{},"Use this only if MySQL struggles on the ",[33,10599,9117],{}," VM.",[116,10602,10603,10616],{"gap":118,"left-width":717,"right-width":717},[123,10604,10605,10608,10613],{"v-slot:left":125},[104,10606,10607],{},"Edit MySQL server settings in:",[104,10609,10610],{},[33,10611,10612],{},"\u002Fetc\u002Fmysql\u002Fmysql.conf.d\u002Fmysqld.cnf",[595,10614],{"language":597,"src":10615},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-mysql-mem-14.sh",[123,10617,10618,10624,10627],{"v-slot:right":125},[104,10619,10620,10621,2157],{},"Add or edit these under ",[33,10622,10623],{},"[mysqld]",[595,10625],{"language":6791,"src":10626},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-mysql-mem-15.txt",[20,10628,10629,10635,10640,10643],{},[23,10630,10631,10632,10634],{},"Keep these under the existing ",[33,10633,10623],{}," heading",[23,10636,10637,10638,10634],{},"Do not create a second ",[33,10639,10623],{},[23,10641,10642],{},"If either setting already exists, edit it instead of adding a duplicate",[23,10644,10645],{},"Restart MySQL after config changes",[11,10647,10649,10652,10655,10658],{"id":10648,"level":110},"low-memory-diagnostics",[16,10650,10651],{"id":10648},"Low Memory Diagnostics",[104,10653,10654],{},"Run these after the minor tuning checks:",[595,10656],{"language":597,"src":10657},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Flow-memory-diagnostics-10.sh",[20,10659,10660,10666,10671,10677,10684],{},[23,10661,10662,10665],{},[33,10663,10664],{},"free -h",": shows RAM and swap",[23,10667,10668,10670],{},[33,10669,10494],{},": confirms whether swap is active",[23,10672,10673,10676],{},[33,10674,10675],{},"systemctl status",": checks whether Apache and MySQL are running",[23,10678,10679,10680,10683],{},"No output from the ",[33,10681,10682],{},"grep"," line is usually good",[23,10685,10686],{},"Do not tune randomly; change one setting, restart, then retest",[11,10688,10690,10694,10696,10699,10702,10705],{"id":10689,"level":14},"step-9-create-local-mysql-db",[16,10691,10693],{"id":10692},"step-9-create-a-local-mysql-database","Step 9: Create A Local MySQL Database",[104,10695,10275],{},[595,10697],{"language":597,"src":10698},"\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",[104,10700,10701],{},"Then run in the MySQL prompt:",[595,10703],{"language":6197,"src":10704},"\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",[20,10706,10707,10711,10714],{},[23,10708,10107,10709,10111],{},[33,10710,10110],{},[23,10712,10713],{},"Database name and username should match your UCID",[23,10715,10716],{},"Password is local-only unless your instructor says otherwise",[11,10718,10720,10723,10726,10739,10742,10748],{"id":10719,"level":14},"local-vs-remote-database",[16,10721,10722],{"id":10719},"Local Vs Remote Database",[104,10724,10725],{},"This MySQL database is only for local testing:",[20,10727,10728,10732,10734,10736],{},[23,10729,5458,10730],{},[33,10731,8814],{},[23,10733,5473],{},[23,10735,5470],{},[23,10737,10738],{},"Password: your local password",[104,10740,10741],{},"Render uses the instructor-provided remote database connection string",[104,10743,10744,10745],{},"Get that string from ",[89,10746,5484],{"href":5484,"rel":10747},[93],[104,10749,10750],{},"After this lesson, you may optionally point local code at that remote database for extra testing",[11,10752,10754,10758,10760,10763,10765,10768,10771],{"id":10753,"level":14},"step-10-confirm-local-mysql",[16,10755,10757],{"id":10756},"step-10-confirm-local-mysql-login","Step 10: Confirm Local MySQL Login",[104,10759,10275],{},[595,10761],{"language":597,"src":10762},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-10-confirm-local-my-13.sh",[104,10764,4970],{},[595,10766],{"language":6197,"src":10767},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-10-confirm-local-my-14.sql",[104,10769,10770],{},"Expected:",[20,10772,10773,10779],{},[23,10774,10775,10778],{},[33,10776,10777],{},"SELECT DATABASE()"," returns your UCID",[23,10780,10781,10784],{},[33,10782,10783],{},"SHOW TABLES"," is empty or shows starter tables later",[11,10786,10788,10794,10797,10800,10803],{"id":10787,"level":14},"step-11-documentroot",[16,10789,10791,10792],{"id":10790},"step-11-point-apache-at-public_html","Step 11: Point Apache At ",[33,10793,1728],{},[104,10795,10796],{},"Apache should serve:",[595,10798],{"language":4324,"src":10799},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-11-point-apache-at--15.txt",[104,10801,10802],{},"Do not serve the whole repo",[20,10804,10805,10814],{},[23,10806,10807,36,10809,40,10811,10813],{},[33,10808,6191],{},[33,10810,6194],{},[33,10812,6197],{}," stay outside the web root",[23,10815,10816,10818],{},[33,10817,1728],{}," is the browser-facing folder",[11,10820,10822,10826,10829,10834,10836,10841,10844,10847],{"id":10821,"level":110},"apache-site-config",[16,10823,10825],{"id":10824},"step-111-apache-site-config","Step 11.1: Apache Site Config",[104,10827,10828],{},"Create or edit this Apache site config file inside Ubuntu:",[104,10830,10831],{},[33,10832,10833],{},"\u002Fetc\u002Fapache2\u002Fsites-available\u002Fit202.conf",[104,10835,637],{},[104,10837,10838],{},[33,10839,10840],{},"sudo nano \u002Fetc\u002Fapache2\u002Fsites-available\u002Fit202.conf",[104,10842,10843],{},"Add this content to that file:",[595,10845],{"language":10565,"src":10846},"\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",[20,10848,10849,10854,10860,10865],{},[23,10850,10107,10851,10853],{},[33,10852,10381],{}," with the actual shared folder name",[23,10855,10856,10857],{},"Save the file as ",[33,10858,10859],{},"it202.conf",[23,10861,10862,10863],{},"Apache listens on guest port ",[33,10864,8596],{},[23,10866,10867,10868],{},"Host browser reaches it through ",[33,10869,8672],{},[11,10871,10873,10877,10879,10882],{"id":10872,"level":110},"enable-site",[16,10874,10876],{"id":10875},"step-112-enable-the-site","Step 11.2: Enable The Site",[104,10878,10275],{},[595,10880],{"language":597,"src":10881},"\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",[20,10883,10884,10890,10896,10902,10910,10916],{},[23,10885,10886,10889],{},[33,10887,10888],{},"a2ensite",": enable a site config",[23,10891,10892,10895],{},[33,10893,10894],{},"a2dissite",": disable a site config",[23,10897,10898,10901],{},[33,10899,10900],{},"www-data",": Apache's user for browser requests",[23,10903,10904,10905,6944,10907,10909],{},"Adding ",[33,10906,10900],{},[33,10908,10346],{}," lets Apache read the shared folder",[23,10911,10912,10915],{},[33,10913,10914],{},"configtest",": check syntax before reload",[23,10917,10918,10921],{},[33,10919,10920],{},"restart",": applies the Apache user group change",[11,10923,10925,10929,10932,10935,10938],{"id":10924,"level":14},"step-12-php-check-page",[16,10926,10928],{"id":10927},"step-12-create-a-php-check-page","Step 12: Create A PHP Check Page",[104,10930,10931],{},"Create this file on the host:",[595,10933],{"language":4324,"src":10934},"\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",[104,10936,10937],{},"Example content:",[595,10939],{"language":5984,"src":10940},"\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,10942,10944,10947,10950,10953,10955],{"id":10943,"level":14},"final-browser-check",[16,10945,10946],{"id":10943},"Final Browser Check",[104,10948,10949],{},"Open from host browser:",[595,10951],{"language":4324,"src":10952},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Ffinal-browser-check-20.txt",[104,10954,10770],{},[20,10956,10957,10960,10963,10966],{},[23,10958,10959],{},"Message appears",[23,10961,10962],{},"Time appears",[23,10964,10965],{},"PHP code is not shown as raw text",[23,10967,10968],{},"Editing the file on host changes output after refresh",[11,10970,10972,10975],{"id":10971,"level":14},"common-problems",[16,10973,10974],{"id":10971},"Common Problems",[20,10976,10977,10980,10983,10988,10991,11004,11014],{},[23,10978,10979],{},"Browser timeout: missing or wrong port-forwarding rule",[23,10981,10982],{},"Connection refused: Apache not running",[23,10984,10985,10986],{},"No internet in VM: check Adapter 1 is still ",[33,10987,9991],{},[23,10989,10990],{},"Shared folder missing: check Auto-mount and guest utilities",[23,10992,10993,10994,10997,10998,11000,11001,11003],{},"Browser shows ",[33,10995,10996],{},"403 Forbidden",": confirm ",[33,10999,10900],{}," is in ",[33,11002,10346],{},", then restart Apache or reboot",[23,11005,11006,11007,11010,11011,11013],{},"Permission denied on ",[33,11008,11009],{},"\u002Fmedia\u002Fsf_...",": confirm your Ubuntu user is in ",[33,11012,10346],{}," and reboot",[23,11015,11016],{},"Raw PHP code: PHP module not running through Apache",[11,11018,11020,11023,11026],{"id":11019,"level":14},"recovery-routine",[16,11021,11022],{"id":11019},"Recovery Routine",[104,11024,11025],{},"Check in this order:",[83,11027,11028,11031,11037,11043,11048,11056,11063,11069,11074,11083],{},[23,11029,11030],{},"VM is running",[23,11032,11033,11036],{},[33,11034,11035],{},"ping github.com"," works inside Ubuntu",[23,11038,11039,11042],{},[33,11040,11041],{},"ssh username@localhost"," works from host",[23,11044,11045,11047],{},[33,11046,10322],{}," shows the shared repo",[23,11049,11050,11053,11054],{},[33,11051,11052],{},"groups"," includes ",[33,11055,10346],{},[23,11057,11058,11053,11061],{},[33,11059,11060],{},"id www-data",[33,11062,10346],{},[23,11064,11065,11068],{},[33,11066,11067],{},"sudo systemctl status apache2"," is active",[23,11070,11071,11068],{},[33,11072,11073],{},"sudo systemctl status mysql",[23,11075,11076,11079,11080],{},[33,11077,11078],{},"sudo apache2ctl configtest"," says ",[33,11081,11082],{},"Syntax OK",[23,11084,11085,11088],{},[33,11086,11087],{},"http:\u002F\u002Flocalhost:3000\u002Fsystem\u002Fvm-check.php"," loads from the host browser",[11,11090,11091,11093],{"id":801,"level":14},[16,11092,802],{"id":801},[116,11094,11095,11136],{"gap":118,"left-width":717,"right-width":717},[123,11096,11097,11099,11105,11114,11119,11125,11131],{"v-slot:left":125},[112,11098,810],{"id":809},[104,11100,11101,11104],{},[814,11102,11103],{},"VM"," - separate computer running inside your host computer",[104,11106,11107,11110,11111,11113],{},[814,11108,11109],{},"Port forwarding"," - host ",[33,11112,8814],{}," traffic routed into the VM",[104,11115,11116,11118],{},[814,11117,10346],{}," - VirtualBox shared-folder permission group",[104,11120,11121,11124],{},[814,11122,11123],{},"Guest utilities"," - VirtualBox tools that help shared folders work inside Ubuntu",[104,11126,11127,11130],{},[814,11128,11129],{},"DocumentRoot"," - folder Apache serves to browsers",[104,11132,11133,11135],{},[814,11134,9991],{}," - VM network mode that gives the VM outbound internet access",[123,11137,11138,11140],{"v-slot:right":125},[112,11139,834],{"id":798},[20,11141,11142,11148,11155,11162,11169,11176,11182],{},[23,11143,11144],{},[89,11145,11147],{"href":8738,"rel":11146},[93],"VirtualBox Downloads",[23,11149,11150],{},[89,11151,11154],{"href":11152,"rel":11153},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002FIntroduction.html",[93],"VirtualBox Manual: Host And Guest Combinations",[23,11156,11157],{},[89,11158,11161],{"href":11159,"rel":11160},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Finstallation.html",[93],"VirtualBox Manual: Installation",[23,11163,11164],{},[89,11165,11168],{"href":11166,"rel":11167},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Fsharedfolders.html",[93],"VirtualBox Manual: Shared Folders",[23,11170,11171],{},[89,11172,11175],{"href":11173,"rel":11174},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Fnetworkingdetails.html#network_nat_service",[93],"VirtualBox Manual: NAT Port Forwarding",[23,11177,11178],{},[89,11179,11181],{"href":8756,"rel":11180},[93],"Ubuntu Server: Installer",[23,11183,11184],{},[89,11185,11188],{"href":11186,"rel":11187},"https:\u002F\u002Fdocumentation.ubuntu.com\u002Fserver\u002Fhow-to\u002Fsecurity\u002Fopenssh-server\u002F",[93],"Ubuntu Server: OpenSSH Server",[11,11190,11191,11193,11195],{"id":865,"level":14},[16,11192,868],{"id":865},[104,11194,2415],{},[20,11196,11197,11200,11203,11206,11209,11214],{},[23,11198,11199],{},"Pick the correct Ubuntu ISO for your host CPU",[23,11201,11202],{},"Configure NAT port forwarding",[23,11204,11205],{},"Connect to Ubuntu with SSH",[23,11207,11208],{},"Find the VirtualBox shared repo",[23,11210,11211,11212],{},"Configure Apache to serve ",[33,11213,1728],{},[23,11215,11216],{},"Create a local MySQL database and user named after your UCID",{"title":125,"searchDepth":895,"depth":895,"links":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,11271,11272,11273,11274,11275,11277,11278,11279,11280,11281,11282,11283,11284],{"id":8618,"depth":895,"text":8610},{"id":8644,"depth":895,"text":8647},{"id":8689,"depth":895,"text":8692},{"id":1544,"depth":895,"text":1547},{"id":8794,"depth":895,"text":8797},{"id":8829,"depth":895,"text":8830},{"id":8853,"depth":895,"text":8856},{"id":8885,"depth":895,"text":8888},{"id":8911,"depth":895,"text":8914},{"id":8940,"depth":895,"text":8943},{"id":8972,"depth":895,"text":8973},{"id":8996,"depth":895,"text":8999},{"id":9027,"depth":895,"text":9030},{"id":9058,"depth":895,"text":9059},{"id":9094,"depth":895,"text":9095},{"id":9156,"depth":895,"text":9159},{"id":9191,"depth":895,"text":9194},{"id":9237,"depth":895,"text":9240},{"id":9280,"depth":895,"text":9283},{"id":9324,"depth":895,"text":9327},{"id":9374,"depth":895,"text":9375},{"id":9437,"depth":895,"text":9438},{"id":9473,"depth":895,"text":9474},{"id":9508,"depth":895,"text":9509},{"id":9545,"depth":895,"text":9546},{"id":9578,"depth":895,"text":9579},{"id":9615,"depth":895,"text":9616},{"id":9648,"depth":895,"text":9649},{"id":9678,"depth":895,"text":9679},{"id":9708,"depth":895,"text":9709},{"id":9738,"depth":895,"text":9739},{"id":9768,"depth":895,"text":9769},{"id":9798,"depth":895,"text":9799},{"id":9832,"depth":895,"text":9833},{"id":9864,"depth":895,"text":9865},{"id":9896,"depth":895,"text":9897},{"id":9928,"depth":895,"text":9929},{"id":9979,"depth":895,"text":9980},{"id":10022,"depth":895,"text":10023},{"id":10048,"depth":895,"text":10049},{"id":10089,"depth":895,"text":10090},{"id":10141,"depth":895,"text":10142},{"id":10220,"depth":895,"text":10221},{"id":10271,"depth":895,"text":10272},{"id":10302,"depth":895,"text":10303},{"id":10332,"depth":895,"text":10333},{"id":10362,"depth":895,"text":10363},{"id":10412,"depth":895,"text":10413},{"id":10437,"depth":895,"text":10438},{"id":10487,"depth":895,"text":10488},{"id":10535,"depth":895,"text":10536},{"id":10593,"depth":895,"text":10594},{"id":10648,"depth":895,"text":10651},{"id":10692,"depth":895,"text":10693},{"id":10719,"depth":895,"text":10722},{"id":10756,"depth":895,"text":10757},{"id":10790,"depth":895,"text":11276},"Step 11: Point Apache At public_html",{"id":10824,"depth":895,"text":10825},{"id":10875,"depth":895,"text":10876},{"id":10927,"depth":895,"text":10928},{"id":10943,"depth":895,"text":10946},{"id":10971,"depth":895,"text":10974},{"id":11019,"depth":895,"text":11022},{"id":801,"depth":895,"text":802},{"id":865,"depth":895,"text":868},"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":8610,"description":11285},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox",[11295,11296,10565,11297,11298],"virtualbox","ubuntu","mysql","vm","1:06:16","ArTDIgihfd4","https:\u002F\u002Fyoutu.be\u002FArTDIgihfd4","IT202 VirtualBox and VM Setup","CNlzYvIiYNPSzbQ6tvCdcnJLlvvGSGmurOGWR_mSnms",[],1780581681049]